/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ahash-0.8.11/src/convert.rs
Line
Count
Source
1
pub(crate) trait Convert<To> {
2
    fn convert(self) -> To;
3
}
4
5
macro_rules! convert {
6
    ($a:ty, $b:ty) => {
7
        impl Convert<$b> for $a {
8
            #[inline(always)]
9
0
            fn convert(self) -> $b {
10
0
                zerocopy::transmute!(self)
11
0
            }
12
        }
13
        impl Convert<$a> for $b {
14
            #[inline(always)]
15
0
            fn convert(self) -> $a {
16
0
                zerocopy::transmute!(self)
17
0
            }
Unexecuted instantiation: _RNvXs8_NtCseb6QmliwlWD_5ahash7convertAyj4_INtB5_7ConvertAoj2_E7convert
Unexecuted instantiation: _RNvXsY_NtCseb6QmliwlWD_5ahash7convertAhj4_INtB5_7ConvertmE7convert
Unexecuted instantiation: _RNvXsQ_NtCseb6QmliwlWD_5ahash7convertAhj8_INtB5_7ConvertyE7convert
Unexecuted instantiation: _RNvXsm_NtCseb6QmliwlWD_5ahash7convertAhj10_INtB5_7ConvertoE7convert
Unexecuted instantiation: _RNvXs12_NtCseb6QmliwlWD_5ahash7convertAhj2_INtB6_7ConverttE7convert
Unexecuted instantiation: _RNvXsg_NtCseb6QmliwlWD_5ahash7convertAyj2_INtB5_7ConvertoE7convert
18
        }
19
    };
20
}
21
22
convert!([u128; 4], [u64; 8]);
23
convert!([u128; 4], [u32; 16]);
24
convert!([u128; 4], [u16; 32]);
25
convert!([u128; 4], [u8; 64]);
26
convert!([u128; 2], [u64; 4]);
27
convert!([u128; 2], [u32; 8]);
28
convert!([u128; 2], [u16; 16]);
29
convert!([u128; 2], [u8; 32]);
30
convert!(u128, [u64; 2]);
31
convert!(u128, [u32; 4]);
32
convert!(u128, [u16; 8]);
33
convert!(u128, [u8; 16]);
34
convert!([u64; 8], [u32; 16]);
35
convert!([u64; 8], [u16; 32]);
36
convert!([u64; 8], [u8; 64]);
37
convert!([u64; 4], [u32; 8]);
38
convert!([u64; 4], [u16; 16]);
39
convert!([u64; 4], [u8; 32]);
40
convert!([u64; 2], [u32; 4]);
41
convert!([u64; 2], [u16; 8]);
42
convert!([u64; 2], [u8; 16]);
43
convert!([u32; 4], [u16; 8]);
44
convert!([u32; 4], [u8; 16]);
45
convert!([u16; 8], [u8; 16]);
46
convert!(u64, [u32; 2]);
47
convert!(u64, [u16; 4]);
48
convert!(u64, [u8; 8]);
49
convert!([u32; 2], [u16; 4]);
50
convert!([u32; 2], [u8; 8]);
51
convert!(u32, [u16; 2]);
52
convert!(u32, [u8; 4]);
53
convert!([u16; 2], [u8; 4]);
54
convert!(u16, [u8; 2]);
55
convert!([[u64; 4]; 2], [u8; 64]);
56
57
convert!([f64; 2], [u8; 16]);
58
convert!([f32; 4], [u8; 16]);
59
convert!(f64, [u8; 8]);
60
convert!([f32; 2], [u8; 8]);
61
convert!(f32, [u8; 4]);
62
63
macro_rules! as_array {
64
    ($input:expr, $len:expr) => {{
65
        {
66
            #[inline(always)]
67
0
            fn as_array<T>(slice: &[T]) -> &[T; $len] {
68
0
                core::convert::TryFrom::try_from(slice).unwrap()
69
0
            }
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice8read_u168as_arrayhEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice8read_u328as_arrayhEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice8read_u648as_arrayhEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice9read_u1288as_arrayhEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice13read_last_u328as_arrayhEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice13read_last_u648as_arrayhEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice14read_last_u1288as_arrayhEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice11read_u128x28as_arraypEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice11read_u128x48as_arraypEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice13read_last_u168as_arraypEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice16read_last_u128x28as_arraypEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice16read_last_u128x48as_arraypEB7_
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice13read_last_u328as_arrayhECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice13read_last_u648as_arrayhECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice14read_last_u1288as_arrayhECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice8read_u168as_arrayhECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice8read_u328as_arrayhECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice8read_u648as_arrayhECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvNvXNtCseb6QmliwlWD_5ahash7convertShNtB5_13ReadFromSlice9read_u1288as_arrayhECs568wuOlRYFZ_8chia_bls
70
            as_array($input)
71
        }
72
    }};
73
}
74
75
pub(crate) trait ReadFromSlice {
76
    fn read_u16(&self) -> (u16, &[u8]);
77
    fn read_u32(&self) -> (u32, &[u8]);
78
    fn read_u64(&self) -> (u64, &[u8]);
79
    fn read_u128(&self) -> (u128, &[u8]);
80
    fn read_u128x2(&self) -> ([u128; 2], &[u8]);
81
    fn read_u128x4(&self) -> ([u128; 4], &[u8]);
82
    fn read_last_u16(&self) -> u16;
83
    fn read_last_u32(&self) -> u32;
84
    fn read_last_u64(&self) -> u64;
85
    fn read_last_u128(&self) -> u128;
86
    fn read_last_u128x2(&self) -> [u128; 2];
87
    fn read_last_u128x4(&self) -> [u128; 4];
88
}
89
90
impl ReadFromSlice for [u8] {
91
    #[inline(always)]
92
0
    fn read_u16(&self) -> (u16, &[u8]) {
93
0
        let (value, rest) = self.split_at(2);
94
0
        (as_array!(value, 2).convert(), rest)
95
0
    }
96
97
    #[inline(always)]
98
0
    fn read_u32(&self) -> (u32, &[u8]) {
99
0
        let (value, rest) = self.split_at(4);
100
0
        (as_array!(value, 4).convert(), rest)
101
0
    }
102
103
    #[inline(always)]
104
0
    fn read_u64(&self) -> (u64, &[u8]) {
105
0
        let (value, rest) = self.split_at(8);
106
0
        (as_array!(value, 8).convert(), rest)
107
0
    }
108
109
    #[inline(always)]
110
0
    fn read_u128(&self) -> (u128, &[u8]) {
111
0
        let (value, rest) = self.split_at(16);
112
0
        (as_array!(value, 16).convert(), rest)
113
0
    }
114
115
    #[inline(always)]
116
    fn read_u128x2(&self) -> ([u128; 2], &[u8]) {
117
        let (value, rest) = self.split_at(32);
118
        (as_array!(value, 32).convert(), rest)
119
    }
120
121
    #[inline(always)]
122
    fn read_u128x4(&self) -> ([u128; 4], &[u8]) {
123
        let (value, rest) = self.split_at(64);
124
        (as_array!(value, 64).convert(), rest)
125
    }
126
127
    #[inline(always)]
128
    fn read_last_u16(&self) -> u16 {
129
        let (_, value) = self.split_at(self.len() - 2);
130
        as_array!(value, 2).convert()
131
    }
132
133
    #[inline(always)]
134
0
    fn read_last_u32(&self) -> u32 {
135
0
        let (_, value) = self.split_at(self.len() - 4);
136
0
        as_array!(value, 4).convert()
137
0
    }
138
139
    #[inline(always)]
140
0
    fn read_last_u64(&self) -> u64 {
141
0
        let (_, value) = self.split_at(self.len() - 8);
142
0
        as_array!(value, 8).convert()
143
0
    }
144
145
    #[inline(always)]
146
0
    fn read_last_u128(&self) -> u128 {
147
0
        let (_, value) = self.split_at(self.len() - 16);
148
0
        as_array!(value, 16).convert()
149
0
    }
150
151
    #[inline(always)]
152
    fn read_last_u128x2(&self) -> [u128; 2] {
153
        let (_, value) = self.split_at(self.len() - 32);
154
        as_array!(value, 32).convert()
155
    }
156
157
    #[inline(always)]
158
    fn read_last_u128x4(&self) -> [u128; 4] {
159
        let (_, value) = self.split_at(self.len() - 64);
160
        as_array!(value, 64).convert()
161
    }
162
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ahash-0.8.11/src/fallback_hash.rs
Line
Count
Source
1
use crate::convert::*;
2
use crate::operations::folded_multiply;
3
use crate::operations::read_small;
4
use crate::operations::MULTIPLE;
5
use crate::random_state::PI;
6
use crate::RandomState;
7
use core::hash::Hasher;
8
9
const ROT: u32 = 23; //17
10
11
/// A `Hasher` for hashing an arbitrary stream of bytes.
12
///
13
/// Instances of [`AHasher`] represent state that is updated while hashing data.
14
///
15
/// Each method updates the internal state based on the new data provided. Once
16
/// all of the data has been provided, the resulting hash can be obtained by calling
17
/// `finish()`
18
///
19
/// [Clone] is also provided in case you wish to calculate hashes for two different items that
20
/// start with the same data.
21
///
22
#[derive(Debug, Clone)]
23
pub struct AHasher {
24
    buffer: u64,
25
    pad: u64,
26
    extra_keys: [u64; 2],
27
}
28
29
impl AHasher {
30
    /// Creates a new hasher keyed to the provided key.
31
    #[inline]
32
    #[allow(dead_code)] // Is not called if non-fallback hash is used.
33
0
    pub(crate) fn new_with_keys(key1: u128, key2: u128) -> AHasher {
34
0
        let pi: [u128; 2] = PI.convert();
35
0
        let key1: [u64; 2] = (key1 ^ pi[0]).convert();
36
0
        let key2: [u64; 2] = (key2 ^ pi[1]).convert();
37
0
        AHasher {
38
0
            buffer: key1[0],
39
0
            pad: key1[1],
40
0
            extra_keys: key2,
41
0
        }
42
0
    }
43
44
    #[allow(unused)] // False positive
45
0
    pub(crate) fn test_with_keys(key1: u128, key2: u128) -> Self {
46
0
        let key1: [u64; 2] = key1.convert();
47
0
        let key2: [u64; 2] = key2.convert();
48
0
        Self {
49
0
            buffer: key1[0],
50
0
            pad: key1[1],
51
0
            extra_keys: key2,
52
0
        }
53
0
    }
54
55
    #[inline]
56
    #[allow(dead_code)] // Is not called if non-fallback hash is used.
57
0
    pub(crate) fn from_random_state(rand_state: &RandomState) -> AHasher {
58
0
        AHasher {
59
0
            buffer: rand_state.k1,
60
0
            pad: rand_state.k0,
61
0
            extra_keys: [rand_state.k2, rand_state.k3],
62
0
        }
63
0
    }
Unexecuted instantiation: _RNvMNtCseb6QmliwlWD_5ahash13fallback_hashNtB2_7AHasher17from_random_stateB4_
Unexecuted instantiation: _RNvMNtCseb6QmliwlWD_5ahash13fallback_hashNtB2_7AHasher17from_random_stateCs568wuOlRYFZ_8chia_bls
64
65
    /// This update function has the goal of updating the buffer with a single multiply
66
    /// FxHash does this but is vulnerable to attack. To avoid this input needs to be masked to with an
67
    /// unpredictable value. Other hashes such as murmurhash have taken this approach but were found vulnerable
68
    /// to attack. The attack was based on the idea of reversing the pre-mixing (Which is necessarily
69
    /// reversible otherwise bits would be lost) then placing a difference in the highest bit before the
70
    /// multiply used to mix the data. Because a multiply can never affect the bits to the right of it, a
71
    /// subsequent update that also differed in this bit could result in a predictable collision.
72
    ///
73
    /// This version avoids this vulnerability while still only using a single multiply. It takes advantage
74
    /// of the fact that when a 64 bit multiply is performed the upper 64 bits are usually computed and thrown
75
    /// away. Instead it creates two 128 bit values where the upper 64 bits are zeros and multiplies them.
76
    /// (The compiler is smart enough to turn this into a 64 bit multiplication in the assembly)
77
    /// Then the upper bits are xored with the lower bits to produce a single 64 bit result.
78
    ///
79
    /// To understand why this is a good scrambling function it helps to understand multiply-with-carry PRNGs:
80
    /// https://en.wikipedia.org/wiki/Multiply-with-carry_pseudorandom_number_generator
81
    /// If the multiple is chosen well, this creates a long period, decent quality PRNG.
82
    /// Notice that this function is equivalent to this except the `buffer`/`state` is being xored with each
83
    /// new block of data. In the event that data is all zeros, it is exactly equivalent to a MWC PRNG.
84
    ///
85
    /// This is impervious to attack because every bit buffer at the end is dependent on every bit in
86
    /// `new_data ^ buffer`. For example suppose two inputs differed in only the 5th bit. Then when the
87
    /// multiplication is performed the `result` will differ in bits 5-69. More specifically it will differ by
88
    /// 2^5 * MULTIPLE. However in the next step bits 65-128 are turned into a separate 64 bit value. So the
89
    /// differing bits will be in the lower 6 bits of this value. The two intermediate values that differ in
90
    /// bits 5-63 and in bits 0-5 respectively get added together. Producing an output that differs in every
91
    /// bit. The addition carries in the multiplication and at the end additionally mean that the even if an
92
    /// attacker somehow knew part of (but not all) the contents of the buffer before hand,
93
    /// they would not be able to predict any of the bits in the buffer at the end.
94
    #[inline(always)]
95
0
    fn update(&mut self, new_data: u64) {
96
0
        self.buffer = folded_multiply(new_data ^ self.buffer, MULTIPLE);
97
0
    }
98
99
    /// Similar to the above this function performs an update using a "folded multiply".
100
    /// However it takes in 128 bits of data instead of 64. Both halves must be masked.
101
    ///
102
    /// This makes it impossible for an attacker to place a single bit difference between
103
    /// two blocks so as to cancel each other.
104
    ///
105
    /// However this is not sufficient. to prevent (a,b) from hashing the same as (b,a) the buffer itself must
106
    /// be updated between calls in a way that does not commute. To achieve this XOR and Rotate are used.
107
    /// Add followed by xor is not the same as xor followed by add, and rotate ensures that the same out bits
108
    /// can't be changed by the same set of input bits. To cancel this sequence with subsequent input would require
109
    /// knowing the keys.
110
    #[inline(always)]
111
0
    fn large_update(&mut self, new_data: u128) {
112
0
        let block: [u64; 2] = new_data.convert();
113
0
        let combined = folded_multiply(block[0] ^ self.extra_keys[0], block[1] ^ self.extra_keys[1]);
114
0
        self.buffer = (self.buffer.wrapping_add(self.pad) ^ combined).rotate_left(ROT);
115
0
    }
116
117
    #[inline]
118
    #[cfg(feature = "specialize")]
119
0
    fn short_finish(&self) -> u64 {
120
0
        folded_multiply(self.buffer, self.pad)
121
0
    }
122
}
123
124
/// Provides [Hasher] methods to hash all of the primitive types.
125
///
126
/// [Hasher]: core::hash::Hasher
127
impl Hasher for AHasher {
128
    #[inline]
129
0
    fn write_u8(&mut self, i: u8) {
130
0
        self.update(i as u64);
131
0
    }
132
133
    #[inline]
134
0
    fn write_u16(&mut self, i: u16) {
135
0
        self.update(i as u64);
136
0
    }
137
138
    #[inline]
139
0
    fn write_u32(&mut self, i: u32) {
140
0
        self.update(i as u64);
141
0
    }
142
143
    #[inline]
144
0
    fn write_u64(&mut self, i: u64) {
145
0
        self.update(i as u64);
146
0
    }
Unexecuted instantiation: _RNvXs_NtCseb6QmliwlWD_5ahash13fallback_hashNtB4_7AHasherNtNtCsbQ8arDwx5Xq_4core4hash6Hasher9write_u64B6_
Unexecuted instantiation: _RNvXs_NtCseb6QmliwlWD_5ahash13fallback_hashNtB4_7AHasherNtNtCsbQ8arDwx5Xq_4core4hash6Hasher9write_u64Cs568wuOlRYFZ_8chia_bls
147
148
    #[inline]
149
0
    fn write_u128(&mut self, i: u128) {
150
0
        self.large_update(i);
151
0
    }
152
153
    #[inline]
154
    #[cfg(any(
155
        target_pointer_width = "64",
156
        target_pointer_width = "32",
157
        target_pointer_width = "16"
158
    ))]
159
0
    fn write_usize(&mut self, i: usize) {
160
0
        self.write_u64(i as u64);
161
0
    }
Unexecuted instantiation: _RNvXs_NtCseb6QmliwlWD_5ahash13fallback_hashNtB4_7AHasherNtNtCsbQ8arDwx5Xq_4core4hash6Hasher11write_usizeB6_
Unexecuted instantiation: _RNvXs_NtCseb6QmliwlWD_5ahash13fallback_hashNtB4_7AHasherNtNtCsbQ8arDwx5Xq_4core4hash6Hasher11write_usizeCs568wuOlRYFZ_8chia_bls
162
163
    #[inline]
164
    #[cfg(target_pointer_width = "128")]
165
    fn write_usize(&mut self, i: usize) {
166
        self.write_u128(i as u128);
167
    }
168
169
    #[inline]
170
    #[allow(clippy::collapsible_if)]
171
0
    fn write(&mut self, input: &[u8]) {
172
0
        let mut data = input;
173
0
        let length = data.len() as u64;
174
0
        //Needs to be an add rather than an xor because otherwise it could be canceled with carefully formed input.
175
0
        self.buffer = self.buffer.wrapping_add(length).wrapping_mul(MULTIPLE);
176
0
        //A 'binary search' on sizes reduces the number of comparisons.
177
0
        if data.len() > 8 {
178
0
            if data.len() > 16 {
179
0
                let tail = data.read_last_u128();
180
0
                self.large_update(tail);
181
0
                while data.len() > 16 {
182
0
                    let (block, rest) = data.read_u128();
183
0
                    self.large_update(block);
184
0
                    data = rest;
185
0
                }
186
0
            } else {
187
0
                self.large_update([data.read_u64().0, data.read_last_u64()].convert());
188
0
            }
189
0
        } else {
190
0
            let value = read_small(data);
191
0
            self.large_update(value.convert());
192
0
        }
193
0
    }
Unexecuted instantiation: _RNvXs_NtCseb6QmliwlWD_5ahash13fallback_hashNtB4_7AHasherNtNtCsbQ8arDwx5Xq_4core4hash6Hasher5writeB6_
Unexecuted instantiation: _RNvXs_NtCseb6QmliwlWD_5ahash13fallback_hashNtB4_7AHasherNtNtCsbQ8arDwx5Xq_4core4hash6Hasher5writeCs568wuOlRYFZ_8chia_bls
194
195
    #[inline]
196
0
    fn finish(&self) -> u64 {
197
0
        let rot = (self.buffer & 63) as u32;
198
0
        folded_multiply(self.buffer, self.pad).rotate_left(rot)
199
0
    }
Unexecuted instantiation: _RNvXs_NtCseb6QmliwlWD_5ahash13fallback_hashNtB4_7AHasherNtNtCsbQ8arDwx5Xq_4core4hash6Hasher6finishB6_
Unexecuted instantiation: _RNvXs_NtCseb6QmliwlWD_5ahash13fallback_hashNtB4_7AHasherNtNtCsbQ8arDwx5Xq_4core4hash6Hasher6finishCs568wuOlRYFZ_8chia_bls
200
}
201
202
#[cfg(feature = "specialize")]
203
pub(crate) struct AHasherU64 {
204
    pub(crate) buffer: u64,
205
    pub(crate) pad: u64,
206
}
207
208
/// A specialized hasher for only primitives under 64 bits.
209
#[cfg(feature = "specialize")]
210
impl Hasher for AHasherU64 {
211
    #[inline]
212
0
    fn finish(&self) -> u64 {
213
0
        folded_multiply(self.buffer, self.pad)
214
0
        //self.buffer
215
0
    }
216
217
    #[inline]
218
0
    fn write(&mut self, _bytes: &[u8]) {
219
0
        unreachable!("Specialized hasher was called with a different type of object")
220
    }
221
222
    #[inline]
223
0
    fn write_u8(&mut self, i: u8) {
224
0
        self.write_u64(i as u64);
225
0
    }
226
227
    #[inline]
228
0
    fn write_u16(&mut self, i: u16) {
229
0
        self.write_u64(i as u64);
230
0
    }
231
232
    #[inline]
233
0
    fn write_u32(&mut self, i: u32) {
234
0
        self.write_u64(i as u64);
235
0
    }
236
237
    #[inline]
238
0
    fn write_u64(&mut self, i: u64) {
239
0
        self.buffer = folded_multiply(i ^ self.buffer, MULTIPLE);
240
0
    }
241
242
    #[inline]
243
0
    fn write_u128(&mut self, _i: u128) {
244
0
        unreachable!("Specialized hasher was called with a different type of object")
245
    }
246
247
    #[inline]
248
0
    fn write_usize(&mut self, _i: usize) {
249
0
        unreachable!("Specialized hasher was called with a different type of object")
250
    }
251
}
252
253
#[cfg(feature = "specialize")]
254
pub(crate) struct AHasherFixed(pub AHasher);
255
256
/// A specialized hasher for fixed size primitives larger than 64 bits.
257
#[cfg(feature = "specialize")]
258
impl Hasher for AHasherFixed {
259
    #[inline]
260
0
    fn finish(&self) -> u64 {
261
0
        self.0.short_finish()
262
0
    }
263
264
    #[inline]
265
0
    fn write(&mut self, bytes: &[u8]) {
266
0
        self.0.write(bytes)
267
0
    }
268
269
    #[inline]
270
0
    fn write_u8(&mut self, i: u8) {
271
0
        self.write_u64(i as u64);
272
0
    }
273
274
    #[inline]
275
0
    fn write_u16(&mut self, i: u16) {
276
0
        self.write_u64(i as u64);
277
0
    }
278
279
    #[inline]
280
0
    fn write_u32(&mut self, i: u32) {
281
0
        self.write_u64(i as u64);
282
0
    }
283
284
    #[inline]
285
0
    fn write_u64(&mut self, i: u64) {
286
0
        self.0.write_u64(i);
287
0
    }
288
289
    #[inline]
290
0
    fn write_u128(&mut self, i: u128) {
291
0
        self.0.write_u128(i);
292
0
    }
293
294
    #[inline]
295
0
    fn write_usize(&mut self, i: usize) {
296
0
        self.0.write_usize(i);
297
0
    }
298
}
299
300
#[cfg(feature = "specialize")]
301
pub(crate) struct AHasherStr(pub AHasher);
302
303
/// A specialized hasher for a single string
304
/// Note that the other types don't panic because the hash impl for String tacks on an unneeded call. (As does vec)
305
#[cfg(feature = "specialize")]
306
impl Hasher for AHasherStr {
307
    #[inline]
308
0
    fn finish(&self) -> u64 {
309
0
        self.0.finish()
310
0
    }
311
312
    #[inline]
313
0
    fn write(&mut self, bytes: &[u8]) {
314
0
        if bytes.len() > 8 {
315
0
            self.0.write(bytes)
316
0
        } else {
317
0
            let value = read_small(bytes);
318
0
            self.0.buffer = folded_multiply(value[0] ^ self.0.buffer, value[1] ^ self.0.extra_keys[1]);
319
0
            self.0.pad = self.0.pad.wrapping_add(bytes.len() as u64);
320
0
        }
321
0
    }
322
323
    #[inline]
324
0
    fn write_u8(&mut self, _i: u8) {}
325
326
    #[inline]
327
0
    fn write_u16(&mut self, _i: u16) {}
328
329
    #[inline]
330
0
    fn write_u32(&mut self, _i: u32) {}
331
332
    #[inline]
333
0
    fn write_u64(&mut self, _i: u64) {}
334
335
    #[inline]
336
0
    fn write_u128(&mut self, _i: u128) {}
337
338
    #[inline]
339
0
    fn write_usize(&mut self, _i: usize) {}
340
}
341
342
#[cfg(test)]
343
mod tests {
344
    use crate::fallback_hash::*;
345
346
    #[test]
347
    fn test_hash() {
348
        let mut hasher = AHasher::new_with_keys(0, 0);
349
        let value: u64 = 1 << 32;
350
        hasher.update(value);
351
        let result = hasher.buffer;
352
        let mut hasher = AHasher::new_with_keys(0, 0);
353
        let value2: u64 = 1;
354
        hasher.update(value2);
355
        let result2 = hasher.buffer;
356
        let result: [u8; 8] = result.convert();
357
        let result2: [u8; 8] = result2.convert();
358
        assert_ne!(hex::encode(result), hex::encode(result2));
359
    }
360
361
    #[test]
362
    fn test_conversion() {
363
        let input: &[u8] = "dddddddd".as_bytes();
364
        let bytes: u64 = as_array!(input, 8).convert();
365
        assert_eq!(bytes, 0x6464646464646464);
366
    }
367
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ahash-0.8.11/src/lib.rs
Line
Count
Source
1
//! AHash is a high performance keyed hash function.
2
//!
3
//! It quickly provides a high quality hash where the result is not predictable without knowing the Key.
4
//! AHash works with `HashMap` to hash keys, but without allowing for the possibility that an malicious user can
5
//! induce a collision.
6
//!
7
//! # How aHash works
8
//!
9
//! When it is available aHash uses the hardware AES instructions to provide a keyed hash function.
10
//! When it is not, aHash falls back on a slightly slower alternative algorithm.
11
//!
12
//! Because aHash does not have a fixed standard for its output, it is able to improve over time.
13
//! But this also means that different computers or computers using different versions of ahash may observe different
14
//! hash values for the same input.
15
#![cfg_attr(
16
    all(
17
        feature = "std",
18
        any(feature = "compile-time-rng", feature = "runtime-rng", feature = "no-rng")
19
    ),
20
    doc = r##"
21
# Basic Usage
22
AHash provides an implementation of the [Hasher] trait.
23
To construct a HashMap using aHash as its hasher do the following:
24
```
25
use ahash::{AHasher, RandomState};
26
use std::collections::HashMap;
27
28
let mut map: HashMap<i32, i32, RandomState> = HashMap::default();
29
map.insert(12, 34);
30
```
31
32
### Randomness
33
34
The above requires a source of randomness to generate keys for the hashmap. By default this obtained from the OS.
35
It is also possible to have randomness supplied via the `compile-time-rng` flag, or manually.
36
37
### If randomess is not available
38
39
[AHasher::default()] can be used to hash using fixed keys. This works with
40
[BuildHasherDefault](std::hash::BuildHasherDefault). For example:
41
42
```
43
use std::hash::BuildHasherDefault;
44
use std::collections::HashMap;
45
use ahash::AHasher;
46
47
let mut m: HashMap<_, _, BuildHasherDefault<AHasher>> = HashMap::default();
48
 # m.insert(12, 34);
49
```
50
It is also possible to instantiate [RandomState] directly:
51
52
```
53
use ahash::HashMap;
54
use ahash::RandomState;
55
56
let mut m = HashMap::with_hasher(RandomState::with_seed(42));
57
 # m.insert(1, 2);
58
```
59
Or for uses besides a hashhmap:
60
```
61
use std::hash::BuildHasher;
62
use ahash::RandomState;
63
64
let hash_builder = RandomState::with_seed(42);
65
let hash = hash_builder.hash_one("Some Data");
66
```
67
There are several constructors for [RandomState] with different ways to supply seeds.
68
69
# Convenience wrappers
70
71
For convenience, both new-type wrappers and type aliases are provided.
72
73
The new type wrappers are called called `AHashMap` and `AHashSet`.
74
```
75
use ahash::AHashMap;
76
77
let mut map: AHashMap<i32, i32> = AHashMap::new();
78
map.insert(12, 34);
79
```
80
This avoids the need to type "RandomState". (For convenience `From`, `Into`, and `Deref` are provided).
81
82
# Aliases
83
84
For even less typing and better interop with existing libraries (such as rayon) which require a `std::collection::HashMap` ,
85
the type aliases [HashMap], [HashSet] are provided.
86
87
```
88
use ahash::{HashMap, HashMapExt};
89
90
let mut map: HashMap<i32, i32> = HashMap::new();
91
map.insert(12, 34);
92
```
93
Note the import of [HashMapExt]. This is needed for the constructor.
94
95
"##
96
)]
97
#![deny(clippy::correctness, clippy::complexity, clippy::perf)]
98
#![allow(clippy::pedantic, clippy::cast_lossless, clippy::unreadable_literal)]
99
#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
100
#![cfg_attr(feature = "specialize", feature(min_specialization))]
101
#![cfg_attr(feature = "nightly-arm-aes", feature(stdarch_arm_neon_intrinsics))]
102
103
#[macro_use]
104
mod convert;
105
106
mod fallback_hash;
107
108
cfg_if::cfg_if! {
109
    if #[cfg(any(
110
            all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)),
111
            all(feature = "nightly-arm-aes", target_arch = "aarch64", target_feature = "aes", not(miri)),
112
            all(feature = "nightly-arm-aes", target_arch = "arm", target_feature = "aes", not(miri)),
113
        ))] {
114
        mod aes_hash;
115
        pub use crate::aes_hash::AHasher;
116
    } else {
117
        pub use crate::fallback_hash::AHasher;
118
    }
119
}
120
121
cfg_if::cfg_if! {
122
    if #[cfg(feature = "std")] {
123
        mod hash_map;
124
        mod hash_set;
125
126
        pub use crate::hash_map::AHashMap;
127
        pub use crate::hash_set::AHashSet;
128
129
        /// [Hasher]: std::hash::Hasher
130
        /// [HashMap]: std::collections::HashMap
131
        /// Type alias for [HashMap]<K, V, ahash::RandomState>
132
        pub type HashMap<K, V> = std::collections::HashMap<K, V, crate::RandomState>;
133
134
        /// Type alias for [HashSet]<K, ahash::RandomState>
135
        pub type HashSet<K> = std::collections::HashSet<K, crate::RandomState>;
136
    }
137
}
138
139
#[cfg(test)]
140
mod hash_quality_test;
141
142
mod operations;
143
pub mod random_state;
144
mod specialize;
145
146
pub use crate::random_state::RandomState;
147
148
use core::hash::BuildHasher;
149
use core::hash::Hash;
150
use core::hash::Hasher;
151
152
#[cfg(feature = "std")]
153
/// A convenience trait that can be used together with the type aliases defined to
154
/// get access to the `new()` and `with_capacity()` methods for the HashMap type alias.
155
pub trait HashMapExt {
156
    /// Constructs a new HashMap
157
    fn new() -> Self;
158
    /// Constructs a new HashMap with a given initial capacity
159
    fn with_capacity(capacity: usize) -> Self;
160
}
161
162
#[cfg(feature = "std")]
163
/// A convenience trait that can be used together with the type aliases defined to
164
/// get access to the `new()` and `with_capacity()` methods for the HashSet type aliases.
165
pub trait HashSetExt {
166
    /// Constructs a new HashSet
167
    fn new() -> Self;
168
    /// Constructs a new HashSet with a given initial capacity
169
    fn with_capacity(capacity: usize) -> Self;
170
}
171
172
#[cfg(feature = "std")]
173
impl<K, V, S> HashMapExt for std::collections::HashMap<K, V, S>
174
where
175
    S: BuildHasher + Default,
176
{
177
    fn new() -> Self {
178
        std::collections::HashMap::with_hasher(S::default())
179
    }
180
181
    fn with_capacity(capacity: usize) -> Self {
182
        std::collections::HashMap::with_capacity_and_hasher(capacity, S::default())
183
    }
184
}
185
186
#[cfg(feature = "std")]
187
impl<K, S> HashSetExt for std::collections::HashSet<K, S>
188
where
189
    S: BuildHasher + Default,
190
{
191
    fn new() -> Self {
192
        std::collections::HashSet::with_hasher(S::default())
193
    }
194
195
    fn with_capacity(capacity: usize) -> Self {
196
        std::collections::HashSet::with_capacity_and_hasher(capacity, S::default())
197
    }
198
}
199
200
/// Provides a default [Hasher] with fixed keys.
201
/// This is typically used in conjunction with [BuildHasherDefault] to create
202
/// [AHasher]s in order to hash the keys of the map.
203
///
204
/// Generally it is preferable to use [RandomState] instead, so that different
205
/// hashmaps will have different keys. However if fixed keys are desirable this
206
/// may be used instead.
207
///
208
/// # Example
209
/// ```
210
/// use std::hash::BuildHasherDefault;
211
/// use ahash::{AHasher, RandomState};
212
/// use std::collections::HashMap;
213
///
214
/// let mut map: HashMap<i32, i32, BuildHasherDefault<AHasher>> = HashMap::default();
215
/// map.insert(12, 34);
216
/// ```
217
///
218
/// [BuildHasherDefault]: std::hash::BuildHasherDefault
219
/// [Hasher]: std::hash::Hasher
220
/// [HashMap]: std::collections::HashMap
221
impl Default for AHasher {
222
    /// Constructs a new [AHasher] with fixed keys.
223
    /// If `std` is enabled these will be generated upon first invocation.
224
    /// Otherwise if the `compile-time-rng`feature is enabled these will be generated at compile time.
225
    /// If neither of these features are available, hardcoded constants will be used.
226
    ///
227
    /// Because the values are fixed, different hashers will all hash elements the same way.
228
    /// This could make hash values predictable, if DOS attacks are a concern. If this behaviour is
229
    /// not required, it may be preferable to use [RandomState] instead.
230
    ///
231
    /// # Examples
232
    ///
233
    /// ```
234
    /// use ahash::AHasher;
235
    /// use std::hash::Hasher;
236
    ///
237
    /// let mut hasher_1 = AHasher::default();
238
    /// let mut hasher_2 = AHasher::default();
239
    ///
240
    /// hasher_1.write_u32(1234);
241
    /// hasher_2.write_u32(1234);
242
    ///
243
    /// assert_eq!(hasher_1.finish(), hasher_2.finish());
244
    /// ```
245
    #[inline]
246
0
    fn default() -> AHasher {
247
0
        RandomState::with_fixed_keys().build_hasher()
248
0
    }
Unexecuted instantiation: _RNvXCseb6QmliwlWD_5ahashNtNtB2_13fallback_hash7AHasherNtNtCsbQ8arDwx5Xq_4core7default7Default7defaultB2_
Unexecuted instantiation: _RNvXCseb6QmliwlWD_5ahashNtNtB2_13fallback_hash7AHasherNtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs568wuOlRYFZ_8chia_bls
249
}
250
251
/// Used for specialization. (Sealed)
252
pub(crate) trait BuildHasherExt: BuildHasher {
253
    #[doc(hidden)]
254
    fn hash_as_u64<T: Hash + ?Sized>(&self, value: &T) -> u64;
255
256
    #[doc(hidden)]
257
    fn hash_as_fixed_length<T: Hash + ?Sized>(&self, value: &T) -> u64;
258
259
    #[doc(hidden)]
260
    fn hash_as_str<T: Hash + ?Sized>(&self, value: &T) -> u64;
261
}
262
263
impl<B: BuildHasher> BuildHasherExt for B {
264
    #[inline]
265
    #[cfg(feature = "specialize")]
266
0
    default fn hash_as_u64<T: Hash + ?Sized>(&self, value: &T) -> u64 {
267
0
        let mut hasher = self.build_hasher();
268
0
        value.hash(&mut hasher);
269
0
        hasher.finish()
270
0
    }
271
    #[inline]
272
    #[cfg(not(feature = "specialize"))]
273
    fn hash_as_u64<T: Hash + ?Sized>(&self, value: &T) -> u64 {
274
        let mut hasher = self.build_hasher();
275
        value.hash(&mut hasher);
276
        hasher.finish()
277
    }
278
    #[inline]
279
    #[cfg(feature = "specialize")]
280
0
    default fn hash_as_fixed_length<T: Hash + ?Sized>(&self, value: &T) -> u64 {
281
0
        let mut hasher = self.build_hasher();
282
0
        value.hash(&mut hasher);
283
0
        hasher.finish()
284
0
    }
285
    #[inline]
286
    #[cfg(not(feature = "specialize"))]
287
    fn hash_as_fixed_length<T: Hash + ?Sized>(&self, value: &T) -> u64 {
288
        let mut hasher = self.build_hasher();
289
        value.hash(&mut hasher);
290
        hasher.finish()
291
    }
292
    #[inline]
293
    #[cfg(feature = "specialize")]
294
0
    default fn hash_as_str<T: Hash + ?Sized>(&self, value: &T) -> u64 {
295
0
        let mut hasher = self.build_hasher();
296
0
        value.hash(&mut hasher);
297
0
        hasher.finish()
298
0
    }
299
    #[inline]
300
    #[cfg(not(feature = "specialize"))]
301
    fn hash_as_str<T: Hash + ?Sized>(&self, value: &T) -> u64 {
302
        let mut hasher = self.build_hasher();
303
        value.hash(&mut hasher);
304
        hasher.finish()
305
    }
306
}
307
308
// #[inline(never)]
309
// #[doc(hidden)]
310
// pub fn hash_test(input: &[u8]) -> u64 {
311
//     let a = RandomState::with_seeds(11, 22, 33, 44);
312
//     <[u8]>::get_hash(input, &a)
313
// }
314
315
#[cfg(feature = "std")]
316
#[cfg(test)]
317
mod test {
318
    use crate::convert::Convert;
319
    use crate::specialize::CallHasher;
320
    use crate::*;
321
    use std::collections::HashMap;
322
323
    #[test]
324
    fn test_ahash_alias_map_construction() {
325
        let mut map = super::HashMap::with_capacity(1234);
326
        map.insert(1, "test");
327
    }
328
329
    #[test]
330
    fn test_ahash_alias_set_construction() {
331
        let mut set = super::HashSet::with_capacity(1234);
332
        set.insert(1);
333
    }
334
335
    #[test]
336
    fn test_default_builder() {
337
        use core::hash::BuildHasherDefault;
338
339
        let mut map = HashMap::<u32, u64, BuildHasherDefault<AHasher>>::default();
340
        map.insert(1, 3);
341
    }
342
343
    #[test]
344
    fn test_builder() {
345
        let mut map = HashMap::<u32, u64, RandomState>::default();
346
        map.insert(1, 3);
347
    }
348
349
    #[test]
350
    fn test_conversion() {
351
        let input: &[u8] = b"dddddddd";
352
        let bytes: u64 = as_array!(input, 8).convert();
353
        assert_eq!(bytes, 0x6464646464646464);
354
    }
355
356
    #[test]
357
    fn test_non_zero() {
358
        let mut hasher1 = AHasher::new_with_keys(0, 0);
359
        let mut hasher2 = AHasher::new_with_keys(0, 0);
360
        "foo".hash(&mut hasher1);
361
        "bar".hash(&mut hasher2);
362
        assert_ne!(hasher1.finish(), 0);
363
        assert_ne!(hasher2.finish(), 0);
364
        assert_ne!(hasher1.finish(), hasher2.finish());
365
366
        let mut hasher1 = AHasher::new_with_keys(0, 0);
367
        let mut hasher2 = AHasher::new_with_keys(0, 0);
368
        3_u64.hash(&mut hasher1);
369
        4_u64.hash(&mut hasher2);
370
        assert_ne!(hasher1.finish(), 0);
371
        assert_ne!(hasher2.finish(), 0);
372
        assert_ne!(hasher1.finish(), hasher2.finish());
373
    }
374
375
    #[test]
376
    fn test_non_zero_specialized() {
377
        let hasher_build = RandomState::with_seeds(0, 0, 0, 0);
378
379
        let h1 = str::get_hash("foo", &hasher_build);
380
        let h2 = str::get_hash("bar", &hasher_build);
381
        assert_ne!(h1, 0);
382
        assert_ne!(h2, 0);
383
        assert_ne!(h1, h2);
384
385
        let h1 = u64::get_hash(&3_u64, &hasher_build);
386
        let h2 = u64::get_hash(&4_u64, &hasher_build);
387
        assert_ne!(h1, 0);
388
        assert_ne!(h2, 0);
389
        assert_ne!(h1, h2);
390
    }
391
392
    #[test]
393
    fn test_ahasher_construction() {
394
        let _ = AHasher::new_with_keys(1234, 5678);
395
    }
396
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ahash-0.8.11/src/operations.rs
Line
Count
Source
1
use crate::convert::*;
2
#[allow(unused)]
3
use zerocopy::transmute;
4
5
///This constant comes from Kunth's prng (Empirically it works better than those from splitmix32).
6
pub(crate) const MULTIPLE: u64 = 6364136223846793005;
7
8
/// This is a constant with a lot of special properties found by automated search.
9
/// See the unit tests below. (Below are alternative values)
10
#[cfg(all(target_feature = "ssse3", not(miri)))]
11
const SHUFFLE_MASK: u128 = 0x020a0700_0c01030e_050f0d08_06090b04_u128;
12
//const SHUFFLE_MASK: u128 = 0x000d0702_0a040301_05080f0c_0e0b0609_u128;
13
//const SHUFFLE_MASK: u128 = 0x040A0700_030E0106_0D050F08_020B0C09_u128;
14
15
#[inline(always)]
16
#[cfg(feature = "folded_multiply")]
17
0
pub(crate) const fn folded_multiply(s: u64, by: u64) -> u64 {
18
0
    let result = (s as u128).wrapping_mul(by as u128);
19
0
    ((result & 0xffff_ffff_ffff_ffff) as u64) ^ ((result >> 64) as u64)
20
0
}
21
22
#[inline(always)]
23
#[cfg(not(feature = "folded_multiply"))]
24
pub(crate) const fn folded_multiply(s: u64, by: u64) -> u64 {
25
    let b1 = s.wrapping_mul(by.swap_bytes());
26
    let b2 = s.swap_bytes().wrapping_mul(!by);
27
    b1 ^ b2.swap_bytes()
28
}
29
30
/// Given a small (less than 8 byte slice) returns the same data stored in two u32s.
31
/// (order of and non-duplication of bytes is NOT guaranteed)
32
#[inline(always)]
33
0
pub(crate) fn read_small(data: &[u8]) -> [u64; 2] {
34
0
    debug_assert!(data.len() <= 8);
35
0
    if data.len() >= 2 {
36
0
        if data.len() >= 4 {
37
            //len 4-8
38
0
            [data.read_u32().0 as u64, data.read_last_u32() as u64]
39
        } else {
40
            //len 2-3
41
0
            [data.read_u16().0 as u64, data[data.len() - 1] as u64]
42
        }
43
    } else {
44
0
        if data.len() > 0 {
45
0
            [data[0] as u64, data[0] as u64]
46
        } else {
47
0
            [0, 0]
48
        }
49
    }
50
0
}
51
52
#[inline(always)]
53
pub(crate) fn shuffle(a: u128) -> u128 {
54
    #[cfg(all(target_feature = "ssse3", not(miri)))]
55
    {
56
        #[cfg(target_arch = "x86")]
57
        use core::arch::x86::*;
58
        #[cfg(target_arch = "x86_64")]
59
        use core::arch::x86_64::*;
60
        unsafe { transmute!(_mm_shuffle_epi8(transmute!(a), transmute!(SHUFFLE_MASK))) }
61
    }
62
    #[cfg(not(all(target_feature = "ssse3", not(miri))))]
63
    {
64
        a.swap_bytes()
65
    }
66
}
67
68
#[allow(unused)] //not used by fallback
69
#[inline(always)]
70
pub(crate) fn add_and_shuffle(a: u128, b: u128) -> u128 {
71
    let sum = add_by_64s(a.convert(), b.convert());
72
    shuffle(sum.convert())
73
}
74
75
#[allow(unused)] //not used by fallback
76
#[inline(always)]
77
pub(crate) fn shuffle_and_add(base: u128, to_add: u128) -> u128 {
78
    let shuffled: [u64; 2] = shuffle(base).convert();
79
    add_by_64s(shuffled, to_add.convert()).convert()
80
}
81
82
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2", not(miri)))]
83
#[inline(always)]
84
pub(crate) fn add_by_64s(a: [u64; 2], b: [u64; 2]) -> [u64; 2] {
85
    unsafe {
86
        #[cfg(target_arch = "x86")]
87
        use core::arch::x86::*;
88
        #[cfg(target_arch = "x86_64")]
89
        use core::arch::x86_64::*;
90
        transmute!(_mm_add_epi64(transmute!(a), transmute!(b)))
91
    }
92
}
93
94
#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2", not(miri))))]
95
#[inline(always)]
96
pub(crate) fn add_by_64s(a: [u64; 2], b: [u64; 2]) -> [u64; 2] {
97
    [a[0].wrapping_add(b[0]), a[1].wrapping_add(b[1])]
98
}
99
100
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))]
101
#[allow(unused)]
102
#[inline(always)]
103
pub(crate) fn aesenc(value: u128, xor: u128) -> u128 {
104
    #[cfg(target_arch = "x86")]
105
    use core::arch::x86::*;
106
    #[cfg(target_arch = "x86_64")]
107
    use core::arch::x86_64::*;
108
    unsafe {
109
        let value = transmute!(value);
110
        transmute!(_mm_aesenc_si128(value, transmute!(xor)))
111
    }
112
}
113
114
#[cfg(any(
115
    all(feature = "nightly-arm-aes", target_arch = "aarch64", target_feature = "aes", not(miri)),
116
    all(feature = "nightly-arm-aes", target_arch = "arm", target_feature = "aes", not(miri)),
117
))]
118
#[allow(unused)]
119
#[inline(always)]
120
pub(crate) fn aesenc(value: u128, xor: u128) -> u128 {
121
    #[cfg(target_arch = "aarch64")]
122
    use core::arch::aarch64::*;
123
    #[cfg(target_arch = "arm")]
124
    use core::arch::arm::*;
125
    let res = unsafe { vaesmcq_u8(vaeseq_u8(transmute!(value), transmute!(0u128))) };
126
    let value: u128 = transmute!(res);
127
    xor ^ value
128
}
129
130
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)))]
131
#[allow(unused)]
132
#[inline(always)]
133
pub(crate) fn aesdec(value: u128, xor: u128) -> u128 {
134
    #[cfg(target_arch = "x86")]
135
    use core::arch::x86::*;
136
    #[cfg(target_arch = "x86_64")]
137
    use core::arch::x86_64::*;
138
    unsafe {
139
        let value = transmute!(value);
140
        transmute!(_mm_aesdec_si128(value, transmute!(xor)))
141
    }
142
}
143
144
#[cfg(any(
145
    all(feature = "nightly-arm-aes", target_arch = "aarch64", target_feature = "aes", not(miri)),
146
    all(feature = "nightly-arm-aes", target_arch = "arm", target_feature = "aes", not(miri)),
147
))]
148
#[allow(unused)]
149
#[inline(always)]
150
pub(crate) fn aesdec(value: u128, xor: u128) -> u128 {
151
    #[cfg(target_arch = "aarch64")]
152
    use core::arch::aarch64::*;
153
    #[cfg(target_arch = "arm")]
154
    use core::arch::arm::*;
155
    let res = unsafe { vaesimcq_u8(vaesdq_u8(transmute!(value), transmute!(0u128))) };
156
    let value: u128 = transmute!(res);
157
    xor ^ value
158
}
159
160
#[allow(unused)]
161
#[inline(always)]
162
pub(crate) fn add_in_length(enc: &mut u128, len: u64) {
163
    #[cfg(all(target_arch = "x86_64", target_feature = "sse2", not(miri)))]
164
    {
165
        #[cfg(target_arch = "x86_64")]
166
        use core::arch::x86_64::*;
167
168
        unsafe {
169
            let enc = enc as *mut u128;
170
            let len = _mm_cvtsi64_si128(len as i64);
171
            let data = _mm_loadu_si128(enc.cast());
172
            let sum = _mm_add_epi64(data, len);
173
            _mm_storeu_si128(enc.cast(), sum);
174
        }
175
    }
176
    #[cfg(not(all(target_arch = "x86_64", target_feature = "sse2", not(miri))))]
177
    {
178
        let mut t: [u64; 2] = enc.convert();
179
        t[0] = t[0].wrapping_add(len);
180
        *enc = t.convert();
181
    }
182
}
183
184
#[cfg(test)]
185
mod test {
186
    use super::*;
187
188
    // This is code to search for the shuffle constant
189
    //
190
    //thread_local! { static MASK: Cell<u128> = Cell::new(0); }
191
    //
192
    // fn shuffle(a: u128) -> u128 {
193
    //     use std::intrinsics::transmute;
194
    //     #[cfg(target_arch = "x86")]
195
    //     use core::arch::x86::*;
196
    //     #[cfg(target_arch = "x86_64")]
197
    //     use core::arch::x86_64::*;
198
    //     MASK.with(|mask| {
199
    //         unsafe { transmute!(_mm_shuffle_epi8(transmute!(a), transmute!(mask.get()))) }
200
    //     })
201
    // }
202
    //
203
    // #[test]
204
    // fn find_shuffle() {
205
    //     use rand::prelude::*;
206
    //     use SliceRandom;
207
    //     use std::panic;
208
    //     use std::io::Write;
209
    //
210
    //     let mut value: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13, 14, 15];
211
    //     let mut rand = thread_rng();
212
    //     let mut successful_list = HashMap::new();
213
    //     for _attempt in 0..10000000 {
214
    //         rand.shuffle(&mut value);
215
    //         let test_val = value.convert();
216
    //         MASK.with(|mask| {
217
    //             mask.set(test_val);
218
    //         });
219
    //         if let Ok(successful) = panic::catch_unwind(|| {
220
    //             test_shuffle_does_not_collide_with_aes();
221
    //             test_shuffle_moves_high_bits();
222
    //             test_shuffle_moves_every_value();
223
    //             //test_shuffle_does_not_loop();
224
    //             value
225
    //         }) {
226
    //             let successful: u128 = successful.convert();
227
    //             successful_list.insert(successful, iters_before_loop());
228
    //         }
229
    //     }
230
    //     let write_file = File::create("/tmp/output").unwrap();
231
    //     let mut writer = BufWriter::new(&write_file);
232
    //
233
    //     for success in successful_list {
234
    //         writeln!(writer, "Found successful: {:x?} - {:?}", success.0, success.1);
235
    //     }
236
    // }
237
    //
238
    // fn iters_before_loop() -> u32 {
239
    //     let numbered = 0x00112233_44556677_8899AABB_CCDDEEFF;
240
    //     let mut shuffled = shuffle(numbered);
241
    //     let mut count = 0;
242
    //     loop {
243
    //         // println!("{:>16x}", shuffled);
244
    //         if numbered == shuffled {
245
    //             break;
246
    //         }
247
    //         count += 1;
248
    //         shuffled = shuffle(shuffled);
249
    //     }
250
    //     count
251
    // }
252
253
    #[cfg(all(
254
        any(target_arch = "x86", target_arch = "x86_64"),
255
        target_feature = "ssse3",
256
        target_feature = "aes",
257
        not(miri)
258
    ))]
259
    #[test]
260
    fn test_shuffle_does_not_collide_with_aes() {
261
        let mut value: [u8; 16] = [0; 16];
262
        let zero_mask_enc = aesenc(0, 0);
263
        let zero_mask_dec = aesdec(0, 0);
264
        for index in 0..16 {
265
            value[index] = 1;
266
            let excluded_positions_enc: [u8; 16] = aesenc(value.convert(), zero_mask_enc).convert();
267
            let excluded_positions_dec: [u8; 16] = aesdec(value.convert(), zero_mask_dec).convert();
268
            let actual_location: [u8; 16] = shuffle(value.convert()).convert();
269
            for pos in 0..16 {
270
                if actual_location[pos] != 0 {
271
                    assert_eq!(
272
                        0, excluded_positions_enc[pos],
273
                        "Forward Overlap between {:?} and {:?} at {}",
274
                        excluded_positions_enc, actual_location, index
275
                    );
276
                    assert_eq!(
277
                        0, excluded_positions_dec[pos],
278
                        "Reverse Overlap between {:?} and {:?} at {}",
279
                        excluded_positions_dec, actual_location, index
280
                    );
281
                }
282
            }
283
            value[index] = 0;
284
        }
285
    }
286
287
    #[test]
288
    fn test_shuffle_contains_each_value() {
289
        let value: [u8; 16] = 0x00010203_04050607_08090A0B_0C0D0E0F_u128.convert();
290
        let shuffled: [u8; 16] = shuffle(value.convert()).convert();
291
        for index in 0..16_u8 {
292
            assert!(shuffled.contains(&index), "Value is missing {}", index);
293
        }
294
    }
295
296
    #[test]
297
    fn test_shuffle_moves_every_value() {
298
        let mut value: [u8; 16] = [0; 16];
299
        for index in 0..16 {
300
            value[index] = 1;
301
            let shuffled: [u8; 16] = shuffle(value.convert()).convert();
302
            assert_eq!(0, shuffled[index], "Value is not moved {}", index);
303
            value[index] = 0;
304
        }
305
    }
306
307
    #[test]
308
    fn test_shuffle_moves_high_bits() {
309
        assert!(
310
            shuffle(1) > (1_u128 << 80),
311
            "Low bits must be moved to other half {:?} -> {:?}",
312
            0,
313
            shuffle(1)
314
        );
315
316
        assert!(
317
            shuffle(1_u128 << 58) >= (1_u128 << 64),
318
            "High bits must be moved to other half {:?} -> {:?}",
319
            7,
320
            shuffle(1_u128 << 58)
321
        );
322
        assert!(
323
            shuffle(1_u128 << 58) < (1_u128 << 112),
324
            "High bits must not remain high {:?} -> {:?}",
325
            7,
326
            shuffle(1_u128 << 58)
327
        );
328
        assert!(
329
            shuffle(1_u128 << 64) < (1_u128 << 64),
330
            "Low bits must be moved to other half {:?} -> {:?}",
331
            8,
332
            shuffle(1_u128 << 64)
333
        );
334
        assert!(
335
            shuffle(1_u128 << 64) >= (1_u128 << 16),
336
            "Low bits must not remain low {:?} -> {:?}",
337
            8,
338
            shuffle(1_u128 << 64)
339
        );
340
341
        assert!(
342
            shuffle(1_u128 << 120) < (1_u128 << 50),
343
            "High bits must be moved to low half {:?} -> {:?}",
344
            15,
345
            shuffle(1_u128 << 120)
346
        );
347
    }
348
349
    #[cfg(all(
350
        any(target_arch = "x86", target_arch = "x86_64"),
351
        target_feature = "ssse3",
352
        not(miri)
353
    ))]
354
    #[test]
355
    fn test_shuffle_does_not_loop() {
356
        let numbered = 0x00112233_44556677_8899AABB_CCDDEEFF;
357
        let mut shuffled = shuffle(numbered);
358
        for count in 0..100 {
359
            // println!("{:>16x}", shuffled);
360
            assert_ne!(numbered, shuffled, "Equal after {} vs {:x}", count, shuffled);
361
            shuffled = shuffle(shuffled);
362
        }
363
    }
364
365
    #[test]
366
    fn test_add_length() {
367
        let mut enc = (u64::MAX as u128) << 64 | 50;
368
        add_in_length(&mut enc, u64::MAX);
369
        assert_eq!(enc >> 64, u64::MAX as u128);
370
        assert_eq!(enc as u64, 49);
371
    }
372
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ahash-0.8.11/src/random_state.rs
Line
Count
Source
1
use core::hash::Hash;
2
cfg_if::cfg_if! {
3
    if #[cfg(any(
4
        all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)),
5
        all(feature = "nightly-arm-aes", target_arch = "aarch64", target_feature = "aes", not(miri)),
6
        all(feature = "nightly-arm-aes", target_arch = "arm", target_feature = "aes", not(miri)),
7
    ))] {
8
        use crate::aes_hash::*;
9
    } else {
10
        use crate::fallback_hash::*;
11
    }
12
}
13
cfg_if::cfg_if! {
14
    if #[cfg(feature = "specialize")]{
15
        use crate::BuildHasherExt;
16
    }
17
}
18
cfg_if::cfg_if! {
19
    if #[cfg(feature = "std")] {
20
        extern crate std as alloc;
21
    } else {
22
        extern crate alloc;
23
    }
24
}
25
26
#[cfg(feature = "atomic-polyfill")]
27
use atomic_polyfill as atomic;
28
#[cfg(not(feature = "atomic-polyfill"))]
29
use core::sync::atomic;
30
31
use alloc::boxed::Box;
32
use atomic::{AtomicUsize, Ordering};
33
use core::any::{Any, TypeId};
34
use core::fmt;
35
use core::hash::BuildHasher;
36
use core::hash::Hasher;
37
38
pub(crate) const PI: [u64; 4] = [
39
    0x243f_6a88_85a3_08d3,
40
    0x1319_8a2e_0370_7344,
41
    0xa409_3822_299f_31d0,
42
    0x082e_fa98_ec4e_6c89,
43
];
44
45
pub(crate) const PI2: [u64; 4] = [
46
    0x4528_21e6_38d0_1377,
47
    0xbe54_66cf_34e9_0c6c,
48
    0xc0ac_29b7_c97c_50dd,
49
    0x3f84_d5b5_b547_0917,
50
];
51
52
cfg_if::cfg_if! {
53
    if #[cfg(all(feature = "compile-time-rng", any(test, fuzzing)))] {
54
        #[inline]
55
        fn get_fixed_seeds() -> &'static [[u64; 4]; 2] {
56
            use const_random::const_random;
57
58
            const RAND: [[u64; 4]; 2] = [
59
                [
60
                    const_random!(u64),
61
                    const_random!(u64),
62
                    const_random!(u64),
63
                    const_random!(u64),
64
                ], [
65
                    const_random!(u64),
66
                    const_random!(u64),
67
                    const_random!(u64),
68
                    const_random!(u64),
69
                ]
70
            ];
71
            &RAND
72
        }
73
    } else if #[cfg(all(feature = "runtime-rng", not(fuzzing)))] {
74
        #[inline]
75
        fn get_fixed_seeds() -> &'static [[u64; 4]; 2] {
76
            use crate::convert::Convert;
77
78
            static SEEDS: OnceBox<[[u64; 4]; 2]> = OnceBox::new();
79
80
            SEEDS.get_or_init(|| {
81
                let mut result: [u8; 64] = [0; 64];
82
                getrandom::getrandom(&mut result).expect("getrandom::getrandom() failed.");
83
                Box::new(result.convert())
84
            })
85
        }
86
    } else if #[cfg(feature = "compile-time-rng")] {
87
        #[inline]
88
        fn get_fixed_seeds() -> &'static [[u64; 4]; 2] {
89
            use const_random::const_random;
90
91
            const RAND: [[u64; 4]; 2] = [
92
                [
93
                    const_random!(u64),
94
                    const_random!(u64),
95
                    const_random!(u64),
96
                    const_random!(u64),
97
                ], [
98
                    const_random!(u64),
99
                    const_random!(u64),
100
                    const_random!(u64),
101
                    const_random!(u64),
102
                ]
103
            ];
104
            &RAND
105
        }
106
    } else {
107
        #[inline]
108
0
        fn get_fixed_seeds() -> &'static [[u64; 4]; 2] {
109
0
            &[PI, PI2]
110
0
        }
Unexecuted instantiation: _RNvNtCseb6QmliwlWD_5ahash12random_state15get_fixed_seedsB3_
Unexecuted instantiation: _RNvNtCseb6QmliwlWD_5ahash12random_state15get_fixed_seedsCs568wuOlRYFZ_8chia_bls
111
    }
112
}
113
114
cfg_if::cfg_if! {
115
    if #[cfg(not(all(target_arch = "arm", target_os = "none")))] {
116
        use once_cell::race::OnceBox;
117
118
        static RAND_SOURCE: OnceBox<Box<dyn RandomSource + Send + Sync>> = OnceBox::new();
119
    }
120
}
121
/// A supplier of Randomness used for different hashers.
122
/// See [set_random_source].
123
///
124
/// If [set_random_source] aHash will default to the best available source of randomness.
125
/// In order this is:
126
/// 1. OS provided random number generator (available if the `runtime-rng` flag is enabled which it is by default) - This should be very strong.
127
/// 2. Strong compile time random numbers used to permute a static "counter". (available if `compile-time-rng` is enabled.
128
/// __Enabling this is recommended if `runtime-rng` is not possible__)
129
/// 3. A static counter that adds the memory address of each [RandomState] created permuted with fixed constants.
130
/// (Similar to above but with fixed keys) - This is the weakest option. The strength of this heavily depends on whether or not ASLR is enabled.
131
/// (Rust enables ASLR by default)
132
pub trait RandomSource {
133
    fn gen_hasher_seed(&self) -> usize;
134
}
135
136
struct DefaultRandomSource {
137
    counter: AtomicUsize,
138
}
139
140
impl DefaultRandomSource {
141
0
    fn new() -> DefaultRandomSource {
142
0
        DefaultRandomSource {
143
0
            counter: AtomicUsize::new(&PI as *const _ as usize),
144
0
        }
145
0
    }
146
147
    #[cfg(all(target_arch = "arm", target_os = "none"))]
148
    const fn default() -> DefaultRandomSource {
149
        DefaultRandomSource {
150
            counter: AtomicUsize::new(PI[3] as usize),
151
        }
152
    }
153
}
154
155
impl RandomSource for DefaultRandomSource {
156
    cfg_if::cfg_if! {
157
        if #[cfg(all(target_arch = "arm", target_os = "none"))] {
158
            fn gen_hasher_seed(&self) -> usize {
159
                let stack = self as *const _ as usize;
160
                let previous = self.counter.load(Ordering::Relaxed);
161
                let new = previous.wrapping_add(stack);
162
                self.counter.store(new, Ordering::Relaxed);
163
                new
164
            }
165
        } else {
166
0
            fn gen_hasher_seed(&self) -> usize {
167
0
                let stack = self as *const _ as usize;
168
0
                self.counter.fetch_add(stack, Ordering::Relaxed)
169
0
            }
170
        }
171
    }
172
}
173
174
cfg_if::cfg_if! {
175
        if #[cfg(all(target_arch = "arm", target_os = "none"))] {
176
            #[inline]
177
            fn get_src() -> &'static dyn RandomSource {
178
                static RAND_SOURCE: DefaultRandomSource = DefaultRandomSource::default();
179
                &RAND_SOURCE
180
            }
181
        } else {
182
            /// Provides an optional way to manually supply a source of randomness for Hasher keys.
183
            ///
184
            /// The provided [RandomSource] will be used to be used as a source of randomness by [RandomState] to generate new states.
185
            /// If this method is not invoked the standard source of randomness is used as described in the Readme.
186
            ///
187
            /// The source of randomness can only be set once, and must be set before the first RandomState is created.
188
            /// If the source has already been specified `Err` is returned with a `bool` indicating if the set failed because
189
            /// method was previously invoked (true) or if the default source is already being used (false).
190
            #[cfg(not(all(target_arch = "arm", target_os = "none")))]
191
0
            pub fn set_random_source(source: impl RandomSource + Send + Sync + 'static) -> Result<(), bool> {
192
0
                RAND_SOURCE.set(Box::new(Box::new(source))).map_err(|s| s.as_ref().type_id() != TypeId::of::<&DefaultRandomSource>())
193
0
            }
194
195
            #[inline]
196
0
            fn get_src() -> &'static dyn RandomSource {
197
0
                RAND_SOURCE.get_or_init(|| Box::new(Box::new(DefaultRandomSource::new()))).as_ref()
198
0
            }
199
        }
200
}
201
202
/// Provides a [Hasher] factory. This is typically used (e.g. by [HashMap]) to create
203
/// [AHasher]s in order to hash the keys of the map. See `build_hasher` below.
204
///
205
/// [build_hasher]: ahash::
206
/// [Hasher]: std::hash::Hasher
207
/// [BuildHasher]: std::hash::BuildHasher
208
/// [HashMap]: std::collections::HashMap
209
///
210
/// There are multiple constructors each is documented in more detail below:
211
///
212
/// | Constructor   | Dynamically random? | Seed |
213
/// |---------------|---------------------|------|
214
/// |`new`          | Each instance unique|_[RandomSource]_|
215
/// |`generate_with`| Each instance unique|`u64` x 4 + [RandomSource]|
216
/// |`with_seed`    | Fixed per process   |`u64` + static random number|
217
/// |`with_seeds`   | Fixed               |`u64` x 4|
218
///
219
#[derive(Clone)]
220
pub struct RandomState {
221
    pub(crate) k0: u64,
222
    pub(crate) k1: u64,
223
    pub(crate) k2: u64,
224
    pub(crate) k3: u64,
225
}
226
227
impl fmt::Debug for RandomState {
228
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229
0
        f.pad("RandomState { .. }")
230
0
    }
231
}
232
233
impl RandomState {
234
    /// Create a new `RandomState` `BuildHasher` using random keys.
235
    ///
236
    /// Each instance will have a unique set of keys derived from [RandomSource].
237
    ///
238
    #[inline]
239
0
    pub fn new() -> RandomState {
240
0
        let src = get_src();
241
0
        let fixed = get_fixed_seeds();
242
0
        Self::from_keys(&fixed[0], &fixed[1], src.gen_hasher_seed())
243
0
    }
244
245
    /// Create a new `RandomState` `BuildHasher` based on the provided seeds, but in such a way
246
    /// that each time it is called the resulting state will be different and of high quality.
247
    /// This allows fixed constant or poor quality seeds to be provided without the problem of different
248
    /// `BuildHasher`s being identical or weak.
249
    ///
250
    /// This is done via permuting the provided values with the value of a static counter and memory address.
251
    /// (This makes this method somewhat more expensive than `with_seeds` below which does not do this).
252
    ///
253
    /// The provided values (k0-k3) do not need to be of high quality but they should not all be the same value.
254
    #[inline]
255
0
    pub fn generate_with(k0: u64, k1: u64, k2: u64, k3: u64) -> RandomState {
256
0
        let src = get_src();
257
0
        let fixed = get_fixed_seeds();
258
0
        RandomState::from_keys(&fixed[0], &[k0, k1, k2, k3], src.gen_hasher_seed())
259
0
    }
260
261
0
    fn from_keys(a: &[u64; 4], b: &[u64; 4], c: usize) -> RandomState {
262
0
        let &[k0, k1, k2, k3] = a;
263
0
        let mut hasher = AHasher::from_random_state(&RandomState { k0, k1, k2, k3 });
264
0
        hasher.write_usize(c);
265
0
        let mix = |l: u64, r: u64| {
266
0
            let mut h = hasher.clone();
267
0
            h.write_u64(l);
268
0
            h.write_u64(r);
269
0
            h.finish()
270
0
        };
271
0
        RandomState {
272
0
            k0: mix(b[0], b[2]),
273
0
            k1: mix(b[1], b[3]),
274
0
            k2: mix(b[2], b[1]),
275
0
            k3: mix(b[3], b[0]),
276
0
        }
277
0
    }
278
279
    /// Internal. Used by Default.
280
    #[inline]
281
0
    pub(crate) fn with_fixed_keys() -> RandomState {
282
0
        let [k0, k1, k2, k3] = get_fixed_seeds()[0];
283
0
        RandomState { k0, k1, k2, k3 }
284
0
    }
Unexecuted instantiation: _RNvMs1_NtCseb6QmliwlWD_5ahash12random_stateNtB5_11RandomState15with_fixed_keysB7_
Unexecuted instantiation: _RNvMs1_NtCseb6QmliwlWD_5ahash12random_stateNtB5_11RandomState15with_fixed_keysCs568wuOlRYFZ_8chia_bls
285
286
    /// Build a `RandomState` from a single key. The provided key does not need to be of high quality,
287
    /// but all `RandomState`s created from the same key will produce identical hashers.
288
    /// (In contrast to `generate_with` above)
289
    ///
290
    /// This allows for explicitly setting the seed to be used.
291
    ///
292
    /// Note: This method does not require the provided seed to be strong.
293
    #[inline]
294
0
    pub fn with_seed(key: usize) -> RandomState {
295
0
        let fixed = get_fixed_seeds();
296
0
        RandomState::from_keys(&fixed[0], &fixed[1], key)
297
0
    }
298
299
    /// Allows for explicitly setting the seeds to used.
300
    /// All `RandomState`s created with the same set of keys key will produce identical hashers.
301
    /// (In contrast to `generate_with` above)
302
    ///
303
    /// Note: If DOS resistance is desired one of these should be a decent quality random number.
304
    /// If 4 high quality random number are not cheaply available this method is robust against 0s being passed for
305
    /// one or more of the parameters or the same value being passed for more than one parameter.
306
    /// It is recommended to pass numbers in order from highest to lowest quality (if there is any difference).
307
    #[inline]
308
0
    pub const fn with_seeds(k0: u64, k1: u64, k2: u64, k3: u64) -> RandomState {
309
0
        RandomState {
310
0
            k0: k0 ^ PI2[0],
311
0
            k1: k1 ^ PI2[1],
312
0
            k2: k2 ^ PI2[2],
313
0
            k3: k3 ^ PI2[3],
314
0
        }
315
0
    }
316
317
    /// Calculates the hash of a single value. This provides a more convenient (and faster) way to obtain a hash:
318
    /// For example:
319
    #[cfg_attr(
320
        feature = "std",
321
        doc = r##" # Examples
322
```
323
    use std::hash::BuildHasher;
324
    use ahash::RandomState;
325
326
    let hash_builder = RandomState::new();
327
    let hash = hash_builder.hash_one("Some Data");
328
```
329
    "##
330
    )]
331
    /// This is similar to:
332
    #[cfg_attr(
333
        feature = "std",
334
        doc = r##" # Examples
335
```
336
    use std::hash::{BuildHasher, Hash, Hasher};
337
    use ahash::RandomState;
338
339
    let hash_builder = RandomState::new();
340
    let mut hasher = hash_builder.build_hasher();
341
    "Some Data".hash(&mut hasher);
342
    let hash = hasher.finish();
343
```
344
    "##
345
    )]
346
    /// (Note that these two ways to get a hash may not produce the same value for the same data)
347
    ///
348
    /// This is intended as a convenience for code which *consumes* hashes, such
349
    /// as the implementation of a hash table or in unit tests that check
350
    /// whether a custom [`Hash`] implementation behaves as expected.
351
    ///
352
    /// This must not be used in any code which *creates* hashes, such as in an
353
    /// implementation of [`Hash`].  The way to create a combined hash of
354
    /// multiple values is to call [`Hash::hash`] multiple times using the same
355
    /// [`Hasher`], not to call this method repeatedly and combine the results.
356
    #[inline]
357
0
    pub fn hash_one<T: Hash>(&self, x: T) -> u64
358
0
    where
359
0
        Self: Sized,
360
0
    {
361
        use crate::specialize::CallHasher;
362
0
        T::get_hash(&x, self)
363
0
    }
364
}
365
366
/// Creates an instance of RandomState using keys obtained from the random number generator.
367
/// Each instance created in this way will have a unique set of keys. (But the resulting instance
368
/// can be used to create many hashers each or which will have the same keys.)
369
///
370
/// This is the same as [RandomState::new()]
371
///
372
/// NOTE: For safety this trait impl is only available available if either of the flags `runtime-rng` (on by default) or
373
/// `compile-time-rng` are enabled. This is to prevent weakly keyed maps from being accidentally created. Instead one of
374
/// constructors for [RandomState] must be used.
375
#[cfg(any(feature = "compile-time-rng", feature = "runtime-rng", feature = "no-rng"))]
376
impl Default for RandomState {
377
    #[inline]
378
    fn default() -> Self {
379
        Self::new()
380
    }
381
}
382
383
impl BuildHasher for RandomState {
384
    type Hasher = AHasher;
385
386
    /// Constructs a new [AHasher] with keys based on this [RandomState] object.
387
    /// This means that two different [RandomState]s will will generate
388
    /// [AHasher]s that will return different hashcodes, but [Hasher]s created from the same [BuildHasher]
389
    /// will generate the same hashes for the same input data.
390
    ///
391
    #[cfg_attr(
392
        feature = "std",
393
        doc = r##" # Examples
394
```
395
        use ahash::{AHasher, RandomState};
396
        use std::hash::{Hasher, BuildHasher};
397
    
398
        let build_hasher = RandomState::new();
399
        let mut hasher_1 = build_hasher.build_hasher();
400
        let mut hasher_2 = build_hasher.build_hasher();
401
    
402
        hasher_1.write_u32(1234);
403
        hasher_2.write_u32(1234);
404
    
405
        assert_eq!(hasher_1.finish(), hasher_2.finish());
406
    
407
        let other_build_hasher = RandomState::new();
408
        let mut different_hasher = other_build_hasher.build_hasher();
409
        different_hasher.write_u32(1234);
410
        assert_ne!(different_hasher.finish(), hasher_1.finish());
411
```
412
    "##
413
    )]
414
    /// [Hasher]: std::hash::Hasher
415
    /// [BuildHasher]: std::hash::BuildHasher
416
    /// [HashMap]: std::collections::HashMap
417
    #[inline]
418
0
    fn build_hasher(&self) -> AHasher {
419
0
        AHasher::from_random_state(self)
420
0
    }
Unexecuted instantiation: _RNvXs2_NtCseb6QmliwlWD_5ahash12random_stateNtB5_11RandomStateNtNtCsbQ8arDwx5Xq_4core4hash11BuildHasher12build_hasherB7_
Unexecuted instantiation: _RNvXs2_NtCseb6QmliwlWD_5ahash12random_stateNtB5_11RandomStateNtNtCsbQ8arDwx5Xq_4core4hash11BuildHasher12build_hasherCs568wuOlRYFZ_8chia_bls
421
422
    /// Calculates the hash of a single value. This provides a more convenient (and faster) way to obtain a hash:
423
    /// For example:
424
    #[cfg_attr(
425
        feature = "std",
426
        doc = r##" # Examples
427
```
428
    use std::hash::BuildHasher;
429
    use ahash::RandomState;
430
431
    let hash_builder = RandomState::new();
432
    let hash = hash_builder.hash_one("Some Data");
433
```
434
    "##
435
    )]
436
    /// This is similar to:
437
    #[cfg_attr(
438
        feature = "std",
439
        doc = r##" # Examples
440
```
441
    use std::hash::{BuildHasher, Hash, Hasher};
442
    use ahash::RandomState;
443
444
    let hash_builder = RandomState::new();
445
    let mut hasher = hash_builder.build_hasher();
446
    "Some Data".hash(&mut hasher);
447
    let hash = hasher.finish();
448
```
449
    "##
450
    )]
451
    /// (Note that these two ways to get a hash may not produce the same value for the same data)
452
    ///
453
    /// This is intended as a convenience for code which *consumes* hashes, such
454
    /// as the implementation of a hash table or in unit tests that check
455
    /// whether a custom [`Hash`] implementation behaves as expected.
456
    ///
457
    /// This must not be used in any code which *creates* hashes, such as in an
458
    /// implementation of [`Hash`].  The way to create a combined hash of
459
    /// multiple values is to call [`Hash::hash`] multiple times using the same
460
    /// [`Hasher`], not to call this method repeatedly and combine the results.
461
    #[cfg(feature = "specialize")]
462
    #[inline]
463
0
    fn hash_one<T: Hash>(&self, x: T) -> u64 {
464
0
        RandomState::hash_one(self, x)
465
0
    }
466
}
467
468
#[cfg(feature = "specialize")]
469
impl BuildHasherExt for RandomState {
470
    #[inline]
471
0
    fn hash_as_u64<T: Hash + ?Sized>(&self, value: &T) -> u64 {
472
0
        let mut hasher = AHasherU64 {
473
0
            buffer: self.k1,
474
0
            pad: self.k0,
475
0
        };
476
0
        value.hash(&mut hasher);
477
0
        hasher.finish()
478
0
    }
479
480
    #[inline]
481
0
    fn hash_as_fixed_length<T: Hash + ?Sized>(&self, value: &T) -> u64 {
482
0
        let mut hasher = AHasherFixed(self.build_hasher());
483
0
        value.hash(&mut hasher);
484
0
        hasher.finish()
485
0
    }
486
487
    #[inline]
488
0
    fn hash_as_str<T: Hash + ?Sized>(&self, value: &T) -> u64 {
489
0
        let mut hasher = AHasherStr(self.build_hasher());
490
0
        value.hash(&mut hasher);
491
0
        hasher.finish()
492
0
    }
493
}
494
495
#[cfg(test)]
496
mod test {
497
    use super::*;
498
499
    #[test]
500
    fn test_unique() {
501
        let a = RandomState::generate_with(1, 2, 3, 4);
502
        let b = RandomState::generate_with(1, 2, 3, 4);
503
        assert_ne!(a.build_hasher().finish(), b.build_hasher().finish());
504
    }
505
506
    #[cfg(all(feature = "runtime-rng", not(all(feature = "compile-time-rng", test))))]
507
    #[test]
508
    fn test_not_pi() {
509
        assert_ne!(PI, get_fixed_seeds()[0]);
510
    }
511
512
    #[cfg(all(feature = "compile-time-rng", any(not(feature = "runtime-rng"), test)))]
513
    #[test]
514
    fn test_not_pi_const() {
515
        assert_ne!(PI, get_fixed_seeds()[0]);
516
    }
517
518
    #[cfg(all(not(feature = "runtime-rng"), not(feature = "compile-time-rng")))]
519
    #[test]
520
    fn test_pi() {
521
        assert_eq!(PI, get_fixed_seeds()[0]);
522
    }
523
524
    #[test]
525
    fn test_with_seeds_const() {
526
        const _CONST_RANDOM_STATE: RandomState = RandomState::with_seeds(17, 19, 21, 23);
527
    }
528
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ahash-0.8.11/src/specialize.rs
Line
Count
Source
1
use core::hash::BuildHasher;
2
use core::hash::Hash;
3
use core::hash::Hasher;
4
5
#[cfg(not(feature = "std"))]
6
extern crate alloc;
7
#[cfg(feature = "std")]
8
extern crate std as alloc;
9
10
#[cfg(feature = "specialize")]
11
use crate::BuildHasherExt;
12
#[cfg(feature = "specialize")]
13
use alloc::string::String;
14
#[cfg(feature = "specialize")]
15
use alloc::vec::Vec;
16
17
/// Provides a way to get an optimized hasher for a given data type.
18
/// Rather than using a Hasher generically which can hash any value, this provides a way to get a specialized hash
19
/// for a specific type. So this may be faster for primitive types.
20
pub(crate) trait CallHasher {
21
    fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64;
22
}
23
24
#[cfg(not(feature = "specialize"))]
25
impl<T> CallHasher for T
26
where
27
    T: Hash + ?Sized,
28
{
29
    #[inline]
30
    fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
31
        let mut hasher = build_hasher.build_hasher();
32
        value.hash(&mut hasher);
33
        hasher.finish()
34
    }
35
}
36
37
#[cfg(feature = "specialize")]
38
impl<T> CallHasher for T
39
where
40
    T: Hash + ?Sized,
41
{
42
    #[inline]
43
0
    default fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
44
0
        let mut hasher = build_hasher.build_hasher();
45
0
        value.hash(&mut hasher);
46
0
        hasher.finish()
47
0
    }
48
}
49
50
macro_rules! call_hasher_impl {
51
    ($typ:ty) => {
52
        #[cfg(feature = "specialize")]
53
        impl CallHasher for $typ {
54
            #[inline]
55
0
            fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
56
0
                build_hasher.hash_as_u64(value)
57
0
            }
Unexecuted instantiation: _RINvXs7_NtCseb6QmliwlWD_5ahash10specializehNtB6_10CallHasher8get_hashppEB8_
Unexecuted instantiation: _RINvXs8_NtCseb6QmliwlWD_5ahash10specializetNtB6_10CallHasher8get_hashppEB8_
Unexecuted instantiation: _RINvXs9_NtCseb6QmliwlWD_5ahash10specializemNtB6_10CallHasher8get_hashppEB8_
Unexecuted instantiation: _RINvXsa_NtCseb6QmliwlWD_5ahash10specializeyNtB6_10CallHasher8get_hashppEB8_
Unexecuted instantiation: _RINvXsb_NtCseb6QmliwlWD_5ahash10specializeaNtB6_10CallHasher8get_hashppEB8_
Unexecuted instantiation: _RINvXsc_NtCseb6QmliwlWD_5ahash10specializesNtB6_10CallHasher8get_hashppEB8_
Unexecuted instantiation: _RINvXsd_NtCseb6QmliwlWD_5ahash10specializelNtB6_10CallHasher8get_hashppEB8_
Unexecuted instantiation: _RINvXse_NtCseb6QmliwlWD_5ahash10specializexNtB6_10CallHasher8get_hashppEB8_
58
        }
59
    };
60
}
61
call_hasher_impl!(u8);
62
call_hasher_impl!(u16);
63
call_hasher_impl!(u32);
64
call_hasher_impl!(u64);
65
call_hasher_impl!(i8);
66
call_hasher_impl!(i16);
67
call_hasher_impl!(i32);
68
call_hasher_impl!(i64);
69
70
#[cfg(feature = "specialize")]
71
impl CallHasher for u128 {
72
    #[inline]
73
0
    fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
74
0
        build_hasher.hash_as_fixed_length(value)
75
0
    }
76
}
77
78
#[cfg(feature = "specialize")]
79
impl CallHasher for i128 {
80
    #[inline]
81
0
    fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
82
0
        build_hasher.hash_as_fixed_length(value)
83
0
    }
84
}
85
86
#[cfg(feature = "specialize")]
87
impl CallHasher for usize {
88
    #[inline]
89
0
    fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
90
0
        build_hasher.hash_as_fixed_length(value)
91
0
    }
92
}
93
94
#[cfg(feature = "specialize")]
95
impl CallHasher for isize {
96
    #[inline]
97
0
    fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
98
0
        build_hasher.hash_as_fixed_length(value)
99
0
    }
100
}
101
102
#[cfg(feature = "specialize")]
103
impl CallHasher for [u8] {
104
    #[inline]
105
0
    fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
106
0
        build_hasher.hash_as_str(value)
107
0
    }
108
}
109
110
#[cfg(feature = "specialize")]
111
impl CallHasher for Vec<u8> {
112
    #[inline]
113
0
    fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
114
0
        build_hasher.hash_as_str(value)
115
0
    }
116
}
117
118
#[cfg(feature = "specialize")]
119
impl CallHasher for str {
120
    #[inline]
121
0
    fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
122
0
        build_hasher.hash_as_str(value)
123
0
    }
124
}
125
126
#[cfg(all(feature = "specialize"))]
127
impl CallHasher for String {
128
    #[inline]
129
0
    fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
130
0
        build_hasher.hash_as_str(value)
131
0
    }
132
}
133
134
#[cfg(test)]
135
mod test {
136
    use super::*;
137
    use crate::*;
138
139
    #[test]
140
    #[cfg(feature = "specialize")]
141
    pub fn test_specialized_invoked() {
142
        let build_hasher = RandomState::with_seeds(1, 2, 3, 4);
143
        let shortened = u64::get_hash(&0, &build_hasher);
144
        let mut hasher = AHasher::new_with_keys(1, 2);
145
        0_u64.hash(&mut hasher);
146
        assert_ne!(hasher.finish(), shortened);
147
    }
148
149
    /// Tests that some non-trivial transformation takes place.
150
    #[test]
151
    pub fn test_input_processed() {
152
        let build_hasher = RandomState::with_seeds(2, 2, 2, 2);
153
        assert_ne!(0, u64::get_hash(&0, &build_hasher));
154
        assert_ne!(1, u64::get_hash(&0, &build_hasher));
155
        assert_ne!(2, u64::get_hash(&0, &build_hasher));
156
        assert_ne!(3, u64::get_hash(&0, &build_hasher));
157
        assert_ne!(4, u64::get_hash(&0, &build_hasher));
158
        assert_ne!(5, u64::get_hash(&0, &build_hasher));
159
160
        assert_ne!(0, u64::get_hash(&1, &build_hasher));
161
        assert_ne!(1, u64::get_hash(&1, &build_hasher));
162
        assert_ne!(2, u64::get_hash(&1, &build_hasher));
163
        assert_ne!(3, u64::get_hash(&1, &build_hasher));
164
        assert_ne!(4, u64::get_hash(&1, &build_hasher));
165
        assert_ne!(5, u64::get_hash(&1, &build_hasher));
166
167
        let xored = u64::get_hash(&0, &build_hasher) ^ u64::get_hash(&1, &build_hasher);
168
        assert_ne!(0, xored);
169
        assert_ne!(1, xored);
170
        assert_ne!(2, xored);
171
        assert_ne!(3, xored);
172
        assert_ne!(4, xored);
173
        assert_ne!(5, xored);
174
    }
175
176
    #[test]
177
    pub fn test_ref_independent() {
178
        let build_hasher = RandomState::with_seeds(1, 2, 3, 4);
179
        assert_eq!(u8::get_hash(&&1, &build_hasher), u8::get_hash(&1, &build_hasher));
180
        assert_eq!(u16::get_hash(&&2, &build_hasher), u16::get_hash(&2, &build_hasher));
181
        assert_eq!(u32::get_hash(&&3, &build_hasher), u32::get_hash(&3, &build_hasher));
182
        assert_eq!(u64::get_hash(&&4, &build_hasher), u64::get_hash(&4, &build_hasher));
183
        assert_eq!(u128::get_hash(&&5, &build_hasher), u128::get_hash(&5, &build_hasher));
184
        assert_eq!(
185
            str::get_hash(&"test", &build_hasher),
186
            str::get_hash("test", &build_hasher)
187
        );
188
        assert_eq!(
189
            str::get_hash(&"test", &build_hasher),
190
            String::get_hash(&"test".to_string(), &build_hasher)
191
        );
192
        #[cfg(feature = "specialize")]
193
        assert_eq!(
194
            str::get_hash(&"test", &build_hasher),
195
            <[u8]>::get_hash("test".as_bytes(), &build_hasher)
196
        );
197
198
        let build_hasher = RandomState::with_seeds(10, 20, 30, 40);
199
        assert_eq!(u8::get_hash(&&&1, &build_hasher), u8::get_hash(&1, &build_hasher));
200
        assert_eq!(u16::get_hash(&&&2, &build_hasher), u16::get_hash(&2, &build_hasher));
201
        assert_eq!(u32::get_hash(&&&3, &build_hasher), u32::get_hash(&3, &build_hasher));
202
        assert_eq!(u64::get_hash(&&&4, &build_hasher), u64::get_hash(&4, &build_hasher));
203
        assert_eq!(u128::get_hash(&&&5, &build_hasher), u128::get_hash(&5, &build_hasher));
204
        assert_eq!(
205
            str::get_hash(&&"test", &build_hasher),
206
            str::get_hash("test", &build_hasher)
207
        );
208
        assert_eq!(
209
            str::get_hash(&&"test", &build_hasher),
210
            String::get_hash(&"test".to_string(), &build_hasher)
211
        );
212
        #[cfg(feature = "specialize")]
213
        assert_eq!(
214
            str::get_hash(&&"test", &build_hasher),
215
            <[u8]>::get_hash(&"test".to_string().into_bytes(), &build_hasher)
216
        );
217
    }
218
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/allocator-api2-0.2.18/src/stable/alloc/global.rs
Line
Count
Source
1
use core::ptr::NonNull;
2
3
use alloc_crate::alloc::{alloc, alloc_zeroed, dealloc, realloc};
4
5
use crate::stable::{assume, invalid_mut};
6
7
use super::{AllocError, Allocator, Layout};
8
9
/// The global memory allocator.
10
///
11
/// This type implements the [`Allocator`] trait by forwarding calls
12
/// to the allocator registered with the `#[global_allocator]` attribute
13
/// if there is one, or the `std` crate’s default.
14
///
15
/// Note: while this type is unstable, the functionality it provides can be
16
/// accessed through the [free functions in `alloc`](crate#functions).
17
#[derive(Copy, Clone, Default, Debug)]
18
pub struct Global;
19
20
impl Global {
21
    #[inline(always)]
22
0
    fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Result<NonNull<[u8]>, AllocError> {
23
0
        match layout.size() {
24
0
            0 => Ok(unsafe {
25
0
                NonNull::new_unchecked(core::ptr::slice_from_raw_parts_mut(
26
0
                    invalid_mut(layout.align()),
27
0
                    0,
28
0
                ))
29
0
            }),
30
            // SAFETY: `layout` is non-zero in size,
31
0
            size => unsafe {
32
0
                let raw_ptr = if zeroed {
33
0
                    alloc_zeroed(layout)
34
                } else {
35
0
                    alloc(layout)
36
                };
37
0
                let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
38
0
                Ok(NonNull::new_unchecked(core::ptr::slice_from_raw_parts_mut(
39
0
                    ptr.as_ptr(),
40
0
                    size,
41
0
                )))
42
            },
43
        }
44
0
    }
45
46
    // SAFETY: Same as `Allocator::grow`
47
    #[inline(always)]
48
    unsafe fn grow_impl(
49
        &self,
50
        ptr: NonNull<u8>,
51
        old_layout: Layout,
52
        new_layout: Layout,
53
        zeroed: bool,
54
    ) -> Result<NonNull<[u8]>, AllocError> {
55
        debug_assert!(
56
            new_layout.size() >= old_layout.size(),
57
            "`new_layout.size()` must be greater than or equal to `old_layout.size()`"
58
        );
59
60
        match old_layout.size() {
61
            0 => self.alloc_impl(new_layout, zeroed),
62
63
            // SAFETY: `new_size` is non-zero as `old_size` is greater than or equal to `new_size`
64
            // as required by safety conditions. Other conditions must be upheld by the caller
65
            old_size if old_layout.align() == new_layout.align() => unsafe {
66
                let new_size = new_layout.size();
67
68
                // `realloc` probably checks for `new_size >= old_layout.size()` or something similar.
69
                assume(new_size >= old_layout.size());
70
71
                let raw_ptr = realloc(ptr.as_ptr(), old_layout, new_size);
72
                let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
73
                if zeroed {
74
                    raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
75
                }
76
                Ok(NonNull::new_unchecked(core::ptr::slice_from_raw_parts_mut(
77
                    ptr.as_ptr(),
78
                    new_size,
79
                )))
80
            },
81
82
            // SAFETY: because `new_layout.size()` must be greater than or equal to `old_size`,
83
            // both the old and new memory allocation are valid for reads and writes for `old_size`
84
            // bytes. Also, because the old allocation wasn't yet deallocated, it cannot overlap
85
            // `new_ptr`. Thus, the call to `copy_nonoverlapping` is safe. The safety contract
86
            // for `dealloc` must be upheld by the caller.
87
            old_size => unsafe {
88
                let new_ptr = self.alloc_impl(new_layout, zeroed)?;
89
                core::ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr().cast(), old_size);
90
                self.deallocate(ptr, old_layout);
91
                Ok(new_ptr)
92
            },
93
        }
94
    }
95
}
96
97
unsafe impl Allocator for Global {
98
    #[inline(always)]
99
0
    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
100
0
        self.alloc_impl(layout, false)
101
0
    }
102
103
    #[inline(always)]
104
0
    fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
105
0
        self.alloc_impl(layout, true)
106
0
    }
107
108
    #[inline(always)]
109
0
    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
110
0
        if layout.size() != 0 {
111
            // SAFETY: `layout` is non-zero in size,
112
            // other conditions must be upheld by the caller
113
0
            unsafe { dealloc(ptr.as_ptr(), layout) }
114
0
        }
115
0
    }
116
117
    #[inline(always)]
118
    unsafe fn grow(
119
        &self,
120
        ptr: NonNull<u8>,
121
        old_layout: Layout,
122
        new_layout: Layout,
123
    ) -> Result<NonNull<[u8]>, AllocError> {
124
        // SAFETY: all conditions must be upheld by the caller
125
        unsafe { self.grow_impl(ptr, old_layout, new_layout, false) }
126
    }
127
128
    #[inline(always)]
129
    unsafe fn grow_zeroed(
130
        &self,
131
        ptr: NonNull<u8>,
132
        old_layout: Layout,
133
        new_layout: Layout,
134
    ) -> Result<NonNull<[u8]>, AllocError> {
135
        // SAFETY: all conditions must be upheld by the caller
136
        unsafe { self.grow_impl(ptr, old_layout, new_layout, true) }
137
    }
138
139
    #[inline(always)]
140
    unsafe fn shrink(
141
        &self,
142
        ptr: NonNull<u8>,
143
        old_layout: Layout,
144
        new_layout: Layout,
145
    ) -> Result<NonNull<[u8]>, AllocError> {
146
        debug_assert!(
147
            new_layout.size() <= old_layout.size(),
148
            "`new_layout.size()` must be smaller than or equal to `old_layout.size()`"
149
        );
150
151
        match new_layout.size() {
152
            // SAFETY: conditions must be upheld by the caller
153
            0 => unsafe {
154
                self.deallocate(ptr, old_layout);
155
                Ok(NonNull::new_unchecked(core::ptr::slice_from_raw_parts_mut(
156
                    invalid_mut(new_layout.align()),
157
                    0,
158
                )))
159
            },
160
161
            // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller
162
            new_size if old_layout.align() == new_layout.align() => unsafe {
163
                // `realloc` probably checks for `new_size <= old_layout.size()` or something similar.
164
                assume(new_size <= old_layout.size());
165
166
                let raw_ptr = realloc(ptr.as_ptr(), old_layout, new_size);
167
                let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
168
                Ok(NonNull::new_unchecked(core::ptr::slice_from_raw_parts_mut(
169
                    ptr.as_ptr(),
170
                    new_size,
171
                )))
172
            },
173
174
            // SAFETY: because `new_size` must be smaller than or equal to `old_layout.size()`,
175
            // both the old and new memory allocation are valid for reads and writes for `new_size`
176
            // bytes. Also, because the old allocation wasn't yet deallocated, it cannot overlap
177
            // `new_ptr`. Thus, the call to `copy_nonoverlapping` is safe. The safety contract
178
            // for `dealloc` must be upheld by the caller.
179
            new_size => unsafe {
180
                let new_ptr = self.allocate(new_layout)?;
181
                core::ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr().cast(), new_size);
182
                self.deallocate(ptr, old_layout);
183
                Ok(new_ptr)
184
            },
185
        }
186
    }
187
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/allocator-api2-0.2.18/src/stable/alloc/mod.rs
Line
Count
Source
1
//! Memory allocation APIs
2
3
use core::{
4
    fmt,
5
    ptr::{self, NonNull},
6
};
7
8
#[cfg(feature = "alloc")]
9
mod global;
10
11
#[cfg(feature = "std")]
12
mod system;
13
14
pub use core::alloc::{GlobalAlloc, Layout, LayoutError};
15
16
#[cfg(feature = "alloc")]
17
pub use self::global::Global;
18
19
#[cfg(feature = "std")]
20
pub use self::system::System;
21
22
#[cfg(feature = "alloc")]
23
pub use alloc_crate::alloc::{alloc, alloc_zeroed, dealloc, realloc};
24
25
#[cfg(all(feature = "alloc", not(no_global_oom_handling)))]
26
pub use alloc_crate::alloc::handle_alloc_error;
27
28
/// The `AllocError` error indicates an allocation failure
29
/// that may be due to resource exhaustion or to
30
/// something wrong when combining the given input arguments with this
31
/// allocator.
32
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
33
pub struct AllocError;
34
35
#[cfg(feature = "std")]
36
impl std::error::Error for AllocError {}
37
38
// (we need this for downstream impl of trait Error)
39
impl fmt::Display for AllocError {
40
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41
0
        f.write_str("memory allocation failed")
42
0
    }
43
}
44
45
/// An implementation of `Allocator` can allocate, grow, shrink, and deallocate arbitrary blocks of
46
/// data described via [`Layout`][].
47
///
48
/// `Allocator` is designed to be implemented on ZSTs, references, or smart pointers because having
49
/// an allocator like `MyAlloc([u8; N])` cannot be moved, without updating the pointers to the
50
/// allocated memory.
51
///
52
/// Unlike [`GlobalAlloc`][], zero-sized allocations are allowed in `Allocator`. If an underlying
53
/// allocator does not support this (like jemalloc) or return a null pointer (such as
54
/// `libc::malloc`), this must be caught by the implementation.
55
///
56
/// ### Currently allocated memory
57
///
58
/// Some of the methods require that a memory block be *currently allocated* via an allocator. This
59
/// means that:
60
///
61
/// * the starting address for that memory block was previously returned by [`allocate`], [`grow`], or
62
///   [`shrink`], and
63
///
64
/// * the memory block has not been subsequently deallocated, where blocks are either deallocated
65
///   directly by being passed to [`deallocate`] or were changed by being passed to [`grow`] or
66
///   [`shrink`] that returns `Ok`. If `grow` or `shrink` have returned `Err`, the passed pointer
67
///   remains valid.
68
///
69
/// [`allocate`]: Allocator::allocate
70
/// [`grow`]: Allocator::grow
71
/// [`shrink`]: Allocator::shrink
72
/// [`deallocate`]: Allocator::deallocate
73
///
74
/// ### Memory fitting
75
///
76
/// Some of the methods require that a layout *fit* a memory block. What it means for a layout to
77
/// "fit" a memory block means (or equivalently, for a memory block to "fit" a layout) is that the
78
/// following conditions must hold:
79
///
80
/// * The block must be allocated with the same alignment as [`layout.align()`], and
81
///
82
/// * The provided [`layout.size()`] must fall in the range `min ..= max`, where:
83
///   - `min` is the size of the layout most recently used to allocate the block, and
84
///   - `max` is the latest actual size returned from [`allocate`], [`grow`], or [`shrink`].
85
///
86
/// [`layout.align()`]: Layout::align
87
/// [`layout.size()`]: Layout::size
88
///
89
/// # Safety
90
///
91
/// * Memory blocks returned from an allocator must point to valid memory and retain their validity
92
///   until the instance and all of its clones are dropped,
93
///
94
/// * cloning or moving the allocator must not invalidate memory blocks returned from this
95
///   allocator. A cloned allocator must behave like the same allocator, and
96
///
97
/// * any pointer to a memory block which is [*currently allocated*] may be passed to any other
98
///   method of the allocator.
99
///
100
/// [*currently allocated*]: #currently-allocated-memory
101
pub unsafe trait Allocator {
102
    /// Attempts to allocate a block of memory.
103
    ///
104
    /// On success, returns a [`NonNull<[u8]>`][NonNull] meeting the size and alignment guarantees of `layout`.
105
    ///
106
    /// The returned block may have a larger size than specified by `layout.size()`, and may or may
107
    /// not have its contents initialized.
108
    ///
109
    /// # Errors
110
    ///
111
    /// Returning `Err` indicates that either memory is exhausted or `layout` does not meet
112
    /// allocator's size or alignment constraints.
113
    ///
114
    /// Implementations are encouraged to return `Err` on memory exhaustion rather than panicking or
115
    /// aborting, but this is not a strict requirement. (Specifically: it is *legal* to implement
116
    /// this trait atop an underlying native allocation library that aborts on memory exhaustion.)
117
    ///
118
    /// Clients wishing to abort computation in response to an allocation error are encouraged to
119
    /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
120
    ///
121
    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
122
    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>;
123
124
    /// Behaves like `allocate`, but also ensures that the returned memory is zero-initialized.
125
    ///
126
    /// # Errors
127
    ///
128
    /// Returning `Err` indicates that either memory is exhausted or `layout` does not meet
129
    /// allocator's size or alignment constraints.
130
    ///
131
    /// Implementations are encouraged to return `Err` on memory exhaustion rather than panicking or
132
    /// aborting, but this is not a strict requirement. (Specifically: it is *legal* to implement
133
    /// this trait atop an underlying native allocation library that aborts on memory exhaustion.)
134
    ///
135
    /// Clients wishing to abort computation in response to an allocation error are encouraged to
136
    /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
137
    ///
138
    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
139
    #[inline(always)]
140
0
    fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
141
0
        let ptr = self.allocate(layout)?;
142
        // SAFETY: `alloc` returns a valid memory block
143
0
        unsafe { ptr.cast::<u8>().as_ptr().write_bytes(0, ptr.len()) }
144
0
        Ok(ptr)
145
0
    }
146
147
    /// Deallocates the memory referenced by `ptr`.
148
    ///
149
    /// # Safety
150
    ///
151
    /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator, and
152
    /// * `layout` must [*fit*] that block of memory.
153
    ///
154
    /// [*currently allocated*]: #currently-allocated-memory
155
    /// [*fit*]: #memory-fitting
156
    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout);
157
158
    /// Attempts to extend the memory block.
159
    ///
160
    /// Returns a new [`NonNull<[u8]>`][NonNull] containing a pointer and the actual size of the allocated
161
    /// memory. The pointer is suitable for holding data described by `new_layout`. To accomplish
162
    /// this, the allocator may extend the allocation referenced by `ptr` to fit the new layout.
163
    ///
164
    /// If this returns `Ok`, then ownership of the memory block referenced by `ptr` has been
165
    /// transferred to this allocator. Any access to the old `ptr` is Undefined Behavior, even if the
166
    /// allocation was grown in-place. The newly returned pointer is the only valid pointer
167
    /// for accessing this memory now.
168
    ///
169
    /// If this method returns `Err`, then ownership of the memory block has not been transferred to
170
    /// this allocator, and the contents of the memory block are unaltered.
171
    ///
172
    /// # Safety
173
    ///
174
    /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator.
175
    /// * `old_layout` must [*fit*] that block of memory (The `new_layout` argument need not fit it.).
176
    /// * `new_layout.size()` must be greater than or equal to `old_layout.size()`.
177
    ///
178
    /// Note that `new_layout.align()` need not be the same as `old_layout.align()`.
179
    ///
180
    /// [*currently allocated*]: #currently-allocated-memory
181
    /// [*fit*]: #memory-fitting
182
    ///
183
    /// # Errors
184
    ///
185
    /// Returns `Err` if the new layout does not meet the allocator's size and alignment
186
    /// constraints of the allocator, or if growing otherwise fails.
187
    ///
188
    /// Implementations are encouraged to return `Err` on memory exhaustion rather than panicking or
189
    /// aborting, but this is not a strict requirement. (Specifically: it is *legal* to implement
190
    /// this trait atop an underlying native allocation library that aborts on memory exhaustion.)
191
    ///
192
    /// Clients wishing to abort computation in response to an allocation error are encouraged to
193
    /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
194
    ///
195
    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
196
    #[inline(always)]
197
0
    unsafe fn grow(
198
0
        &self,
199
0
        ptr: NonNull<u8>,
200
0
        old_layout: Layout,
201
0
        new_layout: Layout,
202
0
    ) -> Result<NonNull<[u8]>, AllocError> {
203
0
        debug_assert!(
204
0
            new_layout.size() >= old_layout.size(),
205
            "`new_layout.size()` must be greater than or equal to `old_layout.size()`"
206
        );
207
208
0
        let new_ptr = self.allocate(new_layout)?;
209
210
        // SAFETY: because `new_layout.size()` must be greater than or equal to
211
        // `old_layout.size()`, both the old and new memory allocation are valid for reads and
212
        // writes for `old_layout.size()` bytes. Also, because the old allocation wasn't yet
213
        // deallocated, it cannot overlap `new_ptr`. Thus, the call to `copy_nonoverlapping` is
214
        // safe. The safety contract for `dealloc` must be upheld by the caller.
215
0
        unsafe {
216
0
            ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr().cast(), old_layout.size());
217
0
            self.deallocate(ptr, old_layout);
218
0
        }
219
0
220
0
        Ok(new_ptr)
221
0
    }
222
223
    /// Behaves like `grow`, but also ensures that the new contents are set to zero before being
224
    /// returned.
225
    ///
226
    /// The memory block will contain the following contents after a successful call to
227
    /// `grow_zeroed`:
228
    ///   * Bytes `0..old_layout.size()` are preserved from the original allocation.
229
    ///   * Bytes `old_layout.size()..old_size` will either be preserved or zeroed, depending on
230
    ///     the allocator implementation. `old_size` refers to the size of the memory block prior
231
    ///     to the `grow_zeroed` call, which may be larger than the size that was originally
232
    ///     requested when it was allocated.
233
    ///   * Bytes `old_size..new_size` are zeroed. `new_size` refers to the size of the memory
234
    ///     block returned by the `grow_zeroed` call.
235
    ///
236
    /// # Safety
237
    ///
238
    /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator.
239
    /// * `old_layout` must [*fit*] that block of memory (The `new_layout` argument need not fit it.).
240
    /// * `new_layout.size()` must be greater than or equal to `old_layout.size()`.
241
    ///
242
    /// Note that `new_layout.align()` need not be the same as `old_layout.align()`.
243
    ///
244
    /// [*currently allocated*]: #currently-allocated-memory
245
    /// [*fit*]: #memory-fitting
246
    ///
247
    /// # Errors
248
    ///
249
    /// Returns `Err` if the new layout does not meet the allocator's size and alignment
250
    /// constraints of the allocator, or if growing otherwise fails.
251
    ///
252
    /// Implementations are encouraged to return `Err` on memory exhaustion rather than panicking or
253
    /// aborting, but this is not a strict requirement. (Specifically: it is *legal* to implement
254
    /// this trait atop an underlying native allocation library that aborts on memory exhaustion.)
255
    ///
256
    /// Clients wishing to abort computation in response to an allocation error are encouraged to
257
    /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
258
    ///
259
    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
260
    #[inline(always)]
261
0
    unsafe fn grow_zeroed(
262
0
        &self,
263
0
        ptr: NonNull<u8>,
264
0
        old_layout: Layout,
265
0
        new_layout: Layout,
266
0
    ) -> Result<NonNull<[u8]>, AllocError> {
267
0
        debug_assert!(
268
0
            new_layout.size() >= old_layout.size(),
269
            "`new_layout.size()` must be greater than or equal to `old_layout.size()`"
270
        );
271
272
0
        let new_ptr = self.allocate_zeroed(new_layout)?;
273
274
        // SAFETY: because `new_layout.size()` must be greater than or equal to
275
        // `old_layout.size()`, both the old and new memory allocation are valid for reads and
276
        // writes for `old_layout.size()` bytes. Also, because the old allocation wasn't yet
277
        // deallocated, it cannot overlap `new_ptr`. Thus, the call to `copy_nonoverlapping` is
278
        // safe. The safety contract for `dealloc` must be upheld by the caller.
279
0
        unsafe {
280
0
            ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr().cast(), old_layout.size());
281
0
            self.deallocate(ptr, old_layout);
282
0
        }
283
0
284
0
        Ok(new_ptr)
285
0
    }
286
287
    /// Attempts to shrink the memory block.
288
    ///
289
    /// Returns a new [`NonNull<[u8]>`][NonNull] containing a pointer and the actual size of the allocated
290
    /// memory. The pointer is suitable for holding data described by `new_layout`. To accomplish
291
    /// this, the allocator may shrink the allocation referenced by `ptr` to fit the new layout.
292
    ///
293
    /// If this returns `Ok`, then ownership of the memory block referenced by `ptr` has been
294
    /// transferred to this allocator. Any access to the old `ptr` is Undefined Behavior, even if the
295
    /// allocation was shrunk in-place. The newly returned pointer is the only valid pointer
296
    /// for accessing this memory now.
297
    ///
298
    /// If this method returns `Err`, then ownership of the memory block has not been transferred to
299
    /// this allocator, and the contents of the memory block are unaltered.
300
    ///
301
    /// # Safety
302
    ///
303
    /// * `ptr` must denote a block of memory [*currently allocated*] via this allocator.
304
    /// * `old_layout` must [*fit*] that block of memory (The `new_layout` argument need not fit it.).
305
    /// * `new_layout.size()` must be smaller than or equal to `old_layout.size()`.
306
    ///
307
    /// Note that `new_layout.align()` need not be the same as `old_layout.align()`.
308
    ///
309
    /// [*currently allocated*]: #currently-allocated-memory
310
    /// [*fit*]: #memory-fitting
311
    ///
312
    /// # Errors
313
    ///
314
    /// Returns `Err` if the new layout does not meet the allocator's size and alignment
315
    /// constraints of the allocator, or if shrinking otherwise fails.
316
    ///
317
    /// Implementations are encouraged to return `Err` on memory exhaustion rather than panicking or
318
    /// aborting, but this is not a strict requirement. (Specifically: it is *legal* to implement
319
    /// this trait atop an underlying native allocation library that aborts on memory exhaustion.)
320
    ///
321
    /// Clients wishing to abort computation in response to an allocation error are encouraged to
322
    /// call the [`handle_alloc_error`] function, rather than directly invoking `panic!` or similar.
323
    ///
324
    /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
325
    #[inline(always)]
326
0
    unsafe fn shrink(
327
0
        &self,
328
0
        ptr: NonNull<u8>,
329
0
        old_layout: Layout,
330
0
        new_layout: Layout,
331
0
    ) -> Result<NonNull<[u8]>, AllocError> {
332
0
        debug_assert!(
333
0
            new_layout.size() <= old_layout.size(),
334
            "`new_layout.size()` must be smaller than or equal to `old_layout.size()`"
335
        );
336
337
0
        let new_ptr = self.allocate(new_layout)?;
338
339
        // SAFETY: because `new_layout.size()` must be lower than or equal to
340
        // `old_layout.size()`, both the old and new memory allocation are valid for reads and
341
        // writes for `new_layout.size()` bytes. Also, because the old allocation wasn't yet
342
        // deallocated, it cannot overlap `new_ptr`. Thus, the call to `copy_nonoverlapping` is
343
        // safe. The safety contract for `dealloc` must be upheld by the caller.
344
0
        unsafe {
345
0
            ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr().cast(), new_layout.size());
346
0
            self.deallocate(ptr, old_layout);
347
0
        }
348
0
349
0
        Ok(new_ptr)
350
0
    }
351
352
    /// Creates a "by reference" adapter for this instance of `Allocator`.
353
    ///
354
    /// The returned adapter also implements `Allocator` and will simply borrow this.
355
    #[inline(always)]
356
    fn by_ref(&self) -> &Self
357
    where
358
        Self: Sized,
359
    {
360
        self
361
    }
362
}
363
364
unsafe impl<A> Allocator for &A
365
where
366
    A: Allocator + ?Sized,
367
{
368
    #[inline(always)]
369
0
    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
370
0
        (**self).allocate(layout)
371
0
    }
372
373
    #[inline(always)]
374
0
    fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
375
0
        (**self).allocate_zeroed(layout)
376
0
    }
377
378
    #[inline(always)]
379
0
    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
380
0
        // SAFETY: the safety contract must be upheld by the caller
381
0
        unsafe { (**self).deallocate(ptr, layout) }
382
0
    }
383
384
    #[inline(always)]
385
0
    unsafe fn grow(
386
0
        &self,
387
0
        ptr: NonNull<u8>,
388
0
        old_layout: Layout,
389
0
        new_layout: Layout,
390
0
    ) -> Result<NonNull<[u8]>, AllocError> {
391
0
        // SAFETY: the safety contract must be upheld by the caller
392
0
        unsafe { (**self).grow(ptr, old_layout, new_layout) }
393
0
    }
394
395
    #[inline(always)]
396
0
    unsafe fn grow_zeroed(
397
0
        &self,
398
0
        ptr: NonNull<u8>,
399
0
        old_layout: Layout,
400
0
        new_layout: Layout,
401
0
    ) -> Result<NonNull<[u8]>, AllocError> {
402
0
        // SAFETY: the safety contract must be upheld by the caller
403
0
        unsafe { (**self).grow_zeroed(ptr, old_layout, new_layout) }
404
0
    }
405
406
    #[inline(always)]
407
0
    unsafe fn shrink(
408
0
        &self,
409
0
        ptr: NonNull<u8>,
410
0
        old_layout: Layout,
411
0
        new_layout: Layout,
412
0
    ) -> Result<NonNull<[u8]>, AllocError> {
413
0
        // SAFETY: the safety contract must be upheld by the caller
414
0
        unsafe { (**self).shrink(ptr, old_layout, new_layout) }
415
0
    }
416
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/allocator-api2-0.2.18/src/stable/boxed.rs
Line
Count
Source
1
//! The `Box<T>` type for heap allocation.
2
//!
3
//! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
4
//! heap allocation in Rust. Boxes provide ownership for this allocation, and
5
//! drop their contents when they go out of scope. Boxes also ensure that they
6
//! never allocate more than `isize::MAX` bytes.
7
//!
8
//! # Examples
9
//!
10
//! Move a value from the stack to the heap by creating a [`Box`]:
11
//!
12
//! ```
13
//! let val: u8 = 5;
14
//! let boxed: Box<u8> = Box::new(val);
15
//! ```
16
//!
17
//! Move a value from a [`Box`] back to the stack by [dereferencing]:
18
//!
19
//! ```
20
//! let boxed: Box<u8> = Box::new(5);
21
//! let val: u8 = *boxed;
22
//! ```
23
//!
24
//! Creating a recursive data structure:
25
//!
26
//! ```
27
//! #[derive(Debug)]
28
//! enum List<T> {
29
//!     Cons(T, Box<List<T>>),
30
//!     Nil,
31
//! }
32
//!
33
//! let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
34
//! println!("{list:?}");
35
//! ```
36
//!
37
//! This will print `Cons(1, Cons(2, Nil))`.
38
//!
39
//! Recursive structures must be boxed, because if the definition of `Cons`
40
//! looked like this:
41
//!
42
//! ```compile_fail,E0072
43
//! # enum List<T> {
44
//! Cons(T, List<T>),
45
//! # }
46
//! ```
47
//!
48
//! It wouldn't work. This is because the size of a `List` depends on how many
49
//! elements are in the list, and so we don't know how much memory to allocate
50
//! for a `Cons`. By introducing a [`Box<T>`], which has a defined size, we know how
51
//! big `Cons` needs to be.
52
//!
53
//! # Memory layout
54
//!
55
//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for
56
//! its allocation. It is valid to convert both ways between a [`Box`] and a
57
//! raw pointer allocated with the [`Global`] allocator, given that the
58
//! [`Layout`] used with the allocator is correct for the type. More precisely,
59
//! a `value: *mut T` that has been allocated with the [`Global`] allocator
60
//! with `Layout::for_value(&*value)` may be converted into a box using
61
//! [`Box::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut
62
//! T` obtained from [`Box::<T>::into_raw`] may be deallocated using the
63
//! [`Global`] allocator with [`Layout::for_value(&*value)`].
64
//!
65
//! For zero-sized values, the `Box` pointer still has to be [valid] for reads
66
//! and writes and sufficiently aligned. In particular, casting any aligned
67
//! non-zero integer literal to a raw pointer produces a valid pointer, but a
68
//! pointer pointing into previously allocated memory that since got freed is
69
//! not valid. The recommended way to build a Box to a ZST if `Box::new` cannot
70
//! be used is to use [`ptr::NonNull::dangling`].
71
//!
72
//! So long as `T: Sized`, a `Box<T>` is guaranteed to be represented
73
//! as a single pointer and is also ABI-compatible with C pointers
74
//! (i.e. the C type `T*`). This means that if you have extern "C"
75
//! Rust functions that will be called from C, you can define those
76
//! Rust functions using `Box<T>` types, and use `T*` as corresponding
77
//! type on the C side. As an example, consider this C header which
78
//! declares functions that create and destroy some kind of `Foo`
79
//! value:
80
//!
81
//! ```c
82
//! /* C header */
83
//!
84
//! /* Returns ownership to the caller */
85
//! struct Foo* foo_new(void);
86
//!
87
//! /* Takes ownership from the caller; no-op when invoked with null */
88
//! void foo_delete(struct Foo*);
89
//! ```
90
//!
91
//! These two functions might be implemented in Rust as follows. Here, the
92
//! `struct Foo*` type from C is translated to `Box<Foo>`, which captures
93
//! the ownership constraints. Note also that the nullable argument to
94
//! `foo_delete` is represented in Rust as `Option<Box<Foo>>`, since `Box<Foo>`
95
//! cannot be null.
96
//!
97
//! ```
98
//! #[repr(C)]
99
//! pub struct Foo;
100
//!
101
//! #[no_mangle]
102
//! pub extern "C" fn foo_new() -> Box<Foo> {
103
//!     Box::new(Foo)
104
//! }
105
//!
106
//! #[no_mangle]
107
//! pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {}
108
//! ```
109
//!
110
//! Even though `Box<T>` has the same representation and C ABI as a C pointer,
111
//! this does not mean that you can convert an arbitrary `T*` into a `Box<T>`
112
//! and expect things to work. `Box<T>` values will always be fully aligned,
113
//! non-null pointers. Moreover, the destructor for `Box<T>` will attempt to
114
//! free the value with the global allocator. In general, the best practice
115
//! is to only use `Box<T>` for pointers that originated from the global
116
//! allocator.
117
//!
118
//! **Important.** At least at present, you should avoid using
119
//! `Box<T>` types for functions that are defined in C but invoked
120
//! from Rust. In those cases, you should directly mirror the C types
121
//! as closely as possible. Using types like `Box<T>` where the C
122
//! definition is just using `T*` can lead to undefined behavior, as
123
//! described in [rust-lang/unsafe-code-guidelines#198][ucg#198].
124
//!
125
//! # Considerations for unsafe code
126
//!
127
//! **Warning: This section is not normative and is subject to change, possibly
128
//! being relaxed in the future! It is a simplified summary of the rules
129
//! currently implemented in the compiler.**
130
//!
131
//! The aliasing rules for `Box<T>` are the same as for `&mut T`. `Box<T>`
132
//! asserts uniqueness over its content. Using raw pointers derived from a box
133
//! after that box has been mutated through, moved or borrowed as `&mut T`
134
//! is not allowed. For more guidance on working with box from unsafe code, see
135
//! [rust-lang/unsafe-code-guidelines#326][ucg#326].
136
//!
137
//!
138
//! [ucg#198]: https://github.com/rust-lang/unsafe-code-guidelines/issues/198
139
//! [ucg#326]: https://github.com/rust-lang/unsafe-code-guidelines/issues/326
140
//! [dereferencing]: core::ops::Deref
141
//! [`Box::<T>::from_raw(value)`]: Box::from_raw
142
//! [`Global`]: crate::alloc::Global
143
//! [`Layout`]: crate::alloc::Layout
144
//! [`Layout::for_value(&*value)`]: crate::alloc::Layout::for_value
145
//! [valid]: ptr#safety
146
147
use core::any::Any;
148
use core::borrow;
149
use core::cmp::Ordering;
150
use core::convert::{From, TryFrom};
151
152
// use core::error::Error;
153
use core::fmt;
154
use core::future::Future;
155
use core::hash::{Hash, Hasher};
156
#[cfg(not(no_global_oom_handling))]
157
use core::iter::FromIterator;
158
use core::iter::{FusedIterator, Iterator};
159
use core::marker::Unpin;
160
use core::mem;
161
use core::ops::{Deref, DerefMut};
162
use core::pin::Pin;
163
use core::ptr::{self, NonNull};
164
use core::task::{Context, Poll};
165
166
use super::alloc::{AllocError, Allocator, Global, Layout};
167
use super::raw_vec::RawVec;
168
#[cfg(not(no_global_oom_handling))]
169
use super::vec::Vec;
170
#[cfg(not(no_global_oom_handling))]
171
use alloc_crate::alloc::handle_alloc_error;
172
173
/// A pointer type for heap allocation.
174
///
175
/// See the [module-level documentation](../../std/boxed/index.html) for more.
176
pub struct Box<T: ?Sized, A: Allocator = Global>(NonNull<T>, A);
177
178
// Safety: Box owns both T and A, so sending is safe if
179
// sending is safe for T and A.
180
unsafe impl<T: ?Sized, A: Allocator> Send for Box<T, A>
181
where
182
    T: Send,
183
    A: Send,
184
{
185
}
186
187
// Safety: Box owns both T and A, so sharing is safe if
188
// sharing is safe for T and A.
189
unsafe impl<T: ?Sized, A: Allocator> Sync for Box<T, A>
190
where
191
    T: Sync,
192
    A: Sync,
193
{
194
}
195
196
impl<T> Box<T> {
197
    /// Allocates memory on the heap and then places `x` into it.
198
    ///
199
    /// This doesn't actually allocate if `T` is zero-sized.
200
    ///
201
    /// # Examples
202
    ///
203
    /// ```
204
    /// let five = Box::new(5);
205
    /// ```
206
    #[cfg(all(not(no_global_oom_handling)))]
207
    #[inline(always)]
208
    #[must_use]
209
0
    pub fn new(x: T) -> Self {
210
0
        Self::new_in(x, Global)
211
0
    }
212
213
    /// Constructs a new box with uninitialized contents.
214
    ///
215
    /// # Examples
216
    ///
217
    /// ```
218
    /// #![feature(new_uninit)]
219
    ///
220
    /// let mut five = Box::<u32>::new_uninit();
221
    ///
222
    /// let five = unsafe {
223
    ///     // Deferred initialization:
224
    ///     five.as_mut_ptr().write(5);
225
    ///
226
    ///     five.assume_init()
227
    /// };
228
    ///
229
    /// assert_eq!(*five, 5)
230
    /// ```
231
    #[cfg(not(no_global_oom_handling))]
232
    #[must_use]
233
    #[inline(always)]
234
0
    pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
235
0
        Self::new_uninit_in(Global)
236
0
    }
237
238
    /// Constructs a new `Box` with uninitialized contents, with the memory
239
    /// being filled with `0` bytes.
240
    ///
241
    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
242
    /// of this method.
243
    ///
244
    /// # Examples
245
    ///
246
    /// ```
247
    /// #![feature(new_uninit)]
248
    ///
249
    /// let zero = Box::<u32>::new_zeroed();
250
    /// let zero = unsafe { zero.assume_init() };
251
    ///
252
    /// assert_eq!(*zero, 0)
253
    /// ```
254
    ///
255
    /// [zeroed]: mem::MaybeUninit::zeroed
256
    #[cfg(not(no_global_oom_handling))]
257
    #[must_use]
258
    #[inline(always)]
259
0
    pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> {
260
0
        Self::new_zeroed_in(Global)
261
0
    }
262
263
    /// Constructs a new `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
264
    /// `x` will be pinned in memory and unable to be moved.
265
    ///
266
    /// Constructing and pinning of the `Box` can also be done in two steps: `Box::pin(x)`
267
    /// does the same as <code>[Box::into_pin]\([Box::new]\(x))</code>. Consider using
268
    /// [`into_pin`](Box::into_pin) if you already have a `Box<T>`, or if you want to
269
    /// construct a (pinned) `Box` in a different way than with [`Box::new`].
270
    #[cfg(not(no_global_oom_handling))]
271
    #[must_use]
272
    #[inline(always)]
273
0
    pub fn pin(x: T) -> Pin<Box<T>> {
274
0
        Box::new(x).into()
275
0
    }
276
277
    /// Allocates memory on the heap then places `x` into it,
278
    /// returning an error if the allocation fails
279
    ///
280
    /// This doesn't actually allocate if `T` is zero-sized.
281
    ///
282
    /// # Examples
283
    ///
284
    /// ```
285
    /// #![feature(allocator_api)]
286
    ///
287
    /// let five = Box::try_new(5)?;
288
    /// # Ok::<(), std::alloc::AllocError>(())
289
    /// ```
290
    #[inline(always)]
291
0
    pub fn try_new(x: T) -> Result<Self, AllocError> {
292
0
        Self::try_new_in(x, Global)
293
0
    }
294
295
    /// Constructs a new box with uninitialized contents on the heap,
296
    /// returning an error if the allocation fails
297
    ///
298
    /// # Examples
299
    ///
300
    /// ```
301
    /// #![feature(allocator_api, new_uninit)]
302
    ///
303
    /// let mut five = Box::<u32>::try_new_uninit()?;
304
    ///
305
    /// let five = unsafe {
306
    ///     // Deferred initialization:
307
    ///     five.as_mut_ptr().write(5);
308
    ///
309
    ///     five.assume_init()
310
    /// };
311
    ///
312
    /// assert_eq!(*five, 5);
313
    /// # Ok::<(), std::alloc::AllocError>(())
314
    /// ```
315
    #[inline(always)]
316
0
    pub fn try_new_uninit() -> Result<Box<mem::MaybeUninit<T>>, AllocError> {
317
0
        Box::try_new_uninit_in(Global)
318
0
    }
319
320
    /// Constructs a new `Box` with uninitialized contents, with the memory
321
    /// being filled with `0` bytes on the heap
322
    ///
323
    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
324
    /// of this method.
325
    ///
326
    /// # Examples
327
    ///
328
    /// ```
329
    /// #![feature(allocator_api, new_uninit)]
330
    ///
331
    /// let zero = Box::<u32>::try_new_zeroed()?;
332
    /// let zero = unsafe { zero.assume_init() };
333
    ///
334
    /// assert_eq!(*zero, 0);
335
    /// # Ok::<(), std::alloc::AllocError>(())
336
    /// ```
337
    ///
338
    /// [zeroed]: mem::MaybeUninit::zeroed
339
    #[inline(always)]
340
0
    pub fn try_new_zeroed() -> Result<Box<mem::MaybeUninit<T>>, AllocError> {
341
0
        Box::try_new_zeroed_in(Global)
342
0
    }
343
}
344
345
impl<T, A: Allocator> Box<T, A> {
346
    /// Allocates memory in the given allocator then places `x` into it.
347
    ///
348
    /// This doesn't actually allocate if `T` is zero-sized.
349
    ///
350
    /// # Examples
351
    ///
352
    /// ```
353
    /// #![feature(allocator_api)]
354
    ///
355
    /// use std::alloc::System;
356
    ///
357
    /// let five = Box::new_in(5, System);
358
    /// ```
359
    #[cfg(not(no_global_oom_handling))]
360
    #[must_use]
361
    #[inline(always)]
362
0
    pub fn new_in(x: T, alloc: A) -> Self
363
0
    where
364
0
        A: Allocator,
365
0
    {
366
0
        let mut boxed = Self::new_uninit_in(alloc);
367
0
        unsafe {
368
0
            boxed.as_mut_ptr().write(x);
369
0
            boxed.assume_init()
370
0
        }
371
0
    }
372
373
    /// Allocates memory in the given allocator then places `x` into it,
374
    /// returning an error if the allocation fails
375
    ///
376
    /// This doesn't actually allocate if `T` is zero-sized.
377
    ///
378
    /// # Examples
379
    ///
380
    /// ```
381
    /// #![feature(allocator_api)]
382
    ///
383
    /// use std::alloc::System;
384
    ///
385
    /// let five = Box::try_new_in(5, System)?;
386
    /// # Ok::<(), std::alloc::AllocError>(())
387
    /// ```
388
    #[inline(always)]
389
0
    pub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
390
0
    where
391
0
        A: Allocator,
392
0
    {
393
0
        let mut boxed = Self::try_new_uninit_in(alloc)?;
394
        unsafe {
395
0
            boxed.as_mut_ptr().write(x);
396
0
            Ok(boxed.assume_init())
397
        }
398
0
    }
399
400
    /// Constructs a new box with uninitialized contents in the provided allocator.
401
    ///
402
    /// # Examples
403
    ///
404
    /// ```
405
    /// #![feature(allocator_api, new_uninit)]
406
    ///
407
    /// use std::alloc::System;
408
    ///
409
    /// let mut five = Box::<u32, _>::new_uninit_in(System);
410
    ///
411
    /// let five = unsafe {
412
    ///     // Deferred initialization:
413
    ///     five.as_mut_ptr().write(5);
414
    ///
415
    ///     five.assume_init()
416
    /// };
417
    ///
418
    /// assert_eq!(*five, 5)
419
    /// ```
420
    #[cfg(not(no_global_oom_handling))]
421
    #[must_use]
422
    // #[unstable(feature = "new_uninit", issue = "63291")]
423
    #[inline(always)]
424
0
    pub fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
425
0
    where
426
0
        A: Allocator,
427
0
    {
428
0
        let layout = Layout::new::<mem::MaybeUninit<T>>();
429
0
        // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
430
0
        // That would make code size bigger.
431
0
        match Box::try_new_uninit_in(alloc) {
432
0
            Ok(m) => m,
433
0
            Err(_) => handle_alloc_error(layout),
434
        }
435
0
    }
436
437
    /// Constructs a new box with uninitialized contents in the provided allocator,
438
    /// returning an error if the allocation fails
439
    ///
440
    /// # Examples
441
    ///
442
    /// ```
443
    /// #![feature(allocator_api, new_uninit)]
444
    ///
445
    /// use std::alloc::System;
446
    ///
447
    /// let mut five = Box::<u32, _>::try_new_uninit_in(System)?;
448
    ///
449
    /// let five = unsafe {
450
    ///     // Deferred initialization:
451
    ///     five.as_mut_ptr().write(5);
452
    ///
453
    ///     five.assume_init()
454
    /// };
455
    ///
456
    /// assert_eq!(*five, 5);
457
    /// # Ok::<(), std::alloc::AllocError>(())
458
    /// ```
459
    #[inline(always)]
460
0
    pub fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
461
0
    where
462
0
        A: Allocator,
463
0
    {
464
0
        let layout = Layout::new::<mem::MaybeUninit<T>>();
465
0
        let ptr = alloc.allocate(layout)?.cast();
466
0
        unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
467
0
    }
468
469
    /// Constructs a new `Box` with uninitialized contents, with the memory
470
    /// being filled with `0` bytes in the provided allocator.
471
    ///
472
    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
473
    /// of this method.
474
    ///
475
    /// # Examples
476
    ///
477
    /// ```
478
    /// #![feature(allocator_api, new_uninit)]
479
    ///
480
    /// use std::alloc::System;
481
    ///
482
    /// let zero = Box::<u32, _>::new_zeroed_in(System);
483
    /// let zero = unsafe { zero.assume_init() };
484
    ///
485
    /// assert_eq!(*zero, 0)
486
    /// ```
487
    ///
488
    /// [zeroed]: mem::MaybeUninit::zeroed
489
    #[cfg(not(no_global_oom_handling))]
490
    // #[unstable(feature = "new_uninit", issue = "63291")]
491
    #[must_use]
492
    #[inline(always)]
493
0
    pub fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
494
0
    where
495
0
        A: Allocator,
496
0
    {
497
0
        let layout = Layout::new::<mem::MaybeUninit<T>>();
498
0
        // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
499
0
        // That would make code size bigger.
500
0
        match Box::try_new_zeroed_in(alloc) {
501
0
            Ok(m) => m,
502
0
            Err(_) => handle_alloc_error(layout),
503
        }
504
0
    }
505
506
    /// Constructs a new `Box` with uninitialized contents, with the memory
507
    /// being filled with `0` bytes in the provided allocator,
508
    /// returning an error if the allocation fails,
509
    ///
510
    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
511
    /// of this method.
512
    ///
513
    /// # Examples
514
    ///
515
    /// ```
516
    /// #![feature(allocator_api, new_uninit)]
517
    ///
518
    /// use std::alloc::System;
519
    ///
520
    /// let zero = Box::<u32, _>::try_new_zeroed_in(System)?;
521
    /// let zero = unsafe { zero.assume_init() };
522
    ///
523
    /// assert_eq!(*zero, 0);
524
    /// # Ok::<(), std::alloc::AllocError>(())
525
    /// ```
526
    ///
527
    /// [zeroed]: mem::MaybeUninit::zeroed
528
    #[inline(always)]
529
0
    pub fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
530
0
    where
531
0
        A: Allocator,
532
0
    {
533
0
        let layout = Layout::new::<mem::MaybeUninit<T>>();
534
0
        let ptr = alloc.allocate_zeroed(layout)?.cast();
535
0
        unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
536
0
    }
537
538
    /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then
539
    /// `x` will be pinned in memory and unable to be moved.
540
    ///
541
    /// Constructing and pinning of the `Box` can also be done in two steps: `Box::pin_in(x, alloc)`
542
    /// does the same as <code>[Box::into_pin]\([Box::new_in]\(x, alloc))</code>. Consider using
543
    /// [`into_pin`](Box::into_pin) if you already have a `Box<T, A>`, or if you want to
544
    /// construct a (pinned) `Box` in a different way than with [`Box::new_in`].
545
    #[cfg(not(no_global_oom_handling))]
546
    #[must_use]
547
    #[inline(always)]
548
0
    pub fn pin_in(x: T, alloc: A) -> Pin<Self>
549
0
    where
550
0
        A: 'static + Allocator,
551
0
    {
552
0
        Self::into_pin(Self::new_in(x, alloc))
553
0
    }
554
555
    /// Converts a `Box<T>` into a `Box<[T]>`
556
    ///
557
    /// This conversion does not allocate on the heap and happens in place.
558
    #[inline(always)]
559
0
    pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
560
0
        let (raw, alloc) = Box::into_raw_with_allocator(boxed);
561
0
        unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) }
562
0
    }
563
564
    /// Consumes the `Box`, returning the wrapped value.
565
    ///
566
    /// # Examples
567
    ///
568
    /// ```
569
    /// #![feature(box_into_inner)]
570
    ///
571
    /// let c = Box::new(5);
572
    ///
573
    /// assert_eq!(Box::into_inner(c), 5);
574
    /// ```
575
    #[inline(always)]
576
0
    pub fn into_inner(boxed: Self) -> T {
577
0
        let ptr = boxed.0;
578
0
        let unboxed = unsafe { ptr.as_ptr().read() };
579
0
        unsafe { boxed.1.deallocate(ptr.cast(), Layout::new::<T>()) };
580
0
        unboxed
581
0
    }
582
}
583
584
impl<T> Box<[T]> {
585
    /// Constructs a new boxed slice with uninitialized contents.
586
    ///
587
    /// # Examples
588
    ///
589
    /// ```
590
    /// #![feature(new_uninit)]
591
    ///
592
    /// let mut values = Box::<[u32]>::new_uninit_slice(3);
593
    ///
594
    /// let values = unsafe {
595
    ///     // Deferred initialization:
596
    ///     values[0].as_mut_ptr().write(1);
597
    ///     values[1].as_mut_ptr().write(2);
598
    ///     values[2].as_mut_ptr().write(3);
599
    ///
600
    ///     values.assume_init()
601
    /// };
602
    ///
603
    /// assert_eq!(*values, [1, 2, 3])
604
    /// ```
605
    #[cfg(not(no_global_oom_handling))]
606
    #[must_use]
607
    #[inline(always)]
608
0
    pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
609
0
        unsafe { RawVec::with_capacity(len).into_box(len) }
610
0
    }
611
612
    /// Constructs a new boxed slice with uninitialized contents, with the memory
613
    /// being filled with `0` bytes.
614
    ///
615
    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
616
    /// of this method.
617
    ///
618
    /// # Examples
619
    ///
620
    /// ```
621
    /// #![feature(new_uninit)]
622
    ///
623
    /// let values = Box::<[u32]>::new_zeroed_slice(3);
624
    /// let values = unsafe { values.assume_init() };
625
    ///
626
    /// assert_eq!(*values, [0, 0, 0])
627
    /// ```
628
    ///
629
    /// [zeroed]: mem::MaybeUninit::zeroed
630
    #[cfg(not(no_global_oom_handling))]
631
    #[must_use]
632
    #[inline(always)]
633
0
    pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
634
0
        unsafe { RawVec::with_capacity_zeroed(len).into_box(len) }
635
0
    }
636
637
    /// Constructs a new boxed slice with uninitialized contents. Returns an error if
638
    /// the allocation fails
639
    ///
640
    /// # Examples
641
    ///
642
    /// ```
643
    /// #![feature(allocator_api, new_uninit)]
644
    ///
645
    /// let mut values = Box::<[u32]>::try_new_uninit_slice(3)?;
646
    /// let values = unsafe {
647
    ///     // Deferred initialization:
648
    ///     values[0].as_mut_ptr().write(1);
649
    ///     values[1].as_mut_ptr().write(2);
650
    ///     values[2].as_mut_ptr().write(3);
651
    ///     values.assume_init()
652
    /// };
653
    ///
654
    /// assert_eq!(*values, [1, 2, 3]);
655
    /// # Ok::<(), std::alloc::AllocError>(())
656
    /// ```
657
    #[inline(always)]
658
0
    pub fn try_new_uninit_slice(len: usize) -> Result<Box<[mem::MaybeUninit<T>]>, AllocError> {
659
        unsafe {
660
0
            let layout = match Layout::array::<mem::MaybeUninit<T>>(len) {
661
0
                Ok(l) => l,
662
0
                Err(_) => return Err(AllocError),
663
            };
664
0
            let ptr = Global.allocate(layout)?;
665
0
            Ok(RawVec::from_raw_parts_in(ptr.as_ptr() as *mut _, len, Global).into_box(len))
666
        }
667
0
    }
668
669
    /// Constructs a new boxed slice with uninitialized contents, with the memory
670
    /// being filled with `0` bytes. Returns an error if the allocation fails
671
    ///
672
    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
673
    /// of this method.
674
    ///
675
    /// # Examples
676
    ///
677
    /// ```
678
    /// #![feature(allocator_api, new_uninit)]
679
    ///
680
    /// let values = Box::<[u32]>::try_new_zeroed_slice(3)?;
681
    /// let values = unsafe { values.assume_init() };
682
    ///
683
    /// assert_eq!(*values, [0, 0, 0]);
684
    /// # Ok::<(), std::alloc::AllocError>(())
685
    /// ```
686
    ///
687
    /// [zeroed]: mem::MaybeUninit::zeroed
688
    #[inline(always)]
689
0
    pub fn try_new_zeroed_slice(len: usize) -> Result<Box<[mem::MaybeUninit<T>]>, AllocError> {
690
        unsafe {
691
0
            let layout = match Layout::array::<mem::MaybeUninit<T>>(len) {
692
0
                Ok(l) => l,
693
0
                Err(_) => return Err(AllocError),
694
            };
695
0
            let ptr = Global.allocate_zeroed(layout)?;
696
0
            Ok(RawVec::from_raw_parts_in(ptr.as_ptr() as *mut _, len, Global).into_box(len))
697
        }
698
0
    }
699
}
700
701
impl<T, A: Allocator> Box<[T], A> {
702
    /// Constructs a new boxed slice with uninitialized contents in the provided allocator.
703
    ///
704
    /// # Examples
705
    ///
706
    /// ```
707
    /// #![feature(allocator_api, new_uninit)]
708
    ///
709
    /// use std::alloc::System;
710
    ///
711
    /// let mut values = Box::<[u32], _>::new_uninit_slice_in(3, System);
712
    ///
713
    /// let values = unsafe {
714
    ///     // Deferred initialization:
715
    ///     values[0].as_mut_ptr().write(1);
716
    ///     values[1].as_mut_ptr().write(2);
717
    ///     values[2].as_mut_ptr().write(3);
718
    ///
719
    ///     values.assume_init()
720
    /// };
721
    ///
722
    /// assert_eq!(*values, [1, 2, 3])
723
    /// ```
724
    #[cfg(not(no_global_oom_handling))]
725
    #[must_use]
726
    #[inline(always)]
727
0
    pub fn new_uninit_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit<T>], A> {
728
0
        unsafe { RawVec::with_capacity_in(len, alloc).into_box(len) }
729
0
    }
730
731
    /// Constructs a new boxed slice with uninitialized contents in the provided allocator,
732
    /// with the memory being filled with `0` bytes.
733
    ///
734
    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
735
    /// of this method.
736
    ///
737
    /// # Examples
738
    ///
739
    /// ```
740
    /// #![feature(allocator_api, new_uninit)]
741
    ///
742
    /// use std::alloc::System;
743
    ///
744
    /// let values = Box::<[u32], _>::new_zeroed_slice_in(3, System);
745
    /// let values = unsafe { values.assume_init() };
746
    ///
747
    /// assert_eq!(*values, [0, 0, 0])
748
    /// ```
749
    ///
750
    /// [zeroed]: mem::MaybeUninit::zeroed
751
    #[cfg(not(no_global_oom_handling))]
752
    #[must_use]
753
    #[inline(always)]
754
0
    pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit<T>], A> {
755
0
        unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) }
756
0
    }
757
758
0
    pub fn into_vec(self) -> Vec<T, A>
759
0
    where
760
0
        A: Allocator,
761
0
    {
762
0
        unsafe {
763
0
            let len = self.len();
764
0
            let (b, alloc) = Box::into_raw_with_allocator(self);
765
0
            Vec::from_raw_parts_in(b as *mut T, len, len, alloc)
766
0
        }
767
0
    }
768
}
769
770
impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
771
    /// Converts to `Box<T, A>`.
772
    ///
773
    /// # Safety
774
    ///
775
    /// As with [`MaybeUninit::assume_init`],
776
    /// it is up to the caller to guarantee that the value
777
    /// really is in an initialized state.
778
    /// Calling this when the content is not yet fully initialized
779
    /// causes immediate undefined behavior.
780
    ///
781
    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
782
    ///
783
    /// # Examples
784
    ///
785
    /// ```
786
    /// #![feature(new_uninit)]
787
    ///
788
    /// let mut five = Box::<u32>::new_uninit();
789
    ///
790
    /// let five: Box<u32> = unsafe {
791
    ///     // Deferred initialization:
792
    ///     five.as_mut_ptr().write(5);
793
    ///
794
    ///     five.assume_init()
795
    /// };
796
    ///
797
    /// assert_eq!(*five, 5)
798
    /// ```
799
    #[inline(always)]
800
0
    pub unsafe fn assume_init(self) -> Box<T, A> {
801
0
        let (raw, alloc) = Box::into_raw_with_allocator(self);
802
0
        unsafe { Box::from_raw_in(raw as *mut T, alloc) }
803
0
    }
804
805
    /// Writes the value and converts to `Box<T, A>`.
806
    ///
807
    /// This method converts the box similarly to [`Box::assume_init`] but
808
    /// writes `value` into it before conversion thus guaranteeing safety.
809
    /// In some scenarios use of this method may improve performance because
810
    /// the compiler may be able to optimize copying from stack.
811
    ///
812
    /// # Examples
813
    ///
814
    /// ```
815
    /// #![feature(new_uninit)]
816
    ///
817
    /// let big_box = Box::<[usize; 1024]>::new_uninit();
818
    ///
819
    /// let mut array = [0; 1024];
820
    /// for (i, place) in array.iter_mut().enumerate() {
821
    ///     *place = i;
822
    /// }
823
    ///
824
    /// // The optimizer may be able to elide this copy, so previous code writes
825
    /// // to heap directly.
826
    /// let big_box = Box::write(big_box, array);
827
    ///
828
    /// for (i, x) in big_box.iter().enumerate() {
829
    ///     assert_eq!(*x, i);
830
    /// }
831
    /// ```
832
    #[inline(always)]
833
0
    pub fn write(mut boxed: Self, value: T) -> Box<T, A> {
834
0
        unsafe {
835
0
            (*boxed).write(value);
836
0
            boxed.assume_init()
837
0
        }
838
0
    }
839
}
840
841
impl<T, A: Allocator> Box<[mem::MaybeUninit<T>], A> {
842
    /// Converts to `Box<[T], A>`.
843
    ///
844
    /// # Safety
845
    ///
846
    /// As with [`MaybeUninit::assume_init`],
847
    /// it is up to the caller to guarantee that the values
848
    /// really are in an initialized state.
849
    /// Calling this when the content is not yet fully initialized
850
    /// causes immediate undefined behavior.
851
    ///
852
    /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
853
    ///
854
    /// # Examples
855
    ///
856
    /// ```
857
    /// #![feature(new_uninit)]
858
    ///
859
    /// let mut values = Box::<[u32]>::new_uninit_slice(3);
860
    ///
861
    /// let values = unsafe {
862
    ///     // Deferred initialization:
863
    ///     values[0].as_mut_ptr().write(1);
864
    ///     values[1].as_mut_ptr().write(2);
865
    ///     values[2].as_mut_ptr().write(3);
866
    ///
867
    ///     values.assume_init()
868
    /// };
869
    ///
870
    /// assert_eq!(*values, [1, 2, 3])
871
    /// ```
872
    #[inline(always)]
873
0
    pub unsafe fn assume_init(self) -> Box<[T], A> {
874
0
        let (raw, alloc) = Box::into_raw_with_allocator(self);
875
0
        unsafe { Box::from_raw_in(raw as *mut [T], alloc) }
876
0
    }
877
}
878
879
impl<T: ?Sized> Box<T> {
880
    /// Constructs a box from a raw pointer.
881
    ///
882
    /// After calling this function, the raw pointer is owned by the
883
    /// resulting `Box`. Specifically, the `Box` destructor will call
884
    /// the destructor of `T` and free the allocated memory. For this
885
    /// to be safe, the memory must have been allocated in accordance
886
    /// with the [memory layout] used by `Box` .
887
    ///
888
    /// # Safety
889
    ///
890
    /// This function is unsafe because improper use may lead to
891
    /// memory problems. For example, a double-free may occur if the
892
    /// function is called twice on the same raw pointer.
893
    ///
894
    /// The safety conditions are described in the [memory layout] section.
895
    ///
896
    /// # Examples
897
    ///
898
    /// Recreate a `Box` which was previously converted to a raw pointer
899
    /// using [`Box::into_raw`]:
900
    /// ```
901
    /// let x = Box::new(5);
902
    /// let ptr = Box::into_raw(x);
903
    /// let x = unsafe { Box::from_raw(ptr) };
904
    /// ```
905
    /// Manually create a `Box` from scratch by using the global allocator:
906
    /// ```
907
    /// use std::alloc::{alloc, Layout};
908
    ///
909
    /// unsafe {
910
    ///     let ptr = alloc(Layout::new::<i32>()) as *mut i32;
911
    ///     // In general .write is required to avoid attempting to destruct
912
    ///     // the (uninitialized) previous contents of `ptr`, though for this
913
    ///     // simple example `*ptr = 5` would have worked as well.
914
    ///     ptr.write(5);
915
    ///     let x = Box::from_raw(ptr);
916
    /// }
917
    /// ```
918
    ///
919
    /// [memory layout]: self#memory-layout
920
    /// [`Layout`]: crate::Layout
921
    #[must_use = "call `drop(from_raw(ptr))` if you intend to drop the `Box`"]
922
    #[inline(always)]
923
0
    pub unsafe fn from_raw(raw: *mut T) -> Self {
924
0
        unsafe { Self::from_raw_in(raw, Global) }
925
0
    }
Unexecuted instantiation: _RNvMs6_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxeE8from_rawB9_
Unexecuted instantiation: _RNvMs6_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxNtNtNtCsbQ8arDwx5Xq_4core3ffi5c_str4CStrE8from_rawB9_
926
}
927
928
impl<T: ?Sized, A: Allocator> Box<T, A> {
929
    /// Constructs a box from a raw pointer in the given allocator.
930
    ///
931
    /// After calling this function, the raw pointer is owned by the
932
    /// resulting `Box`. Specifically, the `Box` destructor will call
933
    /// the destructor of `T` and free the allocated memory. For this
934
    /// to be safe, the memory must have been allocated in accordance
935
    /// with the [memory layout] used by `Box` .
936
    ///
937
    /// # Safety
938
    ///
939
    /// This function is unsafe because improper use may lead to
940
    /// memory problems. For example, a double-free may occur if the
941
    /// function is called twice on the same raw pointer.
942
    ///
943
    ///
944
    /// # Examples
945
    ///
946
    /// Recreate a `Box` which was previously converted to a raw pointer
947
    /// using [`Box::into_raw_with_allocator`]:
948
    /// ```
949
    /// use std::alloc::System;
950
    /// # use allocator_api2::boxed::Box;
951
    ///
952
    /// let x = Box::new_in(5, System);
953
    /// let (ptr, alloc) = Box::into_raw_with_allocator(x);
954
    /// let x = unsafe { Box::from_raw_in(ptr, alloc) };
955
    /// ```
956
    /// Manually create a `Box` from scratch by using the system allocator:
957
    /// ```
958
    /// use allocator_api2::alloc::{Allocator, Layout, System};
959
    /// # use allocator_api2::boxed::Box;
960
    ///
961
    /// unsafe {
962
    ///     let ptr = System.allocate(Layout::new::<i32>())?.as_ptr().cast::<i32>();
963
    ///     // In general .write is required to avoid attempting to destruct
964
    ///     // the (uninitialized) previous contents of `ptr`, though for this
965
    ///     // simple example `*ptr = 5` would have worked as well.
966
    ///     ptr.write(5);
967
    ///     let x = Box::from_raw_in(ptr, System);
968
    /// }
969
    /// # Ok::<(), allocator_api2::alloc::AllocError>(())
970
    /// ```
971
    ///
972
    /// [memory layout]: self#memory-layout
973
    /// [`Layout`]: crate::Layout
974
    #[inline(always)]
975
0
    pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
976
0
        Box(unsafe { NonNull::new_unchecked(raw) }, alloc)
977
0
    }
Unexecuted instantiation: _RNvMs7_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxeE11from_raw_inB9_
Unexecuted instantiation: _RNvMs7_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxShE11from_raw_inB9_
Unexecuted instantiation: _RNvMs7_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxNtNtNtCsbQ8arDwx5Xq_4core3ffi5c_str4CStrE11from_raw_inB9_
Unexecuted instantiation: _RNvMs7_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxSINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninithEE11from_raw_inB9_
978
979
    /// Consumes the `Box`, returning a wrapped raw pointer.
980
    ///
981
    /// The pointer will be properly aligned and non-null.
982
    ///
983
    /// After calling this function, the caller is responsible for the
984
    /// memory previously managed by the `Box`. In particular, the
985
    /// caller should properly destroy `T` and release the memory, taking
986
    /// into account the [memory layout] used by `Box`. The easiest way to
987
    /// do this is to convert the raw pointer back into a `Box` with the
988
    /// [`Box::from_raw`] function, allowing the `Box` destructor to perform
989
    /// the cleanup.
990
    ///
991
    /// Note: this is an associated function, which means that you have
992
    /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This
993
    /// is so that there is no conflict with a method on the inner type.
994
    ///
995
    /// # Examples
996
    /// Converting the raw pointer back into a `Box` with [`Box::from_raw`]
997
    /// for automatic cleanup:
998
    /// ```
999
    /// let x = Box::new(String::from("Hello"));
1000
    /// let ptr = Box::into_raw(x);
1001
    /// let x = unsafe { Box::from_raw(ptr) };
1002
    /// ```
1003
    /// Manual cleanup by explicitly running the destructor and deallocating
1004
    /// the memory:
1005
    /// ```
1006
    /// use std::alloc::{dealloc, Layout};
1007
    /// use std::ptr;
1008
    ///
1009
    /// let x = Box::new(String::from("Hello"));
1010
    /// let p = Box::into_raw(x);
1011
    /// unsafe {
1012
    ///     ptr::drop_in_place(p);
1013
    ///     dealloc(p as *mut u8, Layout::new::<String>());
1014
    /// }
1015
    /// ```
1016
    ///
1017
    /// [memory layout]: self#memory-layout
1018
    #[inline(always)]
1019
0
    pub fn into_raw(b: Self) -> *mut T {
1020
0
        Self::into_raw_with_allocator(b).0
1021
0
    }
1022
1023
    /// Consumes the `Box`, returning a wrapped raw pointer and the allocator.
1024
    ///
1025
    /// The pointer will be properly aligned and non-null.
1026
    ///
1027
    /// After calling this function, the caller is responsible for the
1028
    /// memory previously managed by the `Box`. In particular, the
1029
    /// caller should properly destroy `T` and release the memory, taking
1030
    /// into account the [memory layout] used by `Box`. The easiest way to
1031
    /// do this is to convert the raw pointer back into a `Box` with the
1032
    /// [`Box::from_raw_in`] function, allowing the `Box` destructor to perform
1033
    /// the cleanup.
1034
    ///
1035
    /// Note: this is an associated function, which means that you have
1036
    /// to call it as `Box::into_raw_with_allocator(b)` instead of `b.into_raw_with_allocator()`. This
1037
    /// is so that there is no conflict with a method on the inner type.
1038
    ///
1039
    /// # Examples
1040
    /// Converting the raw pointer back into a `Box` with [`Box::from_raw_in`]
1041
    /// for automatic cleanup:
1042
    /// ```
1043
    /// #![feature(allocator_api)]
1044
    ///
1045
    /// use std::alloc::System;
1046
    ///
1047
    /// let x = Box::new_in(String::from("Hello"), System);
1048
    /// let (ptr, alloc) = Box::into_raw_with_allocator(x);
1049
    /// let x = unsafe { Box::from_raw_in(ptr, alloc) };
1050
    /// ```
1051
    /// Manual cleanup by explicitly running the destructor and deallocating
1052
    /// the memory:
1053
    /// ```
1054
    /// #![feature(allocator_api)]
1055
    ///
1056
    /// use std::alloc::{Allocator, Layout, System};
1057
    /// use std::ptr::{self, NonNull};
1058
    ///
1059
    /// let x = Box::new_in(String::from("Hello"), System);
1060
    /// let (ptr, alloc) = Box::into_raw_with_allocator(x);
1061
    /// unsafe {
1062
    ///     ptr::drop_in_place(ptr);
1063
    ///     let non_null = NonNull::new_unchecked(ptr);
1064
    ///     alloc.deallocate(non_null.cast(), Layout::new::<String>());
1065
    /// }
1066
    /// ```
1067
    ///
1068
    /// [memory layout]: self#memory-layout
1069
    #[inline(always)]
1070
0
    pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
1071
0
        let (leaked, alloc) = Box::into_non_null(b);
1072
0
        (leaked.as_ptr(), alloc)
1073
0
    }
Unexecuted instantiation: _RNvMs7_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxShE23into_raw_with_allocatorB9_
Unexecuted instantiation: _RNvMs7_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxSINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninithEE23into_raw_with_allocatorB9_
1074
1075
    #[inline(always)]
1076
0
    pub fn into_non_null(b: Self) -> (NonNull<T>, A) {
1077
0
        // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
1078
0
        // raw pointer for the type system. Turning it directly into a raw pointer would not be
1079
0
        // recognized as "releasing" the unique pointer to permit aliased raw accesses,
1080
0
        // so all raw pointer methods have to go through `Box::leak`. Turning *that* to a raw pointer
1081
0
        // behaves correctly.
1082
0
        let alloc = unsafe { ptr::read(&b.1) };
1083
0
        (NonNull::from(Box::leak(b)), alloc)
1084
0
    }
Unexecuted instantiation: _RNvMs7_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxShE13into_non_nullB9_
Unexecuted instantiation: _RNvMs7_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxSINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninithEE13into_non_nullB9_
1085
1086
    /// Returns a reference to the underlying allocator.
1087
    ///
1088
    /// Note: this is an associated function, which means that you have
1089
    /// to call it as `Box::allocator(&b)` instead of `b.allocator()`. This
1090
    /// is so that there is no conflict with a method on the inner type.
1091
    #[inline(always)]
1092
0
    pub const fn allocator(b: &Self) -> &A {
1093
0
        &b.1
1094
0
    }
1095
1096
    /// Consumes and leaks the `Box`, returning a mutable reference,
1097
    /// `&'a mut T`. Note that the type `T` must outlive the chosen lifetime
1098
    /// `'a`. If the type has only static references, or none at all, then this
1099
    /// may be chosen to be `'static`.
1100
    ///
1101
    /// This function is mainly useful for data that lives for the remainder of
1102
    /// the program's life. Dropping the returned reference will cause a memory
1103
    /// leak. If this is not acceptable, the reference should first be wrapped
1104
    /// with the [`Box::from_raw`] function producing a `Box`. This `Box` can
1105
    /// then be dropped which will properly destroy `T` and release the
1106
    /// allocated memory.
1107
    ///
1108
    /// Note: this is an associated function, which means that you have
1109
    /// to call it as `Box::leak(b)` instead of `b.leak()`. This
1110
    /// is so that there is no conflict with a method on the inner type.
1111
    ///
1112
    /// # Examples
1113
    ///
1114
    /// Simple usage:
1115
    ///
1116
    /// ```
1117
    /// let x = Box::new(41);
1118
    /// let static_ref: &'static mut usize = Box::leak(x);
1119
    /// *static_ref += 1;
1120
    /// assert_eq!(*static_ref, 42);
1121
    /// ```
1122
    ///
1123
    /// Unsized data:
1124
    ///
1125
    /// ```
1126
    /// let x = vec![1, 2, 3].into_boxed_slice();
1127
    /// let static_ref = Box::leak(x);
1128
    /// static_ref[0] = 4;
1129
    /// assert_eq!(*static_ref, [4, 2, 3]);
1130
    /// ```
1131
    #[inline(always)]
1132
0
    fn leak<'a>(b: Self) -> &'a mut T
1133
0
    where
1134
0
        A: 'a,
1135
0
    {
1136
0
        unsafe { &mut *mem::ManuallyDrop::new(b).0.as_ptr() }
1137
0
    }
Unexecuted instantiation: _RNvMs7_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxShE4leakB9_
Unexecuted instantiation: _RNvMs7_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxSINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninithEE4leakB9_
1138
1139
    /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
1140
    /// `*boxed` will be pinned in memory and unable to be moved.
1141
    ///
1142
    /// This conversion does not allocate on the heap and happens in place.
1143
    ///
1144
    /// This is also available via [`From`].
1145
    ///
1146
    /// Constructing and pinning a `Box` with <code>Box::into_pin([Box::new]\(x))</code>
1147
    /// can also be written more concisely using <code>[Box::pin]\(x)</code>.
1148
    /// This `into_pin` method is useful if you already have a `Box<T>`, or you are
1149
    /// constructing a (pinned) `Box` in a different way than with [`Box::new`].
1150
    ///
1151
    /// # Notes
1152
    ///
1153
    /// It's not recommended that crates add an impl like `From<Box<T>> for Pin<T>`,
1154
    /// as it'll introduce an ambiguity when calling `Pin::from`.
1155
    /// A demonstration of such a poor impl is shown below.
1156
    ///
1157
    /// ```compile_fail
1158
    /// # use std::pin::Pin;
1159
    /// struct Foo; // A type defined in this crate.
1160
    /// impl From<Box<()>> for Pin<Foo> {
1161
    ///     fn from(_: Box<()>) -> Pin<Foo> {
1162
    ///         Pin::new(Foo)
1163
    ///     }
1164
    /// }
1165
    ///
1166
    /// let foo = Box::new(());
1167
    /// let bar = Pin::from(foo);
1168
    /// ```
1169
    #[inline(always)]
1170
0
    pub fn into_pin(boxed: Self) -> Pin<Self>
1171
0
    where
1172
0
        A: 'static,
1173
0
    {
1174
0
        // It's not possible to move or replace the insides of a `Pin<Box<T>>`
1175
0
        // when `T: !Unpin`, so it's safe to pin it directly without any
1176
0
        // additional requirements.
1177
0
        unsafe { Pin::new_unchecked(boxed) }
1178
0
    }
1179
}
1180
1181
impl<T: ?Sized, A: Allocator> Drop for Box<T, A> {
1182
    #[inline(always)]
1183
0
    fn drop(&mut self) {
1184
0
        let layout = Layout::for_value::<T>(&**self);
1185
0
        unsafe {
1186
0
            ptr::drop_in_place(self.0.as_mut());
1187
0
            self.1.deallocate(self.0.cast(), layout);
1188
0
        }
1189
0
    }
Unexecuted instantiation: _RNvXs8_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxNtNtNtCsbQ8arDwx5Xq_4core3ffi5c_str4CStrENtNtNtB16_3ops4drop4Drop4dropB9_
Unexecuted instantiation: _RNvXs8_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxeENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropB9_
1190
}
1191
1192
#[cfg(not(no_global_oom_handling))]
1193
impl<T: Default> Default for Box<T> {
1194
    /// Creates a `Box<T>`, with the `Default` value for T.
1195
    #[inline(always)]
1196
0
    fn default() -> Self {
1197
0
        Box::new(T::default())
1198
0
    }
1199
}
1200
1201
impl<T, A: Allocator + Default> Default for Box<[T], A> {
1202
    #[inline(always)]
1203
0
    fn default() -> Self {
1204
0
        let ptr: NonNull<[T]> = NonNull::<[T; 0]>::dangling();
1205
0
        Box(ptr, A::default())
1206
0
    }
1207
}
1208
1209
impl<A: Allocator + Default> Default for Box<str, A> {
1210
    #[inline(always)]
1211
0
    fn default() -> Self {
1212
0
        // SAFETY: This is the same as `Unique::cast<U>` but with an unsized `U = str`.
1213
0
        let ptr: NonNull<str> = unsafe {
1214
0
            let bytes: NonNull<[u8]> = NonNull::<[u8; 0]>::dangling();
1215
0
            NonNull::new_unchecked(bytes.as_ptr() as *mut str)
1216
0
        };
1217
0
        Box(ptr, A::default())
1218
0
    }
1219
}
1220
1221
#[cfg(not(no_global_oom_handling))]
1222
impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> {
1223
    /// Returns a new box with a `clone()` of this box's contents.
1224
    ///
1225
    /// # Examples
1226
    ///
1227
    /// ```
1228
    /// let x = Box::new(5);
1229
    /// let y = x.clone();
1230
    ///
1231
    /// // The value is the same
1232
    /// assert_eq!(x, y);
1233
    ///
1234
    /// // But they are unique objects
1235
    /// assert_ne!(&*x as *const i32, &*y as *const i32);
1236
    /// ```
1237
    #[inline(always)]
1238
0
    fn clone(&self) -> Self {
1239
0
        // Pre-allocate memory to allow writing the cloned value directly.
1240
0
        let mut boxed = Self::new_uninit_in(self.1.clone());
1241
0
        unsafe {
1242
0
            boxed.write((**self).clone());
1243
0
            boxed.assume_init()
1244
0
        }
1245
0
    }
1246
1247
    /// Copies `source`'s contents into `self` without creating a new allocation.
1248
    ///
1249
    /// # Examples
1250
    ///
1251
    /// ```
1252
    /// let x = Box::new(5);
1253
    /// let mut y = Box::new(10);
1254
    /// let yp: *const i32 = &*y;
1255
    ///
1256
    /// y.clone_from(&x);
1257
    ///
1258
    /// // The value is the same
1259
    /// assert_eq!(x, y);
1260
    ///
1261
    /// // And no allocation occurred
1262
    /// assert_eq!(yp, &*y);
1263
    /// ```
1264
    #[inline(always)]
1265
0
    fn clone_from(&mut self, source: &Self) {
1266
0
        (**self).clone_from(&(**source));
1267
0
    }
1268
}
1269
1270
#[cfg(not(no_global_oom_handling))]
1271
impl Clone for Box<str> {
1272
    #[inline(always)]
1273
0
    fn clone(&self) -> Self {
1274
0
        // this makes a copy of the data
1275
0
        let buf: Box<[u8]> = self.as_bytes().into();
1276
0
        unsafe { Box::from_raw(Box::into_raw(buf) as *mut str) }
1277
0
    }
1278
}
1279
1280
impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for Box<T, A> {
1281
    #[inline(always)]
1282
0
    fn eq(&self, other: &Self) -> bool {
1283
0
        PartialEq::eq(&**self, &**other)
1284
0
    }
1285
    #[inline(always)]
1286
0
    fn ne(&self, other: &Self) -> bool {
1287
0
        PartialEq::ne(&**self, &**other)
1288
0
    }
1289
}
1290
1291
impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for Box<T, A> {
1292
    #[inline(always)]
1293
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1294
0
        PartialOrd::partial_cmp(&**self, &**other)
1295
0
    }
1296
    #[inline(always)]
1297
0
    fn lt(&self, other: &Self) -> bool {
1298
0
        PartialOrd::lt(&**self, &**other)
1299
0
    }
1300
    #[inline(always)]
1301
0
    fn le(&self, other: &Self) -> bool {
1302
0
        PartialOrd::le(&**self, &**other)
1303
0
    }
1304
    #[inline(always)]
1305
0
    fn ge(&self, other: &Self) -> bool {
1306
0
        PartialOrd::ge(&**self, &**other)
1307
0
    }
1308
    #[inline(always)]
1309
0
    fn gt(&self, other: &Self) -> bool {
1310
0
        PartialOrd::gt(&**self, &**other)
1311
0
    }
1312
}
1313
1314
impl<T: ?Sized + Ord, A: Allocator> Ord for Box<T, A> {
1315
    #[inline(always)]
1316
0
    fn cmp(&self, other: &Self) -> Ordering {
1317
0
        Ord::cmp(&**self, &**other)
1318
0
    }
1319
}
1320
1321
impl<T: ?Sized + Eq, A: Allocator> Eq for Box<T, A> {}
1322
1323
impl<T: ?Sized + Hash, A: Allocator> Hash for Box<T, A> {
1324
    #[inline(always)]
1325
0
    fn hash<H: Hasher>(&self, state: &mut H) {
1326
0
        (**self).hash(state);
1327
0
    }
1328
}
1329
1330
impl<T: ?Sized + Hasher, A: Allocator> Hasher for Box<T, A> {
1331
    #[inline(always)]
1332
0
    fn finish(&self) -> u64 {
1333
0
        (**self).finish()
1334
0
    }
1335
    #[inline(always)]
1336
0
    fn write(&mut self, bytes: &[u8]) {
1337
0
        (**self).write(bytes)
1338
0
    }
1339
    #[inline(always)]
1340
0
    fn write_u8(&mut self, i: u8) {
1341
0
        (**self).write_u8(i)
1342
0
    }
1343
    #[inline(always)]
1344
0
    fn write_u16(&mut self, i: u16) {
1345
0
        (**self).write_u16(i)
1346
0
    }
1347
    #[inline(always)]
1348
0
    fn write_u32(&mut self, i: u32) {
1349
0
        (**self).write_u32(i)
1350
0
    }
1351
    #[inline(always)]
1352
0
    fn write_u64(&mut self, i: u64) {
1353
0
        (**self).write_u64(i)
1354
0
    }
1355
    #[inline(always)]
1356
0
    fn write_u128(&mut self, i: u128) {
1357
0
        (**self).write_u128(i)
1358
0
    }
1359
    #[inline(always)]
1360
0
    fn write_usize(&mut self, i: usize) {
1361
0
        (**self).write_usize(i)
1362
0
    }
1363
    #[inline(always)]
1364
0
    fn write_i8(&mut self, i: i8) {
1365
0
        (**self).write_i8(i)
1366
0
    }
1367
    #[inline(always)]
1368
0
    fn write_i16(&mut self, i: i16) {
1369
0
        (**self).write_i16(i)
1370
0
    }
1371
    #[inline(always)]
1372
0
    fn write_i32(&mut self, i: i32) {
1373
0
        (**self).write_i32(i)
1374
0
    }
1375
    #[inline(always)]
1376
0
    fn write_i64(&mut self, i: i64) {
1377
0
        (**self).write_i64(i)
1378
0
    }
1379
    #[inline(always)]
1380
0
    fn write_i128(&mut self, i: i128) {
1381
0
        (**self).write_i128(i)
1382
0
    }
1383
    #[inline(always)]
1384
0
    fn write_isize(&mut self, i: isize) {
1385
0
        (**self).write_isize(i)
1386
0
    }
1387
}
1388
1389
#[cfg(not(no_global_oom_handling))]
1390
impl<T> From<T> for Box<T> {
1391
    /// Converts a `T` into a `Box<T>`
1392
    ///
1393
    /// The conversion allocates on the heap and moves `t`
1394
    /// from the stack into it.
1395
    ///
1396
    /// # Examples
1397
    ///
1398
    /// ```rust
1399
    /// let x = 5;
1400
    /// let boxed = Box::new(5);
1401
    ///
1402
    /// assert_eq!(Box::from(x), boxed);
1403
    /// ```
1404
    #[inline(always)]
1405
0
    fn from(t: T) -> Self {
1406
0
        Box::new(t)
1407
0
    }
1408
}
1409
1410
impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>>
1411
where
1412
    A: 'static,
1413
{
1414
    /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
1415
    /// `*boxed` will be pinned in memory and unable to be moved.
1416
    ///
1417
    /// This conversion does not allocate on the heap and happens in place.
1418
    ///
1419
    /// This is also available via [`Box::into_pin`].
1420
    ///
1421
    /// Constructing and pinning a `Box` with <code><Pin<Box\<T>>>::from([Box::new]\(x))</code>
1422
    /// can also be written more concisely using <code>[Box::pin]\(x)</code>.
1423
    /// This `From` implementation is useful if you already have a `Box<T>`, or you are
1424
    /// constructing a (pinned) `Box` in a different way than with [`Box::new`].
1425
    #[inline(always)]
1426
0
    fn from(boxed: Box<T, A>) -> Self {
1427
0
        Box::into_pin(boxed)
1428
0
    }
1429
}
1430
1431
#[cfg(not(no_global_oom_handling))]
1432
impl<T: Copy, A: Allocator + Default> From<&[T]> for Box<[T], A> {
1433
    /// Converts a `&[T]` into a `Box<[T]>`
1434
    ///
1435
    /// This conversion allocates on the heap
1436
    /// and performs a copy of `slice` and its contents.
1437
    ///
1438
    /// # Examples
1439
    /// ```rust
1440
    /// // create a &[u8] which will be used to create a Box<[u8]>
1441
    /// let slice: &[u8] = &[104, 101, 108, 108, 111];
1442
    /// let boxed_slice: Box<[u8]> = Box::from(slice);
1443
    ///
1444
    /// println!("{boxed_slice:?}");
1445
    /// ```
1446
    #[inline(always)]
1447
0
    fn from(slice: &[T]) -> Box<[T], A> {
1448
0
        let len = slice.len();
1449
0
        let buf = RawVec::with_capacity_in(len, A::default());
1450
0
        unsafe {
1451
0
            ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len);
1452
0
            buf.into_box(slice.len()).assume_init()
1453
0
        }
1454
0
    }
1455
}
1456
1457
#[cfg(not(no_global_oom_handling))]
1458
impl<A: Allocator + Default> From<&str> for Box<str, A> {
1459
    /// Converts a `&str` into a `Box<str>`
1460
    ///
1461
    /// This conversion allocates on the heap
1462
    /// and performs a copy of `s`.
1463
    ///
1464
    /// # Examples
1465
    ///
1466
    /// ```rust
1467
    /// let boxed: Box<str> = Box::from("hello");
1468
    /// println!("{boxed}");
1469
    /// ```
1470
    #[inline(always)]
1471
0
    fn from(s: &str) -> Box<str, A> {
1472
0
        let (raw, alloc) = Box::into_raw_with_allocator(Box::<[u8], A>::from(s.as_bytes()));
1473
0
        unsafe { Box::from_raw_in(raw as *mut str, alloc) }
1474
0
    }
1475
}
1476
1477
impl<A: Allocator> From<Box<str, A>> for Box<[u8], A> {
1478
    /// Converts a `Box<str>` into a `Box<[u8]>`
1479
    ///
1480
    /// This conversion does not allocate on the heap and happens in place.
1481
    ///
1482
    /// # Examples
1483
    /// ```rust
1484
    /// // create a Box<str> which will be used to create a Box<[u8]>
1485
    /// let boxed: Box<str> = Box::from("hello");
1486
    /// let boxed_str: Box<[u8]> = Box::from(boxed);
1487
    ///
1488
    /// // create a &[u8] which will be used to create a Box<[u8]>
1489
    /// let slice: &[u8] = &[104, 101, 108, 108, 111];
1490
    /// let boxed_slice = Box::from(slice);
1491
    ///
1492
    /// assert_eq!(boxed_slice, boxed_str);
1493
    /// ```
1494
    #[inline(always)]
1495
0
    fn from(s: Box<str, A>) -> Self {
1496
0
        let (raw, alloc) = Box::into_raw_with_allocator(s);
1497
0
        unsafe { Box::from_raw_in(raw as *mut [u8], alloc) }
1498
0
    }
1499
}
1500
1501
impl<T, A: Allocator, const N: usize> Box<[T; N], A> {
1502
    #[inline(always)]
1503
0
    pub fn slice(b: Self) -> Box<[T], A> {
1504
0
        let (ptr, alloc) = Box::into_raw_with_allocator(b);
1505
0
        unsafe { Box::from_raw_in(ptr, alloc) }
1506
0
    }
1507
1508
0
    pub fn into_vec(self) -> Vec<T, A>
1509
0
    where
1510
0
        A: Allocator,
1511
0
    {
1512
0
        unsafe {
1513
0
            let (b, alloc) = Box::into_raw_with_allocator(self);
1514
0
            Vec::from_raw_parts_in(b as *mut T, N, N, alloc)
1515
0
        }
1516
0
    }
1517
}
1518
1519
#[cfg(not(no_global_oom_handling))]
1520
impl<T, const N: usize> From<[T; N]> for Box<[T]> {
1521
    /// Converts a `[T; N]` into a `Box<[T]>`
1522
    ///
1523
    /// This conversion moves the array to newly heap-allocated memory.
1524
    ///
1525
    /// # Examples
1526
    ///
1527
    /// ```rust
1528
    /// let boxed: Box<[u8]> = Box::from([4, 2]);
1529
    /// println!("{boxed:?}");
1530
    /// ```
1531
    #[inline(always)]
1532
0
    fn from(array: [T; N]) -> Box<[T]> {
1533
0
        Box::slice(Box::new(array))
1534
0
    }
1535
}
1536
1537
impl<T, A: Allocator, const N: usize> TryFrom<Box<[T], A>> for Box<[T; N], A> {
1538
    type Error = Box<[T], A>;
1539
1540
    /// Attempts to convert a `Box<[T]>` into a `Box<[T; N]>`.
1541
    ///
1542
    /// The conversion occurs in-place and does not require a
1543
    /// new memory allocation.
1544
    ///
1545
    /// # Errors
1546
    ///
1547
    /// Returns the old `Box<[T]>` in the `Err` variant if
1548
    /// `boxed_slice.len()` does not equal `N`.
1549
    #[inline(always)]
1550
0
    fn try_from(boxed_slice: Box<[T], A>) -> Result<Self, Self::Error> {
1551
0
        if boxed_slice.len() == N {
1552
0
            let (ptr, alloc) = Box::into_raw_with_allocator(boxed_slice);
1553
0
            Ok(unsafe { Box::from_raw_in(ptr as *mut [T; N], alloc) })
1554
        } else {
1555
0
            Err(boxed_slice)
1556
        }
1557
0
    }
1558
}
1559
1560
impl<A: Allocator> Box<dyn Any, A> {
1561
    /// Attempt to downcast the box to a concrete type.
1562
    ///
1563
    /// # Examples
1564
    ///
1565
    /// ```
1566
    /// use std::any::Any;
1567
    ///
1568
    /// fn print_if_string(value: Box<dyn Any>) {
1569
    ///     if let Ok(string) = value.downcast::<String>() {
1570
    ///         println!("String ({}): {}", string.len(), string);
1571
    ///     }
1572
    /// }
1573
    ///
1574
    /// let my_string = "Hello World".to_string();
1575
    /// print_if_string(Box::new(my_string));
1576
    /// print_if_string(Box::new(0i8));
1577
    /// ```
1578
    #[inline(always)]
1579
0
    pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
1580
0
        if self.is::<T>() {
1581
0
            unsafe { Ok(self.downcast_unchecked::<T>()) }
1582
        } else {
1583
0
            Err(self)
1584
        }
1585
0
    }
1586
1587
    /// Downcasts the box to a concrete type.
1588
    ///
1589
    /// For a safe alternative see [`downcast`].
1590
    ///
1591
    /// # Examples
1592
    ///
1593
    /// ```
1594
    /// #![feature(downcast_unchecked)]
1595
    ///
1596
    /// use std::any::Any;
1597
    ///
1598
    /// let x: Box<dyn Any> = Box::new(1_usize);
1599
    ///
1600
    /// unsafe {
1601
    ///     assert_eq!(*x.downcast_unchecked::<usize>(), 1);
1602
    /// }
1603
    /// ```
1604
    ///
1605
    /// # Safety
1606
    ///
1607
    /// The contained value must be of type `T`. Calling this method
1608
    /// with the incorrect type is *undefined behavior*.
1609
    ///
1610
    /// [`downcast`]: Self::downcast
1611
    #[inline(always)]
1612
0
    pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
1613
0
        debug_assert!(self.is::<T>());
1614
        unsafe {
1615
0
            let (raw, alloc): (*mut dyn Any, _) = Box::into_raw_with_allocator(self);
1616
0
            Box::from_raw_in(raw as *mut T, alloc)
1617
0
        }
1618
0
    }
1619
}
1620
1621
impl<A: Allocator> Box<dyn Any + Send, A> {
1622
    /// Attempt to downcast the box to a concrete type.
1623
    ///
1624
    /// # Examples
1625
    ///
1626
    /// ```
1627
    /// use std::any::Any;
1628
    ///
1629
    /// fn print_if_string(value: Box<dyn Any + Send>) {
1630
    ///     if let Ok(string) = value.downcast::<String>() {
1631
    ///         println!("String ({}): {}", string.len(), string);
1632
    ///     }
1633
    /// }
1634
    ///
1635
    /// let my_string = "Hello World".to_string();
1636
    /// print_if_string(Box::new(my_string));
1637
    /// print_if_string(Box::new(0i8));
1638
    /// ```
1639
    #[inline(always)]
1640
0
    pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
1641
0
        if self.is::<T>() {
1642
0
            unsafe { Ok(self.downcast_unchecked::<T>()) }
1643
        } else {
1644
0
            Err(self)
1645
        }
1646
0
    }
1647
1648
    /// Downcasts the box to a concrete type.
1649
    ///
1650
    /// For a safe alternative see [`downcast`].
1651
    ///
1652
    /// # Examples
1653
    ///
1654
    /// ```
1655
    /// #![feature(downcast_unchecked)]
1656
    ///
1657
    /// use std::any::Any;
1658
    ///
1659
    /// let x: Box<dyn Any + Send> = Box::new(1_usize);
1660
    ///
1661
    /// unsafe {
1662
    ///     assert_eq!(*x.downcast_unchecked::<usize>(), 1);
1663
    /// }
1664
    /// ```
1665
    ///
1666
    /// # Safety
1667
    ///
1668
    /// The contained value must be of type `T`. Calling this method
1669
    /// with the incorrect type is *undefined behavior*.
1670
    ///
1671
    /// [`downcast`]: Self::downcast
1672
    #[inline(always)]
1673
0
    pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
1674
0
        debug_assert!(self.is::<T>());
1675
        unsafe {
1676
0
            let (raw, alloc): (*mut (dyn Any + Send), _) = Box::into_raw_with_allocator(self);
1677
0
            Box::from_raw_in(raw as *mut T, alloc)
1678
0
        }
1679
0
    }
1680
}
1681
1682
impl<A: Allocator> Box<dyn Any + Send + Sync, A> {
1683
    /// Attempt to downcast the box to a concrete type.
1684
    ///
1685
    /// # Examples
1686
    ///
1687
    /// ```
1688
    /// use std::any::Any;
1689
    ///
1690
    /// fn print_if_string(value: Box<dyn Any + Send + Sync>) {
1691
    ///     if let Ok(string) = value.downcast::<String>() {
1692
    ///         println!("String ({}): {}", string.len(), string);
1693
    ///     }
1694
    /// }
1695
    ///
1696
    /// let my_string = "Hello World".to_string();
1697
    /// print_if_string(Box::new(my_string));
1698
    /// print_if_string(Box::new(0i8));
1699
    /// ```
1700
    #[inline(always)]
1701
0
    pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
1702
0
        if self.is::<T>() {
1703
0
            unsafe { Ok(self.downcast_unchecked::<T>()) }
1704
        } else {
1705
0
            Err(self)
1706
        }
1707
0
    }
1708
1709
    /// Downcasts the box to a concrete type.
1710
    ///
1711
    /// For a safe alternative see [`downcast`].
1712
    ///
1713
    /// # Examples
1714
    ///
1715
    /// ```
1716
    /// #![feature(downcast_unchecked)]
1717
    ///
1718
    /// use std::any::Any;
1719
    ///
1720
    /// let x: Box<dyn Any + Send + Sync> = Box::new(1_usize);
1721
    ///
1722
    /// unsafe {
1723
    ///     assert_eq!(*x.downcast_unchecked::<usize>(), 1);
1724
    /// }
1725
    /// ```
1726
    ///
1727
    /// # Safety
1728
    ///
1729
    /// The contained value must be of type `T`. Calling this method
1730
    /// with the incorrect type is *undefined behavior*.
1731
    ///
1732
    /// [`downcast`]: Self::downcast
1733
    #[inline(always)]
1734
0
    pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
1735
0
        debug_assert!(self.is::<T>());
1736
        unsafe {
1737
0
            let (raw, alloc): (*mut (dyn Any + Send + Sync), _) =
1738
0
                Box::into_raw_with_allocator(self);
1739
0
            Box::from_raw_in(raw as *mut T, alloc)
1740
0
        }
1741
0
    }
1742
}
1743
1744
impl<T: fmt::Display + ?Sized, A: Allocator> fmt::Display for Box<T, A> {
1745
    #[inline(always)]
1746
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1747
0
        fmt::Display::fmt(&**self, f)
1748
0
    }
1749
}
1750
1751
impl<T: fmt::Debug + ?Sized, A: Allocator> fmt::Debug for Box<T, A> {
1752
    #[inline(always)]
1753
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1754
0
        fmt::Debug::fmt(&**self, f)
1755
0
    }
1756
}
1757
1758
impl<T: ?Sized, A: Allocator> fmt::Pointer for Box<T, A> {
1759
    #[inline(always)]
1760
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1761
0
        // It's not possible to extract the inner Uniq directly from the Box,
1762
0
        // instead we cast it to a *const which aliases the Unique
1763
0
        let ptr: *const T = &**self;
1764
0
        fmt::Pointer::fmt(&ptr, f)
1765
0
    }
1766
}
1767
1768
impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
1769
    type Target = T;
1770
1771
    #[inline(always)]
1772
0
    fn deref(&self) -> &T {
1773
0
        unsafe { self.0.as_ref() }
1774
0
    }
Unexecuted instantiation: _RNvXsy_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxNtNtNtCsbQ8arDwx5Xq_4core3ffi5c_str4CStrENtNtNtB16_3ops5deref5Deref5derefB9_
Unexecuted instantiation: _RNvXsy_NtNtCsby83UglaBWc_14allocator_api26stable5boxedINtB5_3BoxeENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefB9_
1775
}
1776
1777
impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> {
1778
    #[inline(always)]
1779
0
    fn deref_mut(&mut self) -> &mut T {
1780
0
        unsafe { self.0.as_mut() }
1781
0
    }
1782
}
1783
1784
impl<I: Iterator + ?Sized, A: Allocator> Iterator for Box<I, A> {
1785
    type Item = I::Item;
1786
1787
    #[inline(always)]
1788
0
    fn next(&mut self) -> Option<I::Item> {
1789
0
        (**self).next()
1790
0
    }
1791
1792
    #[inline(always)]
1793
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1794
0
        (**self).size_hint()
1795
0
    }
1796
1797
    #[inline(always)]
1798
0
    fn nth(&mut self, n: usize) -> Option<I::Item> {
1799
0
        (**self).nth(n)
1800
0
    }
1801
1802
    #[inline(always)]
1803
0
    fn last(self) -> Option<I::Item> {
1804
0
        BoxIter::last(self)
1805
0
    }
1806
}
1807
1808
trait BoxIter {
1809
    type Item;
1810
    fn last(self) -> Option<Self::Item>;
1811
}
1812
1813
impl<I: Iterator + ?Sized, A: Allocator> BoxIter for Box<I, A> {
1814
    type Item = I::Item;
1815
1816
    #[inline(always)]
1817
0
    fn last(self) -> Option<I::Item> {
1818
        #[inline(always)]
1819
0
        fn some<T>(_: Option<T>, x: T) -> Option<T> {
1820
0
            Some(x)
1821
0
        }
1822
1823
0
        self.fold(None, some)
1824
0
    }
1825
}
1826
1827
impl<I: DoubleEndedIterator + ?Sized, A: Allocator> DoubleEndedIterator for Box<I, A> {
1828
    #[inline(always)]
1829
0
    fn next_back(&mut self) -> Option<I::Item> {
1830
0
        (**self).next_back()
1831
0
    }
1832
    #[inline(always)]
1833
0
    fn nth_back(&mut self, n: usize) -> Option<I::Item> {
1834
0
        (**self).nth_back(n)
1835
0
    }
1836
}
1837
1838
impl<I: ExactSizeIterator + ?Sized, A: Allocator> ExactSizeIterator for Box<I, A> {
1839
    #[inline(always)]
1840
0
    fn len(&self) -> usize {
1841
0
        (**self).len()
1842
0
    }
1843
}
1844
1845
impl<I: FusedIterator + ?Sized, A: Allocator> FusedIterator for Box<I, A> {}
1846
1847
#[cfg(not(no_global_oom_handling))]
1848
impl<I> FromIterator<I> for Box<[I]> {
1849
    #[inline(always)]
1850
0
    fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {
1851
0
        iter.into_iter().collect::<Vec<_>>().into_boxed_slice()
1852
0
    }
1853
}
1854
1855
#[cfg(not(no_global_oom_handling))]
1856
impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {
1857
    #[inline(always)]
1858
0
    fn clone(&self) -> Self {
1859
0
        let alloc = Box::allocator(self).clone();
1860
0
        let mut vec = Vec::with_capacity_in(self.len(), alloc);
1861
0
        vec.extend_from_slice(self);
1862
0
        vec.into_boxed_slice()
1863
0
    }
1864
1865
    #[inline(always)]
1866
0
    fn clone_from(&mut self, other: &Self) {
1867
0
        if self.len() == other.len() {
1868
0
            self.clone_from_slice(other);
1869
0
        } else {
1870
0
            *self = other.clone();
1871
0
        }
1872
0
    }
1873
}
1874
1875
impl<T: ?Sized, A: Allocator> borrow::Borrow<T> for Box<T, A> {
1876
    #[inline(always)]
1877
0
    fn borrow(&self) -> &T {
1878
0
        self
1879
0
    }
1880
}
1881
1882
impl<T: ?Sized, A: Allocator> borrow::BorrowMut<T> for Box<T, A> {
1883
    #[inline(always)]
1884
0
    fn borrow_mut(&mut self) -> &mut T {
1885
0
        self
1886
0
    }
1887
}
1888
1889
impl<T: ?Sized, A: Allocator> AsRef<T> for Box<T, A> {
1890
    #[inline(always)]
1891
0
    fn as_ref(&self) -> &T {
1892
0
        self
1893
0
    }
1894
}
1895
1896
impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> {
1897
    #[inline(always)]
1898
0
    fn as_mut(&mut self) -> &mut T {
1899
0
        self
1900
0
    }
1901
}
1902
1903
/* Nota bene
1904
 *
1905
 *  We could have chosen not to add this impl, and instead have written a
1906
 *  function of Pin<Box<T>> to Pin<T>. Such a function would not be sound,
1907
 *  because Box<T> implements Unpin even when T does not, as a result of
1908
 *  this impl.
1909
 *
1910
 *  We chose this API instead of the alternative for a few reasons:
1911
 *      - Logically, it is helpful to understand pinning in regard to the
1912
 *        memory region being pointed to. For this reason none of the
1913
 *        standard library pointer types support projecting through a pin
1914
 *        (Box<T> is the only pointer type in std for which this would be
1915
 *        safe.)
1916
 *      - It is in practice very useful to have Box<T> be unconditionally
1917
 *        Unpin because of trait objects, for which the structural auto
1918
 *        trait functionality does not apply (e.g., Box<dyn Foo> would
1919
 *        otherwise not be Unpin).
1920
 *
1921
 *  Another type with the same semantics as Box but only a conditional
1922
 *  implementation of `Unpin` (where `T: Unpin`) would be valid/safe, and
1923
 *  could have a method to project a Pin<T> from it.
1924
 */
1925
impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> where A: 'static {}
1926
1927
impl<F: ?Sized + Future + Unpin, A: Allocator> Future for Box<F, A>
1928
where
1929
    A: 'static,
1930
{
1931
    type Output = F::Output;
1932
1933
    #[inline(always)]
1934
0
    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1935
0
        F::poll(Pin::new(&mut *self), cx)
1936
0
    }
1937
}
1938
1939
#[cfg(feature = "std")]
1940
mod error {
1941
    use std::error::Error;
1942
1943
    use super::Box;
1944
1945
    #[cfg(not(no_global_oom_handling))]
1946
    impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
1947
        /// Converts a type of [`Error`] into a box of dyn [`Error`].
1948
        ///
1949
        /// # Examples
1950
        ///
1951
        /// ```
1952
        /// use std::error::Error;
1953
        /// use std::fmt;
1954
        /// use std::mem;
1955
        ///
1956
        /// #[derive(Debug)]
1957
        /// struct AnError;
1958
        ///
1959
        /// impl fmt::Display for AnError {
1960
        ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1961
        ///         write!(f, "An error")
1962
        ///     }
1963
        /// }
1964
        ///
1965
        /// impl Error for AnError {}
1966
        ///
1967
        /// let an_error = AnError;
1968
        /// assert!(0 == mem::size_of_val(&an_error));
1969
        /// let a_boxed_error = Box::<dyn Error>::from(an_error);
1970
        /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
1971
        /// ```
1972
        #[inline(always)]
1973
        fn from(err: E) -> Box<dyn Error + 'a> {
1974
            unsafe { Box::from_raw(Box::leak(Box::new(err))) }
1975
        }
1976
    }
1977
1978
    #[cfg(not(no_global_oom_handling))]
1979
    impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
1980
        /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
1981
        /// dyn [`Error`] + [`Send`] + [`Sync`].
1982
        ///
1983
        /// # Examples
1984
        ///
1985
        /// ```
1986
        /// use std::error::Error;
1987
        /// use std::fmt;
1988
        /// use std::mem;
1989
        ///
1990
        /// #[derive(Debug)]
1991
        /// struct AnError;
1992
        ///
1993
        /// impl fmt::Display for AnError {
1994
        ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1995
        ///         write!(f, "An error")
1996
        ///     }
1997
        /// }
1998
        ///
1999
        /// impl Error for AnError {}
2000
        ///
2001
        /// unsafe impl Send for AnError {}
2002
        ///
2003
        /// unsafe impl Sync for AnError {}
2004
        ///
2005
        /// let an_error = AnError;
2006
        /// assert!(0 == mem::size_of_val(&an_error));
2007
        /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
2008
        /// assert!(
2009
        ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
2010
        /// ```
2011
        #[inline(always)]
2012
        fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
2013
            unsafe { Box::from_raw(Box::leak(Box::new(err))) }
2014
        }
2015
    }
2016
2017
    impl<T: Error> Error for Box<T> {
2018
        #[inline(always)]
2019
        fn source(&self) -> Option<&(dyn Error + 'static)> {
2020
            Error::source(&**self)
2021
        }
2022
    }
2023
}
2024
2025
#[cfg(feature = "std")]
2026
impl<R: std::io::Read + ?Sized, A: Allocator> std::io::Read for Box<R, A> {
2027
    #[inline]
2028
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
2029
        (**self).read(buf)
2030
    }
2031
2032
    #[inline]
2033
    fn read_to_end(&mut self, buf: &mut std::vec::Vec<u8>) -> std::io::Result<usize> {
2034
        (**self).read_to_end(buf)
2035
    }
2036
2037
    #[inline]
2038
    fn read_to_string(&mut self, buf: &mut String) -> std::io::Result<usize> {
2039
        (**self).read_to_string(buf)
2040
    }
2041
2042
    #[inline]
2043
    fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
2044
        (**self).read_exact(buf)
2045
    }
2046
}
2047
2048
#[cfg(feature = "std")]
2049
impl<W: std::io::Write + ?Sized, A: Allocator> std::io::Write for Box<W, A> {
2050
    #[inline]
2051
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
2052
        (**self).write(buf)
2053
    }
2054
2055
    #[inline]
2056
    fn flush(&mut self) -> std::io::Result<()> {
2057
        (**self).flush()
2058
    }
2059
2060
    #[inline]
2061
    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
2062
        (**self).write_all(buf)
2063
    }
2064
2065
    #[inline]
2066
    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> std::io::Result<()> {
2067
        (**self).write_fmt(fmt)
2068
    }
2069
}
2070
2071
#[cfg(feature = "std")]
2072
impl<S: std::io::Seek + ?Sized, A: Allocator> std::io::Seek for Box<S, A> {
2073
    #[inline]
2074
    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
2075
        (**self).seek(pos)
2076
    }
2077
2078
    #[inline]
2079
    fn stream_position(&mut self) -> std::io::Result<u64> {
2080
        (**self).stream_position()
2081
    }
2082
}
2083
2084
#[cfg(feature = "std")]
2085
impl<B: std::io::BufRead + ?Sized, A: Allocator> std::io::BufRead for Box<B, A> {
2086
    #[inline]
2087
    fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
2088
        (**self).fill_buf()
2089
    }
2090
2091
    #[inline]
2092
    fn consume(&mut self, amt: usize) {
2093
        (**self).consume(amt)
2094
    }
2095
2096
    #[inline]
2097
    fn read_until(&mut self, byte: u8, buf: &mut std::vec::Vec<u8>) -> std::io::Result<usize> {
2098
        (**self).read_until(byte, buf)
2099
    }
2100
2101
    #[inline]
2102
    fn read_line(&mut self, buf: &mut std::string::String) -> std::io::Result<usize> {
2103
        (**self).read_line(buf)
2104
    }
2105
}
2106
2107
#[cfg(feature = "alloc")]
2108
impl<A: Allocator> Extend<Box<str, A>> for alloc_crate::string::String {
2109
0
    fn extend<I: IntoIterator<Item = Box<str, A>>>(&mut self, iter: I) {
2110
0
        iter.into_iter().for_each(move |s| self.push_str(&s));
2111
0
    }
2112
}
2113
2114
#[cfg(not(no_global_oom_handling))]
2115
impl Clone for Box<core::ffi::CStr> {
2116
    #[inline]
2117
0
    fn clone(&self) -> Self {
2118
0
        (**self).into()
2119
0
    }
2120
}
2121
2122
#[cfg(not(no_global_oom_handling))]
2123
impl From<&core::ffi::CStr> for Box<core::ffi::CStr> {
2124
    /// Converts a `&CStr` into a `Box<CStr>`,
2125
    /// by copying the contents into a newly allocated [`Box`].
2126
0
    fn from(s: &core::ffi::CStr) -> Box<core::ffi::CStr> {
2127
0
        let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul());
2128
0
        unsafe { Box::from_raw(Box::into_raw(boxed) as *mut core::ffi::CStr) }
2129
0
    }
2130
}
2131
2132
#[cfg(feature = "serde")]
2133
impl<T, A> serde::Serialize for Box<T, A>
2134
where
2135
    T: serde::Serialize,
2136
    A: Allocator,
2137
{
2138
    #[inline(always)]
2139
    fn serialize<S: serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
2140
        (**self).serialize(serializer)
2141
    }
2142
}
2143
2144
#[cfg(feature = "serde")]
2145
impl<'de, T, A> serde::Deserialize<'de> for Box<T, A>
2146
where
2147
    T: serde::Deserialize<'de>,
2148
    A: Allocator + Default,
2149
{
2150
    #[inline(always)]
2151
    fn deserialize<D: serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
2152
        let value = T::deserialize(deserializer)?;
2153
        Ok(Box::new_in(value, A::default()))
2154
    }
2155
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/allocator-api2-0.2.18/src/stable/mod.rs
Line
Count
Source
1
#![deny(unsafe_op_in_unsafe_fn)]
2
#![allow(clippy::needless_doctest_main, clippy::partialeq_ne_impl)]
3
4
#[cfg(feature = "alloc")]
5
pub use self::slice::SliceExt;
6
7
pub mod alloc;
8
9
#[cfg(feature = "alloc")]
10
pub mod boxed;
11
12
#[cfg(feature = "alloc")]
13
mod raw_vec;
14
15
#[cfg(feature = "alloc")]
16
pub mod vec;
17
18
#[cfg(feature = "alloc")]
19
mod macros;
20
21
#[cfg(feature = "alloc")]
22
mod slice;
23
24
#[cfg(feature = "alloc")]
25
#[track_caller]
26
#[inline(always)]
27
#[cfg(debug_assertions)]
28
0
unsafe fn assume(v: bool) {
29
0
    if !v {
30
0
        core::unreachable!()
31
0
    }
32
0
}
33
34
#[cfg(feature = "alloc")]
35
#[track_caller]
36
#[inline(always)]
37
#[cfg(not(debug_assertions))]
38
unsafe fn assume(v: bool) {
39
    if !v {
40
        unsafe {
41
            core::hint::unreachable_unchecked();
42
        }
43
    }
44
}
45
46
#[cfg(feature = "alloc")]
47
#[inline(always)]
48
0
fn addr<T>(x: *const T) -> usize {
49
0
    #[allow(clippy::useless_transmute, clippy::transmutes_expressible_as_ptr_casts)]
50
0
    unsafe {
51
0
        core::mem::transmute(x)
52
0
    }
53
0
}
54
55
#[cfg(feature = "alloc")]
56
#[inline(always)]
57
0
fn invalid_mut<T>(addr: usize) -> *mut T {
58
0
    #[allow(clippy::useless_transmute, clippy::transmutes_expressible_as_ptr_casts)]
59
0
    unsafe {
60
0
        core::mem::transmute(addr)
61
0
    }
62
0
}
Unexecuted instantiation: _RINvNtCsby83UglaBWc_14allocator_api26stable11invalid_muthEB4_
Unexecuted instantiation: _RINvNtCsby83UglaBWc_14allocator_api26stable11invalid_muthECs568wuOlRYFZ_8chia_bls
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/allocator-api2-0.2.18/src/stable/raw_vec.rs
Line
Count
Source
1
use core::alloc::LayoutError;
2
use core::mem::{self, ManuallyDrop, MaybeUninit};
3
use core::ops::Drop;
4
use core::ptr::{self, NonNull};
5
use core::slice;
6
use core::{cmp, fmt};
7
8
use super::{
9
    alloc::{Allocator, Global, Layout},
10
    assume,
11
    boxed::Box,
12
};
13
14
#[cfg(not(no_global_oom_handling))]
15
use super::alloc::handle_alloc_error;
16
17
/// The error type for `try_reserve` methods.
18
#[derive(Clone, PartialEq, Eq, Debug)]
19
pub struct TryReserveError {
20
    kind: TryReserveErrorKind,
21
}
22
23
impl TryReserveError {
24
    /// Details about the allocation that caused the error
25
0
    pub fn kind(&self) -> TryReserveErrorKind {
26
0
        self.kind.clone()
27
0
    }
28
}
29
30
/// Details of the allocation that caused a `TryReserveError`
31
#[derive(Clone, PartialEq, Eq, Debug)]
32
pub enum TryReserveErrorKind {
33
    /// Error due to the computed capacity exceeding the collection's maximum
34
    /// (usually `isize::MAX` bytes).
35
    CapacityOverflow,
36
37
    /// The memory allocator returned an error
38
    AllocError {
39
        /// The layout of allocation request that failed
40
        layout: Layout,
41
42
        #[doc(hidden)]
43
        non_exhaustive: (),
44
    },
45
}
46
47
use TryReserveErrorKind::*;
48
49
impl From<TryReserveErrorKind> for TryReserveError {
50
    #[inline(always)]
51
    fn from(kind: TryReserveErrorKind) -> Self {
52
        Self { kind }
53
    }
54
}
55
56
impl From<LayoutError> for TryReserveErrorKind {
57
    /// Always evaluates to [`TryReserveErrorKind::CapacityOverflow`].
58
    #[inline(always)]
59
    fn from(_: LayoutError) -> Self {
60
        TryReserveErrorKind::CapacityOverflow
61
    }
62
}
63
64
impl fmt::Display for TryReserveError {
65
0
    fn fmt(
66
0
        &self,
67
0
        fmt: &mut core::fmt::Formatter<'_>,
68
0
    ) -> core::result::Result<(), core::fmt::Error> {
69
0
        fmt.write_str("memory allocation failed")?;
70
0
        let reason = match self.kind {
71
            TryReserveErrorKind::CapacityOverflow => {
72
0
                " because the computed capacity exceeded the collection's maximum"
73
            }
74
            TryReserveErrorKind::AllocError { .. } => {
75
0
                " because the memory allocator returned an error"
76
            }
77
        };
78
0
        fmt.write_str(reason)
79
0
    }
80
}
81
82
#[cfg(feature = "std")]
83
impl std::error::Error for TryReserveError {}
84
85
#[cfg(not(no_global_oom_handling))]
86
enum AllocInit {
87
    /// The contents of the new memory are uninitialized.
88
    Uninitialized,
89
    /// The new memory is guaranteed to be zeroed.
90
    Zeroed,
91
}
92
93
/// A low-level utility for more ergonomically allocating, reallocating, and deallocating
94
/// a buffer of memory on the heap without having to worry about all the corner cases
95
/// involved. This type is excellent for building your own data structures like Vec and VecDeque.
96
/// In particular:
97
///
98
/// * Produces `NonNull::dangling()` on zero-sized types.
99
/// * Produces `NonNull::dangling()` on zero-length allocations.
100
/// * Avoids freeing `NonNull::dangling()`.
101
/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics).
102
/// * Guards against 32-bit systems allocating more than isize::MAX bytes.
103
/// * Guards against overflowing your length.
104
/// * Calls `handle_alloc_error` for fallible allocations.
105
/// * Contains a `ptr::NonNull` and thus endows the user with all related benefits.
106
/// * Uses the excess returned from the allocator to use the largest available capacity.
107
///
108
/// This type does not in anyway inspect the memory that it manages. When dropped it *will*
109
/// free its memory, but it *won't* try to drop its contents. It is up to the user of `RawVec`
110
/// to handle the actual things *stored* inside of a `RawVec`.
111
///
112
/// Note that the excess of a zero-sized types is always infinite, so `capacity()` always returns
113
/// `usize::MAX`. This means that you need to be careful when round-tripping this type with a
114
/// `Box<[T]>`, since `capacity()` won't yield the length.
115
#[allow(missing_debug_implementations)]
116
pub(crate) struct RawVec<T, A: Allocator = Global> {
117
    ptr: NonNull<T>,
118
    cap: usize,
119
    alloc: A,
120
}
121
122
// Safety: RawVec owns both T and A, so sending is safe if
123
// sending is safe for T and A.
124
unsafe impl<T, A: Allocator> Send for RawVec<T, A>
125
where
126
    T: Send,
127
    A: Send,
128
{
129
}
130
131
// Safety: RawVec owns both T and A, so sharing is safe if
132
// sharing is safe for T and A.
133
unsafe impl<T, A: Allocator> Sync for RawVec<T, A>
134
where
135
    T: Sync,
136
    A: Sync,
137
{
138
}
139
140
impl<T> RawVec<T, Global> {
141
    /// Creates the biggest possible `RawVec` (on the system heap)
142
    /// without allocating. If `T` has positive size, then this makes a
143
    /// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a
144
    /// `RawVec` with capacity `usize::MAX`. Useful for implementing
145
    /// delayed allocation.
146
    #[must_use]
147
0
    pub const fn new() -> Self {
148
0
        Self::new_in(Global)
149
0
    }
150
151
    /// Creates a `RawVec` (on the system heap) with exactly the
152
    /// capacity and alignment requirements for a `[T; capacity]`. This is
153
    /// equivalent to calling `RawVec::new` when `capacity` is `0` or `T` is
154
    /// zero-sized. Note that if `T` is zero-sized this means you will
155
    /// *not* get a `RawVec` with the requested capacity.
156
    ///
157
    /// # Panics
158
    ///
159
    /// Panics if the requested capacity exceeds `isize::MAX` bytes.
160
    ///
161
    /// # Aborts
162
    ///
163
    /// Aborts on OOM.
164
    #[cfg(not(no_global_oom_handling))]
165
    #[must_use]
166
    #[inline(always)]
167
0
    pub fn with_capacity(capacity: usize) -> Self {
168
0
        Self::with_capacity_in(capacity, Global)
169
0
    }
170
171
    /// Like `with_capacity`, but guarantees the buffer is zeroed.
172
    #[cfg(not(no_global_oom_handling))]
173
    #[must_use]
174
    #[inline(always)]
175
0
    pub fn with_capacity_zeroed(capacity: usize) -> Self {
176
0
        Self::with_capacity_zeroed_in(capacity, Global)
177
0
    }
178
}
179
180
impl<T, A: Allocator> RawVec<T, A> {
181
    // Tiny Vecs are dumb. Skip to:
182
    // - 8 if the element size is 1, because any heap allocators is likely
183
    //   to round up a request of less than 8 bytes to at least 8 bytes.
184
    // - 4 if elements are moderate-sized (<= 1 KiB).
185
    // - 1 otherwise, to avoid wasting too much space for very short Vecs.
186
    pub(crate) const MIN_NON_ZERO_CAP: usize = if mem::size_of::<T>() == 1 {
187
        8
188
    } else if mem::size_of::<T>() <= 1024 {
189
        4
190
    } else {
191
        1
192
    };
193
194
    /// Like `new`, but parameterized over the choice of allocator for
195
    /// the returned `RawVec`.
196
    #[inline(always)]
197
0
    pub const fn new_in(alloc: A) -> Self {
198
0
        // `cap: 0` means "unallocated". zero-sized types are ignored.
199
0
        Self {
200
0
            ptr: NonNull::dangling(),
201
0
            cap: 0,
202
0
            alloc,
203
0
        }
204
0
    }
205
206
    /// Like `with_capacity`, but parameterized over the choice of
207
    /// allocator for the returned `RawVec`.
208
    #[cfg(not(no_global_oom_handling))]
209
    #[inline(always)]
210
0
    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
211
0
        Self::allocate_in(capacity, AllocInit::Uninitialized, alloc)
212
0
    }
213
214
    /// Like `with_capacity_zeroed`, but parameterized over the choice
215
    /// of allocator for the returned `RawVec`.
216
    #[cfg(not(no_global_oom_handling))]
217
    #[inline(always)]
218
0
    pub fn with_capacity_zeroed_in(capacity: usize, alloc: A) -> Self {
219
0
        Self::allocate_in(capacity, AllocInit::Zeroed, alloc)
220
0
    }
221
222
    /// Converts the entire buffer into `Box<[MaybeUninit<T>]>` with the specified `len`.
223
    ///
224
    /// Note that this will correctly reconstitute any `cap` changes
225
    /// that may have been performed. (See description of type for details.)
226
    ///
227
    /// # Safety
228
    ///
229
    /// * `len` must be greater than or equal to the most recently requested capacity, and
230
    /// * `len` must be less than or equal to `self.capacity()`.
231
    ///
232
    /// Note, that the requested capacity and `self.capacity()` could differ, as
233
    /// an allocator could overallocate and return a greater memory block than requested.
234
    #[inline(always)]
235
0
    pub unsafe fn into_box(self, len: usize) -> Box<[MaybeUninit<T>], A> {
236
0
        // Sanity-check one half of the safety requirement (we cannot check the other half).
237
0
        debug_assert!(
238
0
            len <= self.capacity(),
239
            "`len` must be smaller than or equal to `self.capacity()`"
240
        );
241
242
0
        let me = ManuallyDrop::new(self);
243
0
        unsafe {
244
0
            let slice = slice::from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len);
245
0
            Box::from_raw_in(slice, ptr::read(&me.alloc))
246
0
        }
247
0
    }
248
249
    #[cfg(not(no_global_oom_handling))]
250
    #[inline(always)]
251
0
    fn allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Self {
252
0
        // Don't allocate here because `Drop` will not deallocate when `capacity` is 0.
253
0
        if mem::size_of::<T>() == 0 || capacity == 0 {
254
0
            Self::new_in(alloc)
255
        } else {
256
            // We avoid `unwrap_or_else` here because it bloats the amount of
257
            // LLVM IR generated.
258
0
            let layout = match Layout::array::<T>(capacity) {
259
0
                Ok(layout) => layout,
260
0
                Err(_) => capacity_overflow(),
261
            };
262
0
            match alloc_guard(layout.size()) {
263
0
                Ok(_) => {}
264
0
                Err(_) => capacity_overflow(),
265
            }
266
0
            let result = match init {
267
0
                AllocInit::Uninitialized => alloc.allocate(layout),
268
0
                AllocInit::Zeroed => alloc.allocate_zeroed(layout),
269
            };
270
0
            let ptr = match result {
271
0
                Ok(ptr) => ptr,
272
0
                Err(_) => handle_alloc_error(layout),
273
            };
274
275
            // Allocators currently return a `NonNull<[u8]>` whose length
276
            // matches the size requested. If that ever changes, the capacity
277
            // here should change to `ptr.len() / mem::size_of::<T>()`.
278
0
            Self {
279
0
                ptr: unsafe { NonNull::new_unchecked(ptr.cast().as_ptr()) },
280
0
                cap: capacity,
281
0
                alloc,
282
0
            }
283
        }
284
0
    }
285
286
    /// Reconstitutes a `RawVec` from a pointer, capacity, and allocator.
287
    ///
288
    /// # Safety
289
    ///
290
    /// The `ptr` must be allocated (via the given allocator `alloc`), and with the given
291
    /// `capacity`.
292
    /// The `capacity` cannot exceed `isize::MAX` for sized types. (only a concern on 32-bit
293
    /// systems). ZST vectors may have a capacity up to `usize::MAX`.
294
    /// If the `ptr` and `capacity` come from a `RawVec` created via `alloc`, then this is
295
    /// guaranteed.
296
    #[inline(always)]
297
0
    pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, alloc: A) -> Self {
298
0
        Self {
299
0
            ptr: unsafe { NonNull::new_unchecked(ptr) },
300
0
            cap: capacity,
301
0
            alloc,
302
0
        }
303
0
    }
304
305
    /// Gets a raw pointer to the start of the allocation. Note that this is
306
    /// `NonNull::dangling()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
307
    /// be careful.
308
    #[inline(always)]
309
0
    pub fn ptr(&self) -> *mut T {
310
0
        self.ptr.as_ptr()
311
0
    }
312
313
    /// Gets the capacity of the allocation.
314
    ///
315
    /// This will always be `usize::MAX` if `T` is zero-sized.
316
    #[inline(always)]
317
0
    pub fn capacity(&self) -> usize {
318
0
        if mem::size_of::<T>() == 0 {
319
0
            usize::MAX
320
        } else {
321
0
            self.cap
322
        }
323
0
    }
324
325
    /// Returns a shared reference to the allocator backing this `RawVec`.
326
    #[inline(always)]
327
0
    pub fn allocator(&self) -> &A {
328
0
        &self.alloc
329
0
    }
330
331
    #[inline(always)]
332
0
    fn current_memory(&self) -> Option<(NonNull<u8>, Layout)> {
333
0
        if mem::size_of::<T>() == 0 || self.cap == 0 {
334
0
            None
335
        } else {
336
            // We have an allocated chunk of memory, so we can bypass runtime
337
            // checks to get our current layout.
338
            unsafe {
339
0
                let layout = Layout::array::<T>(self.cap).unwrap_unchecked();
340
0
                Some((self.ptr.cast(), layout))
341
            }
342
        }
343
0
    }
344
345
    /// Ensures that the buffer contains at least enough space to hold `len +
346
    /// additional` elements. If it doesn't already have enough capacity, will
347
    /// reallocate enough space plus comfortable slack space to get amortized
348
    /// *O*(1) behavior. Will limit this behavior if it would needlessly cause
349
    /// itself to panic.
350
    ///
351
    /// If `len` exceeds `self.capacity()`, this may fail to actually allocate
352
    /// the requested space. This is not really unsafe, but the unsafe
353
    /// code *you* write that relies on the behavior of this function may break.
354
    ///
355
    /// This is ideal for implementing a bulk-push operation like `extend`.
356
    ///
357
    /// # Panics
358
    ///
359
    /// Panics if the new capacity exceeds `isize::MAX` bytes.
360
    ///
361
    /// # Aborts
362
    ///
363
    /// Aborts on OOM.
364
    #[cfg(not(no_global_oom_handling))]
365
    #[inline(always)]
366
0
    pub fn reserve(&mut self, len: usize, additional: usize) {
367
        // Callers expect this function to be very cheap when there is already sufficient capacity.
368
        // Therefore, we move all the resizing and error-handling logic from grow_amortized and
369
        // handle_reserve behind a call, while making sure that this function is likely to be
370
        // inlined as just a comparison and a call if the comparison fails.
371
        #[cold]
372
        #[inline(always)]
373
        fn do_reserve_and_handle<T, A: Allocator>(
374
            slf: &mut RawVec<T, A>,
375
            len: usize,
376
            additional: usize,
377
        ) {
378
            handle_reserve(slf.grow_amortized(len, additional));
379
        }
380
381
0
        if self.needs_to_grow(len, additional) {
382
0
            do_reserve_and_handle(self, len, additional);
383
0
        }
384
0
    }
385
386
    /// A specialized version of `reserve()` used only by the hot and
387
    /// oft-instantiated `Vec::push()`, which does its own capacity check.
388
    #[cfg(not(no_global_oom_handling))]
389
    #[inline(always)]
390
0
    pub fn reserve_for_push(&mut self, len: usize) {
391
0
        handle_reserve(self.grow_amortized(len, 1));
392
0
    }
393
394
    /// The same as `reserve`, but returns on errors instead of panicking or aborting.
395
    #[inline(always)]
396
0
    pub fn try_reserve(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
397
0
        if self.needs_to_grow(len, additional) {
398
0
            self.grow_amortized(len, additional)
399
        } else {
400
0
            Ok(())
401
        }
402
0
    }
403
404
    /// Ensures that the buffer contains at least enough space to hold `len +
405
    /// additional` elements. If it doesn't already, will reallocate the
406
    /// minimum possible amount of memory necessary. Generally this will be
407
    /// exactly the amount of memory necessary, but in principle the allocator
408
    /// is free to give back more than we asked for.
409
    ///
410
    /// If `len` exceeds `self.capacity()`, this may fail to actually allocate
411
    /// the requested space. This is not really unsafe, but the unsafe code
412
    /// *you* write that relies on the behavior of this function may break.
413
    ///
414
    /// # Panics
415
    ///
416
    /// Panics if the new capacity exceeds `isize::MAX` bytes.
417
    ///
418
    /// # Aborts
419
    ///
420
    /// Aborts on OOM.
421
    #[cfg(not(no_global_oom_handling))]
422
    #[inline(always)]
423
0
    pub fn reserve_exact(&mut self, len: usize, additional: usize) {
424
0
        handle_reserve(self.try_reserve_exact(len, additional));
425
0
    }
426
427
    /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting.
428
    #[inline(always)]
429
0
    pub fn try_reserve_exact(
430
0
        &mut self,
431
0
        len: usize,
432
0
        additional: usize,
433
0
    ) -> Result<(), TryReserveError> {
434
0
        if self.needs_to_grow(len, additional) {
435
0
            self.grow_exact(len, additional)
436
        } else {
437
0
            Ok(())
438
        }
439
0
    }
440
441
    /// Shrinks the buffer down to the specified capacity. If the given amount
442
    /// is 0, actually completely deallocates.
443
    ///
444
    /// # Panics
445
    ///
446
    /// Panics if the given amount is *larger* than the current capacity.
447
    ///
448
    /// # Aborts
449
    ///
450
    /// Aborts on OOM.
451
    #[cfg(not(no_global_oom_handling))]
452
    #[inline(always)]
453
0
    pub fn shrink_to_fit(&mut self, cap: usize) {
454
0
        handle_reserve(self.shrink(cap));
455
0
    }
456
}
457
458
impl<T, A: Allocator> RawVec<T, A> {
459
    /// Returns if the buffer needs to grow to fulfill the needed extra capacity.
460
    /// Mainly used to make inlining reserve-calls possible without inlining `grow`.
461
    #[inline(always)]
462
0
    fn needs_to_grow(&self, len: usize, additional: usize) -> bool {
463
0
        additional > self.capacity().wrapping_sub(len)
464
0
    }
465
466
    #[inline(always)]
467
0
    fn set_ptr_and_cap(&mut self, ptr: NonNull<[u8]>, cap: usize) {
468
0
        // Allocators currently return a `NonNull<[u8]>` whose length matches
469
0
        // the size requested. If that ever changes, the capacity here should
470
0
        // change to `ptr.len() / mem::size_of::<T>()`.
471
0
        self.ptr = unsafe { NonNull::new_unchecked(ptr.cast().as_ptr()) };
472
0
        self.cap = cap;
473
0
    }
474
475
    // This method is usually instantiated many times. So we want it to be as
476
    // small as possible, to improve compile times. But we also want as much of
477
    // its contents to be statically computable as possible, to make the
478
    // generated code run faster. Therefore, this method is carefully written
479
    // so that all of the code that depends on `T` is within it, while as much
480
    // of the code that doesn't depend on `T` as possible is in functions that
481
    // are non-generic over `T`.
482
    #[inline(always)]
483
    fn grow_amortized(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
484
        // This is ensured by the calling contexts.
485
        debug_assert!(additional > 0);
486
487
        if mem::size_of::<T>() == 0 {
488
            // Since we return a capacity of `usize::MAX` when `elem_size` is
489
            // 0, getting to here necessarily means the `RawVec` is overfull.
490
            return Err(CapacityOverflow.into());
491
        }
492
493
        // Nothing we can really do about these checks, sadly.
494
        let required_cap = len.checked_add(additional).ok_or(CapacityOverflow)?;
495
496
        // This guarantees exponential growth. The doubling cannot overflow
497
        // because `cap <= isize::MAX` and the type of `cap` is `usize`.
498
        let cap = cmp::max(self.cap * 2, required_cap);
499
        let cap = cmp::max(Self::MIN_NON_ZERO_CAP, cap);
500
501
        let new_layout = Layout::array::<T>(cap);
502
503
        // `finish_grow` is non-generic over `T`.
504
        let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
505
        self.set_ptr_and_cap(ptr, cap);
506
        Ok(())
507
    }
508
509
    // The constraints on this method are much the same as those on
510
    // `grow_amortized`, but this method is usually instantiated less often so
511
    // it's less critical.
512
    #[inline(always)]
513
0
    fn grow_exact(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
514
0
        if mem::size_of::<T>() == 0 {
515
            // Since we return a capacity of `usize::MAX` when the type size is
516
            // 0, getting to here necessarily means the `RawVec` is overfull.
517
0
            return Err(CapacityOverflow.into());
518
0
        }
519
520
0
        let cap = len.checked_add(additional).ok_or(CapacityOverflow)?;
521
0
        let new_layout = Layout::array::<T>(cap);
522
523
        // `finish_grow` is non-generic over `T`.
524
0
        let ptr = finish_grow(new_layout, self.current_memory(), &mut self.alloc)?;
525
0
        self.set_ptr_and_cap(ptr, cap);
526
0
        Ok(())
527
0
    }
528
529
    #[cfg(not(no_global_oom_handling))]
530
    #[inline(always)]
531
0
    fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> {
532
0
        assert!(
533
0
            cap <= self.capacity(),
534
0
            "Tried to shrink to a larger capacity"
535
0
        );
536
537
0
        let (ptr, layout) = if let Some(mem) = self.current_memory() {
538
0
            mem
539
        } else {
540
0
            return Ok(());
541
        };
542
543
0
        let ptr = unsafe {
544
            // `Layout::array` cannot overflow here because it would have
545
            // overflowed earlier when capacity was larger.
546
0
            let new_layout = Layout::array::<T>(cap).unwrap_unchecked();
547
0
            self.alloc
548
0
                .shrink(ptr, layout, new_layout)
549
0
                .map_err(|_| AllocError {
550
0
                    layout: new_layout,
551
0
                    non_exhaustive: (),
552
0
                })?
553
        };
554
0
        self.set_ptr_and_cap(ptr, cap);
555
0
        Ok(())
556
0
    }
557
}
558
559
// This function is outside `RawVec` to minimize compile times. See the comment
560
// above `RawVec::grow_amortized` for details. (The `A` parameter isn't
561
// significant, because the number of different `A` types seen in practice is
562
// much smaller than the number of `T` types.)
563
#[inline(always)]
564
fn finish_grow<A>(
565
    new_layout: Result<Layout, LayoutError>,
566
    current_memory: Option<(NonNull<u8>, Layout)>,
567
    alloc: &mut A,
568
) -> Result<NonNull<[u8]>, TryReserveError>
569
where
570
    A: Allocator,
571
{
572
    // Check for the error here to minimize the size of `RawVec::grow_*`.
573
0
    let new_layout = new_layout.map_err(|_| CapacityOverflow)?;
574
575
    alloc_guard(new_layout.size())?;
576
577
    let memory = if let Some((ptr, old_layout)) = current_memory {
578
        debug_assert_eq!(old_layout.align(), new_layout.align());
579
        unsafe {
580
            // The allocator checks for alignment equality
581
            assume(old_layout.align() == new_layout.align());
582
            alloc.grow(ptr, old_layout, new_layout)
583
        }
584
    } else {
585
        alloc.allocate(new_layout)
586
    };
587
588
0
    memory.map_err(|_| {
589
0
        AllocError {
590
0
            layout: new_layout,
591
0
            non_exhaustive: (),
592
0
        }
593
0
        .into()
594
0
    })
595
}
596
597
impl<T, A: Allocator> Drop for RawVec<T, A> {
598
    /// Frees the memory owned by the `RawVec` *without* trying to drop its contents.
599
    #[inline(always)]
600
0
    fn drop(&mut self) {
601
0
        if let Some((ptr, layout)) = self.current_memory() {
602
0
            unsafe { self.alloc.deallocate(ptr, layout) }
603
0
        }
604
0
    }
605
}
606
607
// Central function for reserve error handling.
608
#[cfg(not(no_global_oom_handling))]
609
#[inline(always)]
610
fn handle_reserve(result: Result<(), TryReserveError>) {
611
0
    match result.map_err(|e| e.kind()) {
612
        Err(CapacityOverflow) => capacity_overflow(),
613
        Err(AllocError { layout, .. }) => handle_alloc_error(layout),
614
        Ok(()) => { /* yay */ }
615
    }
616
}
617
618
// We need to guarantee the following:
619
// * We don't ever allocate `> isize::MAX` byte-size objects.
620
// * We don't overflow `usize::MAX` and actually allocate too little.
621
//
622
// On 64-bit we just need to check for overflow since trying to allocate
623
// `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add
624
// an extra guard for this in case we're running on a platform which can use
625
// all 4GB in user-space, e.g., PAE or x32.
626
627
#[inline(always)]
628
0
fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
629
0
    if usize::BITS < 64 && alloc_size > isize::MAX as usize {
630
0
        Err(CapacityOverflow.into())
631
    } else {
632
0
        Ok(())
633
    }
634
0
}
635
636
// One central function responsible for reporting capacity overflows. This'll
637
// ensure that the code generation related to these panics is minimal as there's
638
// only one location which panics rather than a bunch throughout the module.
639
#[cfg(not(no_global_oom_handling))]
640
0
fn capacity_overflow() -> ! {
641
0
    panic!("capacity overflow");
642
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/allocator-api2-0.2.18/src/stable/slice.rs
Line
Count
Source
1
use crate::{
2
    alloc::{Allocator, Global},
3
    vec::Vec,
4
};
5
6
/// Slice methods that use `Box` and `Vec` from this crate.
7
pub trait SliceExt<T> {
8
    /// Copies `self` into a new `Vec`.
9
    ///
10
    /// # Examples
11
    ///
12
    /// ```
13
    /// let s = [10, 40, 30];
14
    /// let x = s.to_vec();
15
    /// // Here, `s` and `x` can be modified independently.
16
    /// ```
17
    #[cfg(not(no_global_oom_handling))]
18
    #[inline(always)]
19
0
    fn to_vec(&self) -> Vec<T, Global>
20
0
    where
21
0
        T: Clone,
22
0
    {
23
0
        self.to_vec_in(Global)
24
0
    }
25
26
    /// Copies `self` into a new `Vec` with an allocator.
27
    ///
28
    /// # Examples
29
    ///
30
    /// ```
31
    /// #![feature(allocator_api)]
32
    ///
33
    /// use std::alloc::System;
34
    ///
35
    /// let s = [10, 40, 30];
36
    /// let x = s.to_vec_in(System);
37
    /// // Here, `s` and `x` can be modified independently.
38
    /// ```
39
    #[cfg(not(no_global_oom_handling))]
40
    fn to_vec_in<A: Allocator>(&self, alloc: A) -> Vec<T, A>
41
    where
42
        T: Clone;
43
44
    /// Creates a vector by copying a slice `n` times.
45
    ///
46
    /// # Panics
47
    ///
48
    /// This function will panic if the capacity would overflow.
49
    ///
50
    /// # Examples
51
    ///
52
    /// Basic usage:
53
    ///
54
    /// ```
55
    /// assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
56
    /// ```
57
    ///
58
    /// A panic upon overflow:
59
    ///
60
    /// ```should_panic
61
    /// // this will panic at runtime
62
    /// b"0123456789abcdef".repeat(usize::MAX);
63
    /// ```
64
    fn repeat(&self, n: usize) -> Vec<T, Global>
65
    where
66
        T: Copy;
67
}
68
69
impl<T> SliceExt<T> for [T] {
70
    #[cfg(not(no_global_oom_handling))]
71
    #[inline]
72
0
    fn to_vec_in<A: Allocator>(&self, alloc: A) -> Vec<T, A>
73
0
    where
74
0
        T: Clone,
75
0
    {
76
        struct DropGuard<'a, T, A: Allocator> {
77
            vec: &'a mut Vec<T, A>,
78
            num_init: usize,
79
        }
80
        impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> {
81
            #[inline]
82
0
            fn drop(&mut self) {
83
0
                // SAFETY:
84
0
                // items were marked initialized in the loop below
85
0
                unsafe {
86
0
                    self.vec.set_len(self.num_init);
87
0
                }
88
0
            }
89
        }
90
91
0
        let mut vec = Vec::with_capacity_in(self.len(), alloc);
92
0
        let mut guard = DropGuard {
93
0
            vec: &mut vec,
94
0
            num_init: 0,
95
0
        };
96
0
        let slots = guard.vec.spare_capacity_mut();
97
        // .take(slots.len()) is necessary for LLVM to remove bounds checks
98
        // and has better codegen than zip.
99
0
        for (i, b) in self.iter().enumerate().take(slots.len()) {
100
0
            guard.num_init = i;
101
0
            slots[i].write(b.clone());
102
0
        }
103
0
        core::mem::forget(guard);
104
0
        // SAFETY:
105
0
        // the vec was allocated and initialized above to at least this length.
106
0
        unsafe {
107
0
            vec.set_len(self.len());
108
0
        }
109
0
        vec
110
0
    }
111
112
    #[cfg(not(no_global_oom_handling))]
113
    #[inline]
114
0
    fn repeat(&self, n: usize) -> Vec<T, Global>
115
0
    where
116
0
        T: Copy,
117
0
    {
118
0
        if n == 0 {
119
0
            return Vec::new();
120
0
        }
121
0
122
0
        // If `n` is larger than zero, it can be split as
123
0
        // `n = 2^expn + rem (2^expn > rem, expn >= 0, rem >= 0)`.
124
0
        // `2^expn` is the number represented by the leftmost '1' bit of `n`,
125
0
        // and `rem` is the remaining part of `n`.
126
0
127
0
        // Using `Vec` to access `set_len()`.
128
0
        let capacity = self.len().checked_mul(n).expect("capacity overflow");
129
0
        let mut buf = Vec::with_capacity(capacity);
130
0
131
0
        // `2^expn` repetition is done by doubling `buf` `expn`-times.
132
0
        buf.extend(self);
133
0
        {
134
0
            let mut m = n >> 1;
135
            // If `m > 0`, there are remaining bits up to the leftmost '1'.
136
0
            while m > 0 {
137
0
                // `buf.extend(buf)`:
138
0
                unsafe {
139
0
                    core::ptr::copy_nonoverlapping(
140
0
                        buf.as_ptr(),
141
0
                        (buf.as_mut_ptr() as *mut T).add(buf.len()),
142
0
                        buf.len(),
143
0
                    );
144
0
                    // `buf` has capacity of `self.len() * n`.
145
0
                    let buf_len = buf.len();
146
0
                    buf.set_len(buf_len * 2);
147
0
                }
148
0
149
0
                m >>= 1;
150
0
            }
151
        }
152
153
        // `rem` (`= n - 2^expn`) repetition is done by copying
154
        // first `rem` repetitions from `buf` itself.
155
0
        let rem_len = capacity - buf.len(); // `self.len() * rem`
156
0
        if rem_len > 0 {
157
            // `buf.extend(buf[0 .. rem_len])`:
158
0
            unsafe {
159
0
                // This is non-overlapping since `2^expn > rem`.
160
0
                core::ptr::copy_nonoverlapping(
161
0
                    buf.as_ptr(),
162
0
                    (buf.as_mut_ptr() as *mut T).add(buf.len()),
163
0
                    rem_len,
164
0
                );
165
0
                // `buf.len() + rem_len` equals to `buf.capacity()` (`= self.len() * n`).
166
0
                buf.set_len(capacity);
167
0
            }
168
0
        }
169
0
        buf
170
0
    }
171
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/allocator-api2-0.2.18/src/stable/vec/drain.rs
Line
Count
Source
1
use core::fmt;
2
use core::iter::FusedIterator;
3
use core::mem::{self, size_of, ManuallyDrop};
4
use core::ptr::{self, NonNull};
5
use core::slice::{self};
6
7
use crate::stable::alloc::{Allocator, Global};
8
9
use super::Vec;
10
11
/// A draining iterator for `Vec<T>`.
12
///
13
/// This `struct` is created by [`Vec::drain`].
14
/// See its documentation for more.
15
///
16
/// # Example
17
///
18
/// ```
19
/// let mut v = vec![0, 1, 2];
20
/// let iter: std::vec::Drain<_> = v.drain(..);
21
/// ```
22
pub struct Drain<'a, T: 'a, A: Allocator + 'a = Global> {
23
    /// Index of tail to preserve
24
    pub(super) tail_start: usize,
25
    /// Length of tail
26
    pub(super) tail_len: usize,
27
    /// Current remaining range to remove
28
    pub(super) iter: slice::Iter<'a, T>,
29
    pub(super) vec: NonNull<Vec<T, A>>,
30
}
31
32
impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
33
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34
0
        f.debug_tuple("Drain").field(&self.iter.as_slice()).finish()
35
0
    }
36
}
37
38
impl<'a, T, A: Allocator> Drain<'a, T, A> {
39
    /// Returns the remaining items of this iterator as a slice.
40
    ///
41
    /// # Examples
42
    ///
43
    /// ```
44
    /// let mut vec = vec!['a', 'b', 'c'];
45
    /// let mut drain = vec.drain(..);
46
    /// assert_eq!(drain.as_slice(), &['a', 'b', 'c']);
47
    /// let _ = drain.next().unwrap();
48
    /// assert_eq!(drain.as_slice(), &['b', 'c']);
49
    /// ```
50
    #[must_use]
51
    #[inline(always)]
52
0
    pub fn as_slice(&self) -> &[T] {
53
0
        self.iter.as_slice()
54
0
    }
55
56
    /// Returns a reference to the underlying allocator.
57
    #[must_use]
58
    #[inline(always)]
59
0
    pub fn allocator(&self) -> &A {
60
0
        unsafe { self.vec.as_ref().allocator() }
61
0
    }
62
63
    /// Keep unyielded elements in the source `Vec`.
64
    ///
65
    /// # Examples
66
    ///
67
    /// ```
68
    /// #![feature(drain_keep_rest)]
69
    ///
70
    /// let mut vec = vec!['a', 'b', 'c'];
71
    /// let mut drain = vec.drain(..);
72
    ///
73
    /// assert_eq!(drain.next().unwrap(), 'a');
74
    ///
75
    /// // This call keeps 'b' and 'c' in the vec.
76
    /// drain.keep_rest();
77
    ///
78
    /// // If we wouldn't call `keep_rest()`,
79
    /// // `vec` would be empty.
80
    /// assert_eq!(vec, ['b', 'c']);
81
    /// ```
82
    #[inline(always)]
83
0
    pub fn keep_rest(self) {
84
0
        // At this moment layout looks like this:
85
0
        //
86
0
        // [head] [yielded by next] [unyielded] [yielded by next_back] [tail]
87
0
        //        ^-- start         \_________/-- unyielded_len        \____/-- self.tail_len
88
0
        //                          ^-- unyielded_ptr                  ^-- tail
89
0
        //
90
0
        // Normally `Drop` impl would drop [unyielded] and then move [tail] to the `start`.
91
0
        // Here we want to
92
0
        // 1. Move [unyielded] to `start`
93
0
        // 2. Move [tail] to a new start at `start + len(unyielded)`
94
0
        // 3. Update length of the original vec to `len(head) + len(unyielded) + len(tail)`
95
0
        //    a. In case of ZST, this is the only thing we want to do
96
0
        // 4. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do
97
0
        let mut this = ManuallyDrop::new(self);
98
0
99
0
        unsafe {
100
0
            let source_vec = this.vec.as_mut();
101
0
102
0
            let start = source_vec.len();
103
0
            let tail = this.tail_start;
104
0
105
0
            let unyielded_len = this.iter.len();
106
0
            let unyielded_ptr = this.iter.as_slice().as_ptr();
107
0
108
0
            // ZSTs have no identity, so we don't need to move them around.
109
0
            let needs_move = mem::size_of::<T>() != 0;
110
0
111
0
            if needs_move {
112
0
                let start_ptr = source_vec.as_mut_ptr().add(start);
113
0
114
0
                // memmove back unyielded elements
115
0
                if unyielded_ptr != start_ptr {
116
0
                    let src = unyielded_ptr;
117
0
                    let dst = start_ptr;
118
0
119
0
                    ptr::copy(src, dst, unyielded_len);
120
0
                }
121
122
                // memmove back untouched tail
123
0
                if tail != (start + unyielded_len) {
124
0
                    let src = source_vec.as_ptr().add(tail);
125
0
                    let dst = start_ptr.add(unyielded_len);
126
0
                    ptr::copy(src, dst, this.tail_len);
127
0
                }
128
0
            }
129
130
0
            source_vec.set_len(start + unyielded_len + this.tail_len);
131
0
        }
132
0
    }
133
}
134
135
impl<'a, T, A: Allocator> AsRef<[T]> for Drain<'a, T, A> {
136
    #[inline(always)]
137
0
    fn as_ref(&self) -> &[T] {
138
0
        self.as_slice()
139
0
    }
140
}
141
142
unsafe impl<T: Sync, A: Sync + Allocator> Sync for Drain<'_, T, A> {}
143
144
unsafe impl<T: Send, A: Send + Allocator> Send for Drain<'_, T, A> {}
145
146
impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
147
    type Item = T;
148
149
    #[inline(always)]
150
0
    fn next(&mut self) -> Option<T> {
151
0
        self.iter
152
0
            .next()
153
0
            .map(|elt| unsafe { ptr::read(elt as *const _) })
154
0
    }
155
156
    #[inline(always)]
157
0
    fn size_hint(&self) -> (usize, Option<usize>) {
158
0
        self.iter.size_hint()
159
0
    }
160
}
161
162
impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
163
    #[inline(always)]
164
0
    fn next_back(&mut self) -> Option<T> {
165
0
        self.iter
166
0
            .next_back()
167
0
            .map(|elt| unsafe { ptr::read(elt as *const _) })
168
0
    }
169
}
170
171
impl<T, A: Allocator> Drop for Drain<'_, T, A> {
172
    #[inline]
173
0
    fn drop(&mut self) {
174
        /// Moves back the un-`Drain`ed elements to restore the original `Vec`.
175
        struct DropGuard<'r, 'a, T, A: Allocator>(&'r mut Drain<'a, T, A>);
176
177
        impl<'r, 'a, T, A: Allocator> Drop for DropGuard<'r, 'a, T, A> {
178
0
            fn drop(&mut self) {
179
0
                if self.0.tail_len > 0 {
180
                    unsafe {
181
0
                        let source_vec = self.0.vec.as_mut();
182
0
                        // memmove back untouched tail, update to new length
183
0
                        let start = source_vec.len();
184
0
                        let tail = self.0.tail_start;
185
0
                        if tail != start {
186
0
                            let src = source_vec.as_ptr().add(tail);
187
0
                            let dst = source_vec.as_mut_ptr().add(start);
188
0
                            ptr::copy(src, dst, self.0.tail_len);
189
0
                        }
190
0
                        source_vec.set_len(start + self.0.tail_len);
191
                    }
192
0
                }
193
0
            }
194
        }
195
196
0
        let iter = mem::replace(&mut self.iter, [].iter());
197
0
        let drop_len = iter.len();
198
0
199
0
        let mut vec = self.vec;
200
0
201
0
        if size_of::<T>() == 0 {
202
            // ZSTs have no identity, so we don't need to move them around, we only need to drop the correct amount.
203
            // this can be achieved by manipulating the Vec length instead of moving values out from `iter`.
204
0
            unsafe {
205
0
                let vec = vec.as_mut();
206
0
                let old_len = vec.len();
207
0
                vec.set_len(old_len + drop_len + self.tail_len);
208
0
                vec.truncate(old_len + self.tail_len);
209
0
            }
210
0
211
0
            return;
212
0
        }
213
0
214
0
        // ensure elements are moved back into their appropriate places, even when drop_in_place panics
215
0
        let _guard = DropGuard(self);
216
0
217
0
        if drop_len == 0 {
218
0
            return;
219
0
        }
220
0
221
0
        // as_slice() must only be called when iter.len() is > 0 because
222
0
        // vec::Splice modifies vec::Drain fields and may grow the vec which would invalidate
223
0
        // the iterator's internal pointers. Creating a reference to deallocated memory
224
0
        // is invalid even when it is zero-length
225
0
        let drop_ptr = iter.as_slice().as_ptr();
226
0
227
0
        unsafe {
228
0
            // drop_ptr comes from a slice::Iter which only gives us a &[T] but for drop_in_place
229
0
            // a pointer with mutable provenance is necessary. Therefore we must reconstruct
230
0
            // it from the original vec but also avoid creating a &mut to the front since that could
231
0
            // invalidate raw pointers to it which some unsafe code might rely on.
232
0
            let vec_ptr = vec.as_mut().as_mut_ptr();
233
0
            let drop_offset = drop_ptr.offset_from(vec_ptr) as usize;
234
0
            let to_drop = ptr::slice_from_raw_parts_mut(vec_ptr.add(drop_offset), drop_len);
235
0
            ptr::drop_in_place(to_drop);
236
0
        }
237
0
    }
238
}
239
240
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {}
241
242
impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/allocator-api2-0.2.18/src/stable/vec/into_iter.rs
Line
Count
Source
1
use core::fmt;
2
use core::iter::FusedIterator;
3
use core::marker::PhantomData;
4
use core::mem::{self, size_of, ManuallyDrop};
5
6
use core::ptr::{self, NonNull};
7
use core::slice::{self};
8
9
use crate::stable::addr;
10
11
use super::{Allocator, Global, RawVec};
12
13
#[cfg(not(no_global_oom_handling))]
14
use super::Vec;
15
16
/// An iterator that moves out of a vector.
17
///
18
/// This `struct` is created by the `into_iter` method on [`Vec`](super::Vec)
19
/// (provided by the [`IntoIterator`] trait).
20
///
21
/// # Example
22
///
23
/// ```
24
/// let v = vec![0, 1, 2];
25
/// let iter: std::vec::IntoIter<_> = v.into_iter();
26
/// ```
27
pub struct IntoIter<T, A: Allocator = Global> {
28
    pub(super) buf: NonNull<T>,
29
    pub(super) phantom: PhantomData<T>,
30
    pub(super) cap: usize,
31
    // the drop impl reconstructs a RawVec from buf, cap and alloc
32
    // to avoid dropping the allocator twice we need to wrap it into ManuallyDrop
33
    pub(super) alloc: ManuallyDrop<A>,
34
    pub(super) ptr: *const T,
35
    pub(super) end: *const T,
36
}
37
38
impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> {
39
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40
0
        f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
41
0
    }
42
}
43
44
impl<T, A: Allocator> IntoIter<T, A> {
45
    /// Returns the remaining items of this iterator as a slice.
46
    ///
47
    /// # Examples
48
    ///
49
    /// ```
50
    /// let vec = vec!['a', 'b', 'c'];
51
    /// let mut into_iter = vec.into_iter();
52
    /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
53
    /// let _ = into_iter.next().unwrap();
54
    /// assert_eq!(into_iter.as_slice(), &['b', 'c']);
55
    /// ```
56
0
    pub fn as_slice(&self) -> &[T] {
57
0
        unsafe { slice::from_raw_parts(self.ptr, self.len()) }
58
0
    }
59
60
    /// Returns the remaining items of this iterator as a mutable slice.
61
    ///
62
    /// # Examples
63
    ///
64
    /// ```
65
    /// let vec = vec!['a', 'b', 'c'];
66
    /// let mut into_iter = vec.into_iter();
67
    /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
68
    /// into_iter.as_mut_slice()[2] = 'z';
69
    /// assert_eq!(into_iter.next().unwrap(), 'a');
70
    /// assert_eq!(into_iter.next().unwrap(), 'b');
71
    /// assert_eq!(into_iter.next().unwrap(), 'z');
72
    /// ```
73
0
    pub fn as_mut_slice(&mut self) -> &mut [T] {
74
0
        unsafe { &mut *self.as_raw_mut_slice() }
75
0
    }
76
77
    /// Returns a reference to the underlying allocator.
78
    #[inline(always)]
79
0
    pub fn allocator(&self) -> &A {
80
0
        &self.alloc
81
0
    }
82
83
0
    fn as_raw_mut_slice(&mut self) -> *mut [T] {
84
0
        ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len())
85
0
    }
86
}
87
88
impl<T, A: Allocator> AsRef<[T]> for IntoIter<T, A> {
89
0
    fn as_ref(&self) -> &[T] {
90
0
        self.as_slice()
91
0
    }
92
}
93
94
unsafe impl<T: Send, A: Allocator + Send> Send for IntoIter<T, A> {}
95
96
unsafe impl<T: Sync, A: Allocator + Sync> Sync for IntoIter<T, A> {}
97
98
impl<T, A: Allocator> Iterator for IntoIter<T, A> {
99
    type Item = T;
100
101
    #[inline(always)]
102
0
    fn next(&mut self) -> Option<T> {
103
0
        if self.ptr == self.end {
104
0
            None
105
0
        } else if size_of::<T>() == 0 {
106
            // purposefully don't use 'ptr.offset' because for
107
            // vectors with 0-size elements this would return the
108
            // same pointer.
109
0
            self.ptr = self.ptr.cast::<u8>().wrapping_add(1).cast();
110
0
111
0
            // Make up a value of this ZST.
112
0
            Some(unsafe { mem::zeroed() })
113
        } else {
114
0
            let old = self.ptr;
115
0
            self.ptr = unsafe { self.ptr.add(1) };
116
0
117
0
            Some(unsafe { ptr::read(old) })
118
        }
119
0
    }
120
121
    #[inline(always)]
122
0
    fn size_hint(&self) -> (usize, Option<usize>) {
123
0
        let exact = if size_of::<T>() == 0 {
124
0
            addr(self.end).wrapping_sub(addr(self.ptr))
125
        } else {
126
0
            unsafe { self.end.offset_from(self.ptr) as usize }
127
        };
128
0
        (exact, Some(exact))
129
0
    }
130
131
    #[inline(always)]
132
0
    fn count(self) -> usize {
133
0
        self.len()
134
0
    }
135
}
136
137
impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
138
    #[inline(always)]
139
0
    fn next_back(&mut self) -> Option<T> {
140
0
        if self.end == self.ptr {
141
0
            None
142
0
        } else if size_of::<T>() == 0 {
143
            // See above for why 'ptr.offset' isn't used
144
0
            self.end = self.end.cast::<u8>().wrapping_add(1).cast();
145
0
146
0
            // Make up a value of this ZST.
147
0
            Some(unsafe { mem::zeroed() })
148
        } else {
149
0
            self.end = unsafe { self.end.sub(1) };
150
0
151
0
            Some(unsafe { ptr::read(self.end) })
152
        }
153
0
    }
154
}
155
156
impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {}
157
158
impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
159
160
#[doc(hidden)]
161
pub trait NonDrop {}
162
163
// T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr
164
// and thus we can't implement drop-handling
165
impl<T: Copy> NonDrop for T {}
166
167
#[cfg(not(no_global_oom_handling))]
168
impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> {
169
0
    fn clone(&self) -> Self {
170
0
        let mut vec = Vec::<T, A>::with_capacity_in(self.len(), (*self.alloc).clone());
171
0
        vec.extend(self.as_slice().iter().cloned());
172
0
        vec.into_iter()
173
0
    }
174
}
175
176
impl<T, A: Allocator> Drop for IntoIter<T, A> {
177
0
    fn drop(&mut self) {
178
        struct DropGuard<'a, T, A: Allocator>(&'a mut IntoIter<T, A>);
179
180
        impl<T, A: Allocator> Drop for DropGuard<'_, T, A> {
181
0
            fn drop(&mut self) {
182
0
                unsafe {
183
0
                    // `IntoIter::alloc` is not used anymore after this and will be dropped by RawVec
184
0
                    let alloc = ManuallyDrop::take(&mut self.0.alloc);
185
0
                    // RawVec handles deallocation
186
0
                    let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc);
187
0
                }
188
0
            }
189
        }
190
191
0
        let guard = DropGuard(self);
192
0
        // destroy the remaining elements
193
0
        unsafe {
194
0
            ptr::drop_in_place(guard.0.as_raw_mut_slice());
195
0
        }
196
0
        // now `guard` will be dropped and do the rest
197
0
    }
198
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/allocator-api2-0.2.18/src/stable/vec/mod.rs
Line
Count
Source
1
//! A contiguous growable array type with heap-allocated contents, written
2
//! `Vec<T>`.
3
//!
4
//! Vectors have *O*(1) indexing, amortized *O*(1) push (to the end) and
5
//! *O*(1) pop (from the end).
6
//!
7
//! Vectors ensure they never allocate more than `isize::MAX` bytes.
8
//!
9
//! # Examples
10
//!
11
//! You can explicitly create a [`Vec`] with [`Vec::new`]:
12
//!
13
//! ```
14
//! let v: Vec<i32> = Vec::new();
15
//! ```
16
//!
17
//! ...or by using the [`vec!`] macro:
18
//!
19
//! ```
20
//! let v: Vec<i32> = vec![];
21
//!
22
//! let v = vec![1, 2, 3, 4, 5];
23
//!
24
//! let v = vec![0; 10]; // ten zeroes
25
//! ```
26
//!
27
//! You can [`push`] values onto the end of a vector (which will grow the vector
28
//! as needed):
29
//!
30
//! ```
31
//! let mut v = vec![1, 2];
32
//!
33
//! v.push(3);
34
//! ```
35
//!
36
//! Popping values works in much the same way:
37
//!
38
//! ```
39
//! let mut v = vec![1, 2];
40
//!
41
//! let two = v.pop();
42
//! ```
43
//!
44
//! Vectors also support indexing (through the [`Index`] and [`IndexMut`] traits):
45
//!
46
//! ```
47
//! let mut v = vec![1, 2, 3];
48
//! let three = v[2];
49
//! v[1] = v[1] + 5;
50
//! ```
51
//!
52
//! [`push`]: Vec::push
53
54
#[cfg(not(no_global_oom_handling))]
55
use core::cmp;
56
use core::cmp::Ordering;
57
use core::convert::TryFrom;
58
use core::fmt;
59
use core::hash::{Hash, Hasher};
60
#[cfg(not(no_global_oom_handling))]
61
use core::iter;
62
#[cfg(not(no_global_oom_handling))]
63
use core::iter::FromIterator;
64
use core::marker::PhantomData;
65
use core::mem::{self, size_of, ManuallyDrop, MaybeUninit};
66
use core::ops::{self, Bound, Index, IndexMut, Range, RangeBounds};
67
use core::ptr::{self, NonNull};
68
use core::slice::{self, SliceIndex};
69
70
#[cfg(feature = "std")]
71
use std::io;
72
73
use super::{
74
    alloc::{Allocator, Global},
75
    assume,
76
    boxed::Box,
77
    raw_vec::{RawVec, TryReserveError},
78
};
79
80
#[cfg(not(no_global_oom_handling))]
81
pub use self::splice::Splice;
82
83
#[cfg(not(no_global_oom_handling))]
84
mod splice;
85
86
pub use self::drain::Drain;
87
88
mod drain;
89
90
pub use self::into_iter::IntoIter;
91
92
mod into_iter;
93
94
mod partial_eq;
95
96
#[cfg(not(no_global_oom_handling))]
97
mod set_len_on_drop;
98
99
#[cfg(not(no_global_oom_handling))]
100
use self::set_len_on_drop::SetLenOnDrop;
101
102
/// A contiguous growable array type, written as `Vec<T>`, short for 'vector'.
103
///
104
/// # Examples
105
///
106
/// ```
107
/// let mut vec = Vec::new();
108
/// vec.push(1);
109
/// vec.push(2);
110
///
111
/// assert_eq!(vec.len(), 2);
112
/// assert_eq!(vec[0], 1);
113
///
114
/// assert_eq!(vec.pop(), Some(2));
115
/// assert_eq!(vec.len(), 1);
116
///
117
/// vec[0] = 7;
118
/// assert_eq!(vec[0], 7);
119
///
120
/// vec.extend([1, 2, 3].iter().copied());
121
///
122
/// for x in &vec {
123
///     println!("{x}");
124
/// }
125
/// assert_eq!(vec, [7, 1, 2, 3]);
126
/// ```
127
///
128
/// The [`vec!`] macro is provided for convenient initialization:
129
///
130
/// ```
131
/// let mut vec1 = vec![1, 2, 3];
132
/// vec1.push(4);
133
/// let vec2 = Vec::from([1, 2, 3, 4]);
134
/// assert_eq!(vec1, vec2);
135
/// ```
136
///
137
/// It can also initialize each element of a `Vec<T>` with a given value.
138
/// This may be more efficient than performing allocation and initialization
139
/// in separate steps, especially when initializing a vector of zeros:
140
///
141
/// ```
142
/// let vec = vec![0; 5];
143
/// assert_eq!(vec, [0, 0, 0, 0, 0]);
144
///
145
/// // The following is equivalent, but potentially slower:
146
/// let mut vec = Vec::with_capacity(5);
147
/// vec.resize(5, 0);
148
/// assert_eq!(vec, [0, 0, 0, 0, 0]);
149
/// ```
150
///
151
/// For more information, see
152
/// [Capacity and Reallocation](#capacity-and-reallocation).
153
///
154
/// Use a `Vec<T>` as an efficient stack:
155
///
156
/// ```
157
/// let mut stack = Vec::new();
158
///
159
/// stack.push(1);
160
/// stack.push(2);
161
/// stack.push(3);
162
///
163
/// while let Some(top) = stack.pop() {
164
///     // Prints 3, 2, 1
165
///     println!("{top}");
166
/// }
167
/// ```
168
///
169
/// # Indexing
170
///
171
/// The `Vec` type allows to access values by index, because it implements the
172
/// [`Index`] trait. An example will be more explicit:
173
///
174
/// ```
175
/// let v = vec![0, 2, 4, 6];
176
/// println!("{}", v[1]); // it will display '2'
177
/// ```
178
///
179
/// However be careful: if you try to access an index which isn't in the `Vec`,
180
/// your software will panic! You cannot do this:
181
///
182
/// ```should_panic
183
/// let v = vec![0, 2, 4, 6];
184
/// println!("{}", v[6]); // it will panic!
185
/// ```
186
///
187
/// Use [`get`] and [`get_mut`] if you want to check whether the index is in
188
/// the `Vec`.
189
///
190
/// # Slicing
191
///
192
/// A `Vec` can be mutable. On the other hand, slices are read-only objects.
193
/// To get a [slice][prim@slice], use [`&`]. Example:
194
///
195
/// ```
196
/// fn read_slice(slice: &[usize]) {
197
///     // ...
198
/// }
199
///
200
/// let v = vec![0, 1];
201
/// read_slice(&v);
202
///
203
/// // ... and that's all!
204
/// // you can also do it like this:
205
/// let u: &[usize] = &v;
206
/// // or like this:
207
/// let u: &[_] = &v;
208
/// ```
209
///
210
/// In Rust, it's more common to pass slices as arguments rather than vectors
211
/// when you just want to provide read access. The same goes for [`String`] and
212
/// [`&str`].
213
///
214
/// # Capacity and reallocation
215
///
216
/// The capacity of a vector is the amount of space allocated for any future
217
/// elements that will be added onto the vector. This is not to be confused with
218
/// the *length* of a vector, which specifies the number of actual elements
219
/// within the vector. If a vector's length exceeds its capacity, its capacity
220
/// will automatically be increased, but its elements will have to be
221
/// reallocated.
222
///
223
/// For example, a vector with capacity 10 and length 0 would be an empty vector
224
/// with space for 10 more elements. Pushing 10 or fewer elements onto the
225
/// vector will not change its capacity or cause reallocation to occur. However,
226
/// if the vector's length is increased to 11, it will have to reallocate, which
227
/// can be slow. For this reason, it is recommended to use [`Vec::with_capacity`]
228
/// whenever possible to specify how big the vector is expected to get.
229
///
230
/// # Guarantees
231
///
232
/// Due to its incredibly fundamental nature, `Vec` makes a lot of guarantees
233
/// about its design. This ensures that it's as low-overhead as possible in
234
/// the general case, and can be correctly manipulated in primitive ways
235
/// by unsafe code. Note that these guarantees refer to an unqualified `Vec<T>`.
236
/// If additional type parameters are added (e.g., to support custom allocators),
237
/// overriding their defaults may change the behavior.
238
///
239
/// Most fundamentally, `Vec` is and always will be a (pointer, capacity, length)
240
/// triplet. No more, no less. The order of these fields is completely
241
/// unspecified, and you should use the appropriate methods to modify these.
242
/// The pointer will never be null, so this type is null-pointer-optimized.
243
///
244
/// However, the pointer might not actually point to allocated memory. In particular,
245
/// if you construct a `Vec` with capacity 0 via [`Vec::new`], [`vec![]`][`vec!`],
246
/// [`Vec::with_capacity(0)`][`Vec::with_capacity`], or by calling [`shrink_to_fit`]
247
/// on an empty Vec, it will not allocate memory. Similarly, if you store zero-sized
248
/// types inside a `Vec`, it will not allocate space for them. *Note that in this case
249
/// the `Vec` might not report a [`capacity`] of 0*. `Vec` will allocate if and only
250
/// if <code>[mem::size_of::\<T>]\() * [capacity]\() > 0</code>. In general, `Vec`'s allocation
251
/// details are very subtle --- if you intend to allocate memory using a `Vec`
252
/// and use it for something else (either to pass to unsafe code, or to build your
253
/// own memory-backed collection), be sure to deallocate this memory by using
254
/// `from_raw_parts` to recover the `Vec` and then dropping it.
255
///
256
/// If a `Vec` *has* allocated memory, then the memory it points to is on the heap
257
/// (as defined by the allocator Rust is configured to use by default), and its
258
/// pointer points to [`len`] initialized, contiguous elements in order (what
259
/// you would see if you coerced it to a slice), followed by <code>[capacity] - [len]</code>
260
/// logically uninitialized, contiguous elements.
261
///
262
/// A vector containing the elements `'a'` and `'b'` with capacity 4 can be
263
/// visualized as below. The top part is the `Vec` struct, it contains a
264
/// pointer to the head of the allocation in the heap, length and capacity.
265
/// The bottom part is the allocation on the heap, a contiguous memory block.
266
///
267
/// ```text
268
///             ptr      len  capacity
269
///        +--------+--------+--------+
270
///        | 0x0123 |      2 |      4 |
271
///        +--------+--------+--------+
272
///             |
273
///             v
274
/// Heap   +--------+--------+--------+--------+
275
///        |    'a' |    'b' | uninit | uninit |
276
///        +--------+--------+--------+--------+
277
/// ```
278
///
279
/// - **uninit** represents memory that is not initialized, see [`MaybeUninit`].
280
/// - Note: the ABI is not stable and `Vec` makes no guarantees about its memory
281
///   layout (including the order of fields).
282
///
283
/// `Vec` will never perform a "small optimization" where elements are actually
284
/// stored on the stack for two reasons:
285
///
286
/// * It would make it more difficult for unsafe code to correctly manipulate
287
///   a `Vec`. The contents of a `Vec` wouldn't have a stable address if it were
288
///   only moved, and it would be more difficult to determine if a `Vec` had
289
///   actually allocated memory.
290
///
291
/// * It would penalize the general case, incurring an additional branch
292
///   on every access.
293
///
294
/// `Vec` will never automatically shrink itself, even if completely empty. This
295
/// ensures no unnecessary allocations or deallocations occur. Emptying a `Vec`
296
/// and then filling it back up to the same [`len`] should incur no calls to
297
/// the allocator. If you wish to free up unused memory, use
298
/// [`shrink_to_fit`] or [`shrink_to`].
299
///
300
/// [`push`] and [`insert`] will never (re)allocate if the reported capacity is
301
/// sufficient. [`push`] and [`insert`] *will* (re)allocate if
302
/// <code>[len] == [capacity]</code>. That is, the reported capacity is completely
303
/// accurate, and can be relied on. It can even be used to manually free the memory
304
/// allocated by a `Vec` if desired. Bulk insertion methods *may* reallocate, even
305
/// when not necessary.
306
///
307
/// `Vec` does not guarantee any particular growth strategy when reallocating
308
/// when full, nor when [`reserve`] is called. The current strategy is basic
309
/// and it may prove desirable to use a non-constant growth factor. Whatever
310
/// strategy is used will of course guarantee *O*(1) amortized [`push`].
311
///
312
/// `vec![x; n]`, `vec![a, b, c, d]`, and
313
/// [`Vec::with_capacity(n)`][`Vec::with_capacity`], will all produce a `Vec`
314
/// with exactly the requested capacity. If <code>[len] == [capacity]</code>,
315
/// (as is the case for the [`vec!`] macro), then a `Vec<T>` can be converted to
316
/// and from a [`Box<[T]>`][owned slice] without reallocating or moving the elements.
317
///
318
/// `Vec` will not specifically overwrite any data that is removed from it,
319
/// but also won't specifically preserve it. Its uninitialized memory is
320
/// scratch space that it may use however it wants. It will generally just do
321
/// whatever is most efficient or otherwise easy to implement. Do not rely on
322
/// removed data to be erased for security purposes. Even if you drop a `Vec`, its
323
/// buffer may simply be reused by another allocation. Even if you zero a `Vec`'s memory
324
/// first, that might not actually happen because the optimizer does not consider
325
/// this a side-effect that must be preserved. There is one case which we will
326
/// not break, however: using `unsafe` code to write to the excess capacity,
327
/// and then increasing the length to match, is always valid.
328
///
329
/// Currently, `Vec` does not guarantee the order in which elements are dropped.
330
/// The order has changed in the past and may change again.
331
///
332
/// [`get`]: ../../std/vec/struct.Vec.html#method.get
333
/// [`get_mut`]: ../../std/vec/struct.Vec.html#method.get_mut
334
/// [`String`]: alloc_crate::string::String
335
/// [`&str`]: type@str
336
/// [`shrink_to_fit`]: Vec::shrink_to_fit
337
/// [`shrink_to`]: Vec::shrink_to
338
/// [capacity]: Vec::capacity
339
/// [`capacity`]: Vec::capacity
340
/// [mem::size_of::\<T>]: core::mem::size_of
341
/// [len]: Vec::len
342
/// [`len`]: Vec::len
343
/// [`push`]: Vec::push
344
/// [`insert`]: Vec::insert
345
/// [`reserve`]: Vec::reserve
346
/// [`MaybeUninit`]: core::mem::MaybeUninit
347
/// [owned slice]: Box
348
pub struct Vec<T, A: Allocator = Global> {
349
    buf: RawVec<T, A>,
350
    len: usize,
351
}
352
353
////////////////////////////////////////////////////////////////////////////////
354
// Inherent methods
355
////////////////////////////////////////////////////////////////////////////////
356
357
impl<T> Vec<T> {
358
    /// Constructs a new, empty `Vec<T>`.
359
    ///
360
    /// The vector will not allocate until elements are pushed onto it.
361
    ///
362
    /// # Examples
363
    ///
364
    /// ```
365
    /// # #![allow(unused_mut)]
366
    /// let mut vec: Vec<i32> = Vec::new();
367
    /// ```
368
    #[inline(always)]
369
    #[must_use]
370
0
    pub const fn new() -> Self {
371
0
        Vec {
372
0
            buf: RawVec::new(),
373
0
            len: 0,
374
0
        }
375
0
    }
376
377
    /// Constructs a new, empty `Vec<T>` with at least the specified capacity.
378
    ///
379
    /// The vector will be able to hold at least `capacity` elements without
380
    /// reallocating. This method is allowed to allocate for more elements than
381
    /// `capacity`. If `capacity` is 0, the vector will not allocate.
382
    ///
383
    /// It is important to note that although the returned vector has the
384
    /// minimum *capacity* specified, the vector will have a zero *length*. For
385
    /// an explanation of the difference between length and capacity, see
386
    /// *[Capacity and reallocation]*.
387
    ///
388
    /// If it is important to know the exact allocated capacity of a `Vec`,
389
    /// always use the [`capacity`] method after construction.
390
    ///
391
    /// For `Vec<T>` where `T` is a zero-sized type, there will be no allocation
392
    /// and the capacity will always be `usize::MAX`.
393
    ///
394
    /// [Capacity and reallocation]: #capacity-and-reallocation
395
    /// [`capacity`]: Vec::capacity
396
    ///
397
    /// # Panics
398
    ///
399
    /// Panics if the new capacity exceeds `isize::MAX` bytes.
400
    ///
401
    /// # Examples
402
    ///
403
    /// ```
404
    /// let mut vec = Vec::with_capacity(10);
405
    ///
406
    /// // The vector contains no items, even though it has capacity for more
407
    /// assert_eq!(vec.len(), 0);
408
    /// assert!(vec.capacity() >= 10);
409
    ///
410
    /// // These are all done without reallocating...
411
    /// for i in 0..10 {
412
    ///     vec.push(i);
413
    /// }
414
    /// assert_eq!(vec.len(), 10);
415
    /// assert!(vec.capacity() >= 10);
416
    ///
417
    /// // ...but this may make the vector reallocate
418
    /// vec.push(11);
419
    /// assert_eq!(vec.len(), 11);
420
    /// assert!(vec.capacity() >= 11);
421
    ///
422
    /// // A vector of a zero-sized type will always over-allocate, since no
423
    /// // allocation is necessary
424
    /// let vec_units = Vec::<()>::with_capacity(10);
425
    /// assert_eq!(vec_units.capacity(), usize::MAX);
426
    /// ```
427
    #[cfg(not(no_global_oom_handling))]
428
    #[inline(always)]
429
    #[must_use]
430
0
    pub fn with_capacity(capacity: usize) -> Self {
431
0
        Self::with_capacity_in(capacity, Global)
432
0
    }
433
434
    /// Creates a `Vec<T>` directly from a pointer, a capacity, and a length.
435
    ///
436
    /// # Safety
437
    ///
438
    /// This is highly unsafe, due to the number of invariants that aren't
439
    /// checked:
440
    ///
441
    /// * `T` needs to have the same alignment as what `ptr` was allocated with.
442
    ///   (`T` having a less strict alignment is not sufficient, the alignment really
443
    ///   needs to be equal to satisfy the [`dealloc`] requirement that memory must be
444
    ///   allocated and deallocated with the same layout.)
445
    /// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs
446
    ///   to be the same size as the pointer was allocated with. (Because similar to
447
    ///   alignment, [`dealloc`] must be called with the same layout `size`.)
448
    /// * `length` needs to be less than or equal to `capacity`.
449
    /// * The first `length` values must be properly initialized values of type `T`.
450
    /// * `capacity` needs to be the capacity that the pointer was allocated with.
451
    /// * The allocated size in bytes must be no larger than `isize::MAX`.
452
    ///   See the safety documentation of [`pointer::offset`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset).
453
    ///
454
    /// These requirements are always upheld by any `ptr` that has been allocated
455
    /// via `Vec<T>`. Other allocation sources are allowed if the invariants are
456
    /// upheld.
457
    ///
458
    /// Violating these may cause problems like corrupting the allocator's
459
    /// internal data structures. For example it is normally **not** safe
460
    /// to build a `Vec<u8>` from a pointer to a C `char` array with length
461
    /// `size_t`, doing so is only safe if the array was initially allocated by
462
    /// a `Vec` or `String`.
463
    /// It's also not safe to build one from a `Vec<u16>` and its length, because
464
    /// the allocator cares about the alignment, and these two types have different
465
    /// alignments. The buffer was allocated with alignment 2 (for `u16`), but after
466
    /// turning it into a `Vec<u8>` it'll be deallocated with alignment 1. To avoid
467
    /// these issues, it is often preferable to do casting/transmuting using
468
    /// [`slice::from_raw_parts`] instead.
469
    ///
470
    /// The ownership of `ptr` is effectively transferred to the
471
    /// `Vec<T>` which may then deallocate, reallocate or change the
472
    /// contents of memory pointed to by the pointer at will. Ensure
473
    /// that nothing else uses the pointer after calling this
474
    /// function.
475
    ///
476
    /// [`String`]: alloc_crate::string::String
477
    /// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
478
    ///
479
    /// # Examples
480
    ///
481
    /// ```
482
    /// use std::ptr;
483
    /// use std::mem;
484
    ///
485
    /// let v = vec![1, 2, 3];
486
    ///
487
    // FIXME Update this when vec_into_raw_parts is stabilized
488
    /// // Prevent running `v`'s destructor so we are in complete control
489
    /// // of the allocation.
490
    /// let mut v = mem::ManuallyDrop::new(v);
491
    ///
492
    /// // Pull out the various important pieces of information about `v`
493
    /// let p = v.as_mut_ptr();
494
    /// let len = v.len();
495
    /// let cap = v.capacity();
496
    ///
497
    /// unsafe {
498
    ///     // Overwrite memory with 4, 5, 6
499
    ///     for i in 0..len {
500
    ///         ptr::write(p.add(i), 4 + i);
501
    ///     }
502
    ///
503
    ///     // Put everything back together into a Vec
504
    ///     let rebuilt = Vec::from_raw_parts(p, len, cap);
505
    ///     assert_eq!(rebuilt, [4, 5, 6]);
506
    /// }
507
    /// ```
508
    ///
509
    /// Using memory that was allocated elsewhere:
510
    ///
511
    /// ```rust
512
    /// #![feature(allocator_api)]
513
    ///
514
    /// use std::alloc::{AllocError, Allocator, Global, Layout};
515
    ///
516
    /// fn main() {
517
    ///     let layout = Layout::array::<u32>(16).expect("overflow cannot happen");
518
    ///
519
    ///     let vec = unsafe {
520
    ///         let mem = match Global.allocate(layout) {
521
    ///             Ok(mem) => mem.cast::<u32>().as_ptr(),
522
    ///             Err(AllocError) => return,
523
    ///         };
524
    ///
525
    ///         mem.write(1_000_000);
526
    ///
527
    ///         Vec::from_raw_parts_in(mem, 1, 16, Global)
528
    ///     };
529
    ///
530
    ///     assert_eq!(vec, &[1_000_000]);
531
    ///     assert_eq!(vec.capacity(), 16);
532
    /// }
533
    /// ```
534
    #[inline(always)]
535
0
    pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self {
536
0
        unsafe { Self::from_raw_parts_in(ptr, length, capacity, Global) }
537
0
    }
538
}
539
540
impl<T, A: Allocator> Vec<T, A> {
541
    /// Constructs a new, empty `Vec<T, A>`.
542
    ///
543
    /// The vector will not allocate until elements are pushed onto it.
544
    ///
545
    /// # Examples
546
    ///
547
    /// ```
548
    /// use std::alloc::System;
549
    ///
550
    /// # #[allow(unused_mut)]
551
    /// let mut vec: Vec<i32, _> = Vec::new_in(System);
552
    /// ```
553
    #[inline(always)]
554
0
    pub const fn new_in(alloc: A) -> Self {
555
0
        Vec {
556
0
            buf: RawVec::new_in(alloc),
557
0
            len: 0,
558
0
        }
559
0
    }
560
561
    /// Constructs a new, empty `Vec<T, A>` with at least the specified capacity
562
    /// with the provided allocator.
563
    ///
564
    /// The vector will be able to hold at least `capacity` elements without
565
    /// reallocating. This method is allowed to allocate for more elements than
566
    /// `capacity`. If `capacity` is 0, the vector will not allocate.
567
    ///
568
    /// It is important to note that although the returned vector has the
569
    /// minimum *capacity* specified, the vector will have a zero *length*. For
570
    /// an explanation of the difference between length and capacity, see
571
    /// *[Capacity and reallocation]*.
572
    ///
573
    /// If it is important to know the exact allocated capacity of a `Vec`,
574
    /// always use the [`capacity`] method after construction.
575
    ///
576
    /// For `Vec<T, A>` where `T` is a zero-sized type, there will be no allocation
577
    /// and the capacity will always be `usize::MAX`.
578
    ///
579
    /// [Capacity and reallocation]: #capacity-and-reallocation
580
    /// [`capacity`]: Vec::capacity
581
    ///
582
    /// # Panics
583
    ///
584
    /// Panics if the new capacity exceeds `isize::MAX` bytes.
585
    ///
586
    /// # Examples
587
    ///
588
    /// ```
589
    /// use std::alloc::System;
590
    ///
591
    /// let mut vec = Vec::with_capacity_in(10, System);
592
    ///
593
    /// // The vector contains no items, even though it has capacity for more
594
    /// assert_eq!(vec.len(), 0);
595
    /// assert_eq!(vec.capacity(), 10);
596
    ///
597
    /// // These are all done without reallocating...
598
    /// for i in 0..10 {
599
    ///     vec.push(i);
600
    /// }
601
    /// assert_eq!(vec.len(), 10);
602
    /// assert_eq!(vec.capacity(), 10);
603
    ///
604
    /// // ...but this may make the vector reallocate
605
    /// vec.push(11);
606
    /// assert_eq!(vec.len(), 11);
607
    /// assert!(vec.capacity() >= 11);
608
    ///
609
    /// // A vector of a zero-sized type will always over-allocate, since no
610
    /// // allocation is necessary
611
    /// let vec_units = Vec::<(), System>::with_capacity_in(10, System);
612
    /// assert_eq!(vec_units.capacity(), usize::MAX);
613
    /// ```
614
    #[cfg(not(no_global_oom_handling))]
615
    #[inline(always)]
616
0
    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
617
0
        Vec {
618
0
            buf: RawVec::with_capacity_in(capacity, alloc),
619
0
            len: 0,
620
0
        }
621
0
    }
622
623
    /// Creates a `Vec<T, A>` directly from a pointer, a capacity, a length,
624
    /// and an allocator.
625
    ///
626
    /// # Safety
627
    ///
628
    /// This is highly unsafe, due to the number of invariants that aren't
629
    /// checked:
630
    ///
631
    /// * `T` needs to have the same alignment as what `ptr` was allocated with.
632
    ///   (`T` having a less strict alignment is not sufficient, the alignment really
633
    ///   needs to be equal to satisfy the [`dealloc`] requirement that memory must be
634
    ///   allocated and deallocated with the same layout.)
635
    /// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs
636
    ///   to be the same size as the pointer was allocated with. (Because similar to
637
    ///   alignment, [`dealloc`] must be called with the same layout `size`.)
638
    /// * `length` needs to be less than or equal to `capacity`.
639
    /// * The first `length` values must be properly initialized values of type `T`.
640
    /// * `capacity` needs to [*fit*] the layout size that the pointer was allocated with.
641
    /// * The allocated size in bytes must be no larger than `isize::MAX`.
642
    ///   See the safety documentation of [`pointer::offset`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset).
643
    ///
644
    /// These requirements are always upheld by any `ptr` that has been allocated
645
    /// via `Vec<T, A>`. Other allocation sources are allowed if the invariants are
646
    /// upheld.
647
    ///
648
    /// Violating these may cause problems like corrupting the allocator's
649
    /// internal data structures. For example it is **not** safe
650
    /// to build a `Vec<u8>` from a pointer to a C `char` array with length `size_t`.
651
    /// It's also not safe to build one from a `Vec<u16>` and its length, because
652
    /// the allocator cares about the alignment, and these two types have different
653
    /// alignments. The buffer was allocated with alignment 2 (for `u16`), but after
654
    /// turning it into a `Vec<u8>` it'll be deallocated with alignment 1.
655
    ///
656
    /// The ownership of `ptr` is effectively transferred to the
657
    /// `Vec<T>` which may then deallocate, reallocate or change the
658
    /// contents of memory pointed to by the pointer at will. Ensure
659
    /// that nothing else uses the pointer after calling this
660
    /// function.
661
    ///
662
    /// [`String`]: alloc_crate::string::String
663
    /// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc
664
    /// [*fit*]: crate::alloc::Allocator#memory-fitting
665
    ///
666
    /// # Examples
667
    ///
668
    /// ```
669
    /// use std::alloc::System;
670
    ///
671
    /// use std::ptr;
672
    /// use std::mem;
673
    ///
674
    ///
675
    /// # use allocator_api2::vec::Vec;
676
    /// let mut v = Vec::with_capacity_in(3, System);
677
    /// v.push(1);
678
    /// v.push(2);
679
    /// v.push(3);
680
    ///
681
    // FIXME Update this when vec_into_raw_parts is stabilized
682
    /// // Prevent running `v`'s destructor so we are in complete control
683
    /// // of the allocation.
684
    /// let mut v = mem::ManuallyDrop::new(v);
685
    ///
686
    /// // Pull out the various important pieces of information about `v`
687
    /// let p = v.as_mut_ptr();
688
    /// let len = v.len();
689
    /// let cap = v.capacity();
690
    /// let alloc = v.allocator();
691
    ///
692
    /// unsafe {
693
    ///     // Overwrite memory with 4, 5, 6
694
    ///     for i in 0..len {
695
    ///         ptr::write(p.add(i), 4 + i);
696
    ///     }
697
    ///
698
    ///     // Put everything back together into a Vec
699
    ///     let rebuilt = Vec::from_raw_parts_in(p, len, cap, alloc.clone());
700
    ///     assert_eq!(rebuilt, [4, 5, 6]);
701
    /// }
702
    /// ```
703
    ///
704
    /// Using memory that was allocated elsewhere:
705
    ///
706
    /// ```rust
707
    /// use std::alloc::{alloc, Layout};
708
    ///
709
    /// fn main() {
710
    ///     let layout = Layout::array::<u32>(16).expect("overflow cannot happen");
711
    ///     let vec = unsafe {
712
    ///         let mem = alloc(layout).cast::<u32>();
713
    ///         if mem.is_null() {
714
    ///             return;
715
    ///         }
716
    ///
717
    ///         mem.write(1_000_000);
718
    ///
719
    ///         Vec::from_raw_parts(mem, 1, 16)
720
    ///     };
721
    ///
722
    ///     assert_eq!(vec, &[1_000_000]);
723
    ///     assert_eq!(vec.capacity(), 16);
724
    /// }
725
    /// ```
726
    #[inline(always)]
727
0
    pub unsafe fn from_raw_parts_in(ptr: *mut T, length: usize, capacity: usize, alloc: A) -> Self {
728
0
        unsafe {
729
0
            Vec {
730
0
                buf: RawVec::from_raw_parts_in(ptr, capacity, alloc),
731
0
                len: length,
732
0
            }
733
0
        }
734
0
    }
735
736
    /// Decomposes a `Vec<T>` into its raw components.
737
    ///
738
    /// Returns the raw pointer to the underlying data, the length of
739
    /// the vector (in elements), and the allocated capacity of the
740
    /// data (in elements). These are the same arguments in the same
741
    /// order as the arguments to [`from_raw_parts`].
742
    ///
743
    /// After calling this function, the caller is responsible for the
744
    /// memory previously managed by the `Vec`. The only way to do
745
    /// this is to convert the raw pointer, length, and capacity back
746
    /// into a `Vec` with the [`from_raw_parts`] function, allowing
747
    /// the destructor to perform the cleanup.
748
    ///
749
    /// [`from_raw_parts`]: Vec::from_raw_parts
750
    ///
751
    /// # Examples
752
    ///
753
    /// ```
754
    /// #![feature(vec_into_raw_parts)]
755
    /// let v: Vec<i32> = vec![-1, 0, 1];
756
    ///
757
    /// let (ptr, len, cap) = v.into_raw_parts();
758
    ///
759
    /// let rebuilt = unsafe {
760
    ///     // We can now make changes to the components, such as
761
    ///     // transmuting the raw pointer to a compatible type.
762
    ///     let ptr = ptr as *mut u32;
763
    ///
764
    ///     Vec::from_raw_parts(ptr, len, cap)
765
    /// };
766
    /// assert_eq!(rebuilt, [4294967295, 0, 1]);
767
    /// ```
768
0
    pub fn into_raw_parts(self) -> (*mut T, usize, usize) {
769
0
        let mut me = ManuallyDrop::new(self);
770
0
        (me.as_mut_ptr(), me.len(), me.capacity())
771
0
    }
772
773
    /// Decomposes a `Vec<T>` into its raw components.
774
    ///
775
    /// Returns the raw pointer to the underlying data, the length of the vector (in elements),
776
    /// the allocated capacity of the data (in elements), and the allocator. These are the same
777
    /// arguments in the same order as the arguments to [`from_raw_parts_in`].
778
    ///
779
    /// After calling this function, the caller is responsible for the
780
    /// memory previously managed by the `Vec`. The only way to do
781
    /// this is to convert the raw pointer, length, and capacity back
782
    /// into a `Vec` with the [`from_raw_parts_in`] function, allowing
783
    /// the destructor to perform the cleanup.
784
    ///
785
    /// [`from_raw_parts_in`]: Vec::from_raw_parts_in
786
    ///
787
    /// # Examples
788
    ///
789
    /// ```
790
    /// #![feature(allocator_api, vec_into_raw_parts)]
791
    ///
792
    /// use std::alloc::System;
793
    ///
794
    /// let mut v: Vec<i32, System> = Vec::new_in(System);
795
    /// v.push(-1);
796
    /// v.push(0);
797
    /// v.push(1);
798
    ///
799
    /// let (ptr, len, cap, alloc) = v.into_raw_parts_with_alloc();
800
    ///
801
    /// let rebuilt = unsafe {
802
    ///     // We can now make changes to the components, such as
803
    ///     // transmuting the raw pointer to a compatible type.
804
    ///     let ptr = ptr as *mut u32;
805
    ///
806
    ///     Vec::from_raw_parts_in(ptr, len, cap, alloc)
807
    /// };
808
    /// assert_eq!(rebuilt, [4294967295, 0, 1]);
809
    /// ```
810
    // #[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
811
0
    pub fn into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A) {
812
0
        let mut me = ManuallyDrop::new(self);
813
0
        let len = me.len();
814
0
        let capacity = me.capacity();
815
0
        let ptr = me.as_mut_ptr();
816
0
        let alloc = unsafe { ptr::read(me.allocator()) };
817
0
        (ptr, len, capacity, alloc)
818
0
    }
819
820
    /// Returns the total number of elements the vector can hold without
821
    /// reallocating.
822
    ///
823
    /// # Examples
824
    ///
825
    /// ```
826
    /// let mut vec: Vec<i32> = Vec::with_capacity(10);
827
    /// vec.push(42);
828
    /// assert_eq!(vec.capacity(), 10);
829
    /// ```
830
    #[inline(always)]
831
0
    pub fn capacity(&self) -> usize {
832
0
        self.buf.capacity()
833
0
    }
834
835
    /// Reserves capacity for at least `additional` more elements to be inserted
836
    /// in the given `Vec<T>`. The collection may reserve more space to
837
    /// speculatively avoid frequent reallocations. After calling `reserve`,
838
    /// capacity will be greater than or equal to `self.len() + additional`.
839
    /// Does nothing if capacity is already sufficient.
840
    ///
841
    /// # Panics
842
    ///
843
    /// Panics if the new capacity exceeds `isize::MAX` bytes.
844
    ///
845
    /// # Examples
846
    ///
847
    /// ```
848
    /// let mut vec = vec![1];
849
    /// vec.reserve(10);
850
    /// assert!(vec.capacity() >= 11);
851
    /// ```
852
    #[cfg(not(no_global_oom_handling))]
853
    #[inline(always)]
854
0
    pub fn reserve(&mut self, additional: usize) {
855
0
        self.buf.reserve(self.len, additional);
856
0
    }
857
858
    /// Reserves the minimum capacity for at least `additional` more elements to
859
    /// be inserted in the given `Vec<T>`. Unlike [`reserve`], this will not
860
    /// deliberately over-allocate to speculatively avoid frequent allocations.
861
    /// After calling `reserve_exact`, capacity will be greater than or equal to
862
    /// `self.len() + additional`. Does nothing if the capacity is already
863
    /// sufficient.
864
    ///
865
    /// Note that the allocator may give the collection more space than it
866
    /// requests. Therefore, capacity can not be relied upon to be precisely
867
    /// minimal. Prefer [`reserve`] if future insertions are expected.
868
    ///
869
    /// [`reserve`]: Vec::reserve
870
    ///
871
    /// # Panics
872
    ///
873
    /// Panics if the new capacity exceeds `isize::MAX` bytes.
874
    ///
875
    /// # Examples
876
    ///
877
    /// ```
878
    /// let mut vec = vec![1];
879
    /// vec.reserve_exact(10);
880
    /// assert!(vec.capacity() >= 11);
881
    /// ```
882
    #[cfg(not(no_global_oom_handling))]
883
    #[inline(always)]
884
0
    pub fn reserve_exact(&mut self, additional: usize) {
885
0
        self.buf.reserve_exact(self.len, additional);
886
0
    }
887
888
    /// Tries to reserve capacity for at least `additional` more elements to be inserted
889
    /// in the given `Vec<T>`. The collection may reserve more space to speculatively avoid
890
    /// frequent reallocations. After calling `try_reserve`, capacity will be
891
    /// greater than or equal to `self.len() + additional` if it returns
892
    /// `Ok(())`. Does nothing if capacity is already sufficient. This method
893
    /// preserves the contents even if an error occurs.
894
    ///
895
    /// # Errors
896
    ///
897
    /// If the capacity overflows, or the allocator reports a failure, then an error
898
    /// is returned.
899
    ///
900
    /// # Examples
901
    ///
902
    /// ```
903
    /// use std::collections::TryReserveError;
904
    ///
905
    /// fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
906
    ///     let mut output = Vec::new();
907
    ///
908
    ///     // Pre-reserve the memory, exiting if we can't
909
    ///     output.try_reserve(data.len())?;
910
    ///
911
    ///     // Now we know this can't OOM in the middle of our complex work
912
    ///     output.extend(data.iter().map(|&val| {
913
    ///         val * 2 + 5 // very complicated
914
    ///     }));
915
    ///
916
    ///     Ok(output)
917
    /// }
918
    /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
919
    /// ```
920
    #[inline(always)]
921
0
    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
922
0
        self.buf.try_reserve(self.len, additional)
923
0
    }
924
925
    /// Tries to reserve the minimum capacity for at least `additional`
926
    /// elements to be inserted in the given `Vec<T>`. Unlike [`try_reserve`],
927
    /// this will not deliberately over-allocate to speculatively avoid frequent
928
    /// allocations. After calling `try_reserve_exact`, capacity will be greater
929
    /// than or equal to `self.len() + additional` if it returns `Ok(())`.
930
    /// Does nothing if the capacity is already sufficient.
931
    ///
932
    /// Note that the allocator may give the collection more space than it
933
    /// requests. Therefore, capacity can not be relied upon to be precisely
934
    /// minimal. Prefer [`try_reserve`] if future insertions are expected.
935
    ///
936
    /// [`try_reserve`]: Vec::try_reserve
937
    ///
938
    /// # Errors
939
    ///
940
    /// If the capacity overflows, or the allocator reports a failure, then an error
941
    /// is returned.
942
    ///
943
    /// # Examples
944
    ///
945
    /// ```
946
    /// use std::collections::TryReserveError;
947
    ///
948
    /// fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
949
    ///     let mut output = Vec::new();
950
    ///
951
    ///     // Pre-reserve the memory, exiting if we can't
952
    ///     output.try_reserve_exact(data.len())?;
953
    ///
954
    ///     // Now we know this can't OOM in the middle of our complex work
955
    ///     output.extend(data.iter().map(|&val| {
956
    ///         val * 2 + 5 // very complicated
957
    ///     }));
958
    ///
959
    ///     Ok(output)
960
    /// }
961
    /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
962
    /// ```
963
    #[inline(always)]
964
0
    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
965
0
        self.buf.try_reserve_exact(self.len, additional)
966
0
    }
967
968
    /// Shrinks the capacity of the vector as much as possible.
969
    ///
970
    /// It will drop down as close as possible to the length but the allocator
971
    /// may still inform the vector that there is space for a few more elements.
972
    ///
973
    /// # Examples
974
    ///
975
    /// ```
976
    /// let mut vec = Vec::with_capacity(10);
977
    /// vec.extend([1, 2, 3]);
978
    /// assert_eq!(vec.capacity(), 10);
979
    /// vec.shrink_to_fit();
980
    /// assert!(vec.capacity() >= 3);
981
    /// ```
982
    #[cfg(not(no_global_oom_handling))]
983
    #[inline(always)]
984
0
    pub fn shrink_to_fit(&mut self) {
985
0
        // The capacity is never less than the length, and there's nothing to do when
986
0
        // they are equal, so we can avoid the panic case in `RawVec::shrink_to_fit`
987
0
        // by only calling it with a greater capacity.
988
0
        if self.capacity() > self.len {
989
0
            self.buf.shrink_to_fit(self.len);
990
0
        }
991
0
    }
992
993
    /// Shrinks the capacity of the vector with a lower bound.
994
    ///
995
    /// The capacity will remain at least as large as both the length
996
    /// and the supplied value.
997
    ///
998
    /// If the current capacity is less than the lower limit, this is a no-op.
999
    ///
1000
    /// # Examples
1001
    ///
1002
    /// ```
1003
    /// let mut vec = Vec::with_capacity(10);
1004
    /// vec.extend([1, 2, 3]);
1005
    /// assert_eq!(vec.capacity(), 10);
1006
    /// vec.shrink_to(4);
1007
    /// assert!(vec.capacity() >= 4);
1008
    /// vec.shrink_to(0);
1009
    /// assert!(vec.capacity() >= 3);
1010
    /// ```
1011
    #[cfg(not(no_global_oom_handling))]
1012
    #[inline(always)]
1013
0
    pub fn shrink_to(&mut self, min_capacity: usize) {
1014
0
        if self.capacity() > min_capacity {
1015
0
            self.buf.shrink_to_fit(cmp::max(self.len, min_capacity));
1016
0
        }
1017
0
    }
1018
1019
    /// Converts the vector into [`Box<[T]>`][owned slice].
1020
    ///
1021
    /// If the vector has excess capacity, its items will be moved into a
1022
    /// newly-allocated buffer with exactly the right capacity.
1023
    ///
1024
    /// [owned slice]: Box
1025
    ///
1026
    /// # Examples
1027
    ///
1028
    /// ```
1029
    /// let v = vec![1, 2, 3];
1030
    ///
1031
    /// let slice = v.into_boxed_slice();
1032
    /// ```
1033
    ///
1034
    /// Any excess capacity is removed:
1035
    ///
1036
    /// ```
1037
    /// let mut vec = Vec::with_capacity(10);
1038
    /// vec.extend([1, 2, 3]);
1039
    ///
1040
    /// assert_eq!(vec.capacity(), 10);
1041
    /// let slice = vec.into_boxed_slice();
1042
    /// assert_eq!(slice.into_vec().capacity(), 3);
1043
    /// ```
1044
    #[cfg(not(no_global_oom_handling))]
1045
    #[inline(always)]
1046
0
    pub fn into_boxed_slice(mut self) -> Box<[T], A> {
1047
0
        unsafe {
1048
0
            self.shrink_to_fit();
1049
0
            let me = ManuallyDrop::new(self);
1050
0
            let buf = ptr::read(&me.buf);
1051
0
            let len = me.len();
1052
0
            buf.into_box(len).assume_init()
1053
0
        }
1054
0
    }
1055
1056
    /// Shortens the vector, keeping the first `len` elements and dropping
1057
    /// the rest.
1058
    ///
1059
    /// If `len` is greater than the vector's current length, this has no
1060
    /// effect.
1061
    ///
1062
    /// The [`drain`] method can emulate `truncate`, but causes the excess
1063
    /// elements to be returned instead of dropped.
1064
    ///
1065
    /// Note that this method has no effect on the allocated capacity
1066
    /// of the vector.
1067
    ///
1068
    /// # Examples
1069
    ///
1070
    /// Truncating a five element vector to two elements:
1071
    ///
1072
    /// ```
1073
    /// let mut vec = vec![1, 2, 3, 4, 5];
1074
    /// vec.truncate(2);
1075
    /// assert_eq!(vec, [1, 2]);
1076
    /// ```
1077
    ///
1078
    /// No truncation occurs when `len` is greater than the vector's current
1079
    /// length:
1080
    ///
1081
    /// ```
1082
    /// let mut vec = vec![1, 2, 3];
1083
    /// vec.truncate(8);
1084
    /// assert_eq!(vec, [1, 2, 3]);
1085
    /// ```
1086
    ///
1087
    /// Truncating when `len == 0` is equivalent to calling the [`clear`]
1088
    /// method.
1089
    ///
1090
    /// ```
1091
    /// let mut vec = vec![1, 2, 3];
1092
    /// vec.truncate(0);
1093
    /// assert_eq!(vec, []);
1094
    /// ```
1095
    ///
1096
    /// [`clear`]: Vec::clear
1097
    /// [`drain`]: Vec::drain
1098
    #[inline(always)]
1099
0
    pub fn truncate(&mut self, len: usize) {
1100
0
        // This is safe because:
1101
0
        //
1102
0
        // * the slice passed to `drop_in_place` is valid; the `len > self.len`
1103
0
        //   case avoids creating an invalid slice, and
1104
0
        // * the `len` of the vector is shrunk before calling `drop_in_place`,
1105
0
        //   such that no value will be dropped twice in case `drop_in_place`
1106
0
        //   were to panic once (if it panics twice, the program aborts).
1107
0
        unsafe {
1108
0
            // Note: It's intentional that this is `>` and not `>=`.
1109
0
            //       Changing it to `>=` has negative performance
1110
0
            //       implications in some cases. See #78884 for more.
1111
0
            if len > self.len {
1112
0
                return;
1113
0
            }
1114
0
            let remaining_len = self.len - len;
1115
0
            let s = ptr::slice_from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len);
1116
0
            self.len = len;
1117
0
            ptr::drop_in_place(s);
1118
        }
1119
0
    }
1120
1121
    /// Extracts a slice containing the entire vector.
1122
    ///
1123
    /// Equivalent to `&s[..]`.
1124
    ///
1125
    /// # Examples
1126
    ///
1127
    /// ```
1128
    /// use std::io::{self, Write};
1129
    /// let buffer = vec![1, 2, 3, 5, 8];
1130
    /// io::sink().write(buffer.as_slice()).unwrap();
1131
    /// ```
1132
    #[inline(always)]
1133
0
    pub fn as_slice(&self) -> &[T] {
1134
0
        self
1135
0
    }
1136
1137
    /// Extracts a mutable slice of the entire vector.
1138
    ///
1139
    /// Equivalent to `&mut s[..]`.
1140
    ///
1141
    /// # Examples
1142
    ///
1143
    /// ```
1144
    /// use std::io::{self, Read};
1145
    /// let mut buffer = vec![0; 3];
1146
    /// io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
1147
    /// ```
1148
    #[inline(always)]
1149
0
    pub fn as_mut_slice(&mut self) -> &mut [T] {
1150
0
        self
1151
0
    }
1152
1153
    /// Returns a raw pointer to the vector's buffer, or a dangling raw pointer
1154
    /// valid for zero sized reads if the vector didn't allocate.
1155
    ///
1156
    /// The caller must ensure that the vector outlives the pointer this
1157
    /// function returns, or else it will end up pointing to garbage.
1158
    /// Modifying the vector may cause its buffer to be reallocated,
1159
    /// which would also make any pointers to it invalid.
1160
    ///
1161
    /// The caller must also ensure that the memory the pointer (non-transitively) points to
1162
    /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
1163
    /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
1164
    ///
1165
    /// # Examples
1166
    ///
1167
    /// ```
1168
    /// let x = vec![1, 2, 4];
1169
    /// let x_ptr = x.as_ptr();
1170
    ///
1171
    /// unsafe {
1172
    ///     for i in 0..x.len() {
1173
    ///         assert_eq!(*x_ptr.add(i), 1 << i);
1174
    ///     }
1175
    /// }
1176
    /// ```
1177
    ///
1178
    /// [`as_mut_ptr`]: Vec::as_mut_ptr
1179
    #[inline(always)]
1180
0
    pub fn as_ptr(&self) -> *const T {
1181
0
        // We shadow the slice method of the same name to avoid going through
1182
0
        // `deref`, which creates an intermediate reference.
1183
0
        let ptr = self.buf.ptr();
1184
0
        unsafe {
1185
0
            assume(!ptr.is_null());
1186
0
        }
1187
0
        ptr
1188
0
    }
1189
1190
    /// Returns an unsafe mutable pointer to the vector's buffer, or a dangling
1191
    /// raw pointer valid for zero sized reads if the vector didn't allocate.
1192
    ///
1193
    /// The caller must ensure that the vector outlives the pointer this
1194
    /// function returns, or else it will end up pointing to garbage.
1195
    /// Modifying the vector may cause its buffer to be reallocated,
1196
    /// which would also make any pointers to it invalid.
1197
    ///
1198
    /// # Examples
1199
    ///
1200
    /// ```
1201
    /// // Allocate vector big enough for 4 elements.
1202
    /// let size = 4;
1203
    /// let mut x: Vec<i32> = Vec::with_capacity(size);
1204
    /// let x_ptr = x.as_mut_ptr();
1205
    ///
1206
    /// // Initialize elements via raw pointer writes, then set length.
1207
    /// unsafe {
1208
    ///     for i in 0..size {
1209
    ///         *x_ptr.add(i) = i as i32;
1210
    ///     }
1211
    ///     x.set_len(size);
1212
    /// }
1213
    /// assert_eq!(&*x, &[0, 1, 2, 3]);
1214
    /// ```
1215
    #[inline(always)]
1216
0
    pub fn as_mut_ptr(&mut self) -> *mut T {
1217
0
        // We shadow the slice method of the same name to avoid going through
1218
0
        // `deref_mut`, which creates an intermediate reference.
1219
0
        let ptr = self.buf.ptr();
1220
0
        unsafe {
1221
0
            assume(!ptr.is_null());
1222
0
        }
1223
0
        ptr
1224
0
    }
1225
1226
    /// Returns a reference to the underlying allocator.
1227
    #[inline(always)]
1228
0
    pub fn allocator(&self) -> &A {
1229
0
        self.buf.allocator()
1230
0
    }
1231
1232
    /// Forces the length of the vector to `new_len`.
1233
    ///
1234
    /// This is a low-level operation that maintains none of the normal
1235
    /// invariants of the type. Normally changing the length of a vector
1236
    /// is done using one of the safe operations instead, such as
1237
    /// [`truncate`], [`resize`], [`extend`], or [`clear`].
1238
    ///
1239
    /// [`truncate`]: Vec::truncate
1240
    /// [`resize`]: Vec::resize
1241
    /// [`extend`]: Extend::extend
1242
    /// [`clear`]: Vec::clear
1243
    ///
1244
    /// # Safety
1245
    ///
1246
    /// - `new_len` must be less than or equal to [`capacity()`].
1247
    /// - The elements at `old_len..new_len` must be initialized.
1248
    ///
1249
    /// [`capacity()`]: Vec::capacity
1250
    ///
1251
    /// # Examples
1252
    ///
1253
    /// This method can be useful for situations in which the vector
1254
    /// is serving as a buffer for other code, particularly over FFI:
1255
    ///
1256
    /// ```no_run
1257
    /// # #![allow(dead_code)]
1258
    /// # // This is just a minimal skeleton for the doc example;
1259
    /// # // don't use this as a starting point for a real library.
1260
    /// # pub struct StreamWrapper { strm: *mut std::ffi::c_void }
1261
    /// # const Z_OK: i32 = 0;
1262
    /// # extern "C" {
1263
    /// #     fn deflateGetDictionary(
1264
    /// #         strm: *mut std::ffi::c_void,
1265
    /// #         dictionary: *mut u8,
1266
    /// #         dictLength: *mut usize,
1267
    /// #     ) -> i32;
1268
    /// # }
1269
    /// # impl StreamWrapper {
1270
    /// pub fn get_dictionary(&self) -> Option<Vec<u8>> {
1271
    ///     // Per the FFI method's docs, "32768 bytes is always enough".
1272
    ///     let mut dict = Vec::with_capacity(32_768);
1273
    ///     let mut dict_length = 0;
1274
    ///     // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
1275
    ///     // 1. `dict_length` elements were initialized.
1276
    ///     // 2. `dict_length` <= the capacity (32_768)
1277
    ///     // which makes `set_len` safe to call.
1278
    ///     unsafe {
1279
    ///         // Make the FFI call...
1280
    ///         let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
1281
    ///         if r == Z_OK {
1282
    ///             // ...and update the length to what was initialized.
1283
    ///             dict.set_len(dict_length);
1284
    ///             Some(dict)
1285
    ///         } else {
1286
    ///             None
1287
    ///         }
1288
    ///     }
1289
    /// }
1290
    /// # }
1291
    /// ```
1292
    ///
1293
    /// While the following example is sound, there is a memory leak since
1294
    /// the inner vectors were not freed prior to the `set_len` call:
1295
    ///
1296
    /// ```
1297
    /// let mut vec = vec![vec![1, 0, 0],
1298
    ///                    vec![0, 1, 0],
1299
    ///                    vec![0, 0, 1]];
1300
    /// // SAFETY:
1301
    /// // 1. `old_len..0` is empty so no elements need to be initialized.
1302
    /// // 2. `0 <= capacity` always holds whatever `capacity` is.
1303
    /// unsafe {
1304
    ///     vec.set_len(0);
1305
    /// }
1306
    /// ```
1307
    ///
1308
    /// Normally, here, one would use [`clear`] instead to correctly drop
1309
    /// the contents and thus not leak memory.
1310
    #[inline(always)]
1311
0
    pub unsafe fn set_len(&mut self, new_len: usize) {
1312
0
        debug_assert!(new_len <= self.capacity());
1313
1314
0
        self.len = new_len;
1315
0
    }
1316
1317
    /// Removes an element from the vector and returns it.
1318
    ///
1319
    /// The removed element is replaced by the last element of the vector.
1320
    ///
1321
    /// This does not preserve ordering, but is *O*(1).
1322
    /// If you need to preserve the element order, use [`remove`] instead.
1323
    ///
1324
    /// [`remove`]: Vec::remove
1325
    ///
1326
    /// # Panics
1327
    ///
1328
    /// Panics if `index` is out of bounds.
1329
    ///
1330
    /// # Examples
1331
    ///
1332
    /// ```
1333
    /// let mut v = vec!["foo", "bar", "baz", "qux"];
1334
    ///
1335
    /// assert_eq!(v.swap_remove(1), "bar");
1336
    /// assert_eq!(v, ["foo", "qux", "baz"]);
1337
    ///
1338
    /// assert_eq!(v.swap_remove(0), "foo");
1339
    /// assert_eq!(v, ["baz", "qux"]);
1340
    /// ```
1341
    #[inline(always)]
1342
0
    pub fn swap_remove(&mut self, index: usize) -> T {
1343
        #[cold]
1344
        #[inline(never)]
1345
0
        fn assert_failed(index: usize, len: usize) -> ! {
1346
0
            panic!(
1347
0
                "swap_remove index (is {}) should be < len (is {})",
1348
0
                index, len
1349
0
            );
1350
        }
1351
1352
0
        let len = self.len();
1353
0
        if index >= len {
1354
0
            assert_failed(index, len);
1355
0
        }
1356
0
        unsafe {
1357
0
            // We replace self[index] with the last element. Note that if the
1358
0
            // bounds check above succeeds there must be a last element (which
1359
0
            // can be self[index] itself).
1360
0
            let value = ptr::read(self.as_ptr().add(index));
1361
0
            let base_ptr = self.as_mut_ptr();
1362
0
            ptr::copy(base_ptr.add(len - 1), base_ptr.add(index), 1);
1363
0
            self.set_len(len - 1);
1364
0
            value
1365
0
        }
1366
0
    }
1367
1368
    /// Inserts an element at position `index` within the vector, shifting all
1369
    /// elements after it to the right.
1370
    ///
1371
    /// # Panics
1372
    ///
1373
    /// Panics if `index > len`.
1374
    ///
1375
    /// # Examples
1376
    ///
1377
    /// ```
1378
    /// let mut vec = vec![1, 2, 3];
1379
    /// vec.insert(1, 4);
1380
    /// assert_eq!(vec, [1, 4, 2, 3]);
1381
    /// vec.insert(4, 5);
1382
    /// assert_eq!(vec, [1, 4, 2, 3, 5]);
1383
    /// ```
1384
    #[cfg(not(no_global_oom_handling))]
1385
0
    pub fn insert(&mut self, index: usize, element: T) {
1386
        #[cold]
1387
        #[inline(never)]
1388
0
        fn assert_failed(index: usize, len: usize) -> ! {
1389
0
            panic!(
1390
0
                "insertion index (is {}) should be <= len (is {})",
1391
0
                index, len
1392
0
            );
1393
        }
1394
1395
0
        let len = self.len();
1396
0
1397
0
        // space for the new element
1398
0
        if len == self.buf.capacity() {
1399
0
            self.reserve(1);
1400
0
        }
1401
1402
        unsafe {
1403
            // infallible
1404
            // The spot to put the new value
1405
            {
1406
0
                let p = self.as_mut_ptr().add(index);
1407
0
                match cmp::Ord::cmp(&index, &len) {
1408
0
                    Ordering::Less => {
1409
0
                        // Shift everything over to make space. (Duplicating the
1410
0
                        // `index`th element into two consecutive places.)
1411
0
                        ptr::copy(p, p.add(1), len - index);
1412
0
                    }
1413
0
                    Ordering::Equal => {
1414
0
                        // No elements need shifting.
1415
0
                    }
1416
                    Ordering::Greater => {
1417
0
                        assert_failed(index, len);
1418
                    }
1419
                }
1420
                // Write it in, overwriting the first copy of the `index`th
1421
                // element.
1422
0
                ptr::write(p, element);
1423
0
            }
1424
0
            self.set_len(len + 1);
1425
0
        }
1426
0
    }
1427
1428
    /// Removes and returns the element at position `index` within the vector,
1429
    /// shifting all elements after it to the left.
1430
    ///
1431
    /// Note: Because this shifts over the remaining elements, it has a
1432
    /// worst-case performance of *O*(*n*). If you don't need the order of elements
1433
    /// to be preserved, use [`swap_remove`] instead. If you'd like to remove
1434
    /// elements from the beginning of the `Vec`, consider using
1435
    /// [`VecDeque::pop_front`] instead.
1436
    ///
1437
    /// [`swap_remove`]: Vec::swap_remove
1438
    /// [`VecDeque::pop_front`]: alloc_crate::collections::VecDeque::pop_front
1439
    ///
1440
    /// # Panics
1441
    ///
1442
    /// Panics if `index` is out of bounds.
1443
    ///
1444
    /// # Examples
1445
    ///
1446
    /// ```
1447
    /// let mut v = vec![1, 2, 3];
1448
    /// assert_eq!(v.remove(1), 2);
1449
    /// assert_eq!(v, [1, 3]);
1450
    /// ```
1451
    #[track_caller]
1452
    #[inline(always)]
1453
0
    pub fn remove(&mut self, index: usize) -> T {
1454
        #[cold]
1455
        #[inline(never)]
1456
        #[track_caller]
1457
0
        fn assert_failed(index: usize, len: usize) -> ! {
1458
0
            panic!("removal index (is {}) should be < len (is {})", index, len);
1459
        }
1460
1461
0
        let len = self.len();
1462
0
        if index >= len {
1463
0
            assert_failed(index, len);
1464
0
        }
1465
0
        unsafe {
1466
0
            // infallible
1467
0
            let ret;
1468
0
            {
1469
0
                // the place we are taking from.
1470
0
                let ptr = self.as_mut_ptr().add(index);
1471
0
                // copy it out, unsafely having a copy of the value on
1472
0
                // the stack and in the vector at the same time.
1473
0
                ret = ptr::read(ptr);
1474
0
1475
0
                // Shift everything down to fill in that spot.
1476
0
                ptr::copy(ptr.add(1), ptr, len - index - 1);
1477
0
            }
1478
0
            self.set_len(len - 1);
1479
0
            ret
1480
0
        }
1481
0
    }
1482
1483
    /// Retains only the elements specified by the predicate.
1484
    ///
1485
    /// In other words, remove all elements `e` for which `f(&e)` returns `false`.
1486
    /// This method operates in place, visiting each element exactly once in the
1487
    /// original order, and preserves the order of the retained elements.
1488
    ///
1489
    /// # Examples
1490
    ///
1491
    /// ```
1492
    /// let mut vec = vec![1, 2, 3, 4];
1493
    /// vec.retain(|&x| x % 2 == 0);
1494
    /// assert_eq!(vec, [2, 4]);
1495
    /// ```
1496
    ///
1497
    /// Because the elements are visited exactly once in the original order,
1498
    /// external state may be used to decide which elements to keep.
1499
    ///
1500
    /// ```
1501
    /// let mut vec = vec![1, 2, 3, 4, 5];
1502
    /// let keep = [false, true, true, false, true];
1503
    /// let mut iter = keep.iter();
1504
    /// vec.retain(|_| *iter.next().unwrap());
1505
    /// assert_eq!(vec, [2, 3, 5]);
1506
    /// ```
1507
    #[inline(always)]
1508
0
    pub fn retain<F>(&mut self, mut f: F)
1509
0
    where
1510
0
        F: FnMut(&T) -> bool,
1511
0
    {
1512
0
        self.retain_mut(|elem| f(elem));
1513
0
    }
1514
1515
    /// Retains only the elements specified by the predicate, passing a mutable reference to it.
1516
    ///
1517
    /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
1518
    /// This method operates in place, visiting each element exactly once in the
1519
    /// original order, and preserves the order of the retained elements.
1520
    ///
1521
    /// # Examples
1522
    ///
1523
    /// ```
1524
    /// let mut vec = vec![1, 2, 3, 4];
1525
    /// vec.retain_mut(|x| if *x <= 3 {
1526
    ///     *x += 1;
1527
    ///     true
1528
    /// } else {
1529
    ///     false
1530
    /// });
1531
    /// assert_eq!(vec, [2, 3, 4]);
1532
    /// ```
1533
    #[inline]
1534
0
    pub fn retain_mut<F>(&mut self, mut f: F)
1535
0
    where
1536
0
        F: FnMut(&mut T) -> bool,
1537
0
    {
1538
0
        let original_len = self.len();
1539
0
        // Avoid double drop if the drop guard is not executed,
1540
0
        // since we may make some holes during the process.
1541
0
        unsafe { self.set_len(0) };
1542
1543
        // Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked]
1544
        //      |<-              processed len   ->| ^- next to check
1545
        //                  |<-  deleted cnt     ->|
1546
        //      |<-              original_len                          ->|
1547
        // Kept: Elements which predicate returns true on.
1548
        // Hole: Moved or dropped element slot.
1549
        // Unchecked: Unchecked valid elements.
1550
        //
1551
        // This drop guard will be invoked when predicate or `drop` of element panicked.
1552
        // It shifts unchecked elements to cover holes and `set_len` to the correct length.
1553
        // In cases when predicate and `drop` never panick, it will be optimized out.
1554
        struct BackshiftOnDrop<'a, T, A: Allocator> {
1555
            v: &'a mut Vec<T, A>,
1556
            processed_len: usize,
1557
            deleted_cnt: usize,
1558
            original_len: usize,
1559
        }
1560
1561
        impl<T, A: Allocator> Drop for BackshiftOnDrop<'_, T, A> {
1562
0
            fn drop(&mut self) {
1563
0
                if self.deleted_cnt > 0 {
1564
                    // SAFETY: Trailing unchecked items must be valid since we never touch them.
1565
0
                    unsafe {
1566
0
                        ptr::copy(
1567
0
                            self.v.as_ptr().add(self.processed_len),
1568
0
                            self.v
1569
0
                                .as_mut_ptr()
1570
0
                                .add(self.processed_len - self.deleted_cnt),
1571
0
                            self.original_len - self.processed_len,
1572
0
                        );
1573
0
                    }
1574
0
                }
1575
                // SAFETY: After filling holes, all items are in contiguous memory.
1576
0
                unsafe {
1577
0
                    self.v.set_len(self.original_len - self.deleted_cnt);
1578
0
                }
1579
0
            }
1580
        }
1581
1582
0
        let mut g = BackshiftOnDrop {
1583
0
            v: self,
1584
0
            processed_len: 0,
1585
0
            deleted_cnt: 0,
1586
0
            original_len,
1587
0
        };
1588
1589
0
        fn process_loop<F, T, A: Allocator, const DELETED: bool>(
1590
0
            original_len: usize,
1591
0
            f: &mut F,
1592
0
            g: &mut BackshiftOnDrop<'_, T, A>,
1593
0
        ) where
1594
0
            F: FnMut(&mut T) -> bool,
1595
0
        {
1596
0
            while g.processed_len != original_len {
1597
                // SAFETY: Unchecked element must be valid.
1598
0
                let cur = unsafe { &mut *g.v.as_mut_ptr().add(g.processed_len) };
1599
0
                if !f(cur) {
1600
                    // Advance early to avoid double drop if `drop_in_place` panicked.
1601
0
                    g.processed_len += 1;
1602
0
                    g.deleted_cnt += 1;
1603
0
                    // SAFETY: We never touch this element again after dropped.
1604
0
                    unsafe { ptr::drop_in_place(cur) };
1605
0
                    // We already advanced the counter.
1606
0
                    if DELETED {
1607
0
                        continue;
1608
                    } else {
1609
0
                        break;
1610
                    }
1611
0
                }
1612
0
                if DELETED {
1613
                    // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
1614
                    // We use copy for move, and never touch this element again.
1615
0
                    unsafe {
1616
0
                        let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt);
1617
0
                        ptr::copy_nonoverlapping(cur, hole_slot, 1);
1618
0
                    }
1619
0
                }
1620
0
                g.processed_len += 1;
1621
            }
1622
0
        }
1623
1624
        // Stage 1: Nothing was deleted.
1625
0
        process_loop::<F, T, A, false>(original_len, &mut f, &mut g);
1626
0
1627
0
        // Stage 2: Some elements were deleted.
1628
0
        process_loop::<F, T, A, true>(original_len, &mut f, &mut g);
1629
0
1630
0
        // All item are processed. This can be optimized to `set_len` by LLVM.
1631
0
        drop(g);
1632
0
    }
1633
1634
    /// Removes all but the first of consecutive elements in the vector that resolve to the same
1635
    /// key.
1636
    ///
1637
    /// If the vector is sorted, this removes all duplicates.
1638
    ///
1639
    /// # Examples
1640
    ///
1641
    /// ```
1642
    /// let mut vec = vec![10, 20, 21, 30, 20];
1643
    ///
1644
    /// vec.dedup_by_key(|i| *i / 10);
1645
    ///
1646
    /// assert_eq!(vec, [10, 20, 30, 20]);
1647
    /// ```
1648
    #[inline(always)]
1649
0
    pub fn dedup_by_key<F, K>(&mut self, mut key: F)
1650
0
    where
1651
0
        F: FnMut(&mut T) -> K,
1652
0
        K: PartialEq,
1653
0
    {
1654
0
        self.dedup_by(|a, b| key(a) == key(b))
1655
0
    }
1656
1657
    /// Removes all but the first of consecutive elements in the vector satisfying a given equality
1658
    /// relation.
1659
    ///
1660
    /// The `same_bucket` function is passed references to two elements from the vector and
1661
    /// must determine if the elements compare equal. The elements are passed in opposite order
1662
    /// from their order in the slice, so if `same_bucket(a, b)` returns `true`, `a` is removed.
1663
    ///
1664
    /// If the vector is sorted, this removes all duplicates.
1665
    ///
1666
    /// # Examples
1667
    ///
1668
    /// ```
1669
    /// let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
1670
    ///
1671
    /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
1672
    ///
1673
    /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
1674
    /// ```
1675
    #[inline]
1676
0
    pub fn dedup_by<F>(&mut self, mut same_bucket: F)
1677
0
    where
1678
0
        F: FnMut(&mut T, &mut T) -> bool,
1679
0
    {
1680
0
        let len = self.len();
1681
0
        if len <= 1 {
1682
0
            return;
1683
0
        }
1684
1685
        /* INVARIANT: vec.len() > read >= write > write-1 >= 0 */
1686
        struct FillGapOnDrop<'a, T, A: Allocator> {
1687
            /* Offset of the element we want to check if it is duplicate */
1688
            read: usize,
1689
1690
            /* Offset of the place where we want to place the non-duplicate
1691
             * when we find it. */
1692
            write: usize,
1693
1694
            /* The Vec that would need correction if `same_bucket` panicked */
1695
            vec: &'a mut Vec<T, A>,
1696
        }
1697
1698
        impl<'a, T, A: Allocator> Drop for FillGapOnDrop<'a, T, A> {
1699
0
            fn drop(&mut self) {
1700
0
                /* This code gets executed when `same_bucket` panics */
1701
0
1702
0
                /* SAFETY: invariant guarantees that `read - write`
1703
0
                 * and `len - read` never overflow and that the copy is always
1704
0
                 * in-bounds. */
1705
0
                unsafe {
1706
0
                    let ptr = self.vec.as_mut_ptr();
1707
0
                    let len = self.vec.len();
1708
0
1709
0
                    /* How many items were left when `same_bucket` panicked.
1710
0
                     * Basically vec[read..].len() */
1711
0
                    let items_left = len.wrapping_sub(self.read);
1712
0
1713
0
                    /* Pointer to first item in vec[write..write+items_left] slice */
1714
0
                    let dropped_ptr = ptr.add(self.write);
1715
0
                    /* Pointer to first item in vec[read..] slice */
1716
0
                    let valid_ptr = ptr.add(self.read);
1717
0
1718
0
                    /* Copy `vec[read..]` to `vec[write..write+items_left]`.
1719
0
                     * The slices can overlap, so `copy_nonoverlapping` cannot be used */
1720
0
                    ptr::copy(valid_ptr, dropped_ptr, items_left);
1721
0
1722
0
                    /* How many items have been already dropped
1723
0
                     * Basically vec[read..write].len() */
1724
0
                    let dropped = self.read.wrapping_sub(self.write);
1725
0
1726
0
                    self.vec.set_len(len - dropped);
1727
0
                }
1728
0
            }
1729
        }
1730
1731
0
        let mut gap = FillGapOnDrop {
1732
0
            read: 1,
1733
0
            write: 1,
1734
0
            vec: self,
1735
0
        };
1736
0
        let ptr = gap.vec.as_mut_ptr();
1737
1738
        /* Drop items while going through Vec, it should be more efficient than
1739
         * doing slice partition_dedup + truncate */
1740
1741
        /* SAFETY: Because of the invariant, read_ptr, prev_ptr and write_ptr
1742
         * are always in-bounds and read_ptr never aliases prev_ptr */
1743
        unsafe {
1744
0
            while gap.read < len {
1745
0
                let read_ptr = ptr.add(gap.read);
1746
0
                let prev_ptr = ptr.add(gap.write.wrapping_sub(1));
1747
0
1748
0
                if same_bucket(&mut *read_ptr, &mut *prev_ptr) {
1749
0
                    // Increase `gap.read` now since the drop may panic.
1750
0
                    gap.read += 1;
1751
0
                    /* We have found duplicate, drop it in-place */
1752
0
                    ptr::drop_in_place(read_ptr);
1753
0
                } else {
1754
0
                    let write_ptr = ptr.add(gap.write);
1755
0
1756
0
                    /* Because `read_ptr` can be equal to `write_ptr`, we either
1757
0
                     * have to use `copy` or conditional `copy_nonoverlapping`.
1758
0
                     * Looks like the first option is faster. */
1759
0
                    ptr::copy(read_ptr, write_ptr, 1);
1760
0
1761
0
                    /* We have filled that place, so go further */
1762
0
                    gap.write += 1;
1763
0
                    gap.read += 1;
1764
0
                }
1765
            }
1766
1767
            /* Technically we could let `gap` clean up with its Drop, but
1768
             * when `same_bucket` is guaranteed to not panic, this bloats a little
1769
             * the codegen, so we just do it manually */
1770
0
            gap.vec.set_len(gap.write);
1771
0
            mem::forget(gap);
1772
        }
1773
0
    }
1774
1775
    /// Appends an element to the back of a collection.
1776
    ///
1777
    /// # Panics
1778
    ///
1779
    /// Panics if the new capacity exceeds `isize::MAX` bytes.
1780
    ///
1781
    /// # Examples
1782
    ///
1783
    /// ```
1784
    /// let mut vec = vec![1, 2];
1785
    /// vec.push(3);
1786
    /// assert_eq!(vec, [1, 2, 3]);
1787
    /// ```
1788
    #[cfg(not(no_global_oom_handling))]
1789
    #[inline(always)]
1790
0
    pub fn push(&mut self, value: T) {
1791
0
        // This will panic or abort if we would allocate > isize::MAX bytes
1792
0
        // or if the length increment would overflow for zero-sized types.
1793
0
        if self.len == self.buf.capacity() {
1794
0
            self.buf.reserve_for_push(self.len);
1795
0
        }
1796
0
        unsafe {
1797
0
            let end = self.as_mut_ptr().add(self.len);
1798
0
            ptr::write(end, value);
1799
0
            self.len += 1;
1800
0
        }
1801
0
    }
1802
1803
    /// Appends an element if there is sufficient spare capacity, otherwise an error is returned
1804
    /// with the element.
1805
    ///
1806
    /// Unlike [`push`] this method will not reallocate when there's insufficient capacity.
1807
    /// The caller should use [`reserve`] or [`try_reserve`] to ensure that there is enough capacity.
1808
    ///
1809
    /// [`push`]: Vec::push
1810
    /// [`reserve`]: Vec::reserve
1811
    /// [`try_reserve`]: Vec::try_reserve
1812
    ///
1813
    /// # Examples
1814
    ///
1815
    /// A manual, panic-free alternative to [`FromIterator`]:
1816
    ///
1817
    /// ```
1818
    /// #![feature(vec_push_within_capacity)]
1819
    ///
1820
    /// use std::collections::TryReserveError;
1821
    /// fn from_iter_fallible<T>(iter: impl Iterator<Item=T>) -> Result<Vec<T>, TryReserveError> {
1822
    ///     let mut vec = Vec::new();
1823
    ///     for value in iter {
1824
    ///         if let Err(value) = vec.push_within_capacity(value) {
1825
    ///             vec.try_reserve(1)?;
1826
    ///             // this cannot fail, the previous line either returned or added at least 1 free slot
1827
    ///             let _ = vec.push_within_capacity(value);
1828
    ///         }
1829
    ///     }
1830
    ///     Ok(vec)
1831
    /// }
1832
    /// assert_eq!(from_iter_fallible(0..100), Ok(Vec::from_iter(0..100)));
1833
    /// ```
1834
    #[inline(always)]
1835
0
    pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> {
1836
0
        if self.len == self.buf.capacity() {
1837
0
            return Err(value);
1838
0
        }
1839
0
        unsafe {
1840
0
            let end = self.as_mut_ptr().add(self.len);
1841
0
            ptr::write(end, value);
1842
0
            self.len += 1;
1843
0
        }
1844
0
        Ok(())
1845
0
    }
1846
1847
    /// Removes the last element from a vector and returns it, or [`None`] if it
1848
    /// is empty.
1849
    ///
1850
    /// If you'd like to pop the first element, consider using
1851
    /// [`VecDeque::pop_front`] instead.
1852
    ///
1853
    /// [`VecDeque::pop_front`]: alloc_crate::collections::VecDeque::pop_front
1854
    ///
1855
    /// # Examples
1856
    ///
1857
    /// ```
1858
    /// let mut vec = vec![1, 2, 3];
1859
    /// assert_eq!(vec.pop(), Some(3));
1860
    /// assert_eq!(vec, [1, 2]);
1861
    /// ```
1862
    #[inline(always)]
1863
0
    pub fn pop(&mut self) -> Option<T> {
1864
0
        if self.len == 0 {
1865
0
            None
1866
        } else {
1867
            unsafe {
1868
0
                self.len -= 1;
1869
0
                Some(ptr::read(self.as_ptr().add(self.len())))
1870
            }
1871
        }
1872
0
    }
1873
1874
    /// Moves all the elements of `other` into `self`, leaving `other` empty.
1875
    ///
1876
    /// # Panics
1877
    ///
1878
    /// Panics if the new capacity exceeds `isize::MAX` bytes.
1879
    ///
1880
    /// # Examples
1881
    ///
1882
    /// ```
1883
    /// let mut vec = vec![1, 2, 3];
1884
    /// let mut vec2 = vec![4, 5, 6];
1885
    /// vec.append(&mut vec2);
1886
    /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
1887
    /// assert_eq!(vec2, []);
1888
    /// ```
1889
    #[cfg(not(no_global_oom_handling))]
1890
    #[inline(always)]
1891
0
    pub fn append(&mut self, other: &mut Self) {
1892
0
        unsafe {
1893
0
            self.append_elements(other.as_slice() as _);
1894
0
            other.set_len(0);
1895
0
        }
1896
0
    }
1897
1898
    /// Appends elements to `self` from other buffer.
1899
    #[cfg(not(no_global_oom_handling))]
1900
    #[inline(always)]
1901
0
    unsafe fn append_elements(&mut self, other: *const [T]) {
1902
0
        let count = unsafe { (*other).len() };
1903
0
        self.reserve(count);
1904
0
        let len = self.len();
1905
0
        unsafe { ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) };
1906
0
        self.len += count;
1907
0
    }
1908
1909
    /// Removes the specified range from the vector in bulk, returning all
1910
    /// removed elements as an iterator. If the iterator is dropped before
1911
    /// being fully consumed, it drops the remaining removed elements.
1912
    ///
1913
    /// The returned iterator keeps a mutable borrow on the vector to optimize
1914
    /// its implementation.
1915
    ///
1916
    /// # Panics
1917
    ///
1918
    /// Panics if the starting point is greater than the end point or if
1919
    /// the end point is greater than the length of the vector.
1920
    ///
1921
    /// # Leaking
1922
    ///
1923
    /// If the returned iterator goes out of scope without being dropped (due to
1924
    /// [`mem::forget`], for example), the vector may have lost and leaked
1925
    /// elements arbitrarily, including elements outside the range.
1926
    ///
1927
    /// # Examples
1928
    ///
1929
    /// ```
1930
    /// let mut v = vec![1, 2, 3];
1931
    /// let u: Vec<_> = v.drain(1..).collect();
1932
    /// assert_eq!(v, &[1]);
1933
    /// assert_eq!(u, &[2, 3]);
1934
    ///
1935
    /// // A full range clears the vector, like `clear()` does
1936
    /// v.drain(..);
1937
    /// assert_eq!(v, &[]);
1938
    /// ```
1939
    #[inline(always)]
1940
0
    pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>
1941
0
    where
1942
0
        R: RangeBounds<usize>,
1943
0
    {
1944
0
        // Memory safety
1945
0
        //
1946
0
        // When the Drain is first created, it shortens the length of
1947
0
        // the source vector to make sure no uninitialized or moved-from elements
1948
0
        // are accessible at all if the Drain's destructor never gets to run.
1949
0
        //
1950
0
        // Drain will ptr::read out the values to remove.
1951
0
        // When finished, remaining tail of the vec is copied back to cover
1952
0
        // the hole, and the vector length is restored to the new length.
1953
0
        //
1954
0
        let len = self.len();
1955
0
1956
0
        // Replaced by code below
1957
0
        // let Range { start, end } = slice::range(range, ..len);
1958
0
1959
0
        // Panics if range is out of bounds
1960
0
        let _ = &self.as_slice()[(range.start_bound().cloned(), range.end_bound().cloned())];
1961
1962
0
        let start = match range.start_bound() {
1963
0
            Bound::Included(&n) => n,
1964
0
            Bound::Excluded(&n) => n + 1,
1965
0
            Bound::Unbounded => 0,
1966
        };
1967
0
        let end = match range.end_bound() {
1968
0
            Bound::Included(&n) => n + 1,
1969
0
            Bound::Excluded(&n) => n,
1970
0
            Bound::Unbounded => len,
1971
        };
1972
1973
        unsafe {
1974
            // set self.vec length's to start, to be safe in case Drain is leaked
1975
0
            self.set_len(start);
1976
0
            let range_slice = slice::from_raw_parts(self.as_ptr().add(start), end - start);
1977
0
            Drain {
1978
0
                tail_start: end,
1979
0
                tail_len: len - end,
1980
0
                iter: range_slice.iter(),
1981
0
                vec: NonNull::from(self),
1982
0
            }
1983
0
        }
1984
0
    }
1985
1986
    /// Clears the vector, removing all values.
1987
    ///
1988
    /// Note that this method has no effect on the allocated capacity
1989
    /// of the vector.
1990
    ///
1991
    /// # Examples
1992
    ///
1993
    /// ```
1994
    /// let mut v = vec![1, 2, 3];
1995
    ///
1996
    /// v.clear();
1997
    ///
1998
    /// assert!(v.is_empty());
1999
    /// ```
2000
    #[inline(always)]
2001
0
    pub fn clear(&mut self) {
2002
0
        let elems: *mut [T] = self.as_mut_slice();
2003
0
2004
0
        // SAFETY:
2005
0
        // - `elems` comes directly from `as_mut_slice` and is therefore valid.
2006
0
        // - Setting `self.len` before calling `drop_in_place` means that,
2007
0
        //   if an element's `Drop` impl panics, the vector's `Drop` impl will
2008
0
        //   do nothing (leaking the rest of the elements) instead of dropping
2009
0
        //   some twice.
2010
0
        unsafe {
2011
0
            self.len = 0;
2012
0
            ptr::drop_in_place(elems);
2013
0
        }
2014
0
    }
2015
2016
    /// Returns the number of elements in the vector, also referred to
2017
    /// as its 'length'.
2018
    ///
2019
    /// # Examples
2020
    ///
2021
    /// ```
2022
    /// let a = vec![1, 2, 3];
2023
    /// assert_eq!(a.len(), 3);
2024
    /// ```
2025
    #[inline(always)]
2026
0
    pub fn len(&self) -> usize {
2027
0
        self.len
2028
0
    }
2029
2030
    /// Returns `true` if the vector contains no elements.
2031
    ///
2032
    /// # Examples
2033
    ///
2034
    /// ```
2035
    /// let mut v = Vec::new();
2036
    /// assert!(v.is_empty());
2037
    ///
2038
    /// v.push(1);
2039
    /// assert!(!v.is_empty());
2040
    /// ```
2041
    #[inline(always)]
2042
0
    pub fn is_empty(&self) -> bool {
2043
0
        self.len() == 0
2044
0
    }
2045
2046
    /// Splits the collection into two at the given index.
2047
    ///
2048
    /// Returns a newly allocated vector containing the elements in the range
2049
    /// `[at, len)`. After the call, the original vector will be left containing
2050
    /// the elements `[0, at)` with its previous capacity unchanged.
2051
    ///
2052
    /// # Panics
2053
    ///
2054
    /// Panics if `at > len`.
2055
    ///
2056
    /// # Examples
2057
    ///
2058
    /// ```
2059
    /// let mut vec = vec![1, 2, 3];
2060
    /// let vec2 = vec.split_off(1);
2061
    /// assert_eq!(vec, [1]);
2062
    /// assert_eq!(vec2, [2, 3]);
2063
    /// ```
2064
    #[cfg(not(no_global_oom_handling))]
2065
    #[inline(always)]
2066
    #[must_use = "use `.truncate()` if you don't need the other half"]
2067
0
    pub fn split_off(&mut self, at: usize) -> Self
2068
0
    where
2069
0
        A: Clone,
2070
0
    {
2071
        #[cold]
2072
        #[inline(never)]
2073
0
        fn assert_failed(at: usize, len: usize) -> ! {
2074
0
            panic!("`at` split index (is {}) should be <= len (is {})", at, len);
2075
        }
2076
2077
0
        if at > self.len() {
2078
0
            assert_failed(at, self.len());
2079
0
        }
2080
0
2081
0
        if at == 0 {
2082
            // the new vector can take over the original buffer and avoid the copy
2083
0
            return mem::replace(
2084
0
                self,
2085
0
                Vec::with_capacity_in(self.capacity(), self.allocator().clone()),
2086
0
            );
2087
0
        }
2088
0
2089
0
        let other_len = self.len - at;
2090
0
        let mut other = Vec::with_capacity_in(other_len, self.allocator().clone());
2091
0
2092
0
        // Unsafely `set_len` and copy items to `other`.
2093
0
        unsafe {
2094
0
            self.set_len(at);
2095
0
            other.set_len(other_len);
2096
0
2097
0
            ptr::copy_nonoverlapping(self.as_ptr().add(at), other.as_mut_ptr(), other.len());
2098
0
        }
2099
0
        other
2100
0
    }
2101
2102
    /// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
2103
    ///
2104
    /// If `new_len` is greater than `len`, the `Vec` is extended by the
2105
    /// difference, with each additional slot filled with the result of
2106
    /// calling the closure `f`. The return values from `f` will end up
2107
    /// in the `Vec` in the order they have been generated.
2108
    ///
2109
    /// If `new_len` is less than `len`, the `Vec` is simply truncated.
2110
    ///
2111
    /// This method uses a closure to create new values on every push. If
2112
    /// you'd rather [`Clone`] a given value, use [`Vec::resize`]. If you
2113
    /// want to use the [`Default`] trait to generate values, you can
2114
    /// pass [`Default::default`] as the second argument.
2115
    ///
2116
    /// # Examples
2117
    ///
2118
    /// ```
2119
    /// let mut vec = vec![1, 2, 3];
2120
    /// vec.resize_with(5, Default::default);
2121
    /// assert_eq!(vec, [1, 2, 3, 0, 0]);
2122
    ///
2123
    /// let mut vec = vec![];
2124
    /// let mut p = 1;
2125
    /// vec.resize_with(4, || { p *= 2; p });
2126
    /// assert_eq!(vec, [2, 4, 8, 16]);
2127
    /// ```
2128
    #[cfg(not(no_global_oom_handling))]
2129
    #[inline(always)]
2130
0
    pub fn resize_with<F>(&mut self, new_len: usize, f: F)
2131
0
    where
2132
0
        F: FnMut() -> T,
2133
0
    {
2134
0
        let len = self.len();
2135
0
        if new_len > len {
2136
0
            self.extend(iter::repeat_with(f).take(new_len - len));
2137
0
        } else {
2138
0
            self.truncate(new_len);
2139
0
        }
2140
0
    }
2141
2142
    /// Consumes and leaks the `Vec`, returning a mutable reference to the contents,
2143
    /// `&'a mut [T]`. Note that the type `T` must outlive the chosen lifetime
2144
    /// `'a`. If the type has only static references, or none at all, then this
2145
    /// may be chosen to be `'static`.
2146
    ///
2147
    /// As of Rust 1.57, this method does not reallocate or shrink the `Vec`,
2148
    /// so the leaked allocation may include unused capacity that is not part
2149
    /// of the returned slice.
2150
    ///
2151
    /// This function is mainly useful for data that lives for the remainder of
2152
    /// the program's life. Dropping the returned reference will cause a memory
2153
    /// leak.
2154
    ///
2155
    /// # Examples
2156
    ///
2157
    /// Simple usage:
2158
    ///
2159
    /// ```
2160
    /// let x = vec![1, 2, 3];
2161
    /// let static_ref: &'static mut [usize] = x.leak();
2162
    /// static_ref[0] += 1;
2163
    /// assert_eq!(static_ref, &[2, 2, 3]);
2164
    /// ```
2165
    #[inline(always)]
2166
0
    pub fn leak<'a>(self) -> &'a mut [T]
2167
0
    where
2168
0
        A: 'a,
2169
0
    {
2170
0
        let mut me = ManuallyDrop::new(self);
2171
0
        unsafe { slice::from_raw_parts_mut(me.as_mut_ptr(), me.len) }
2172
0
    }
2173
2174
    /// Returns the remaining spare capacity of the vector as a slice of
2175
    /// `MaybeUninit<T>`.
2176
    ///
2177
    /// The returned slice can be used to fill the vector with data (e.g. by
2178
    /// reading from a file) before marking the data as initialized using the
2179
    /// [`set_len`] method.
2180
    ///
2181
    /// [`set_len`]: Vec::set_len
2182
    ///
2183
    /// # Examples
2184
    ///
2185
    /// ```
2186
    /// // Allocate vector big enough for 10 elements.
2187
    /// let mut v = Vec::with_capacity(10);
2188
    ///
2189
    /// // Fill in the first 3 elements.
2190
    /// let uninit = v.spare_capacity_mut();
2191
    /// uninit[0].write(0);
2192
    /// uninit[1].write(1);
2193
    /// uninit[2].write(2);
2194
    ///
2195
    /// // Mark the first 3 elements of the vector as being initialized.
2196
    /// unsafe {
2197
    ///     v.set_len(3);
2198
    /// }
2199
    ///
2200
    /// assert_eq!(&v, &[0, 1, 2]);
2201
    /// ```
2202
    #[inline(always)]
2203
0
    pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
2204
0
        // Note:
2205
0
        // This method is not implemented in terms of `split_at_spare_mut`,
2206
0
        // to prevent invalidation of pointers to the buffer.
2207
0
        unsafe {
2208
0
            slice::from_raw_parts_mut(
2209
0
                self.as_mut_ptr().add(self.len) as *mut MaybeUninit<T>,
2210
0
                self.buf.capacity() - self.len,
2211
0
            )
2212
0
        }
2213
0
    }
2214
2215
    /// Returns vector content as a slice of `T`, along with the remaining spare
2216
    /// capacity of the vector as a slice of `MaybeUninit<T>`.
2217
    ///
2218
    /// The returned spare capacity slice can be used to fill the vector with data
2219
    /// (e.g. by reading from a file) before marking the data as initialized using
2220
    /// the [`set_len`] method.
2221
    ///
2222
    /// [`set_len`]: Vec::set_len
2223
    ///
2224
    /// Note that this is a low-level API, which should be used with care for
2225
    /// optimization purposes. If you need to append data to a `Vec`
2226
    /// you can use [`push`], [`extend`], [`extend_from_slice`],
2227
    /// [`extend_from_within`], [`insert`], [`append`], [`resize`] or
2228
    /// [`resize_with`], depending on your exact needs.
2229
    ///
2230
    /// [`push`]: Vec::push
2231
    /// [`extend`]: Vec::extend
2232
    /// [`extend_from_slice`]: Vec::extend_from_slice
2233
    /// [`extend_from_within`]: Vec::extend_from_within
2234
    /// [`insert`]: Vec::insert
2235
    /// [`append`]: Vec::append
2236
    /// [`resize`]: Vec::resize
2237
    /// [`resize_with`]: Vec::resize_with
2238
    ///
2239
    /// # Examples
2240
    ///
2241
    /// ```
2242
    /// #![feature(vec_split_at_spare)]
2243
    ///
2244
    /// let mut v = vec![1, 1, 2];
2245
    ///
2246
    /// // Reserve additional space big enough for 10 elements.
2247
    /// v.reserve(10);
2248
    ///
2249
    /// let (init, uninit) = v.split_at_spare_mut();
2250
    /// let sum = init.iter().copied().sum::<u32>();
2251
    ///
2252
    /// // Fill in the next 4 elements.
2253
    /// uninit[0].write(sum);
2254
    /// uninit[1].write(sum * 2);
2255
    /// uninit[2].write(sum * 3);
2256
    /// uninit[3].write(sum * 4);
2257
    ///
2258
    /// // Mark the 4 elements of the vector as being initialized.
2259
    /// unsafe {
2260
    ///     let len = v.len();
2261
    ///     v.set_len(len + 4);
2262
    /// }
2263
    ///
2264
    /// assert_eq!(&v, &[1, 1, 2, 4, 8, 12, 16]);
2265
    /// ```
2266
    #[inline(always)]
2267
0
    pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>]) {
2268
0
        // SAFETY:
2269
0
        // - len is ignored and so never changed
2270
0
        let (init, spare, _) = unsafe { self.split_at_spare_mut_with_len() };
2271
0
        (init, spare)
2272
0
    }
2273
2274
    /// Safety: changing returned .2 (&mut usize) is considered the same as calling `.set_len(_)`.
2275
    ///
2276
    /// This method provides unique access to all vec parts at once in `extend_from_within`.
2277
0
    unsafe fn split_at_spare_mut_with_len(
2278
0
        &mut self,
2279
0
    ) -> (&mut [T], &mut [MaybeUninit<T>], &mut usize) {
2280
0
        let ptr = self.as_mut_ptr();
2281
0
        // SAFETY:
2282
0
        // - `ptr` is guaranteed to be valid for `self.len` elements
2283
0
        // - but the allocation extends out to `self.buf.capacity()` elements, possibly
2284
0
        // uninitialized
2285
0
        let spare_ptr = unsafe { ptr.add(self.len) };
2286
0
        let spare_ptr = spare_ptr.cast::<MaybeUninit<T>>();
2287
0
        let spare_len = self.buf.capacity() - self.len;
2288
0
2289
0
        // SAFETY:
2290
0
        // - `ptr` is guaranteed to be valid for `self.len` elements
2291
0
        // - `spare_ptr` is pointing one element past the buffer, so it doesn't overlap with `initialized`
2292
0
        unsafe {
2293
0
            let initialized = slice::from_raw_parts_mut(ptr, self.len);
2294
0
            let spare = slice::from_raw_parts_mut(spare_ptr, spare_len);
2295
0
2296
0
            (initialized, spare, &mut self.len)
2297
0
        }
2298
0
    }
2299
}
2300
2301
impl<T: Clone, A: Allocator> Vec<T, A> {
2302
    /// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
2303
    ///
2304
    /// If `new_len` is greater than `len`, the `Vec` is extended by the
2305
    /// difference, with each additional slot filled with `value`.
2306
    /// If `new_len` is less than `len`, the `Vec` is simply truncated.
2307
    ///
2308
    /// This method requires `T` to implement [`Clone`],
2309
    /// in order to be able to clone the passed value.
2310
    /// If you need more flexibility (or want to rely on [`Default`] instead of
2311
    /// [`Clone`]), use [`Vec::resize_with`].
2312
    /// If you only need to resize to a smaller size, use [`Vec::truncate`].
2313
    ///
2314
    /// # Examples
2315
    ///
2316
    /// ```
2317
    /// let mut vec = vec!["hello"];
2318
    /// vec.resize(3, "world");
2319
    /// assert_eq!(vec, ["hello", "world", "world"]);
2320
    ///
2321
    /// let mut vec = vec![1, 2, 3, 4];
2322
    /// vec.resize(2, 0);
2323
    /// assert_eq!(vec, [1, 2]);
2324
    /// ```
2325
    #[cfg(not(no_global_oom_handling))]
2326
    #[inline(always)]
2327
0
    pub fn resize(&mut self, new_len: usize, value: T) {
2328
0
        let len = self.len();
2329
0
2330
0
        if new_len > len {
2331
0
            self.extend_with(new_len - len, ExtendElement(value))
2332
0
        } else {
2333
0
            self.truncate(new_len);
2334
0
        }
2335
0
    }
2336
2337
    /// Clones and appends all elements in a slice to the `Vec`.
2338
    ///
2339
    /// Iterates over the slice `other`, clones each element, and then appends
2340
    /// it to this `Vec`. The `other` slice is traversed in-order.
2341
    ///
2342
    /// Note that this function is same as [`extend`] except that it is
2343
    /// specialized to work with slices instead. If and when Rust gets
2344
    /// specialization this function will likely be deprecated (but still
2345
    /// available).
2346
    ///
2347
    /// # Examples
2348
    ///
2349
    /// ```
2350
    /// let mut vec = vec![1];
2351
    /// vec.extend_from_slice(&[2, 3, 4]);
2352
    /// assert_eq!(vec, [1, 2, 3, 4]);
2353
    /// ```
2354
    ///
2355
    /// [`extend`]: Vec::extend
2356
    #[cfg(not(no_global_oom_handling))]
2357
    #[inline(always)]
2358
0
    pub fn extend_from_slice(&mut self, other: &[T]) {
2359
0
        self.extend(other.iter().cloned())
2360
0
    }
2361
2362
    /// Copies elements from `src` range to the end of the vector.
2363
    ///
2364
    /// # Panics
2365
    ///
2366
    /// Panics if the starting point is greater than the end point or if
2367
    /// the end point is greater than the length of the vector.
2368
    ///
2369
    /// # Examples
2370
    ///
2371
    /// ```
2372
    /// let mut vec = vec![0, 1, 2, 3, 4];
2373
    ///
2374
    /// vec.extend_from_within(2..);
2375
    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
2376
    ///
2377
    /// vec.extend_from_within(..2);
2378
    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
2379
    ///
2380
    /// vec.extend_from_within(4..8);
2381
    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
2382
    /// ```
2383
    #[cfg(not(no_global_oom_handling))]
2384
    #[inline(always)]
2385
0
    pub fn extend_from_within<R>(&mut self, src: R)
2386
0
    where
2387
0
        R: RangeBounds<usize>,
2388
0
    {
2389
0
        // let range = slice::range(src, ..self.len());
2390
0
2391
0
        let _ = &self.as_slice()[(src.start_bound().cloned(), src.end_bound().cloned())];
2392
0
2393
0
        let len = self.len();
2394
0
2395
0
        let start: ops::Bound<&usize> = src.start_bound();
2396
0
        let start = match start {
2397
0
            ops::Bound::Included(&start) => start,
2398
0
            ops::Bound::Excluded(start) => start + 1,
2399
0
            ops::Bound::Unbounded => 0,
2400
        };
2401
2402
0
        let end: ops::Bound<&usize> = src.end_bound();
2403
0
        let end = match end {
2404
0
            ops::Bound::Included(end) => end + 1,
2405
0
            ops::Bound::Excluded(&end) => end,
2406
0
            ops::Bound::Unbounded => len,
2407
        };
2408
2409
0
        let range = start..end;
2410
0
2411
0
        self.reserve(range.len());
2412
0
2413
0
        // SAFETY:
2414
0
        // - len is increased only after initializing elements
2415
0
        let (this, spare, len) = unsafe { self.split_at_spare_mut_with_len() };
2416
0
2417
0
        // SAFETY:
2418
0
        // - caller guarantees that src is a valid index
2419
0
        let to_clone = unsafe { this.get_unchecked(range) };
2420
0
2421
0
        iter::zip(to_clone, spare)
2422
0
            .map(|(src, dst)| dst.write(src.clone()))
2423
0
            // Note:
2424
0
            // - Element was just initialized with `MaybeUninit::write`, so it's ok to increase len
2425
0
            // - len is increased after each element to prevent leaks (see issue #82533)
2426
0
            .for_each(|_| *len += 1);
2427
0
    }
2428
}
2429
2430
impl<T, A: Allocator, const N: usize> Vec<[T; N], A> {
2431
    /// Takes a `Vec<[T; N]>` and flattens it into a `Vec<T>`.
2432
    ///
2433
    /// # Panics
2434
    ///
2435
    /// Panics if the length of the resulting vector would overflow a `usize`.
2436
    ///
2437
    /// This is only possible when flattening a vector of arrays of zero-sized
2438
    /// types, and thus tends to be irrelevant in practice. If
2439
    /// `size_of::<T>() > 0`, this will never panic.
2440
    ///
2441
    /// # Examples
2442
    ///
2443
    /// ```
2444
    /// #![feature(slice_flatten)]
2445
    ///
2446
    /// let mut vec = vec![[1, 2, 3], [4, 5, 6], [7, 8, 9]];
2447
    /// assert_eq!(vec.pop(), Some([7, 8, 9]));
2448
    ///
2449
    /// let mut flattened = vec.into_flattened();
2450
    /// assert_eq!(flattened.pop(), Some(6));
2451
    /// ```
2452
    #[inline(always)]
2453
0
    pub fn into_flattened(self) -> Vec<T, A> {
2454
0
        let (ptr, len, cap, alloc) = self.into_raw_parts_with_alloc();
2455
0
        let (new_len, new_cap) = if size_of::<T>() == 0 {
2456
0
            (len.checked_mul(N).expect("vec len overflow"), usize::MAX)
2457
        } else {
2458
            // SAFETY:
2459
            // - `cap * N` cannot overflow because the allocation is already in
2460
            // the address space.
2461
            // - Each `[T; N]` has `N` valid elements, so there are `len * N`
2462
            // valid elements in the allocation.
2463
0
            (len * N, cap * N)
2464
        };
2465
        // SAFETY:
2466
        // - `ptr` was allocated by `self`
2467
        // - `ptr` is well-aligned because `[T; N]` has the same alignment as `T`.
2468
        // - `new_cap` refers to the same sized allocation as `cap` because
2469
        // `new_cap * size_of::<T>()` == `cap * size_of::<[T; N]>()`
2470
        // - `len` <= `cap`, so `len * N` <= `cap * N`.
2471
0
        unsafe { Vec::<T, A>::from_raw_parts_in(ptr.cast(), new_len, new_cap, alloc) }
2472
0
    }
2473
}
2474
2475
// This code generalizes `extend_with_{element,default}`.
2476
trait ExtendWith<T> {
2477
    fn next(&mut self) -> T;
2478
    fn last(self) -> T;
2479
}
2480
2481
struct ExtendElement<T>(T);
2482
impl<T: Clone> ExtendWith<T> for ExtendElement<T> {
2483
    #[inline(always)]
2484
0
    fn next(&mut self) -> T {
2485
0
        self.0.clone()
2486
0
    }
2487
2488
    #[inline(always)]
2489
0
    fn last(self) -> T {
2490
0
        self.0
2491
0
    }
2492
}
2493
2494
impl<T, A: Allocator> Vec<T, A> {
2495
    #[cfg(not(no_global_oom_handling))]
2496
    #[inline(always)]
2497
    /// Extend the vector by `n` values, using the given generator.
2498
0
    fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, mut value: E) {
2499
0
        self.reserve(n);
2500
0
2501
0
        unsafe {
2502
0
            let mut ptr = self.as_mut_ptr().add(self.len());
2503
0
            // Use SetLenOnDrop to work around bug where compiler
2504
0
            // might not realize the store through `ptr` through self.set_len()
2505
0
            // don't alias.
2506
0
            let mut local_len = SetLenOnDrop::new(&mut self.len);
2507
0
2508
0
            // Write all elements except the last one
2509
0
            for _ in 1..n {
2510
0
                ptr::write(ptr, value.next());
2511
0
                ptr = ptr.add(1);
2512
0
                // Increment the length in every step in case next() panics
2513
0
                local_len.increment_len(1);
2514
0
            }
2515
2516
0
            if n > 0 {
2517
0
                // We can write the last element directly without cloning needlessly
2518
0
                ptr::write(ptr, value.last());
2519
0
                local_len.increment_len(1);
2520
0
            }
2521
2522
            // len set by scope guard
2523
        }
2524
0
    }
2525
}
2526
2527
impl<T: PartialEq, A: Allocator> Vec<T, A> {
2528
    /// Removes consecutive repeated elements in the vector according to the
2529
    /// [`PartialEq`] trait implementation.
2530
    ///
2531
    /// If the vector is sorted, this removes all duplicates.
2532
    ///
2533
    /// # Examples
2534
    ///
2535
    /// ```
2536
    /// let mut vec = vec![1, 2, 2, 3, 2];
2537
    ///
2538
    /// vec.dedup();
2539
    ///
2540
    /// assert_eq!(vec, [1, 2, 3, 2]);
2541
    /// ```
2542
    #[inline(always)]
2543
0
    pub fn dedup(&mut self) {
2544
0
        self.dedup_by(|a, b| a == b)
2545
0
    }
2546
}
2547
2548
trait ExtendFromWithinSpec {
2549
    /// # Safety
2550
    ///
2551
    /// - `src` needs to be valid index
2552
    /// - `self.capacity() - self.len()` must be `>= src.len()`
2553
    unsafe fn spec_extend_from_within(&mut self, src: Range<usize>);
2554
}
2555
2556
// impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
2557
//     default unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
2558
//         // SAFETY:
2559
//         // - len is increased only after initializing elements
2560
//         let (this, spare, len) = unsafe { self.split_at_spare_mut_with_len() };
2561
2562
//         // SAFETY:
2563
//         // - caller guarantees that src is a valid index
2564
//         let to_clone = unsafe { this.get_unchecked(src) };
2565
2566
//         iter::zip(to_clone, spare)
2567
//             .map(|(src, dst)| dst.write(src.clone()))
2568
//             // Note:
2569
//             // - Element was just initialized with `MaybeUninit::write`, so it's ok to increase len
2570
//             // - len is increased after each element to prevent leaks (see issue #82533)
2571
//             .for_each(|_| *len += 1);
2572
//     }
2573
// }
2574
2575
impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
2576
    #[inline(always)]
2577
0
    unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
2578
0
        let count = src.len();
2579
0
        {
2580
0
            let (init, spare) = self.split_at_spare_mut();
2581
0
2582
0
            // SAFETY:
2583
0
            // - caller guarantees that `src` is a valid index
2584
0
            let source = unsafe { init.get_unchecked(src) };
2585
0
2586
0
            // SAFETY:
2587
0
            // - Both pointers are created from unique slice references (`&mut [_]`)
2588
0
            //   so they are valid and do not overlap.
2589
0
            // - Elements are :Copy so it's OK to copy them, without doing
2590
0
            //   anything with the original values
2591
0
            // - `count` is equal to the len of `source`, so source is valid for
2592
0
            //   `count` reads
2593
0
            // - `.reserve(count)` guarantees that `spare.len() >= count` so spare
2594
0
            //   is valid for `count` writes
2595
0
            unsafe { ptr::copy_nonoverlapping(source.as_ptr(), spare.as_mut_ptr() as _, count) };
2596
0
        }
2597
0
2598
0
        // SAFETY:
2599
0
        // - The elements were just initialized by `copy_nonoverlapping`
2600
0
        self.len += count;
2601
0
    }
2602
}
2603
2604
////////////////////////////////////////////////////////////////////////////////
2605
// Common trait implementations for Vec
2606
////////////////////////////////////////////////////////////////////////////////
2607
2608
impl<T, A: Allocator> ops::Deref for Vec<T, A> {
2609
    type Target = [T];
2610
2611
    #[inline(always)]
2612
0
    fn deref(&self) -> &[T] {
2613
0
        unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
2614
0
    }
2615
}
2616
2617
impl<T, A: Allocator> ops::DerefMut for Vec<T, A> {
2618
    #[inline(always)]
2619
0
    fn deref_mut(&mut self) -> &mut [T] {
2620
0
        unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
2621
0
    }
2622
}
2623
2624
#[cfg(not(no_global_oom_handling))]
2625
impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {
2626
    #[inline(always)]
2627
0
    fn clone(&self) -> Self {
2628
0
        let alloc = self.allocator().clone();
2629
0
        let mut vec = Vec::with_capacity_in(self.len(), alloc);
2630
0
        vec.extend_from_slice(self);
2631
0
        vec
2632
0
    }
2633
2634
    #[inline(always)]
2635
0
    fn clone_from(&mut self, other: &Self) {
2636
0
        // drop anything that will not be overwritten
2637
0
        self.truncate(other.len());
2638
0
2639
0
        // self.len <= other.len due to the truncate above, so the
2640
0
        // slices here are always in-bounds.
2641
0
        let (init, tail) = other.split_at(self.len());
2642
0
2643
0
        // reuse the contained values' allocations/resources.
2644
0
        self.clone_from_slice(init);
2645
0
        self.extend_from_slice(tail);
2646
0
    }
2647
}
2648
2649
/// The hash of a vector is the same as that of the corresponding slice,
2650
/// as required by the `core::borrow::Borrow` implementation.
2651
///
2652
/// ```
2653
/// #![feature(build_hasher_simple_hash_one)]
2654
/// use std::hash::BuildHasher;
2655
///
2656
/// let b = std::collections::hash_map::RandomState::new();
2657
/// let v: Vec<u8> = vec![0xa8, 0x3c, 0x09];
2658
/// let s: &[u8] = &[0xa8, 0x3c, 0x09];
2659
/// assert_eq!(b.hash_one(v), b.hash_one(s));
2660
/// ```
2661
impl<T: Hash, A: Allocator> Hash for Vec<T, A> {
2662
    #[inline(always)]
2663
0
    fn hash<H: Hasher>(&self, state: &mut H) {
2664
0
        Hash::hash(&**self, state)
2665
0
    }
2666
}
2667
2668
impl<T, I: SliceIndex<[T]>, A: Allocator> Index<I> for Vec<T, A> {
2669
    type Output = I::Output;
2670
2671
    #[inline(always)]
2672
0
    fn index(&self, index: I) -> &Self::Output {
2673
0
        Index::index(&**self, index)
2674
0
    }
2675
}
2676
2677
impl<T, I: SliceIndex<[T]>, A: Allocator> IndexMut<I> for Vec<T, A> {
2678
    #[inline(always)]
2679
0
    fn index_mut(&mut self, index: I) -> &mut Self::Output {
2680
0
        IndexMut::index_mut(&mut **self, index)
2681
0
    }
2682
}
2683
2684
#[cfg(not(no_global_oom_handling))]
2685
impl<T> FromIterator<T> for Vec<T> {
2686
    #[inline(always)]
2687
0
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Vec<T> {
2688
0
        let mut vec = Vec::new();
2689
0
        vec.extend(iter);
2690
0
        vec
2691
0
    }
2692
}
2693
2694
impl<T, A: Allocator> IntoIterator for Vec<T, A> {
2695
    type Item = T;
2696
    type IntoIter = IntoIter<T, A>;
2697
2698
    /// Creates a consuming iterator, that is, one that moves each value out of
2699
    /// the vector (from start to end). The vector cannot be used after calling
2700
    /// this.
2701
    ///
2702
    /// # Examples
2703
    ///
2704
    /// ```
2705
    /// let v = vec!["a".to_string(), "b".to_string()];
2706
    /// let mut v_iter = v.into_iter();
2707
    ///
2708
    /// let first_element: Option<String> = v_iter.next();
2709
    ///
2710
    /// assert_eq!(first_element, Some("a".to_string()));
2711
    /// assert_eq!(v_iter.next(), Some("b".to_string()));
2712
    /// assert_eq!(v_iter.next(), None);
2713
    /// ```
2714
    #[inline(always)]
2715
0
    fn into_iter(self) -> Self::IntoIter {
2716
0
        unsafe {
2717
0
            let mut me = ManuallyDrop::new(self);
2718
0
            let alloc = ManuallyDrop::new(ptr::read(me.allocator()));
2719
0
            let begin = me.as_mut_ptr();
2720
0
            let end = if size_of::<T>() == 0 {
2721
0
                begin.cast::<u8>().wrapping_add(me.len()).cast()
2722
0
            } else {
2723
0
                begin.add(me.len()) as *const T
2724
            };
2725
0
            let cap = me.buf.capacity();
2726
0
            IntoIter {
2727
0
                buf: NonNull::new_unchecked(begin),
2728
0
                phantom: PhantomData,
2729
0
                cap,
2730
0
                alloc,
2731
0
                ptr: begin,
2732
0
                end,
2733
0
            }
2734
0
        }
2735
0
    }
2736
}
2737
2738
impl<'a, T, A: Allocator> IntoIterator for &'a Vec<T, A> {
2739
    type Item = &'a T;
2740
    type IntoIter = slice::Iter<'a, T>;
2741
2742
    #[inline(always)]
2743
0
    fn into_iter(self) -> Self::IntoIter {
2744
0
        self.iter()
2745
0
    }
2746
}
2747
2748
impl<'a, T, A: Allocator> IntoIterator for &'a mut Vec<T, A> {
2749
    type Item = &'a mut T;
2750
    type IntoIter = slice::IterMut<'a, T>;
2751
2752
0
    fn into_iter(self) -> Self::IntoIter {
2753
0
        self.iter_mut()
2754
0
    }
2755
}
2756
2757
#[cfg(not(no_global_oom_handling))]
2758
impl<T, A: Allocator> Extend<T> for Vec<T, A> {
2759
    #[inline(always)]
2760
    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
2761
        // This is the case for a general iter.
2762
        //
2763
        // This function should be the moral equivalent of:
2764
        //
2765
        //      for item in iter {
2766
        //          self.push(item);
2767
        //      }
2768
2769
        let mut iter = iter.into_iter();
2770
        while let Some(element) = iter.next() {
2771
            let len = self.len();
2772
            if len == self.capacity() {
2773
                let (lower, _) = iter.size_hint();
2774
                self.reserve(lower.saturating_add(1));
2775
            }
2776
            unsafe {
2777
                ptr::write(self.as_mut_ptr().add(len), element);
2778
                // Since next() executes user code which can panic we have to bump the length
2779
                // after each step.
2780
                // NB can't overflow since we would have had to alloc the address space
2781
                self.set_len(len + 1);
2782
            }
2783
        }
2784
    }
2785
}
2786
2787
impl<T, A: Allocator> Vec<T, A> {
2788
    /// Creates a splicing iterator that replaces the specified range in the vector
2789
    /// with the given `replace_with` iterator and yields the removed items.
2790
    /// `replace_with` does not need to be the same length as `range`.
2791
    ///
2792
    /// `range` is removed even if the iterator is not consumed until the end.
2793
    ///
2794
    /// It is unspecified how many elements are removed from the vector
2795
    /// if the `Splice` value is leaked.
2796
    ///
2797
    /// The input iterator `replace_with` is only consumed when the `Splice` value is dropped.
2798
    ///
2799
    /// This is optimal if:
2800
    ///
2801
    /// * The tail (elements in the vector after `range`) is empty,
2802
    /// * or `replace_with` yields fewer or equal elements than `range`’s length
2803
    /// * or the lower bound of its `size_hint()` is exact.
2804
    ///
2805
    /// Otherwise, a temporary vector is allocated and the tail is moved twice.
2806
    ///
2807
    /// # Panics
2808
    ///
2809
    /// Panics if the starting point is greater than the end point or if
2810
    /// the end point is greater than the length of the vector.
2811
    ///
2812
    /// # Examples
2813
    ///
2814
    /// ```
2815
    /// let mut v = vec![1, 2, 3, 4];
2816
    /// let new = [7, 8, 9];
2817
    /// let u: Vec<_> = v.splice(1..3, new).collect();
2818
    /// assert_eq!(v, &[1, 7, 8, 9, 4]);
2819
    /// assert_eq!(u, &[2, 3]);
2820
    /// ```
2821
    #[cfg(not(no_global_oom_handling))]
2822
    #[inline(always)]
2823
0
    pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter, A>
2824
0
    where
2825
0
        R: RangeBounds<usize>,
2826
0
        I: IntoIterator<Item = T>,
2827
0
    {
2828
0
        Splice {
2829
0
            drain: self.drain(range),
2830
0
            replace_with: replace_with.into_iter(),
2831
0
        }
2832
0
    }
2833
}
2834
2835
/// Extend implementation that copies elements out of references before pushing them onto the Vec.
2836
///
2837
/// This implementation is specialized for slice iterators, where it uses [`copy_from_slice`] to
2838
/// append the entire slice at once.
2839
///
2840
/// [`copy_from_slice`]: slice::copy_from_slice
2841
#[cfg(not(no_global_oom_handling))]
2842
impl<'a, T: Copy + 'a, A: Allocator + 'a> Extend<&'a T> for Vec<T, A> {
2843
    #[inline(always)]
2844
0
    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
2845
0
        let mut iter = iter.into_iter();
2846
0
        while let Some(element) = iter.next() {
2847
0
            let len = self.len();
2848
0
            if len == self.capacity() {
2849
0
                let (lower, _) = iter.size_hint();
2850
0
                self.reserve(lower.saturating_add(1));
2851
0
            }
2852
0
            unsafe {
2853
0
                ptr::write(self.as_mut_ptr().add(len), *element);
2854
0
                // Since next() executes user code which can panic we have to bump the length
2855
0
                // after each step.
2856
0
                // NB can't overflow since we would have had to alloc the address space
2857
0
                self.set_len(len + 1);
2858
0
            }
2859
        }
2860
0
    }
2861
}
2862
2863
/// Implements comparison of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison).
2864
impl<T: PartialOrd, A: Allocator> PartialOrd for Vec<T, A> {
2865
    #[inline(always)]
2866
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
2867
0
        PartialOrd::partial_cmp(&**self, &**other)
2868
0
    }
2869
}
2870
2871
impl<T: Eq, A: Allocator> Eq for Vec<T, A> {}
2872
2873
/// Implements ordering of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison).
2874
impl<T: Ord, A: Allocator> Ord for Vec<T, A> {
2875
    #[inline(always)]
2876
0
    fn cmp(&self, other: &Self) -> Ordering {
2877
0
        Ord::cmp(&**self, &**other)
2878
0
    }
2879
}
2880
2881
impl<T, A: Allocator> Drop for Vec<T, A> {
2882
    #[inline(always)]
2883
0
    fn drop(&mut self) {
2884
0
        unsafe {
2885
0
            // use drop for [T]
2886
0
            // use a raw slice to refer to the elements of the vector as weakest necessary type;
2887
0
            // could avoid questions of validity in certain cases
2888
0
            ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len))
2889
0
        }
2890
0
        // RawVec handles deallocation
2891
0
    }
2892
}
2893
2894
impl<T> Default for Vec<T> {
2895
    /// Creates an empty `Vec<T>`.
2896
    ///
2897
    /// The vector will not allocate until elements are pushed onto it.
2898
    #[inline(always)]
2899
0
    fn default() -> Vec<T> {
2900
0
        Vec::new()
2901
0
    }
2902
}
2903
2904
impl<T: fmt::Debug, A: Allocator> fmt::Debug for Vec<T, A> {
2905
    #[inline(always)]
2906
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2907
0
        fmt::Debug::fmt(&**self, f)
2908
0
    }
2909
}
2910
2911
impl<T, A: Allocator> AsRef<Vec<T, A>> for Vec<T, A> {
2912
    #[inline(always)]
2913
0
    fn as_ref(&self) -> &Vec<T, A> {
2914
0
        self
2915
0
    }
2916
}
2917
2918
impl<T, A: Allocator> AsMut<Vec<T, A>> for Vec<T, A> {
2919
    #[inline(always)]
2920
0
    fn as_mut(&mut self) -> &mut Vec<T, A> {
2921
0
        self
2922
0
    }
2923
}
2924
2925
impl<T, A: Allocator> AsRef<[T]> for Vec<T, A> {
2926
    #[inline(always)]
2927
0
    fn as_ref(&self) -> &[T] {
2928
0
        self
2929
0
    }
2930
}
2931
2932
impl<T, A: Allocator> AsMut<[T]> for Vec<T, A> {
2933
    #[inline(always)]
2934
0
    fn as_mut(&mut self) -> &mut [T] {
2935
0
        self
2936
0
    }
2937
}
2938
2939
#[cfg(not(no_global_oom_handling))]
2940
impl<T: Clone> From<&[T]> for Vec<T> {
2941
    /// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
2942
    ///
2943
    /// # Examples
2944
    ///
2945
    /// ```
2946
    /// assert_eq!(Vec::from(&[1, 2, 3][..]), vec![1, 2, 3]);
2947
    /// ```
2948
    #[inline(always)]
2949
    fn from(s: &[T]) -> Vec<T> {
2950
        let mut vec = Vec::with_capacity(s.len());
2951
        vec.extend_from_slice(s);
2952
        vec
2953
    }
2954
}
2955
2956
#[cfg(not(no_global_oom_handling))]
2957
impl<T: Clone> From<&mut [T]> for Vec<T> {
2958
    /// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
2959
    ///
2960
    /// # Examples
2961
    ///
2962
    /// ```
2963
    /// assert_eq!(Vec::from(&mut [1, 2, 3][..]), vec![1, 2, 3]);
2964
    /// ```
2965
    #[inline(always)]
2966
0
    fn from(s: &mut [T]) -> Vec<T> {
2967
0
        let mut vec = Vec::with_capacity(s.len());
2968
0
        vec.extend_from_slice(s);
2969
0
        vec
2970
0
    }
2971
}
2972
2973
#[cfg(not(no_global_oom_handling))]
2974
impl<T, const N: usize> From<[T; N]> for Vec<T> {
2975
    #[inline(always)]
2976
0
    fn from(s: [T; N]) -> Vec<T> {
2977
0
        Box::slice(Box::new(s)).into_vec()
2978
0
    }
2979
}
2980
2981
impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A> {
2982
    /// Convert a boxed slice into a vector by transferring ownership of
2983
    /// the existing heap allocation.
2984
    ///
2985
    /// # Examples
2986
    ///
2987
    /// ```
2988
    /// let b: Box<[i32]> = vec![1, 2, 3].into_boxed_slice();
2989
    /// assert_eq!(Vec::from(b), vec![1, 2, 3]);
2990
    /// ```
2991
    #[inline(always)]
2992
0
    fn from(s: Box<[T], A>) -> Self {
2993
0
        s.into_vec()
2994
0
    }
2995
}
2996
2997
impl<T, A: Allocator, const N: usize> From<Box<[T; N], A>> for Vec<T, A> {
2998
    /// Convert a boxed array into a vector by transferring ownership of
2999
    /// the existing heap allocation.
3000
    ///
3001
    /// # Examples
3002
    ///
3003
    /// ```
3004
    /// let b: Box<[i32; 3]> = Box::new([1, 2, 3]);
3005
    /// assert_eq!(Vec::from(b), vec![1, 2, 3]);
3006
    /// ```
3007
    #[inline(always)]
3008
0
    fn from(s: Box<[T; N], A>) -> Self {
3009
0
        s.into_vec()
3010
0
    }
3011
}
3012
3013
// note: test pulls in libstd, which causes errors here
3014
#[cfg(not(no_global_oom_handling))]
3015
impl<T, A: Allocator> From<Vec<T, A>> for Box<[T], A> {
3016
    /// Convert a vector into a boxed slice.
3017
    ///
3018
    /// If `v` has excess capacity, its items will be moved into a
3019
    /// newly-allocated buffer with exactly the right capacity.
3020
    ///
3021
    /// # Examples
3022
    ///
3023
    /// ```
3024
    /// assert_eq!(Box::from(vec![1, 2, 3]), vec![1, 2, 3].into_boxed_slice());
3025
    /// ```
3026
    ///
3027
    /// Any excess capacity is removed:
3028
    /// ```
3029
    /// let mut vec = Vec::with_capacity(10);
3030
    /// vec.extend([1, 2, 3]);
3031
    ///
3032
    /// assert_eq!(Box::from(vec), vec![1, 2, 3].into_boxed_slice());
3033
    /// ```
3034
    #[inline(always)]
3035
0
    fn from(v: Vec<T, A>) -> Self {
3036
0
        v.into_boxed_slice()
3037
0
    }
3038
}
3039
3040
#[cfg(not(no_global_oom_handling))]
3041
impl From<&str> for Vec<u8> {
3042
    /// Allocate a `Vec<u8>` and fill it with a UTF-8 string.
3043
    ///
3044
    /// # Examples
3045
    ///
3046
    /// ```
3047
    /// assert_eq!(Vec::from("123"), vec![b'1', b'2', b'3']);
3048
    /// ```
3049
    #[inline(always)]
3050
    fn from(s: &str) -> Vec<u8> {
3051
        From::from(s.as_bytes())
3052
    }
3053
}
3054
3055
impl<T, A: Allocator, const N: usize> TryFrom<Vec<T, A>> for [T; N] {
3056
    type Error = Vec<T, A>;
3057
3058
    /// Gets the entire contents of the `Vec<T>` as an array,
3059
    /// if its size exactly matches that of the requested array.
3060
    ///
3061
    /// # Examples
3062
    ///
3063
    /// ```
3064
    /// assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
3065
    /// assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));
3066
    /// ```
3067
    ///
3068
    /// If the length doesn't match, the input comes back in `Err`:
3069
    /// ```
3070
    /// let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into();
3071
    /// assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
3072
    /// ```
3073
    ///
3074
    /// If you're fine with just getting a prefix of the `Vec<T>`,
3075
    /// you can call [`.truncate(N)`](Vec::truncate) first.
3076
    /// ```
3077
    /// let mut v = String::from("hello world").into_bytes();
3078
    /// v.sort();
3079
    /// v.truncate(2);
3080
    /// let [a, b]: [_; 2] = v.try_into().unwrap();
3081
    /// assert_eq!(a, b' ');
3082
    /// assert_eq!(b, b'd');
3083
    /// ```
3084
    #[inline(always)]
3085
0
    fn try_from(mut vec: Vec<T, A>) -> Result<[T; N], Vec<T, A>> {
3086
0
        if vec.len() != N {
3087
0
            return Err(vec);
3088
0
        }
3089
0
3090
0
        // SAFETY: `.set_len(0)` is always sound.
3091
0
        unsafe { vec.set_len(0) };
3092
0
3093
0
        // SAFETY: A `Vec`'s pointer is always aligned properly, and
3094
0
        // the alignment the array needs is the same as the items.
3095
0
        // We checked earlier that we have sufficient items.
3096
0
        // The items will not double-drop as the `set_len`
3097
0
        // tells the `Vec` not to also drop them.
3098
0
        let array = unsafe { ptr::read(vec.as_ptr() as *const [T; N]) };
3099
0
        Ok(array)
3100
0
    }
3101
}
3102
3103
#[inline(always)]
3104
#[cfg(not(no_global_oom_handling))]
3105
#[doc(hidden)]
3106
0
pub fn from_elem_in<T: Clone, A: Allocator>(elem: T, n: usize, alloc: A) -> Vec<T, A> {
3107
0
    let mut v = Vec::with_capacity_in(n, alloc);
3108
0
    v.extend_with(n, ExtendElement(elem));
3109
0
    v
3110
0
}
3111
3112
#[inline(always)]
3113
#[cfg(not(no_global_oom_handling))]
3114
#[doc(hidden)]
3115
0
pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
3116
0
    let mut v = Vec::with_capacity(n);
3117
0
    v.extend_with(n, ExtendElement(elem));
3118
0
    v
3119
0
}
3120
3121
/// Write is implemented for `Vec<u8>` by appending to the vector.
3122
/// The vector will grow as needed.
3123
#[cfg(feature = "std")]
3124
impl<A: Allocator> io::Write for Vec<u8, A> {
3125
    #[inline]
3126
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
3127
        self.extend_from_slice(buf);
3128
        Ok(buf.len())
3129
    }
3130
3131
    #[inline]
3132
    fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
3133
        let len = bufs.iter().map(|b| b.len()).sum();
3134
        self.reserve(len);
3135
        for buf in bufs {
3136
            self.extend_from_slice(buf);
3137
        }
3138
        Ok(len)
3139
    }
3140
3141
    #[inline]
3142
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
3143
        self.extend_from_slice(buf);
3144
        Ok(())
3145
    }
3146
3147
    #[inline]
3148
    fn flush(&mut self) -> io::Result<()> {
3149
        Ok(())
3150
    }
3151
}
3152
3153
#[cfg(feature = "serde")]
3154
impl<T, A> serde::Serialize for Vec<T, A>
3155
where
3156
    T: serde::Serialize,
3157
    A: Allocator,
3158
{
3159
    #[inline(always)]
3160
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
3161
    where
3162
        S: serde::ser::Serializer,
3163
    {
3164
        serializer.collect_seq(self)
3165
    }
3166
}
3167
3168
#[cfg(feature = "serde")]
3169
impl<'de, T, A> serde::de::Deserialize<'de> for Vec<T, A>
3170
where
3171
    T: serde::de::Deserialize<'de>,
3172
    A: Allocator + Default,
3173
{
3174
    #[inline(always)]
3175
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
3176
    where
3177
        D: serde::de::Deserializer<'de>,
3178
    {
3179
        struct VecVisitor<T, A> {
3180
            marker: PhantomData<(T, A)>,
3181
        }
3182
3183
        impl<'de, T, A> serde::de::Visitor<'de> for VecVisitor<T, A>
3184
        where
3185
            T: serde::de::Deserialize<'de>,
3186
            A: Allocator + Default,
3187
        {
3188
            type Value = Vec<T, A>;
3189
3190
            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
3191
                formatter.write_str("a sequence")
3192
            }
3193
3194
            fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
3195
            where
3196
                S: serde::de::SeqAccess<'de>,
3197
            {
3198
                let mut values = Vec::with_capacity_in(cautious(seq.size_hint()), A::default());
3199
3200
                while let Some(value) = seq.next_element()? {
3201
                    values.push(value);
3202
                }
3203
3204
                Ok(values)
3205
            }
3206
        }
3207
3208
        let visitor = VecVisitor {
3209
            marker: PhantomData,
3210
        };
3211
        deserializer.deserialize_seq(visitor)
3212
    }
3213
3214
    #[inline(always)]
3215
    fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
3216
    where
3217
        D: serde::de::Deserializer<'de>,
3218
    {
3219
        struct VecInPlaceVisitor<'a, T: 'a, A: Allocator + 'a>(&'a mut Vec<T, A>);
3220
3221
        impl<'a, 'de, T, A> serde::de::Visitor<'de> for VecInPlaceVisitor<'a, T, A>
3222
        where
3223
            T: serde::de::Deserialize<'de>,
3224
            A: Allocator + Default,
3225
        {
3226
            type Value = ();
3227
3228
            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
3229
                formatter.write_str("a sequence")
3230
            }
3231
3232
            fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
3233
            where
3234
                S: serde::de::SeqAccess<'de>,
3235
            {
3236
                let hint = cautious(seq.size_hint());
3237
                if let Some(additional) = hint.checked_sub(self.0.len()) {
3238
                    self.0.reserve(additional);
3239
                }
3240
3241
                for i in 0..self.0.len() {
3242
                    let next = {
3243
                        let next_place = InPlaceSeed(&mut self.0[i]);
3244
                        seq.next_element_seed(next_place)?
3245
                    };
3246
                    if next.is_none() {
3247
                        self.0.truncate(i);
3248
                        return Ok(());
3249
                    }
3250
                }
3251
3252
                while let Some(value) = seq.next_element()? {
3253
                    self.0.push(value);
3254
                }
3255
3256
                Ok(())
3257
            }
3258
        }
3259
3260
        deserializer.deserialize_seq(VecInPlaceVisitor(place))
3261
    }
3262
}
3263
3264
#[cfg(feature = "serde")]
3265
pub fn cautious(hint: Option<usize>) -> usize {
3266
    cmp::min(hint.unwrap_or(0), 4096)
3267
}
3268
3269
/// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
3270
///
3271
/// Wraps a mutable reference and calls deserialize_in_place on it.
3272
3273
#[cfg(feature = "serde")]
3274
pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T);
3275
3276
#[cfg(feature = "serde")]
3277
impl<'a, 'de, T> serde::de::DeserializeSeed<'de> for InPlaceSeed<'a, T>
3278
where
3279
    T: serde::de::Deserialize<'de>,
3280
{
3281
    type Value = ();
3282
    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
3283
    where
3284
        D: serde::de::Deserializer<'de>,
3285
    {
3286
        T::deserialize_in_place(deserializer, self.0)
3287
    }
3288
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/allocator-api2-0.2.18/src/stable/vec/partial_eq.rs
Line
Count
Source
1
#[cfg(not(no_global_oom_handling))]
2
use alloc_crate::borrow::Cow;
3
4
use crate::stable::alloc::Allocator;
5
6
use super::Vec;
7
8
macro_rules! __impl_slice_eq1 {
9
    ([$($vars:tt)*] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?) => {
10
        impl<T, U, $($vars)*> PartialEq<$rhs> for $lhs
11
        where
12
            T: PartialEq<U>,
13
            $($ty: $bound)?
14
        {
15
            #[inline(always)]
16
0
            fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] }
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eq0ppppEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqIB19_ppEE2eqBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs_0pppEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqRSpE2eqBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs0_0pppEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqQSpE2eqBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs1_0pppERSpINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqINtB7_3VecppEE2eqBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs2_0pppEQSpINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqINtB7_3VecppEE2eqBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs3_0pppEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqSpE2eqBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs4_0pppESpINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqINtB7_3VecppEE2eqBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs5_0pppEINtNtCsiBl6Lc3cFal_5alloc6borrow3CowSpEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqINtB7_3VecppEE2eqBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs6_0pppKpEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqAppE2eqBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs7_0pppKpEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqRAppE2eqBb_
17
            #[inline(always)]
18
0
            fn ne(&self, other: &$rhs) -> bool { self[..] != other[..] }
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eq0ppppEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqIB19_ppEE2neBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs_0pppEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqRSpE2neBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs0_0pppEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqQSpE2neBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs1_0pppERSpINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqINtB7_3VecppEE2neBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs2_0pppEQSpINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqINtB7_3VecppEE2neBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs3_0pppEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqSpE2neBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs4_0pppESpINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqINtB7_3VecppEE2neBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs5_0pppEINtNtCsiBl6Lc3cFal_5alloc6borrow3CowSpEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqINtB7_3VecppEE2neBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs6_0pppKpEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqAppE2neBb_
Unexecuted instantiation: _RNvXININtNtNtCsby83UglaBWc_14allocator_api26stable3vec10partial_eqs7_0pppKpEINtB7_3VecppEINtNtCsbQ8arDwx5Xq_4core3cmp9PartialEqRAppE2neBb_
19
        }
20
    }
21
}
22
23
__impl_slice_eq1! { [A1: Allocator, A2: Allocator] Vec<T, A1>, Vec<U, A2> }
24
__impl_slice_eq1! { [A: Allocator] Vec<T, A>, &[U] }
25
__impl_slice_eq1! { [A: Allocator] Vec<T, A>, &mut [U] }
26
__impl_slice_eq1! { [A: Allocator] &[T], Vec<U, A> }
27
__impl_slice_eq1! { [A: Allocator] &mut [T], Vec<U, A> }
28
__impl_slice_eq1! { [A: Allocator] Vec<T, A>, [U]  }
29
__impl_slice_eq1! { [A: Allocator] [T], Vec<U, A>  }
30
#[cfg(not(no_global_oom_handling))]
31
__impl_slice_eq1! { [A: Allocator] Cow<'_, [T]>, Vec<U, A> where T: Clone }
32
__impl_slice_eq1! { [A: Allocator, const N: usize] Vec<T, A>, [U; N] }
33
__impl_slice_eq1! { [A: Allocator, const N: usize] Vec<T, A>, &[U; N] }
34
35
// NOTE: some less important impls are omitted to reduce code bloat
36
// FIXME(Centril): Reconsider this?
37
//__impl_slice_eq1! { [const N: usize] Vec<A>, &mut [B; N], }
38
//__impl_slice_eq1! { [const N: usize] [A; N], Vec<B>, }
39
//__impl_slice_eq1! { [const N: usize] &[A; N], Vec<B>, }
40
//__impl_slice_eq1! { [const N: usize] &mut [A; N], Vec<B>, }
41
//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, [B; N], }
42
//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &[B; N], }
43
//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &mut [B; N], }
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/allocator-api2-0.2.18/src/stable/vec/splice.rs
Line
Count
Source
1
use core::ptr::{self};
2
use core::slice::{self};
3
4
use crate::stable::alloc::{Allocator, Global};
5
6
use super::{Drain, Vec};
7
8
/// A splicing iterator for `Vec`.
9
///
10
/// This struct is created by [`Vec::splice()`].
11
/// See its documentation for more.
12
///
13
/// # Example
14
///
15
/// ```
16
/// let mut v = vec![0, 1, 2];
17
/// let new = [7, 8];
18
/// let iter: std::vec::Splice<_> = v.splice(1.., new);
19
/// ```
20
#[derive(Debug)]
21
pub struct Splice<'a, I: Iterator + 'a, A: Allocator + 'a = Global> {
22
    pub(super) drain: Drain<'a, I::Item, A>,
23
    pub(super) replace_with: I,
24
}
25
26
impl<I: Iterator, A: Allocator> Iterator for Splice<'_, I, A> {
27
    type Item = I::Item;
28
29
    #[inline(always)]
30
0
    fn next(&mut self) -> Option<Self::Item> {
31
0
        self.drain.next()
32
0
    }
33
34
    #[inline(always)]
35
0
    fn size_hint(&self) -> (usize, Option<usize>) {
36
0
        self.drain.size_hint()
37
0
    }
38
}
39
40
impl<I: Iterator, A: Allocator> DoubleEndedIterator for Splice<'_, I, A> {
41
    #[inline(always)]
42
0
    fn next_back(&mut self) -> Option<Self::Item> {
43
0
        self.drain.next_back()
44
0
    }
45
}
46
47
impl<I: Iterator, A: Allocator> ExactSizeIterator for Splice<'_, I, A> {}
48
49
impl<I: Iterator, A: Allocator> Drop for Splice<'_, I, A> {
50
    #[inline]
51
0
    fn drop(&mut self) {
52
0
        self.drain.by_ref().for_each(drop);
53
0
54
0
        unsafe {
55
0
            if self.drain.tail_len == 0 {
56
0
                self.drain.vec.as_mut().extend(self.replace_with.by_ref());
57
0
                return;
58
0
            }
59
0
60
0
            // First fill the range left by drain().
61
0
            if !self.drain.fill(&mut self.replace_with) {
62
0
                return;
63
0
            }
64
0
65
0
            // There may be more elements. Use the lower bound as an estimate.
66
0
            // FIXME: Is the upper bound a better guess? Or something else?
67
0
            let (lower_bound, _upper_bound) = self.replace_with.size_hint();
68
0
            if lower_bound > 0 {
69
0
                self.drain.move_tail(lower_bound);
70
0
                if !self.drain.fill(&mut self.replace_with) {
71
0
                    return;
72
0
                }
73
0
            }
74
75
            // Collect any remaining elements.
76
            // This is a zero-length vector which does not allocate if `lower_bound` was exact.
77
0
            let mut collected = self
78
0
                .replace_with
79
0
                .by_ref()
80
0
                .collect::<Vec<I::Item>>()
81
0
                .into_iter();
82
0
            // Now we have an exact count.
83
0
            if collected.len() > 0 {
84
0
                self.drain.move_tail(collected.len());
85
0
                let filled = self.drain.fill(&mut collected);
86
0
                debug_assert!(filled);
87
0
                debug_assert_eq!(collected.len(), 0);
88
0
            }
89
        }
90
        // Let `Drain::drop` move the tail back if necessary and restore `vec.len`.
91
0
    }
92
}
93
94
/// Private helper methods for `Splice::drop`
95
impl<T, A: Allocator> Drain<'_, T, A> {
96
    /// The range from `self.vec.len` to `self.tail_start` contains elements
97
    /// that have been moved out.
98
    /// Fill that range as much as possible with new elements from the `replace_with` iterator.
99
    /// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.)
100
    #[inline(always)]
101
0
    unsafe fn fill<I: Iterator<Item = T>>(&mut self, replace_with: &mut I) -> bool {
102
0
        let vec = unsafe { self.vec.as_mut() };
103
0
        let range_start = vec.len;
104
0
        let range_end = self.tail_start;
105
0
        let range_slice = unsafe {
106
0
            slice::from_raw_parts_mut(vec.as_mut_ptr().add(range_start), range_end - range_start)
107
        };
108
109
0
        for place in range_slice {
110
0
            if let Some(new_item) = replace_with.next() {
111
0
                unsafe { ptr::write(place, new_item) };
112
0
                vec.len += 1;
113
0
            } else {
114
0
                return false;
115
            }
116
        }
117
0
        true
118
0
    }
119
120
    /// Makes room for inserting more elements before the tail.
121
    #[inline(always)]
122
0
    unsafe fn move_tail(&mut self, additional: usize) {
123
0
        let vec = unsafe { self.vec.as_mut() };
124
0
        let len = self.tail_start + self.tail_len;
125
0
        vec.buf.reserve(len, additional);
126
0
127
0
        let new_tail_start = self.tail_start + additional;
128
0
        unsafe {
129
0
            let src = vec.as_ptr().add(self.tail_start);
130
0
            let dst = vec.as_mut_ptr().add(new_tail_start);
131
0
            ptr::copy(src, dst, self.tail_len);
132
0
        }
133
0
        self.tail_start = new_tail_start;
134
0
    }
135
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/arbitrary-1.3.2/src/error.rs
Line
Count
Source
1
use std::{error, fmt};
2
3
/// An enumeration of buffer creation errors
4
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5
#[non_exhaustive]
6
pub enum Error {
7
    /// No choices were provided to the Unstructured::choose call
8
    EmptyChoose,
9
    /// There was not enough underlying data to fulfill some request for raw
10
    /// bytes.
11
    NotEnoughData,
12
    /// The input bytes were not of the right format
13
    IncorrectFormat,
14
}
15
16
impl fmt::Display for Error {
17
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18
0
        match self {
19
0
            Error::EmptyChoose => write!(
20
0
                f,
21
0
                "`arbitrary::Unstructured::choose` must be given a non-empty set of choices"
22
0
            ),
23
0
            Error::NotEnoughData => write!(
24
0
                f,
25
0
                "There is not enough underlying raw data to construct an `Arbitrary` instance"
26
0
            ),
27
0
            Error::IncorrectFormat => write!(
28
0
                f,
29
0
                "The raw data is not of the correct format to construct this type"
30
0
            ),
31
        }
32
0
    }
33
}
34
35
impl error::Error for Error {}
36
37
/// A `Result` with the error type fixed as `arbitrary::Error`.
38
///
39
/// Either an `Ok(T)` or `Err(arbitrary::Error)`.
40
pub type Result<T, E = Error> = std::result::Result<T, E>;
41
42
#[cfg(test)]
43
mod tests {
44
    // Often people will import our custom `Result` type because 99.9% of
45
    // results in a file will be `arbitrary::Result` but then have that one last
46
    // 0.1% that want to have a custom error type. Don't make them prefix that
47
    // 0.1% as `std::result::Result`; instead, let `arbitrary::Result` have an
48
    // overridable error type.
49
    #[test]
50
    fn can_use_custom_error_types_with_result() -> super::Result<(), String> {
51
        Ok(())
52
    }
53
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/arbitrary-1.3.2/src/lib.rs
Line
Count
Source
1
// Copyright © 2019 The Rust Fuzz Project Developers.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
//! The `Arbitrary` trait crate.
10
//!
11
//! This trait provides an [`Arbitrary`](./trait.Arbitrary.html) trait to
12
//! produce well-typed, structured values, from raw, byte buffers. It is
13
//! generally intended to be used with fuzzers like AFL or libFuzzer. See the
14
//! [`Arbitrary`](./trait.Arbitrary.html) trait's documentation for details on
15
//! automatically deriving, implementing, and/or using the trait.
16
17
#![deny(bad_style)]
18
#![deny(missing_docs)]
19
#![deny(future_incompatible)]
20
#![deny(nonstandard_style)]
21
#![deny(rust_2018_compatibility)]
22
#![deny(rust_2018_idioms)]
23
#![deny(unused)]
24
25
#[cfg(feature = "derive_arbitrary")]
26
pub use derive_arbitrary::*;
27
28
mod error;
29
pub use error::*;
30
31
pub mod unstructured;
32
#[doc(inline)]
33
pub use unstructured::Unstructured;
34
35
pub mod size_hint;
36
37
use core::array;
38
use core::cell::{Cell, RefCell, UnsafeCell};
39
use core::iter;
40
use core::mem;
41
use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
42
use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
43
use core::ops::{Range, RangeBounds, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
44
use core::str;
45
use core::time::Duration;
46
use std::borrow::{Cow, ToOwned};
47
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
48
use std::ffi::{CString, OsString};
49
use std::hash::BuildHasher;
50
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
51
use std::ops::Bound;
52
use std::path::PathBuf;
53
use std::rc::Rc;
54
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize};
55
use std::sync::{Arc, Mutex};
56
57
/// Generate arbitrary structured values from raw, unstructured data.
58
///
59
/// The `Arbitrary` trait allows you to generate valid structured values, like
60
/// `HashMap`s, or ASTs, or `MyTomlConfig`, or any other data structure from
61
/// raw, unstructured bytes provided by a fuzzer.
62
///
63
/// # Deriving `Arbitrary`
64
///
65
/// Automatically deriving the `Arbitrary` trait is the recommended way to
66
/// implement `Arbitrary` for your types.
67
///
68
/// Using the custom derive requires that you enable the `"derive"` cargo
69
/// feature in your `Cargo.toml`:
70
///
71
/// ```toml
72
/// [dependencies]
73
/// arbitrary = { version = "1", features = ["derive"] }
74
/// ```
75
///
76
/// Then, you add the `#[derive(Arbitrary)]` annotation to your `struct` or
77
/// `enum` type definition:
78
///
79
/// ```
80
/// # #[cfg(feature = "derive")] mod foo {
81
/// use arbitrary::Arbitrary;
82
/// use std::collections::HashSet;
83
///
84
/// #[derive(Arbitrary)]
85
/// pub struct AddressBook {
86
///     friends: HashSet<Friend>,
87
/// }
88
///
89
/// #[derive(Arbitrary, Hash, Eq, PartialEq)]
90
/// pub enum Friend {
91
///     Buddy { name: String },
92
///     Pal { age: usize },
93
/// }
94
/// # }
95
/// ```
96
///
97
/// Every member of the `struct` or `enum` must also implement `Arbitrary`.
98
///
99
/// # Implementing `Arbitrary` By Hand
100
///
101
/// Implementing `Arbitrary` mostly involves nested calls to other `Arbitrary`
102
/// arbitrary implementations for each of your `struct` or `enum`'s members. But
103
/// sometimes you need some amount of raw data, or you need to generate a
104
/// variably-sized collection type, or something of that sort. The
105
/// [`Unstructured`][crate::Unstructured] type helps you with these tasks.
106
///
107
/// ```
108
/// # #[cfg(feature = "derive")] mod foo {
109
/// # pub struct MyCollection<T> { _t: std::marker::PhantomData<T> }
110
/// # impl<T> MyCollection<T> {
111
/// #     pub fn new() -> Self { MyCollection { _t: std::marker::PhantomData } }
112
/// #     pub fn insert(&mut self, element: T) {}
113
/// # }
114
/// use arbitrary::{Arbitrary, Result, Unstructured};
115
///
116
/// impl<'a, T> Arbitrary<'a> for MyCollection<T>
117
/// where
118
///     T: Arbitrary<'a>,
119
/// {
120
///     fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
121
///         // Get an iterator of arbitrary `T`s.
122
///         let iter = u.arbitrary_iter::<T>()?;
123
///
124
///         // And then create a collection!
125
///         let mut my_collection = MyCollection::new();
126
///         for elem_result in iter {
127
///             let elem = elem_result?;
128
///             my_collection.insert(elem);
129
///         }
130
///
131
///         Ok(my_collection)
132
///     }
133
/// }
134
/// # }
135
/// ```
136
pub trait Arbitrary<'a>: Sized {
137
    /// Generate an arbitrary value of `Self` from the given unstructured data.
138
    ///
139
    /// Calling `Arbitrary::arbitrary` requires that you have some raw data,
140
    /// perhaps given to you by a fuzzer like AFL or libFuzzer. You wrap this
141
    /// raw data in an `Unstructured`, and then you can call `<MyType as
142
    /// Arbitrary>::arbitrary` to construct an arbitrary instance of `MyType`
143
    /// from that unstructured data.
144
    ///
145
    /// Implementations may return an error if there is not enough data to
146
    /// construct a full instance of `Self`, or they may fill out the rest of
147
    /// `Self` with dummy values. Using dummy values when the underlying data is
148
    /// exhausted can help avoid accidentally "defeating" some of the fuzzer's
149
    /// mutations to the underlying byte stream that might otherwise lead to
150
    /// interesting runtime behavior or new code coverage if only we had just a
151
    /// few more bytes. However, it also requires that implementations for
152
    /// recursive types (e.g. `struct Foo(Option<Box<Foo>>)`) avoid infinite
153
    /// recursion when the underlying data is exhausted.
154
    ///
155
    /// ```
156
    /// # #[cfg(feature = "derive")] fn foo() {
157
    /// use arbitrary::{Arbitrary, Unstructured};
158
    ///
159
    /// #[derive(Arbitrary)]
160
    /// pub struct MyType {
161
    ///     // ...
162
    /// }
163
    ///
164
    /// // Get the raw data from the fuzzer or wherever else.
165
    /// # let get_raw_data_from_fuzzer = || &[];
166
    /// let raw_data: &[u8] = get_raw_data_from_fuzzer();
167
    ///
168
    /// // Wrap that raw data in an `Unstructured`.
169
    /// let mut unstructured = Unstructured::new(raw_data);
170
    ///
171
    /// // Generate an arbitrary instance of `MyType` and do stuff with it.
172
    /// if let Ok(value) = MyType::arbitrary(&mut unstructured) {
173
    /// #   let do_stuff = |_| {};
174
    ///     do_stuff(value);
175
    /// }
176
    /// # }
177
    /// ```
178
    ///
179
    /// See also the documentation for [`Unstructured`][crate::Unstructured].
180
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self>;
181
182
    /// Generate an arbitrary value of `Self` from the entirety of the given
183
    /// unstructured data.
184
    ///
185
    /// This is similar to Arbitrary::arbitrary, however it assumes that it is
186
    /// the last consumer of the given data, and is thus able to consume it all
187
    /// if it needs.  See also the documentation for
188
    /// [`Unstructured`][crate::Unstructured].
189
0
    fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
190
0
        Self::arbitrary(&mut u)
191
0
    }
Unexecuted instantiation: _RNvYINtNtCsiBl6Lc3cFal_5alloc2rc2RceENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBB_
Unexecuted instantiation: _RNvYINtNtCsiBl6Lc3cFal_5alloc4sync3ArceENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBE_
Unexecuted instantiation: _RNvYINtNtCsiBl6Lc3cFal_5alloc5boxed3BoxeENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBF_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYNtNtCsVNp5ty2IzJ_3std4path7PathBufNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBC_
Unexecuted instantiation: _RNvYNtNtCsbQ8arDwx5Xq_4core4time8DurationNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBF_
Unexecuted instantiation: _RNvYNtNtNtCsVNp5ty2IzJ_3std3ffi6os_str8OsStringNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBL_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core3net7ip_addr6IpAddrNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBM_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core3net7ip_addr8Ipv4AddrNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBO_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core3net7ip_addr8Ipv6AddrNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBO_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core4sync6atomic10AtomicBoolNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBR_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core4sync6atomic11AtomicIsizeNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBS_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core4sync6atomic11AtomicUsizeNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBS_
Unexecuted instantiation: _RNvYNtNtNtCsiBl6Lc3cFal_5alloc3ffi5c_str7CStringNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restBM_
Unexecuted instantiation: _RNvYaNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYbNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYcNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYdNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYfNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYhNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYiNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYjNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYlNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYmNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYnNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYoNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYsNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYtNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYuNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYxNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYyNtCsjLyxDhx7q6s_9arbitrary9Arbitrary19arbitrary_take_restB5_
192
193
    /// Get a size hint for how many bytes out of an `Unstructured` this type
194
    /// needs to construct itself.
195
    ///
196
    /// This is useful for determining how many elements we should insert when
197
    /// creating an arbitrary collection.
198
    ///
199
    /// The return value is similar to
200
    /// [`Iterator::size_hint`][iterator-size-hint]: it returns a tuple where
201
    /// the first element is a lower bound on the number of bytes required, and
202
    /// the second element is an optional upper bound.
203
    ///
204
    /// The default implementation return `(0, None)` which is correct for any
205
    /// type, but not ultimately that useful. Using `#[derive(Arbitrary)]` will
206
    /// create a better implementation. If you are writing an `Arbitrary`
207
    /// implementation by hand, and your type can be part of a dynamically sized
208
    /// collection (such as `Vec`), you are strongly encouraged to override this
209
    /// default with a better implementation. The
210
    /// [`size_hint`][crate::size_hint] module will help with this task.
211
    ///
212
    /// ## Invariant
213
    ///
214
    /// It must be possible to construct every possible output using only inputs
215
    /// of lengths bounded by these parameters. This applies to both
216
    /// [`Arbitrary::arbitrary`] and [`Arbitrary::arbitrary_take_rest`].
217
    ///
218
    /// This is trivially true for `(0, None)`. To restrict this further, it
219
    /// must be proven that all inputs that are now excluded produced redundant
220
    /// outputs which are still possible to produce using the reduced input
221
    /// space.
222
    ///
223
    /// ## The `depth` Parameter
224
    ///
225
    /// If you 100% know that the type you are implementing `Arbitrary` for is
226
    /// not a recursive type, or your implementation is not transitively calling
227
    /// any other `size_hint` methods, you can ignore the `depth` parameter.
228
    /// Note that if you are implementing `Arbitrary` for a generic type, you
229
    /// cannot guarantee the lack of type recursion!
230
    ///
231
    /// Otherwise, you need to use
232
    /// [`arbitrary::size_hint::recursion_guard(depth)`][crate::size_hint::recursion_guard]
233
    /// to prevent potential infinite recursion when calculating size hints for
234
    /// potentially recursive types:
235
    ///
236
    /// ```
237
    /// use arbitrary::{Arbitrary, Unstructured, size_hint};
238
    ///
239
    /// // This can potentially be a recursive type if `L` or `R` contain
240
    /// // something like `Box<Option<MyEither<L, R>>>`!
241
    /// enum MyEither<L, R> {
242
    ///     Left(L),
243
    ///     Right(R),
244
    /// }
245
    ///
246
    /// impl<'a, L, R> Arbitrary<'a> for MyEither<L, R>
247
    /// where
248
    ///     L: Arbitrary<'a>,
249
    ///     R: Arbitrary<'a>,
250
    /// {
251
    ///     fn arbitrary(u: &mut Unstructured) -> arbitrary::Result<Self> {
252
    ///         // ...
253
    /// #       unimplemented!()
254
    ///     }
255
    ///
256
    ///     fn size_hint(depth: usize) -> (usize, Option<usize>) {
257
    ///         // Protect against potential infinite recursion with
258
    ///         // `recursion_guard`.
259
    ///         size_hint::recursion_guard(depth, |depth| {
260
    ///             // If we aren't too deep, then `recursion_guard` calls
261
    ///             // this closure, which implements the natural size hint.
262
    ///             // Don't forget to use the new `depth` in all nested
263
    ///             // `size_hint` calls! We recommend shadowing the
264
    ///             // parameter, like what is done here, so that you can't
265
    ///             // accidentally use the wrong depth.
266
    ///             size_hint::or(
267
    ///                 <L as Arbitrary>::size_hint(depth),
268
    ///                 <R as Arbitrary>::size_hint(depth),
269
    ///             )
270
    ///         })
271
    ///     }
272
    /// }
273
    /// ```
274
    ///
275
    /// [iterator-size-hint]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.size_hint
276
    #[inline]
277
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
278
0
        let _ = depth;
279
0
        (0, None)
280
0
    }
281
}
282
283
impl<'a> Arbitrary<'a> for () {
284
0
    fn arbitrary(_: &mut Unstructured<'a>) -> Result<Self> {
285
0
        Ok(())
286
0
    }
287
288
    #[inline]
289
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
290
0
        (0, Some(0))
291
0
    }
292
}
293
294
impl<'a> Arbitrary<'a> for bool {
295
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
296
0
        Ok(<u8 as Arbitrary<'a>>::arbitrary(u)? & 1 == 1)
297
0
    }
298
299
    #[inline]
300
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
301
0
        <u8 as Arbitrary<'a>>::size_hint(depth)
302
0
    }
303
}
304
305
macro_rules! impl_arbitrary_for_integers {
306
    ( $( $ty:ty: $unsigned:ty; )* ) => {
307
        $(
308
            impl<'a> Arbitrary<'a> for $ty {
309
0
                fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
310
0
                    let mut buf = [0; mem::size_of::<$ty>()];
311
0
                    u.fill_buffer(&mut buf)?;
312
0
                    let mut x: $unsigned = 0;
313
0
                    for i in 0..mem::size_of::<$ty>() {
314
0
                        x |= buf[i] as $unsigned << (i * 8);
315
0
                    }
316
0
                    Ok(x as $ty)
317
0
                }
Unexecuted instantiation: _RNvXsI_CsjLyxDhx7q6s_9arbitraryhNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsJ_CsjLyxDhx7q6s_9arbitrarytNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsK_CsjLyxDhx7q6s_9arbitrarymNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsL_CsjLyxDhx7q6s_9arbitraryyNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsM_CsjLyxDhx7q6s_9arbitraryoNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsN_CsjLyxDhx7q6s_9arbitraryjNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsO_CsjLyxDhx7q6s_9arbitraryaNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsP_CsjLyxDhx7q6s_9arbitrarysNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsQ_CsjLyxDhx7q6s_9arbitrarylNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsR_CsjLyxDhx7q6s_9arbitraryxNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsS_CsjLyxDhx7q6s_9arbitrarynNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsT_CsjLyxDhx7q6s_9arbitraryiNtB5_9Arbitrary9arbitrary
318
319
                #[inline]
320
0
                fn size_hint(_depth: usize) -> (usize, Option<usize>) {
321
0
                    let n = mem::size_of::<$ty>();
322
0
                    (n, Some(n))
323
0
                }
Unexecuted instantiation: _RNvXsI_CsjLyxDhx7q6s_9arbitraryhNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsK_CsjLyxDhx7q6s_9arbitrarymNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsT_CsjLyxDhx7q6s_9arbitraryiNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsN_CsjLyxDhx7q6s_9arbitraryjNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsL_CsjLyxDhx7q6s_9arbitraryyNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsJ_CsjLyxDhx7q6s_9arbitrarytNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsM_CsjLyxDhx7q6s_9arbitraryoNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsO_CsjLyxDhx7q6s_9arbitraryaNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsP_CsjLyxDhx7q6s_9arbitrarysNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsQ_CsjLyxDhx7q6s_9arbitrarylNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsR_CsjLyxDhx7q6s_9arbitraryxNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsS_CsjLyxDhx7q6s_9arbitrarynNtB5_9Arbitrary9size_hintB5_
324
325
            }
326
        )*
327
    }
328
}
329
330
impl_arbitrary_for_integers! {
331
    u8: u8;
332
    u16: u16;
333
    u32: u32;
334
    u64: u64;
335
    u128: u128;
336
    usize: usize;
337
    i8: u8;
338
    i16: u16;
339
    i32: u32;
340
    i64: u64;
341
    i128: u128;
342
    isize: usize;
343
}
344
345
macro_rules! impl_arbitrary_for_floats {
346
    ( $( $ty:ident : $unsigned:ty; )* ) => {
347
        $(
348
            impl<'a> Arbitrary<'a> for $ty {
349
0
                fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
350
0
                    Ok(Self::from_bits(<$unsigned as Arbitrary<'a>>::arbitrary(u)?))
351
0
                }
Unexecuted instantiation: _RNvXsU_CsjLyxDhx7q6s_9arbitraryfNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsV_CsjLyxDhx7q6s_9arbitrarydNtB5_9Arbitrary9arbitrary
352
353
                #[inline]
354
0
                fn size_hint(depth: usize) -> (usize, Option<usize>) {
355
0
                    <$unsigned as Arbitrary<'a>>::size_hint(depth)
356
0
                }
Unexecuted instantiation: _RNvXsU_CsjLyxDhx7q6s_9arbitraryfNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsV_CsjLyxDhx7q6s_9arbitrarydNtB5_9Arbitrary9size_hintB5_
357
            }
358
        )*
359
    }
360
}
361
362
impl_arbitrary_for_floats! {
363
    f32: u32;
364
    f64: u64;
365
}
366
367
impl<'a> Arbitrary<'a> for char {
368
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
369
        use std::char;
370
        // The highest unicode code point is 0x11_FFFF
371
        const CHAR_END: u32 = 0x11_0000;
372
        // The size of the surrogate blocks
373
        const SURROGATES_START: u32 = 0xD800;
374
0
        let mut c = <u32 as Arbitrary<'a>>::arbitrary(u)? % CHAR_END;
375
0
        if let Some(c) = char::from_u32(c) {
376
0
            Ok(c)
377
        } else {
378
            // We found a surrogate, wrap and try again
379
0
            c -= SURROGATES_START;
380
0
            Ok(char::from_u32(c)
381
0
                .expect("Generated character should be valid! This is a bug in arbitrary-rs"))
382
        }
383
0
    }
384
385
    #[inline]
386
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
387
0
        <u32 as Arbitrary<'a>>::size_hint(depth)
388
0
    }
389
}
390
391
impl<'a> Arbitrary<'a> for AtomicBool {
392
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
393
0
        Arbitrary::arbitrary(u).map(Self::new)
394
0
    }
395
396
    #[inline]
397
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
398
0
        <bool as Arbitrary<'a>>::size_hint(depth)
399
0
    }
400
}
401
402
impl<'a> Arbitrary<'a> for AtomicIsize {
403
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
404
0
        Arbitrary::arbitrary(u).map(Self::new)
405
0
    }
406
407
    #[inline]
408
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
409
0
        <isize as Arbitrary<'a>>::size_hint(depth)
410
0
    }
411
}
412
413
impl<'a> Arbitrary<'a> for AtomicUsize {
414
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
415
0
        Arbitrary::arbitrary(u).map(Self::new)
416
0
    }
417
418
    #[inline]
419
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
420
0
        <usize as Arbitrary<'a>>::size_hint(depth)
421
0
    }
422
}
423
424
macro_rules! impl_range {
425
    (
426
        $range:ty,
427
        $value_closure:expr,
428
        $value_ty:ty,
429
        $fun:ident($fun_closure:expr),
430
        $size_hint_closure:expr
431
    ) => {
432
        impl<'a, A> Arbitrary<'a> for $range
433
        where
434
            A: Arbitrary<'a> + Clone + PartialOrd,
435
        {
436
0
            fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
437
0
                let value: $value_ty = Arbitrary::arbitrary(u)?;
438
0
                Ok($fun(value, $fun_closure))
439
0
            }
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarysW_0pEINtNtNtCsbQ8arDwx5Xq_4core3ops5range5RangepENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarysX_0pEINtNtNtCsbQ8arDwx5Xq_4core3ops5range9RangeFrompENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarysY_0pEINtNtNtCsbQ8arDwx5Xq_4core3ops5range14RangeInclusivepENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarysZ_0pEINtNtNtCsbQ8arDwx5Xq_4core3ops5range7RangeTopENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys10_0pEINtNtNtCsbQ8arDwx5Xq_4core3ops5range16RangeToInclusivepENtB5_9Arbitrary9arbitraryB5_
440
441
            #[inline]
442
0
            fn size_hint(depth: usize) -> (usize, Option<usize>) {
443
0
                #[allow(clippy::redundant_closure_call)]
444
0
                $size_hint_closure(depth)
445
0
            }
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarysW_0pEINtNtNtCsbQ8arDwx5Xq_4core3ops5range5RangepENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarysX_0pEINtNtNtCsbQ8arDwx5Xq_4core3ops5range9RangeFrompENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarysY_0pEINtNtNtCsbQ8arDwx5Xq_4core3ops5range14RangeInclusivepENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarysZ_0pEINtNtNtCsbQ8arDwx5Xq_4core3ops5range7RangeTopENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys10_0pEINtNtNtCsbQ8arDwx5Xq_4core3ops5range16RangeToInclusivepENtB5_9Arbitrary9size_hintB5_
446
        }
447
    };
448
}
449
450
impl_range!(
451
    Range<A>,
452
    |r: &Range<A>| (r.start.clone(), r.end.clone()),
453
    (A, A),
454
0
    bounded_range(|(a, b)| a..b),
455
0
    |depth| crate::size_hint::and(
456
0
        <A as Arbitrary>::size_hint(depth),
457
0
        <A as Arbitrary>::size_hint(depth)
458
0
    )
459
);
460
impl_range!(
461
    RangeFrom<A>,
462
    |r: &RangeFrom<A>| r.start.clone(),
463
    A,
464
0
    unbounded_range(|a| a..),
465
0
    |depth| <A as Arbitrary>::size_hint(depth)
466
);
467
impl_range!(
468
    RangeInclusive<A>,
469
    |r: &RangeInclusive<A>| (r.start().clone(), r.end().clone()),
470
    (A, A),
471
0
    bounded_range(|(a, b)| a..=b),
472
0
    |depth| crate::size_hint::and(
473
0
        <A as Arbitrary>::size_hint(depth),
474
0
        <A as Arbitrary>::size_hint(depth)
475
0
    )
476
);
477
impl_range!(
478
    RangeTo<A>,
479
    |r: &RangeTo<A>| r.end.clone(),
480
    A,
481
0
    unbounded_range(|b| ..b),
482
0
    |depth| <A as Arbitrary>::size_hint(depth)
483
);
484
impl_range!(
485
    RangeToInclusive<A>,
486
    |r: &RangeToInclusive<A>| r.end.clone(),
487
    A,
488
0
    unbounded_range(|b| ..=b),
489
0
    |depth| <A as Arbitrary>::size_hint(depth)
490
);
491
492
0
pub(crate) fn bounded_range<CB, I, R>(bounds: (I, I), cb: CB) -> R
493
0
where
494
0
    CB: Fn((I, I)) -> R,
495
0
    I: PartialOrd,
496
0
    R: RangeBounds<I>,
497
0
{
498
0
    let (mut start, mut end) = bounds;
499
0
    if start > end {
500
0
        mem::swap(&mut start, &mut end);
501
0
    }
502
0
    cb((start, end))
503
0
}
504
505
0
pub(crate) fn unbounded_range<CB, I, R>(bound: I, cb: CB) -> R
506
0
where
507
0
    CB: Fn(I) -> R,
508
0
    R: RangeBounds<I>,
509
0
{
510
0
    cb(bound)
511
0
}
512
513
impl<'a> Arbitrary<'a> for Duration {
514
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
515
0
        Ok(Self::new(
516
0
            <u64 as Arbitrary>::arbitrary(u)?,
517
0
            u.int_in_range(0..=999_999_999)?,
518
        ))
519
0
    }
520
521
    #[inline]
522
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
523
0
        crate::size_hint::and(
524
0
            <u64 as Arbitrary>::size_hint(depth),
525
0
            <u32 as Arbitrary>::size_hint(depth),
526
0
        )
527
0
    }
528
}
529
530
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Option<A> {
531
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
532
0
        Ok(if <bool as Arbitrary<'a>>::arbitrary(u)? {
533
0
            Some(Arbitrary::arbitrary(u)?)
534
        } else {
535
0
            None
536
        })
537
0
    }
538
539
    #[inline]
540
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
541
0
        crate::size_hint::and(
542
0
            <bool as Arbitrary>::size_hint(depth),
543
0
            crate::size_hint::or((0, Some(0)), <A as Arbitrary>::size_hint(depth)),
544
0
        )
545
0
    }
546
}
547
548
impl<'a, A: Arbitrary<'a>, B: Arbitrary<'a>> Arbitrary<'a> for std::result::Result<A, B> {
549
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
550
0
        Ok(if <bool as Arbitrary<'a>>::arbitrary(u)? {
551
0
            Ok(<A as Arbitrary>::arbitrary(u)?)
552
        } else {
553
0
            Err(<B as Arbitrary>::arbitrary(u)?)
554
        })
555
0
    }
556
557
    #[inline]
558
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
559
0
        crate::size_hint::and(
560
0
            <bool as Arbitrary>::size_hint(depth),
561
0
            crate::size_hint::or(
562
0
                <A as Arbitrary>::size_hint(depth),
563
0
                <B as Arbitrary>::size_hint(depth),
564
0
            ),
565
0
        )
566
0
    }
567
}
568
569
macro_rules! arbitrary_tuple {
570
    () => {};
571
    ($last: ident $($xs: ident)*) => {
572
        arbitrary_tuple!($($xs)*);
573
574
        impl<'a, $($xs: Arbitrary<'a>,)* $last: Arbitrary<'a>> Arbitrary<'a> for ($($xs,)* $last,) {
575
0
            fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
576
0
                Ok(($($xs::arbitrary(u)?,)* Arbitrary::arbitrary(u)?,))
577
0
            }
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1q_0pETpENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1p_0ppETppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1o_0pppETpppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1n_0ppppETppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1m_0pppppETpppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1l_0ppppppETppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1k_0pppppppETpppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1j_0ppppppppETppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1i_0pppppppppETpppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1h_0ppppppppppETppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1g_0pppppppppppETpppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1f_0ppppppppppppETppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1e_0pppppppppppppETpppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1d_0ppppppppppppppETppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1c_0pppppppppppppppETpppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1b_0ppppppppppppppppETppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1a_0pppppppppppppppppETpppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys19_0ppppppppppppppppppETppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys18_0pppppppppppppppppppETpppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys17_0ppppppppppppppppppppETppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys16_0pppppppppppppppppppppETpppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys15_0ppppppppppppppppppppppETppppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys14_0pppppppppppppppppppppppETpppppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys13_0ppppppppppppppppppppppppETppppppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys12_0pppppppppppppppppppppppppETpppppppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys11_0ppppppppppppppppppppppppppETppppppppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
578
579
            #[allow(unused_mut, non_snake_case)]
580
0
            fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
581
0
                $(let $xs = $xs::arbitrary(&mut u)?;)*
582
0
                let $last = $last::arbitrary_take_rest(u)?;
583
0
                Ok(($($xs,)* $last,))
584
0
            }
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1q_0pETpENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1p_0ppETppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1o_0pppETpppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1n_0ppppETppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1m_0pppppETpppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1l_0ppppppETppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1k_0pppppppETpppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1j_0ppppppppETppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1i_0pppppppppETpppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1h_0ppppppppppETppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1g_0pppppppppppETpppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1f_0ppppppppppppETppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1e_0pppppppppppppETpppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1d_0ppppppppppppppETppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1c_0pppppppppppppppETpppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1b_0ppppppppppppppppETppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1a_0pppppppppppppppppETpppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys19_0ppppppppppppppppppETppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys18_0pppppppppppppppppppETpppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys17_0ppppppppppppppppppppETppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys16_0pppppppppppppppppppppETpppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys15_0ppppppppppppppppppppppETppppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys14_0pppppppppppppppppppppppETpppppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys13_0ppppppppppppppppppppppppETppppppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys12_0pppppppppppppppppppppppppETpppppppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys11_0ppppppppppppppppppppppppppETppppppppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
585
586
            #[inline]
587
0
            fn size_hint(depth: usize) -> (usize, Option<usize>) {
588
0
                crate::size_hint::and_all(&[
589
0
                    <$last as Arbitrary>::size_hint(depth),
590
0
                    $( <$xs as Arbitrary>::size_hint(depth) ),*
591
0
                ])
592
0
            }
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1q_0pETpENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1p_0ppETppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1o_0pppETpppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1n_0ppppETppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1m_0pppppETpppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1l_0ppppppETppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1k_0pppppppETpppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1j_0ppppppppETppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1i_0pppppppppETpppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1h_0ppppppppppETppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1g_0pppppppppppETpppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1f_0ppppppppppppETppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1e_0pppppppppppppETpppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1d_0ppppppppppppppETppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1c_0pppppppppppppppETpppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1b_0ppppppppppppppppETppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys1a_0pppppppppppppppppETpppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys19_0ppppppppppppppppppETppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys18_0pppppppppppppppppppETpppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys17_0ppppppppppppppppppppETppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys16_0pppppppppppppppppppppETpppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys15_0ppppppppppppppppppppppETppppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys14_0pppppppppppppppppppppppETpppppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys13_0ppppppppppppppppppppppppETppppppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys12_0pppppppppppppppppppppppppETpppppppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsjLyxDhx7q6s_9arbitrarys11_0ppppppppppppppppppppppppppETppppppppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
593
        }
594
    };
595
}
596
arbitrary_tuple!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);
597
598
// Helper to safely create arrays since the standard library doesn't
599
// provide one yet. Shouldn't be necessary in the future.
600
struct ArrayGuard<T, const N: usize> {
601
    dst: *mut T,
602
    initialized: usize,
603
}
604
605
impl<T, const N: usize> Drop for ArrayGuard<T, N> {
606
0
    fn drop(&mut self) {
607
0
        debug_assert!(self.initialized <= N);
608
0
        let initialized_part = core::ptr::slice_from_raw_parts_mut(self.dst, self.initialized);
609
0
        unsafe {
610
0
            core::ptr::drop_in_place(initialized_part);
611
0
        }
612
0
    }
613
}
614
615
0
fn try_create_array<F, T, const N: usize>(mut cb: F) -> Result<[T; N]>
616
0
where
617
0
    F: FnMut(usize) -> Result<T>,
618
0
{
619
0
    let mut array: mem::MaybeUninit<[T; N]> = mem::MaybeUninit::uninit();
620
0
    let array_ptr = array.as_mut_ptr();
621
0
    let dst = array_ptr as _;
622
0
    let mut guard: ArrayGuard<T, N> = ArrayGuard {
623
0
        dst,
624
0
        initialized: 0,
625
0
    };
626
    unsafe {
627
0
        for (idx, value_ptr) in (*array.as_mut_ptr()).iter_mut().enumerate() {
628
0
            core::ptr::write(value_ptr, cb(idx)?);
629
0
            guard.initialized += 1;
630
        }
631
0
        mem::forget(guard);
632
0
        Ok(array.assume_init())
633
    }
634
0
}
635
636
impl<'a, T, const N: usize> Arbitrary<'a> for [T; N]
637
where
638
    T: Arbitrary<'a>,
639
{
640
    #[inline]
641
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
642
0
        try_create_array(|_| <T as Arbitrary<'a>>::arbitrary(u))
643
0
    }
644
645
    #[inline]
646
0
    fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
647
0
        let mut array = Self::arbitrary(&mut u)?;
648
0
        if let Some(last) = array.last_mut() {
649
0
            *last = Arbitrary::arbitrary_take_rest(u)?;
650
0
        }
651
0
        Ok(array)
652
0
    }
653
654
    #[inline]
655
0
    fn size_hint(d: usize) -> (usize, Option<usize>) {
656
0
        crate::size_hint::and_all(&array::from_fn::<_, N, _>(|_| {
657
0
            <T as Arbitrary>::size_hint(d)
658
0
        }))
659
0
    }
660
}
661
662
impl<'a> Arbitrary<'a> for &'a [u8] {
663
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
664
0
        let len = u.arbitrary_len::<u8>()?;
665
0
        u.bytes(len)
666
0
    }
667
668
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
669
0
        Ok(u.take_rest())
670
0
    }
671
672
    #[inline]
673
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
674
0
        (0, None)
675
0
    }
676
}
677
678
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Vec<A> {
679
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
680
0
        u.arbitrary_iter()?.collect()
681
0
    }
682
683
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
684
0
        u.arbitrary_take_rest_iter()?.collect()
685
0
    }
686
687
    #[inline]
688
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
689
0
        (0, None)
690
0
    }
691
}
692
693
impl<'a, K: Arbitrary<'a> + Ord, V: Arbitrary<'a>> Arbitrary<'a> for BTreeMap<K, V> {
694
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
695
0
        u.arbitrary_iter()?.collect()
696
0
    }
697
698
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
699
0
        u.arbitrary_take_rest_iter()?.collect()
700
0
    }
701
702
    #[inline]
703
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
704
0
        (0, None)
705
0
    }
706
}
707
708
impl<'a, A: Arbitrary<'a> + Ord> Arbitrary<'a> for BTreeSet<A> {
709
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
710
0
        u.arbitrary_iter()?.collect()
711
0
    }
712
713
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
714
0
        u.arbitrary_take_rest_iter()?.collect()
715
0
    }
716
717
    #[inline]
718
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
719
0
        (0, None)
720
0
    }
721
}
722
723
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Bound<A> {
724
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
725
0
        match u.int_in_range::<u8>(0..=2)? {
726
0
            0 => Ok(Bound::Included(A::arbitrary(u)?)),
727
0
            1 => Ok(Bound::Excluded(A::arbitrary(u)?)),
728
0
            2 => Ok(Bound::Unbounded),
729
0
            _ => unreachable!(),
730
        }
731
0
    }
732
733
    #[inline]
734
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
735
0
        size_hint::or(
736
0
            size_hint::and((1, Some(1)), A::size_hint(depth)),
737
0
            (1, Some(1)),
738
0
        )
739
0
    }
740
}
741
742
impl<'a, A: Arbitrary<'a> + Ord> Arbitrary<'a> for BinaryHeap<A> {
743
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
744
0
        u.arbitrary_iter()?.collect()
745
0
    }
746
747
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
748
0
        u.arbitrary_take_rest_iter()?.collect()
749
0
    }
750
751
    #[inline]
752
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
753
0
        (0, None)
754
0
    }
755
}
756
757
impl<'a, K: Arbitrary<'a> + Eq + ::std::hash::Hash, V: Arbitrary<'a>, S: BuildHasher + Default>
758
    Arbitrary<'a> for HashMap<K, V, S>
759
{
760
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
761
0
        u.arbitrary_iter()?.collect()
762
0
    }
763
764
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
765
0
        u.arbitrary_take_rest_iter()?.collect()
766
0
    }
767
768
    #[inline]
769
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
770
0
        (0, None)
771
0
    }
772
}
773
774
impl<'a, A: Arbitrary<'a> + Eq + ::std::hash::Hash, S: BuildHasher + Default> Arbitrary<'a>
775
    for HashSet<A, S>
776
{
777
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
778
0
        u.arbitrary_iter()?.collect()
779
0
    }
780
781
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
782
0
        u.arbitrary_take_rest_iter()?.collect()
783
0
    }
784
785
    #[inline]
786
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
787
0
        (0, None)
788
0
    }
789
}
790
791
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for LinkedList<A> {
792
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
793
0
        u.arbitrary_iter()?.collect()
794
0
    }
795
796
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
797
0
        u.arbitrary_take_rest_iter()?.collect()
798
0
    }
799
800
    #[inline]
801
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
802
0
        (0, None)
803
0
    }
804
}
805
806
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for VecDeque<A> {
807
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
808
0
        u.arbitrary_iter()?.collect()
809
0
    }
810
811
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
812
0
        u.arbitrary_take_rest_iter()?.collect()
813
0
    }
814
815
    #[inline]
816
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
817
0
        (0, None)
818
0
    }
819
}
820
821
impl<'a, A> Arbitrary<'a> for Cow<'a, A>
822
where
823
    A: ToOwned + ?Sized,
824
    <A as ToOwned>::Owned: Arbitrary<'a>,
825
{
826
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
827
0
        Arbitrary::arbitrary(u).map(Cow::Owned)
828
0
    }
829
830
    #[inline]
831
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
832
0
        crate::size_hint::recursion_guard(depth, |depth| {
833
0
            <<A as ToOwned>::Owned as Arbitrary>::size_hint(depth)
834
0
        })
835
0
    }
836
}
837
838
0
fn arbitrary_str<'a>(u: &mut Unstructured<'a>, size: usize) -> Result<&'a str> {
839
0
    match str::from_utf8(u.peek_bytes(size).unwrap()) {
840
0
        Ok(s) => {
841
0
            u.bytes(size).unwrap();
842
0
            Ok(s)
843
        }
844
0
        Err(e) => {
845
0
            let i = e.valid_up_to();
846
0
            let valid = u.bytes(i).unwrap();
847
0
            let s = unsafe {
848
0
                debug_assert!(str::from_utf8(valid).is_ok());
849
0
                str::from_utf8_unchecked(valid)
850
0
            };
851
0
            Ok(s)
852
        }
853
    }
854
0
}
855
856
impl<'a> Arbitrary<'a> for &'a str {
857
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
858
0
        let size = u.arbitrary_len::<u8>()?;
859
0
        arbitrary_str(u, size)
860
0
    }
861
862
0
    fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
863
0
        let size = u.len();
864
0
        arbitrary_str(&mut u, size)
865
0
    }
866
867
    #[inline]
868
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
869
0
        (0, None)
870
0
    }
871
}
872
873
impl<'a> Arbitrary<'a> for String {
874
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
875
0
        <&str as Arbitrary>::arbitrary(u).map(Into::into)
876
0
    }
877
878
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
879
0
        <&str as Arbitrary>::arbitrary_take_rest(u).map(Into::into)
880
0
    }
881
882
    #[inline]
883
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
884
0
        <&str as Arbitrary>::size_hint(depth)
885
0
    }
886
}
887
888
impl<'a> Arbitrary<'a> for CString {
889
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
890
0
        <Vec<u8> as Arbitrary>::arbitrary(u).map(|mut x| {
891
0
            x.retain(|&c| c != 0);
892
0
            Self::new(x).unwrap()
893
0
        })
894
0
    }
895
896
    #[inline]
897
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
898
0
        <Vec<u8> as Arbitrary>::size_hint(depth)
899
0
    }
900
}
901
902
impl<'a> Arbitrary<'a> for OsString {
903
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
904
0
        <String as Arbitrary>::arbitrary(u).map(From::from)
905
0
    }
906
907
    #[inline]
908
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
909
0
        <String as Arbitrary>::size_hint(depth)
910
0
    }
911
}
912
913
impl<'a> Arbitrary<'a> for PathBuf {
914
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
915
0
        <OsString as Arbitrary>::arbitrary(u).map(From::from)
916
0
    }
917
918
    #[inline]
919
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
920
0
        <OsString as Arbitrary>::size_hint(depth)
921
0
    }
922
}
923
924
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box<A> {
925
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
926
0
        Arbitrary::arbitrary(u).map(Self::new)
927
0
    }
928
929
    #[inline]
930
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
931
0
        crate::size_hint::recursion_guard(depth, <A as Arbitrary>::size_hint)
932
0
    }
933
}
934
935
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box<[A]> {
936
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
937
0
        u.arbitrary_iter()?.collect()
938
0
    }
939
940
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
941
0
        u.arbitrary_take_rest_iter()?.collect()
942
0
    }
943
944
    #[inline]
945
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
946
0
        (0, None)
947
0
    }
948
}
949
950
impl<'a> Arbitrary<'a> for Box<str> {
951
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
952
0
        <String as Arbitrary>::arbitrary(u).map(|x| x.into_boxed_str())
953
0
    }
954
955
    #[inline]
956
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
957
0
        <String as Arbitrary>::size_hint(depth)
958
0
    }
959
}
960
961
// impl Arbitrary for Box<CStr> {
962
//     fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self> {
963
//         <CString as Arbitrary>::arbitrary(u).map(|x| x.into_boxed_c_str())
964
//     }
965
// }
966
967
// impl Arbitrary for Box<OsStr> {
968
//     fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self> {
969
//         <OsString as Arbitrary>::arbitrary(u).map(|x| x.into_boxed_osstr())
970
//
971
//     }
972
// }
973
974
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Arc<A> {
975
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
976
0
        Arbitrary::arbitrary(u).map(Self::new)
977
0
    }
978
979
    #[inline]
980
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
981
0
        crate::size_hint::recursion_guard(depth, <A as Arbitrary>::size_hint)
982
0
    }
983
}
984
985
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Arc<[A]> {
986
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
987
0
        u.arbitrary_iter()?.collect()
988
0
    }
989
990
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
991
0
        u.arbitrary_take_rest_iter()?.collect()
992
0
    }
993
994
    #[inline]
995
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
996
0
        (0, None)
997
0
    }
998
}
999
1000
impl<'a> Arbitrary<'a> for Arc<str> {
1001
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1002
0
        <&str as Arbitrary>::arbitrary(u).map(Into::into)
1003
0
    }
1004
1005
    #[inline]
1006
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1007
0
        <&str as Arbitrary>::size_hint(depth)
1008
0
    }
1009
}
1010
1011
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Rc<A> {
1012
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1013
0
        Arbitrary::arbitrary(u).map(Self::new)
1014
0
    }
1015
1016
    #[inline]
1017
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1018
0
        crate::size_hint::recursion_guard(depth, <A as Arbitrary>::size_hint)
1019
0
    }
1020
}
1021
1022
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Rc<[A]> {
1023
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1024
0
        u.arbitrary_iter()?.collect()
1025
0
    }
1026
1027
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
1028
0
        u.arbitrary_take_rest_iter()?.collect()
1029
0
    }
1030
1031
    #[inline]
1032
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
1033
0
        (0, None)
1034
0
    }
1035
}
1036
1037
impl<'a> Arbitrary<'a> for Rc<str> {
1038
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1039
0
        <&str as Arbitrary>::arbitrary(u).map(Into::into)
1040
0
    }
1041
1042
    #[inline]
1043
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1044
0
        <&str as Arbitrary>::size_hint(depth)
1045
0
    }
1046
}
1047
1048
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Cell<A> {
1049
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1050
0
        Arbitrary::arbitrary(u).map(Self::new)
1051
0
    }
1052
1053
    #[inline]
1054
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1055
0
        <A as Arbitrary<'a>>::size_hint(depth)
1056
0
    }
1057
}
1058
1059
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for RefCell<A> {
1060
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1061
0
        Arbitrary::arbitrary(u).map(Self::new)
1062
0
    }
1063
1064
    #[inline]
1065
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1066
0
        <A as Arbitrary<'a>>::size_hint(depth)
1067
0
    }
1068
}
1069
1070
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for UnsafeCell<A> {
1071
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1072
0
        Arbitrary::arbitrary(u).map(Self::new)
1073
0
    }
1074
1075
    #[inline]
1076
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1077
0
        <A as Arbitrary<'a>>::size_hint(depth)
1078
0
    }
1079
}
1080
1081
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Mutex<A> {
1082
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1083
0
        Arbitrary::arbitrary(u).map(Self::new)
1084
0
    }
1085
1086
    #[inline]
1087
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1088
0
        <A as Arbitrary<'a>>::size_hint(depth)
1089
0
    }
1090
}
1091
1092
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for iter::Empty<A> {
1093
0
    fn arbitrary(_: &mut Unstructured<'a>) -> Result<Self> {
1094
0
        Ok(iter::empty())
1095
0
    }
1096
1097
    #[inline]
1098
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
1099
0
        (0, Some(0))
1100
0
    }
1101
}
1102
1103
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for ::std::marker::PhantomData<A> {
1104
0
    fn arbitrary(_: &mut Unstructured<'a>) -> Result<Self> {
1105
0
        Ok(::std::marker::PhantomData)
1106
0
    }
1107
1108
    #[inline]
1109
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
1110
0
        (0, Some(0))
1111
0
    }
1112
}
1113
1114
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for ::std::num::Wrapping<A> {
1115
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1116
0
        Arbitrary::arbitrary(u).map(::std::num::Wrapping)
1117
0
    }
1118
1119
    #[inline]
1120
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1121
0
        <A as Arbitrary<'a>>::size_hint(depth)
1122
0
    }
1123
}
1124
1125
macro_rules! implement_nonzero_int {
1126
    ($nonzero:ty, $int:ty) => {
1127
        impl<'a> Arbitrary<'a> for $nonzero {
1128
0
            fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1129
0
                match Self::new(<$int as Arbitrary<'a>>::arbitrary(u)?) {
1130
0
                    Some(n) => Ok(n),
1131
0
                    None => Err(Error::IncorrectFormat),
1132
                }
1133
0
            }
Unexecuted instantiation: _RNvXs1r_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1s_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1t_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1u_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1v_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1w_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1x_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1y_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1z_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1A_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1B_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1C_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtB6_9Arbitrary9arbitrary
1134
1135
            #[inline]
1136
0
            fn size_hint(depth: usize) -> (usize, Option<usize>) {
1137
0
                <$int as Arbitrary<'a>>::size_hint(depth)
1138
0
            }
Unexecuted instantiation: _RNvXs1r_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1s_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1t_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1u_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1v_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1w_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1x_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1y_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1z_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1A_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1B_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1C_CsjLyxDhx7q6s_9arbitraryINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtB6_9Arbitrary9size_hintB6_
1139
        }
1140
    };
1141
}
1142
1143
implement_nonzero_int! { NonZeroI8, i8 }
1144
implement_nonzero_int! { NonZeroI16, i16 }
1145
implement_nonzero_int! { NonZeroI32, i32 }
1146
implement_nonzero_int! { NonZeroI64, i64 }
1147
implement_nonzero_int! { NonZeroI128, i128 }
1148
implement_nonzero_int! { NonZeroIsize, isize }
1149
implement_nonzero_int! { NonZeroU8, u8 }
1150
implement_nonzero_int! { NonZeroU16, u16 }
1151
implement_nonzero_int! { NonZeroU32, u32 }
1152
implement_nonzero_int! { NonZeroU64, u64 }
1153
implement_nonzero_int! { NonZeroU128, u128 }
1154
implement_nonzero_int! { NonZeroUsize, usize }
1155
1156
impl<'a> Arbitrary<'a> for Ipv4Addr {
1157
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1158
0
        Ok(Ipv4Addr::from(u32::arbitrary(u)?))
1159
0
    }
1160
1161
    #[inline]
1162
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
1163
0
        (4, Some(4))
1164
0
    }
1165
}
1166
1167
impl<'a> Arbitrary<'a> for Ipv6Addr {
1168
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1169
0
        Ok(Ipv6Addr::from(u128::arbitrary(u)?))
1170
0
    }
1171
1172
    #[inline]
1173
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
1174
0
        (16, Some(16))
1175
0
    }
1176
}
1177
1178
impl<'a> Arbitrary<'a> for IpAddr {
1179
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1180
0
        if u.arbitrary()? {
1181
0
            Ok(IpAddr::V4(u.arbitrary()?))
1182
        } else {
1183
0
            Ok(IpAddr::V6(u.arbitrary()?))
1184
        }
1185
0
    }
1186
1187
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1188
0
        size_hint::and(
1189
0
            bool::size_hint(depth),
1190
0
            size_hint::or(Ipv4Addr::size_hint(depth), Ipv6Addr::size_hint(depth)),
1191
0
        )
1192
0
    }
1193
}
1194
1195
#[cfg(test)]
1196
mod test {
1197
    use super::*;
1198
1199
    /// Assert that the given expected values are all generated.
1200
    ///
1201
    /// Exhaustively enumerates all buffers up to length 10 containing the
1202
    /// following bytes: `0x00`, `0x01`, `0x61` (aka ASCII 'a'), and `0xff`
1203
    fn assert_generates<T>(expected_values: impl IntoIterator<Item = T>)
1204
    where
1205
        T: Clone + std::fmt::Debug + std::hash::Hash + Eq + for<'a> Arbitrary<'a>,
1206
    {
1207
        let expected_values: HashSet<_> = expected_values.into_iter().collect();
1208
        let mut arbitrary_expected = expected_values.clone();
1209
        let mut arbitrary_take_rest_expected = expected_values;
1210
1211
        let bytes = [0, 1, b'a', 0xff];
1212
        let max_len = 10;
1213
1214
        let mut buf = Vec::with_capacity(max_len);
1215
1216
        let mut g = exhaustigen::Gen::new();
1217
        while !g.done() {
1218
            let len = g.gen(max_len);
1219
1220
            buf.clear();
1221
            buf.extend(
1222
                std::iter::repeat_with(|| {
1223
                    let index = g.gen(bytes.len() - 1);
1224
                    bytes[index]
1225
                })
1226
                .take(len),
1227
            );
1228
1229
            let mut u = Unstructured::new(&buf);
1230
            let val = T::arbitrary(&mut u).unwrap();
1231
            arbitrary_expected.remove(&val);
1232
1233
            let u = Unstructured::new(&buf);
1234
            let val = T::arbitrary_take_rest(u).unwrap();
1235
            arbitrary_take_rest_expected.remove(&val);
1236
1237
            if arbitrary_expected.is_empty() && arbitrary_take_rest_expected.is_empty() {
1238
                return;
1239
            }
1240
        }
1241
1242
        panic!(
1243
            "failed to generate all expected values!\n\n\
1244
             T::arbitrary did not generate: {arbitrary_expected:#?}\n\n\
1245
             T::arbitrary_take_rest did not generate {arbitrary_take_rest_expected:#?}"
1246
        )
1247
    }
1248
1249
    /// Generates an arbitrary `T`, and checks that the result is consistent with the
1250
    /// `size_hint()` reported by `T`.
1251
    fn checked_arbitrary<'a, T: Arbitrary<'a>>(u: &mut Unstructured<'a>) -> Result<T> {
1252
        let (min, max) = T::size_hint(0);
1253
1254
        let len_before = u.len();
1255
        let result = T::arbitrary(u);
1256
1257
        let consumed = len_before - u.len();
1258
1259
        if let Some(max) = max {
1260
            assert!(
1261
                consumed <= max,
1262
                "incorrect maximum size: indicated {}, actually consumed {}",
1263
                max,
1264
                consumed
1265
            );
1266
        }
1267
1268
        if result.is_ok() {
1269
            assert!(
1270
                consumed >= min,
1271
                "incorrect minimum size: indicated {}, actually consumed {}",
1272
                min,
1273
                consumed
1274
            );
1275
        }
1276
1277
        result
1278
    }
1279
1280
    /// Like `checked_arbitrary()`, but calls `arbitrary_take_rest()` instead of `arbitrary()`.
1281
    fn checked_arbitrary_take_rest<'a, T: Arbitrary<'a>>(u: Unstructured<'a>) -> Result<T> {
1282
        let (min, _) = T::size_hint(0);
1283
1284
        let len_before = u.len();
1285
        let result = T::arbitrary_take_rest(u);
1286
1287
        if result.is_ok() {
1288
            assert!(
1289
                len_before >= min,
1290
                "incorrect minimum size: indicated {}, worked with {}",
1291
                min,
1292
                len_before
1293
            );
1294
        }
1295
1296
        result
1297
    }
1298
1299
    #[test]
1300
    fn finite_buffer_fill_buffer() {
1301
        let x = [1, 2, 3, 4];
1302
        let mut rb = Unstructured::new(&x);
1303
        let mut z = [0; 2];
1304
        rb.fill_buffer(&mut z).unwrap();
1305
        assert_eq!(z, [1, 2]);
1306
        rb.fill_buffer(&mut z).unwrap();
1307
        assert_eq!(z, [3, 4]);
1308
        rb.fill_buffer(&mut z).unwrap();
1309
        assert_eq!(z, [0, 0]);
1310
    }
1311
1312
    #[test]
1313
    fn arbitrary_for_integers() {
1314
        let x = [1, 2, 3, 4];
1315
        let mut buf = Unstructured::new(&x);
1316
        let expected = 1 | (2 << 8) | (3 << 16) | (4 << 24);
1317
        let actual = checked_arbitrary::<i32>(&mut buf).unwrap();
1318
        assert_eq!(expected, actual);
1319
1320
        assert_generates([
1321
            i32::from_ne_bytes([0, 0, 0, 0]),
1322
            i32::from_ne_bytes([0, 0, 0, 1]),
1323
            i32::from_ne_bytes([0, 0, 1, 0]),
1324
            i32::from_ne_bytes([0, 1, 0, 0]),
1325
            i32::from_ne_bytes([1, 0, 0, 0]),
1326
            i32::from_ne_bytes([1, 1, 1, 1]),
1327
            i32::from_ne_bytes([0xff, 0xff, 0xff, 0xff]),
1328
        ]);
1329
    }
1330
1331
    #[test]
1332
    fn arbitrary_for_bytes() {
1333
        let x = [1, 2, 3, 4, 4];
1334
        let mut buf = Unstructured::new(&x);
1335
        let expected = &[1, 2, 3, 4];
1336
        let actual = checked_arbitrary::<&[u8]>(&mut buf).unwrap();
1337
        assert_eq!(expected, actual);
1338
    }
1339
1340
    #[test]
1341
    fn arbitrary_take_rest_for_bytes() {
1342
        let x = [1, 2, 3, 4];
1343
        let buf = Unstructured::new(&x);
1344
        let expected = &[1, 2, 3, 4];
1345
        let actual = checked_arbitrary_take_rest::<&[u8]>(buf).unwrap();
1346
        assert_eq!(expected, actual);
1347
    }
1348
1349
    #[test]
1350
    fn arbitrary_for_vec_u8() {
1351
        assert_generates::<Vec<u8>>([
1352
            vec![],
1353
            vec![0],
1354
            vec![1],
1355
            vec![0, 0],
1356
            vec![0, 1],
1357
            vec![1, 0],
1358
            vec![1, 1],
1359
            vec![0, 0, 0],
1360
            vec![0, 0, 1],
1361
            vec![0, 1, 0],
1362
            vec![0, 1, 1],
1363
            vec![1, 0, 0],
1364
            vec![1, 0, 1],
1365
            vec![1, 1, 0],
1366
            vec![1, 1, 1],
1367
        ]);
1368
    }
1369
1370
    #[test]
1371
    fn arbitrary_for_vec_vec_u8() {
1372
        assert_generates::<Vec<Vec<u8>>>([
1373
            vec![],
1374
            vec![vec![]],
1375
            vec![vec![0]],
1376
            vec![vec![1]],
1377
            vec![vec![0, 1]],
1378
            vec![vec![], vec![]],
1379
            vec![vec![0], vec![]],
1380
            vec![vec![], vec![1]],
1381
            vec![vec![0], vec![1]],
1382
            vec![vec![0, 1], vec![]],
1383
            vec![vec![], vec![1, 0]],
1384
            vec![vec![], vec![], vec![]],
1385
        ]);
1386
    }
1387
1388
    #[test]
1389
    fn arbitrary_for_vec_vec_vec_u8() {
1390
        assert_generates::<Vec<Vec<Vec<u8>>>>([
1391
            vec![],
1392
            vec![vec![]],
1393
            vec![vec![vec![0]]],
1394
            vec![vec![vec![1]]],
1395
            vec![vec![vec![0, 1]]],
1396
            vec![vec![], vec![]],
1397
            vec![vec![], vec![vec![]]],
1398
            vec![vec![vec![]], vec![]],
1399
            vec![vec![vec![]], vec![vec![]]],
1400
            vec![vec![vec![0]], vec![]],
1401
            vec![vec![], vec![vec![1]]],
1402
            vec![vec![vec![0]], vec![vec![1]]],
1403
            vec![vec![vec![0, 1]], vec![]],
1404
            vec![vec![], vec![vec![0, 1]]],
1405
            vec![vec![], vec![], vec![]],
1406
            vec![vec![vec![]], vec![], vec![]],
1407
            vec![vec![], vec![vec![]], vec![]],
1408
            vec![vec![], vec![], vec![vec![]]],
1409
        ]);
1410
    }
1411
1412
    #[test]
1413
    fn arbitrary_for_string() {
1414
        assert_generates::<String>(["".into(), "a".into(), "aa".into(), "aaa".into()]);
1415
    }
1416
1417
    #[test]
1418
    fn arbitrary_collection() {
1419
        let x = [
1420
            1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 12,
1421
        ];
1422
        assert_eq!(
1423
            checked_arbitrary::<&[u8]>(&mut Unstructured::new(&x)).unwrap(),
1424
            &[1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3]
1425
        );
1426
        assert_eq!(
1427
            checked_arbitrary::<Vec<u8>>(&mut Unstructured::new(&x)).unwrap(),
1428
            &[2, 4, 6, 8, 1]
1429
        );
1430
        assert_eq!(
1431
            &*checked_arbitrary::<Box<[u8]>>(&mut Unstructured::new(&x)).unwrap(),
1432
            &[2, 4, 6, 8, 1]
1433
        );
1434
        assert_eq!(
1435
            &*checked_arbitrary::<Arc<[u8]>>(&mut Unstructured::new(&x)).unwrap(),
1436
            &[2, 4, 6, 8, 1]
1437
        );
1438
        assert_eq!(
1439
            &*checked_arbitrary::<Rc<[u8]>>(&mut Unstructured::new(&x)).unwrap(),
1440
            &[2, 4, 6, 8, 1]
1441
        );
1442
        assert_eq!(
1443
            checked_arbitrary::<Vec<u32>>(&mut Unstructured::new(&x)).unwrap(),
1444
            &[84148994]
1445
        );
1446
        assert_eq!(
1447
            checked_arbitrary::<String>(&mut Unstructured::new(&x)).unwrap(),
1448
            "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x01\x02\x03"
1449
        );
1450
    }
1451
1452
    #[test]
1453
    fn arbitrary_take_rest() {
1454
        // Basic examples
1455
        let x = [1, 2, 3, 4];
1456
        assert_eq!(
1457
            checked_arbitrary_take_rest::<&[u8]>(Unstructured::new(&x)).unwrap(),
1458
            &[1, 2, 3, 4]
1459
        );
1460
        assert_eq!(
1461
            checked_arbitrary_take_rest::<Vec<u8>>(Unstructured::new(&x)).unwrap(),
1462
            &[2, 4]
1463
        );
1464
        assert_eq!(
1465
            &*checked_arbitrary_take_rest::<Box<[u8]>>(Unstructured::new(&x)).unwrap(),
1466
            &[2, 4]
1467
        );
1468
        assert_eq!(
1469
            &*checked_arbitrary_take_rest::<Arc<[u8]>>(Unstructured::new(&x)).unwrap(),
1470
            &[2, 4]
1471
        );
1472
        assert_eq!(
1473
            &*checked_arbitrary_take_rest::<Rc<[u8]>>(Unstructured::new(&x)).unwrap(),
1474
            &[2, 4]
1475
        );
1476
        assert_eq!(
1477
            checked_arbitrary_take_rest::<Vec<u32>>(Unstructured::new(&x)).unwrap(),
1478
            &[0x040302]
1479
        );
1480
        assert_eq!(
1481
            checked_arbitrary_take_rest::<String>(Unstructured::new(&x)).unwrap(),
1482
            "\x01\x02\x03\x04"
1483
        );
1484
1485
        // Empty remainder
1486
        assert_eq!(
1487
            checked_arbitrary_take_rest::<&[u8]>(Unstructured::new(&[])).unwrap(),
1488
            &[]
1489
        );
1490
        assert_eq!(
1491
            checked_arbitrary_take_rest::<Vec<u8>>(Unstructured::new(&[])).unwrap(),
1492
            &[]
1493
        );
1494
1495
        // Cannot consume all but can consume part of the input
1496
        assert_eq!(
1497
            checked_arbitrary_take_rest::<String>(Unstructured::new(&[1, 0xFF, 2])).unwrap(),
1498
            "\x01"
1499
        );
1500
    }
1501
1502
    #[test]
1503
    fn size_hint_for_tuples() {
1504
        assert_eq!(
1505
            (7, Some(7)),
1506
            <(bool, u16, i32) as Arbitrary<'_>>::size_hint(0)
1507
        );
1508
        assert_eq!((1, None), <(u8, Vec<u8>) as Arbitrary>::size_hint(0));
1509
    }
1510
}
1511
1512
/// Multiple conflicting arbitrary attributes are used on the same field:
1513
/// ```compile_fail
1514
/// #[derive(::arbitrary::Arbitrary)]
1515
/// struct Point {
1516
///     #[arbitrary(value = 2)]
1517
///     #[arbitrary(value = 2)]
1518
///     x: i32,
1519
/// }
1520
/// ```
1521
///
1522
/// An unknown attribute:
1523
/// ```compile_fail
1524
/// #[derive(::arbitrary::Arbitrary)]
1525
/// struct Point {
1526
///     #[arbitrary(unknown_attr)]
1527
///     x: i32,
1528
/// }
1529
/// ```
1530
///
1531
/// An unknown attribute with a value:
1532
/// ```compile_fail
1533
/// #[derive(::arbitrary::Arbitrary)]
1534
/// struct Point {
1535
///     #[arbitrary(unknown_attr = 13)]
1536
///     x: i32,
1537
/// }
1538
/// ```
1539
///
1540
/// `value` without RHS:
1541
/// ```compile_fail
1542
/// #[derive(::arbitrary::Arbitrary)]
1543
/// struct Point {
1544
///     #[arbitrary(value)]
1545
///     x: i32,
1546
/// }
1547
/// ```
1548
///
1549
/// `with` without RHS:
1550
/// ```compile_fail
1551
/// #[derive(::arbitrary::Arbitrary)]
1552
/// struct Point {
1553
///     #[arbitrary(with)]
1554
///     x: i32,
1555
/// }
1556
/// ```
1557
///
1558
/// Multiple conflicting bounds at the container-level:
1559
/// ```compile_fail
1560
/// #[derive(::arbitrary::Arbitrary)]
1561
/// #[arbitrary(bound = "T: Default")]
1562
/// #[arbitrary(bound = "T: Default")]
1563
/// struct Point<T: Default> {
1564
///     #[arbitrary(default)]
1565
///     x: T,
1566
/// }
1567
/// ```
1568
///
1569
/// Multiple conflicting bounds in a single bound attribute:
1570
/// ```compile_fail
1571
/// #[derive(::arbitrary::Arbitrary)]
1572
/// #[arbitrary(bound = "T: Default, T: Default")]
1573
/// struct Point<T: Default> {
1574
///     #[arbitrary(default)]
1575
///     x: T,
1576
/// }
1577
/// ```
1578
///
1579
/// Multiple conflicting bounds in multiple bound attributes:
1580
/// ```compile_fail
1581
/// #[derive(::arbitrary::Arbitrary)]
1582
/// #[arbitrary(bound = "T: Default", bound = "T: Default")]
1583
/// struct Point<T: Default> {
1584
///     #[arbitrary(default)]
1585
///     x: T,
1586
/// }
1587
/// ```
1588
///
1589
/// Too many bounds supplied:
1590
/// ```compile_fail
1591
/// #[derive(::arbitrary::Arbitrary)]
1592
/// #[arbitrary(bound = "T: Default")]
1593
/// struct Point {
1594
///     x: i32,
1595
/// }
1596
/// ```
1597
///
1598
/// Too many bounds supplied across multiple attributes:
1599
/// ```compile_fail
1600
/// #[derive(::arbitrary::Arbitrary)]
1601
/// #[arbitrary(bound = "T: Default")]
1602
/// #[arbitrary(bound = "U: Default")]
1603
/// struct Point<T: Default> {
1604
///     #[arbitrary(default)]
1605
///     x: T,
1606
/// }
1607
/// ```
1608
#[cfg(all(doctest, feature = "derive"))]
1609
pub struct CompileFailTests;
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/arbitrary-1.3.2/src/size_hint.rs
Line
Count
Source
1
//! Utilities for working with and combining the results of
2
//! [`Arbitrary::size_hint`][crate::Arbitrary::size_hint].
3
4
/// Protects against potential infinite recursion when calculating size hints
5
/// due to indirect type recursion.
6
///
7
/// When the depth is not too deep, calls `f` with `depth + 1` to calculate the
8
/// size hint.
9
///
10
/// Otherwise, returns the default size hint: `(0, None)`.
11
#[inline]
12
0
pub fn recursion_guard(
13
0
    depth: usize,
14
0
    f: impl FnOnce(usize) -> (usize, Option<usize>),
15
0
) -> (usize, Option<usize>) {
16
    const MAX_DEPTH: usize = 20;
17
0
    if depth > MAX_DEPTH {
18
0
        (0, None)
19
    } else {
20
0
        f(depth + 1)
21
    }
22
0
}
23
24
/// Take the sum of the `lhs` and `rhs` size hints.
25
#[inline]
26
0
pub fn and(lhs: (usize, Option<usize>), rhs: (usize, Option<usize>)) -> (usize, Option<usize>) {
27
0
    let lower = lhs.0 + rhs.0;
28
0
    let upper = lhs.1.and_then(|lhs| rhs.1.map(|rhs| lhs + rhs));
29
0
    (lower, upper)
30
0
}
31
32
/// Take the sum of all of the given size hints.
33
///
34
/// If `hints` is empty, returns `(0, Some(0))`, aka the size of consuming
35
/// nothing.
36
#[inline]
37
0
pub fn and_all(hints: &[(usize, Option<usize>)]) -> (usize, Option<usize>) {
38
0
    hints.iter().copied().fold((0, Some(0)), and)
39
0
}
40
41
/// Take the minimum of the lower bounds and maximum of the upper bounds in the
42
/// `lhs` and `rhs` size hints.
43
#[inline]
44
0
pub fn or(lhs: (usize, Option<usize>), rhs: (usize, Option<usize>)) -> (usize, Option<usize>) {
45
0
    let lower = std::cmp::min(lhs.0, rhs.0);
46
0
    let upper = lhs
47
0
        .1
48
0
        .and_then(|lhs| rhs.1.map(|rhs| std::cmp::max(lhs, rhs)));
49
0
    (lower, upper)
50
0
}
51
52
/// Take the maximum of the `lhs` and `rhs` size hints.
53
///
54
/// If `hints` is empty, returns `(0, Some(0))`, aka the size of consuming
55
/// nothing.
56
#[inline]
57
0
pub fn or_all(hints: &[(usize, Option<usize>)]) -> (usize, Option<usize>) {
58
0
    if let Some(head) = hints.first().copied() {
59
0
        hints[1..].iter().copied().fold(head, or)
60
    } else {
61
0
        (0, Some(0))
62
    }
63
0
}
64
65
#[cfg(test)]
66
mod tests {
67
    #[test]
68
    fn and() {
69
        assert_eq!((5, Some(5)), super::and((2, Some(2)), (3, Some(3))));
70
        assert_eq!((5, None), super::and((2, Some(2)), (3, None)));
71
        assert_eq!((5, None), super::and((2, None), (3, Some(3))));
72
        assert_eq!((5, None), super::and((2, None), (3, None)));
73
    }
74
75
    #[test]
76
    fn or() {
77
        assert_eq!((2, Some(3)), super::or((2, Some(2)), (3, Some(3))));
78
        assert_eq!((2, None), super::or((2, Some(2)), (3, None)));
79
        assert_eq!((2, None), super::or((2, None), (3, Some(3))));
80
        assert_eq!((2, None), super::or((2, None), (3, None)));
81
    }
82
83
    #[test]
84
    fn and_all() {
85
        assert_eq!((0, Some(0)), super::and_all(&[]));
86
        assert_eq!(
87
            (7, Some(7)),
88
            super::and_all(&[(1, Some(1)), (2, Some(2)), (4, Some(4))])
89
        );
90
        assert_eq!(
91
            (7, None),
92
            super::and_all(&[(1, Some(1)), (2, Some(2)), (4, None)])
93
        );
94
        assert_eq!(
95
            (7, None),
96
            super::and_all(&[(1, Some(1)), (2, None), (4, Some(4))])
97
        );
98
        assert_eq!(
99
            (7, None),
100
            super::and_all(&[(1, None), (2, Some(2)), (4, Some(4))])
101
        );
102
    }
103
104
    #[test]
105
    fn or_all() {
106
        assert_eq!((0, Some(0)), super::or_all(&[]));
107
        assert_eq!(
108
            (1, Some(4)),
109
            super::or_all(&[(1, Some(1)), (2, Some(2)), (4, Some(4))])
110
        );
111
        assert_eq!(
112
            (1, None),
113
            super::or_all(&[(1, Some(1)), (2, Some(2)), (4, None)])
114
        );
115
        assert_eq!(
116
            (1, None),
117
            super::or_all(&[(1, Some(1)), (2, None), (4, Some(4))])
118
        );
119
        assert_eq!(
120
            (1, None),
121
            super::or_all(&[(1, None), (2, Some(2)), (4, Some(4))])
122
        );
123
    }
124
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/arbitrary-1.3.2/src/unstructured.rs
Line
Count
Source
1
// Copyright © 2019 The Rust Fuzz Project Developers.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
//! Wrappers around raw, unstructured bytes.
10
11
use crate::{Arbitrary, Error, Result};
12
use std::marker::PhantomData;
13
use std::ops::ControlFlow;
14
use std::{mem, ops};
15
16
/// A source of unstructured data.
17
///
18
/// An `Unstructured` helps `Arbitrary` implementations interpret raw data
19
/// (typically provided by a fuzzer) as a "DNA string" that describes how to
20
/// construct the `Arbitrary` type. The goal is that a small change to the "DNA
21
/// string" (the raw data wrapped by an `Unstructured`) results in a small
22
/// change to the generated `Arbitrary` instance. This helps a fuzzer
23
/// efficiently explore the `Arbitrary`'s input space.
24
///
25
/// `Unstructured` is deterministic: given the same raw data, the same series of
26
/// API calls will return the same results (modulo system resource constraints,
27
/// like running out of memory). However, `Unstructured` does not guarantee
28
/// anything beyond that: it makes not guarantee that it will yield bytes from
29
/// the underlying data in any particular order.
30
///
31
/// You shouldn't generally need to use an `Unstructured` unless you are writing
32
/// a custom `Arbitrary` implementation by hand, instead of deriving it. Mostly,
33
/// you should just be passing it through to nested `Arbitrary::arbitrary`
34
/// calls.
35
///
36
/// # Example
37
///
38
/// Imagine you were writing a color conversion crate. You might want to write
39
/// fuzz tests that take a random RGB color and assert various properties, run
40
/// functions and make sure nothing panics, etc.
41
///
42
/// Below is what translating the fuzzer's raw input into an `Unstructured` and
43
/// using that to generate an arbitrary RGB color might look like:
44
///
45
/// ```
46
/// # #[cfg(feature = "derive")] fn foo() {
47
/// use arbitrary::{Arbitrary, Unstructured};
48
///
49
/// /// An RGB color.
50
/// #[derive(Arbitrary)]
51
/// pub struct Rgb {
52
///     r: u8,
53
///     g: u8,
54
///     b: u8,
55
/// }
56
///
57
/// // Get the raw bytes from the fuzzer.
58
/// #   let get_input_from_fuzzer = || &[];
59
/// let raw_data: &[u8] = get_input_from_fuzzer();
60
///
61
/// // Wrap it in an `Unstructured`.
62
/// let mut unstructured = Unstructured::new(raw_data);
63
///
64
/// // Generate an `Rgb` color and run our checks.
65
/// if let Ok(rgb) = Rgb::arbitrary(&mut unstructured) {
66
/// #   let run_my_color_conversion_checks = |_| {};
67
///     run_my_color_conversion_checks(rgb);
68
/// }
69
/// # }
70
/// ```
71
pub struct Unstructured<'a> {
72
    data: &'a [u8],
73
}
74
75
impl<'a> Unstructured<'a> {
76
    /// Create a new `Unstructured` from the given raw data.
77
    ///
78
    /// # Example
79
    ///
80
    /// ```
81
    /// use arbitrary::Unstructured;
82
    ///
83
    /// let u = Unstructured::new(&[1, 2, 3, 4]);
84
    /// ```
85
0
    pub fn new(data: &'a [u8]) -> Self {
86
0
        Unstructured { data }
87
0
    }
88
89
    /// Get the number of remaining bytes of underlying data that are still
90
    /// available.
91
    ///
92
    /// # Example
93
    ///
94
    /// ```
95
    /// use arbitrary::{Arbitrary, Unstructured};
96
    ///
97
    /// let mut u = Unstructured::new(&[1, 2, 3]);
98
    ///
99
    /// // Initially have three bytes of data.
100
    /// assert_eq!(u.len(), 3);
101
    ///
102
    /// // Generating a `bool` consumes one byte from the underlying data, so
103
    /// // we are left with two bytes afterwards.
104
    /// let _ = bool::arbitrary(&mut u);
105
    /// assert_eq!(u.len(), 2);
106
    /// ```
107
    #[inline]
108
0
    pub fn len(&self) -> usize {
109
0
        self.data.len()
110
0
    }
111
112
    /// Is the underlying unstructured data exhausted?
113
    ///
114
    /// `unstructured.is_empty()` is the same as `unstructured.len() == 0`.
115
    ///
116
    /// # Example
117
    ///
118
    /// ```
119
    /// use arbitrary::{Arbitrary, Unstructured};
120
    ///
121
    /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
122
    ///
123
    /// // Initially, we are not empty.
124
    /// assert!(!u.is_empty());
125
    ///
126
    /// // Generating a `u32` consumes all four bytes of the underlying data, so
127
    /// // we become empty afterwards.
128
    /// let _ = u32::arbitrary(&mut u);
129
    /// assert!(u.is_empty());
130
    /// ```
131
    #[inline]
132
0
    pub fn is_empty(&self) -> bool {
133
0
        self.len() == 0
134
0
    }
135
136
    /// Generate an arbitrary instance of `A`.
137
    ///
138
    /// This is simply a helper method that is equivalent to `<A as
139
    /// Arbitrary>::arbitrary(self)`. This helper is a little bit more concise,
140
    /// and can be used in situations where Rust's type inference will figure
141
    /// out what `A` should be.
142
    ///
143
    /// # Example
144
    ///
145
    /// ```
146
    /// # #[cfg(feature="derive")] fn foo() -> arbitrary::Result<()> {
147
    /// use arbitrary::{Arbitrary, Unstructured};
148
    ///
149
    /// #[derive(Arbitrary)]
150
    /// struct MyType {
151
    ///     // ...
152
    /// }
153
    ///
154
    /// fn do_stuff(value: MyType) {
155
    /// #   let _ = value;
156
    ///     // ...
157
    /// }
158
    ///
159
    /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
160
    ///
161
    /// // Rust's type inference can figure out that `value` should be of type
162
    /// // `MyType` here:
163
    /// let value = u.arbitrary()?;
164
    /// do_stuff(value);
165
    /// # Ok(()) }
166
    /// ```
167
0
    pub fn arbitrary<A>(&mut self) -> Result<A>
168
0
    where
169
0
        A: Arbitrary<'a>,
170
0
    {
171
0
        <A as Arbitrary<'a>>::arbitrary(self)
172
0
    }
Unexecuted instantiation: _RINvMNtCsjLyxDhx7q6s_9arbitrary12unstructuredNtB3_12Unstructured9arbitrarybEB5_
Unexecuted instantiation: _RINvMNtCsjLyxDhx7q6s_9arbitrary12unstructuredNtB3_12Unstructured9arbitraryNtNtNtCsbQ8arDwx5Xq_4core3net7ip_addr8Ipv6AddrEB5_
Unexecuted instantiation: _RINvMNtCsjLyxDhx7q6s_9arbitrary12unstructuredNtB3_12Unstructured9arbitraryNtNtNtCsbQ8arDwx5Xq_4core3net7ip_addr8Ipv4AddrEB5_
173
174
    /// Get the number of elements to insert when building up a collection of
175
    /// arbitrary `ElementType`s.
176
    ///
177
    /// This uses the [`<ElementType as
178
    /// Arbitrary>::size_hint`][crate::Arbitrary::size_hint] method to smartly
179
    /// choose a length such that we most likely have enough underlying bytes to
180
    /// construct that many arbitrary `ElementType`s.
181
    ///
182
    /// This should only be called within an `Arbitrary` implementation.
183
    ///
184
    /// # Example
185
    ///
186
    /// ```
187
    /// use arbitrary::{Arbitrary, Result, Unstructured};
188
    /// # pub struct MyCollection<T> { _t: std::marker::PhantomData<T> }
189
    /// # impl<T> MyCollection<T> {
190
    /// #     pub fn with_capacity(capacity: usize) -> Self { MyCollection { _t: std::marker::PhantomData } }
191
    /// #     pub fn insert(&mut self, element: T) {}
192
    /// # }
193
    ///
194
    /// impl<'a, T> Arbitrary<'a> for MyCollection<T>
195
    /// where
196
    ///     T: Arbitrary<'a>,
197
    /// {
198
    ///     fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
199
    ///         // Get the number of `T`s we should insert into our collection.
200
    ///         let len = u.arbitrary_len::<T>()?;
201
    ///
202
    ///         // And then create a collection of that length!
203
    ///         let mut my_collection = MyCollection::with_capacity(len);
204
    ///         for _ in 0..len {
205
    ///             let element = T::arbitrary(u)?;
206
    ///             my_collection.insert(element);
207
    ///         }
208
    ///
209
    ///         Ok(my_collection)
210
    ///     }
211
    /// }
212
    /// ```
213
0
    pub fn arbitrary_len<ElementType>(&mut self) -> Result<usize>
214
0
    where
215
0
        ElementType: Arbitrary<'a>,
216
0
    {
217
0
        let byte_size = self.arbitrary_byte_size()?;
218
0
        let (lower, upper) = <ElementType as Arbitrary>::size_hint(0);
219
0
        let elem_size = upper.unwrap_or(lower * 2);
220
0
        let elem_size = std::cmp::max(1, elem_size);
221
0
        Ok(byte_size / elem_size)
222
0
    }
223
224
0
    fn arbitrary_byte_size(&mut self) -> Result<usize> {
225
0
        if self.data.is_empty() {
226
0
            Ok(0)
227
0
        } else if self.data.len() == 1 {
228
0
            self.data = &[];
229
0
            Ok(0)
230
        } else {
231
            // Take lengths from the end of the data, since the `libFuzzer` folks
232
            // found that this lets fuzzers more efficiently explore the input
233
            // space.
234
            //
235
            // https://github.com/rust-fuzz/libfuzzer-sys/blob/0c450753/libfuzzer/utils/FuzzedDataProvider.h#L92-L97
236
237
            // We only consume as many bytes as necessary to cover the entire
238
            // range of the byte string.
239
            // Note: We cast to u64 so we don't overflow when checking std::u32::MAX + 4 on 32-bit archs
240
0
            let len = if self.data.len() as u64 <= std::u8::MAX as u64 + 1 {
241
0
                let bytes = 1;
242
0
                let max_size = self.data.len() - bytes;
243
0
                let (rest, for_size) = self.data.split_at(max_size);
244
0
                self.data = rest;
245
0
                Self::int_in_range_impl(0..=max_size as u8, for_size.iter().copied())?.0 as usize
246
0
            } else if self.data.len() as u64 <= std::u16::MAX as u64 + 2 {
247
0
                let bytes = 2;
248
0
                let max_size = self.data.len() - bytes;
249
0
                let (rest, for_size) = self.data.split_at(max_size);
250
0
                self.data = rest;
251
0
                Self::int_in_range_impl(0..=max_size as u16, for_size.iter().copied())?.0 as usize
252
0
            } else if self.data.len() as u64 <= std::u32::MAX as u64 + 4 {
253
0
                let bytes = 4;
254
0
                let max_size = self.data.len() - bytes;
255
0
                let (rest, for_size) = self.data.split_at(max_size);
256
0
                self.data = rest;
257
0
                Self::int_in_range_impl(0..=max_size as u32, for_size.iter().copied())?.0 as usize
258
            } else {
259
0
                let bytes = 8;
260
0
                let max_size = self.data.len() - bytes;
261
0
                let (rest, for_size) = self.data.split_at(max_size);
262
0
                self.data = rest;
263
0
                Self::int_in_range_impl(0..=max_size as u64, for_size.iter().copied())?.0 as usize
264
            };
265
266
0
            Ok(len)
267
        }
268
0
    }
269
270
    /// Generate an integer within the given range.
271
    ///
272
    /// Do not use this to generate the size of a collection. Use
273
    /// `arbitrary_len` instead.
274
    ///
275
    /// # Panics
276
    ///
277
    /// Panics if `range.start > range.end`. That is, the given range must be
278
    /// non-empty.
279
    ///
280
    /// # Example
281
    ///
282
    /// ```
283
    /// use arbitrary::{Arbitrary, Unstructured};
284
    ///
285
    /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
286
    ///
287
    /// let x: i32 = u.int_in_range(-5_000..=-1_000)
288
    ///     .expect("constructed `u` with enough bytes to generate an `i32`");
289
    ///
290
    /// assert!(-5_000 <= x);
291
    /// assert!(x <= -1_000);
292
    /// ```
293
0
    pub fn int_in_range<T>(&mut self, range: ops::RangeInclusive<T>) -> Result<T>
294
0
    where
295
0
        T: Int,
296
0
    {
297
0
        let (result, bytes_consumed) = Self::int_in_range_impl(range, self.data.iter().cloned())?;
298
0
        self.data = &self.data[bytes_consumed..];
299
0
        Ok(result)
300
0
    }
Unexecuted instantiation: _RINvMNtCsjLyxDhx7q6s_9arbitrary12unstructuredNtB3_12Unstructured12int_in_rangejEB5_
Unexecuted instantiation: _RINvMNtCsjLyxDhx7q6s_9arbitrary12unstructuredNtB3_12Unstructured12int_in_rangemEB5_
301
302
0
    fn int_in_range_impl<T>(
303
0
        range: ops::RangeInclusive<T>,
304
0
        mut bytes: impl Iterator<Item = u8>,
305
0
    ) -> Result<(T, usize)>
306
0
    where
307
0
        T: Int,
308
0
    {
309
0
        let start = *range.start();
310
0
        let end = *range.end();
311
0
        assert!(
312
0
            start <= end,
313
0
            "`arbitrary::Unstructured::int_in_range` requires a non-empty range"
314
        );
315
316
        // When there is only one possible choice, don't waste any entropy from
317
        // the underlying data.
318
0
        if start == end {
319
0
            return Ok((start, 0));
320
0
        }
321
0
322
0
        // From here on out we work with the unsigned representation. All of the
323
0
        // operations performed below work out just as well whether or not `T`
324
0
        // is a signed or unsigned integer.
325
0
        let start = start.to_unsigned();
326
0
        let end = end.to_unsigned();
327
0
328
0
        let delta = end.wrapping_sub(start);
329
0
        debug_assert_ne!(delta, T::Unsigned::ZERO);
330
331
        // Compute an arbitrary integer offset from the start of the range. We
332
        // do this by consuming `size_of(T)` bytes from the input to create an
333
        // arbitrary integer and then clamping that int into our range bounds
334
        // with a modulo operation.
335
0
        let mut arbitrary_int = T::Unsigned::ZERO;
336
0
        let mut bytes_consumed: usize = 0;
337
338
0
        while (bytes_consumed < mem::size_of::<T>())
339
0
            && (delta >> T::Unsigned::from_usize(bytes_consumed * 8)) > T::Unsigned::ZERO
340
        {
341
0
            let byte = match bytes.next() {
342
0
                None => break,
343
0
                Some(b) => b,
344
0
            };
345
0
            bytes_consumed += 1;
346
0
347
0
            // Combine this byte into our arbitrary integer, but avoid
348
0
            // overflowing the shift for `u8` and `i8`.
349
0
            arbitrary_int = if mem::size_of::<T>() == 1 {
350
0
                T::Unsigned::from_u8(byte)
351
            } else {
352
0
                (arbitrary_int << 8) | T::Unsigned::from_u8(byte)
353
            };
354
        }
355
356
0
        let offset = if delta == T::Unsigned::MAX {
357
0
            arbitrary_int
358
        } else {
359
0
            arbitrary_int % (delta.checked_add(T::Unsigned::ONE).unwrap())
360
        };
361
362
        // Finally, we add `start` to our offset from `start` to get the result
363
        // actual value within the range.
364
0
        let result = start.wrapping_add(offset);
365
0
366
0
        // And convert back to our maybe-signed representation.
367
0
        let result = T::from_unsigned(result);
368
0
        debug_assert!(*range.start() <= result);
369
0
        debug_assert!(result <= *range.end());
370
371
0
        Ok((result, bytes_consumed))
372
0
    }
Unexecuted instantiation: _RINvMNtCsjLyxDhx7q6s_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_implhINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6copied6CopiedINtNtNtB1t_5slice4iter4IterhEEEB5_
Unexecuted instantiation: _RINvMNtCsjLyxDhx7q6s_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_impljINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6cloned6ClonedINtNtNtB1t_5slice4iter4IterhEEEB5_
Unexecuted instantiation: _RINvMNtCsjLyxDhx7q6s_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_implmINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6cloned6ClonedINtNtNtB1t_5slice4iter4IterhEEEB5_
Unexecuted instantiation: _RINvMNtCsjLyxDhx7q6s_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_implmINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6copied6CopiedINtNtNtB1t_5slice4iter4IterhEEEB5_
Unexecuted instantiation: _RINvMNtCsjLyxDhx7q6s_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_impltINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6copied6CopiedINtNtNtB1t_5slice4iter4IterhEEEB5_
Unexecuted instantiation: _RINvMNtCsjLyxDhx7q6s_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_implyINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6copied6CopiedINtNtNtB1t_5slice4iter4IterhEEEB5_
373
374
    /// Choose one of the given choices.
375
    ///
376
    /// This should only be used inside of `Arbitrary` implementations.
377
    ///
378
    /// Returns an error if there is not enough underlying data to make a
379
    /// choice or if no choices are provided.
380
    ///
381
    /// # Examples
382
    ///
383
    /// Selecting from an array of choices:
384
    ///
385
    /// ```
386
    /// use arbitrary::Unstructured;
387
    ///
388
    /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
389
    /// let choices = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
390
    ///
391
    /// let choice = u.choose(&choices).unwrap();
392
    ///
393
    /// println!("chose {}", choice);
394
    /// ```
395
    ///
396
    /// An error is returned if no choices are provided:
397
    ///
398
    /// ```
399
    /// use arbitrary::Unstructured;
400
    ///
401
    /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
402
    /// let choices: [char; 0] = [];
403
    ///
404
    /// let result = u.choose(&choices);
405
    ///
406
    /// assert!(result.is_err());
407
    /// ```
408
0
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
0
        let idx = self.choose_index(choices.len())?;
410
0
        Ok(&choices[idx])
411
0
    }
412
413
    /// Choose a value in `0..len`.
414
    ///
415
    /// Returns an error if the `len` is zero.
416
    ///
417
    /// # Examples
418
    ///
419
    /// Using Fisher–Yates shuffle shuffle to gerate an arbitrary permutation.
420
    ///
421
    /// [Fisher–Yates shuffle]: https://en.wikipedia.org/wiki/Fisher–Yates_shuffle
422
    ///
423
    /// ```
424
    /// use arbitrary::Unstructured;
425
    ///
426
    /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
427
    /// let mut permutation = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
428
    /// let mut to_permute = &mut permutation[..];
429
    /// while to_permute.len() > 1 {
430
    ///     let idx = u.choose_index(to_permute.len()).unwrap();
431
    ///     to_permute.swap(0, idx);
432
    ///     to_permute = &mut to_permute[1..];
433
    /// }
434
    ///
435
    /// println!("permutation: {:?}", permutation);
436
    /// ```
437
    ///
438
    /// An error is returned if the length is zero:
439
    ///
440
    /// ```
441
    /// use arbitrary::Unstructured;
442
    ///
443
    /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
444
    /// let array: [i32; 0] = [];
445
    ///
446
    /// let result = u.choose_index(array.len());
447
    ///
448
    /// assert!(result.is_err());
449
    /// ```
450
0
    pub fn choose_index(&mut self, len: usize) -> Result<usize> {
451
0
        if len == 0 {
452
0
            return Err(Error::EmptyChoose);
453
0
        }
454
0
        let idx = self.int_in_range(0..=len - 1)?;
455
0
        Ok(idx)
456
0
    }
457
458
    /// Generate a boolean according to the given ratio.
459
    ///
460
    /// # Panics
461
    ///
462
    /// Panics when the numerator and denominator do not meet these constraints:
463
    ///
464
    /// * `0 < numerator <= denominator`
465
    ///
466
    /// # Example
467
    ///
468
    /// Generate a boolean that is `true` five sevenths of the time:
469
    ///
470
    /// ```
471
    /// # fn foo() -> arbitrary::Result<()> {
472
    /// use arbitrary::Unstructured;
473
    ///
474
    /// # let my_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
475
    /// let mut u = Unstructured::new(&my_data);
476
    ///
477
    /// if u.ratio(5, 7)? {
478
    ///     // Take this branch 5/7 of the time.
479
    /// }
480
    /// # Ok(())
481
    /// # }
482
    /// ```
483
0
    pub fn ratio<T>(&mut self, numerator: T, denominator: T) -> Result<bool>
484
0
    where
485
0
        T: Int,
486
0
    {
487
0
        assert!(T::ZERO < numerator);
488
0
        assert!(numerator <= denominator);
489
0
        let x = self.int_in_range(T::ONE..=denominator)?;
490
0
        Ok(x <= numerator)
491
0
    }
492
493
    /// Fill a `buffer` with bytes from the underlying raw data.
494
    ///
495
    /// This should only be called within an `Arbitrary` implementation. This is
496
    /// a very low-level operation. You should generally prefer calling nested
497
    /// `Arbitrary` implementations like `<Vec<u8>>::arbitrary` and
498
    /// `String::arbitrary` over using this method directly.
499
    ///
500
    /// If this `Unstructured` does not have enough underlying data to fill the
501
    /// whole `buffer`, it pads the buffer out with zeros.
502
    ///
503
    /// # Example
504
    ///
505
    /// ```
506
    /// use arbitrary::Unstructured;
507
    ///
508
    /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
509
    ///
510
    /// let mut buf = [0; 2];
511
    ///
512
    /// assert!(u.fill_buffer(&mut buf).is_ok());
513
    /// assert_eq!(buf, [1, 2]);
514
    ///
515
    /// assert!(u.fill_buffer(&mut buf).is_ok());
516
    /// assert_eq!(buf, [3, 4]);
517
    ///
518
    /// assert!(u.fill_buffer(&mut buf).is_ok());
519
    /// assert_eq!(buf, [0, 0]);
520
    /// ```
521
0
    pub fn fill_buffer(&mut self, buffer: &mut [u8]) -> Result<()> {
522
0
        let n = std::cmp::min(buffer.len(), self.data.len());
523
0
        buffer[..n].copy_from_slice(&self.data[..n]);
524
0
        for byte in buffer[n..].iter_mut() {
525
0
            *byte = 0;
526
0
        }
527
0
        self.data = &self.data[n..];
528
0
        Ok(())
529
0
    }
530
531
    /// Provide `size` bytes from the underlying raw data.
532
    ///
533
    /// This should only be called within an `Arbitrary` implementation. This is
534
    /// a very low-level operation. You should generally prefer calling nested
535
    /// `Arbitrary` implementations like `<Vec<u8>>::arbitrary` and
536
    /// `String::arbitrary` over using this method directly.
537
    ///
538
    /// # Example
539
    ///
540
    /// ```
541
    /// use arbitrary::Unstructured;
542
    ///
543
    /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
544
    ///
545
    /// assert!(u.bytes(2).unwrap() == &[1, 2]);
546
    /// assert!(u.bytes(2).unwrap() == &[3, 4]);
547
    /// ```
548
0
    pub fn bytes(&mut self, size: usize) -> Result<&'a [u8]> {
549
0
        if self.data.len() < size {
550
0
            return Err(Error::NotEnoughData);
551
0
        }
552
0
553
0
        let (for_buf, rest) = self.data.split_at(size);
554
0
        self.data = rest;
555
0
        Ok(for_buf)
556
0
    }
557
558
    /// Peek at `size` number of bytes of the underlying raw input.
559
    ///
560
    /// Does not consume the bytes, only peeks at them.
561
    ///
562
    /// Returns `None` if there are not `size` bytes left in the underlying raw
563
    /// input.
564
    ///
565
    /// # Example
566
    ///
567
    /// ```
568
    /// use arbitrary::Unstructured;
569
    ///
570
    /// let u = Unstructured::new(&[1, 2, 3]);
571
    ///
572
    /// assert_eq!(u.peek_bytes(0).unwrap(), []);
573
    /// assert_eq!(u.peek_bytes(1).unwrap(), [1]);
574
    /// assert_eq!(u.peek_bytes(2).unwrap(), [1, 2]);
575
    /// assert_eq!(u.peek_bytes(3).unwrap(), [1, 2, 3]);
576
    ///
577
    /// assert!(u.peek_bytes(4).is_none());
578
    /// ```
579
0
    pub fn peek_bytes(&self, size: usize) -> Option<&'a [u8]> {
580
0
        self.data.get(..size)
581
0
    }
582
583
    /// Consume all of the rest of the remaining underlying bytes.
584
    ///
585
    /// Returns a slice of all the remaining, unconsumed bytes.
586
    ///
587
    /// # Example
588
    ///
589
    /// ```
590
    /// use arbitrary::Unstructured;
591
    ///
592
    /// let mut u = Unstructured::new(&[1, 2, 3]);
593
    ///
594
    /// let mut remaining = u.take_rest();
595
    ///
596
    /// assert_eq!(remaining, [1, 2, 3]);
597
    /// ```
598
0
    pub fn take_rest(mut self) -> &'a [u8] {
599
0
        mem::take(&mut self.data)
600
0
    }
601
602
    /// Provide an iterator over elements for constructing a collection
603
    ///
604
    /// This is useful for implementing [`Arbitrary::arbitrary`] on collections
605
    /// since the implementation is simply `u.arbitrary_iter()?.collect()`
606
0
    pub fn arbitrary_iter<'b, ElementType: Arbitrary<'a>>(
607
0
        &'b mut self,
608
0
    ) -> Result<ArbitraryIter<'a, 'b, ElementType>> {
609
0
        Ok(ArbitraryIter {
610
0
            u: &mut *self,
611
0
            _marker: PhantomData,
612
0
        })
613
0
    }
614
615
    /// Provide an iterator over elements for constructing a collection from
616
    /// all the remaining bytes.
617
    ///
618
    /// This is useful for implementing [`Arbitrary::arbitrary_take_rest`] on collections
619
    /// since the implementation is simply `u.arbitrary_take_rest_iter()?.collect()`
620
0
    pub fn arbitrary_take_rest_iter<ElementType: Arbitrary<'a>>(
621
0
        self,
622
0
    ) -> Result<ArbitraryTakeRestIter<'a, ElementType>> {
623
0
        Ok(ArbitraryTakeRestIter {
624
0
            u: self,
625
0
            _marker: PhantomData,
626
0
        })
627
0
    }
628
629
    /// Call the given function an arbitrary number of times.
630
    ///
631
    /// The function is given this `Unstructured` so that it can continue to
632
    /// generate arbitrary data and structures.
633
    ///
634
    /// You may optionaly specify minimum and maximum bounds on the number of
635
    /// times the function is called.
636
    ///
637
    /// You may break out of the loop early by returning
638
    /// `Ok(std::ops::ControlFlow::Break)`. To continue the loop, return
639
    /// `Ok(std::ops::ControlFlow::Continue)`.
640
    ///
641
    /// # Panics
642
    ///
643
    /// Panics if `min > max`.
644
    ///
645
    /// # Example
646
    ///
647
    /// Call a closure that generates an arbitrary type inside a context an
648
    /// arbitrary number of times:
649
    ///
650
    /// ```
651
    /// use arbitrary::{Result, Unstructured};
652
    /// use std::ops::ControlFlow;
653
    ///
654
    /// enum Type {
655
    ///     /// A boolean type.
656
    ///     Bool,
657
    ///
658
    ///     /// An integer type.
659
    ///     Int,
660
    ///
661
    ///     /// A list of the `i`th type in this type's context.
662
    ///     List(usize),
663
    /// }
664
    ///
665
    /// fn arbitrary_types_context(u: &mut Unstructured) -> Result<Vec<Type>> {
666
    ///     let mut context = vec![];
667
    ///
668
    ///     u.arbitrary_loop(Some(10), Some(20), |u| {
669
    ///         let num_choices = if context.is_empty() {
670
    ///             2
671
    ///         } else {
672
    ///             3
673
    ///         };
674
    ///         let ty = match u.int_in_range::<u8>(1..=num_choices)? {
675
    ///             1 => Type::Bool,
676
    ///             2 => Type::Int,
677
    ///             3 => Type::List(u.int_in_range(0..=context.len() - 1)?),
678
    ///             _ => unreachable!(),
679
    ///         };
680
    ///         context.push(ty);
681
    ///         Ok(ControlFlow::Continue(()))
682
    ///     })?;
683
    ///
684
    ///     // The number of loop iterations are constrained by the min/max
685
    ///     // bounds that we provided.
686
    ///     assert!(context.len() >= 10);
687
    ///     assert!(context.len() <= 20);
688
    ///
689
    ///     Ok(context)
690
    /// }
691
    /// ```
692
0
    pub fn arbitrary_loop(
693
0
        &mut self,
694
0
        min: Option<u32>,
695
0
        max: Option<u32>,
696
0
        mut f: impl FnMut(&mut Self) -> Result<ControlFlow<(), ()>>,
697
0
    ) -> Result<()> {
698
0
        let min = min.unwrap_or(0);
699
0
        let max = max.unwrap_or(u32::MAX);
700
0
701
0
        for _ in 0..self.int_in_range(min..=max)? {
702
0
            match f(self)? {
703
0
                ControlFlow::Continue(_) => continue,
704
0
                ControlFlow::Break(_) => break,
705
            }
706
        }
707
708
0
        Ok(())
709
0
    }
710
}
711
712
/// Utility iterator produced by [`Unstructured::arbitrary_iter`]
713
pub struct ArbitraryIter<'a, 'b, ElementType> {
714
    u: &'b mut Unstructured<'a>,
715
    _marker: PhantomData<ElementType>,
716
}
717
718
impl<'a, 'b, ElementType: Arbitrary<'a>> Iterator for ArbitraryIter<'a, 'b, ElementType> {
719
    type Item = Result<ElementType>;
720
0
    fn next(&mut self) -> Option<Result<ElementType>> {
721
0
        let keep_going = self.u.arbitrary().unwrap_or(false);
722
0
        if keep_going {
723
0
            Some(Arbitrary::arbitrary(self.u))
724
        } else {
725
0
            None
726
        }
727
0
    }
728
}
729
730
/// Utility iterator produced by [`Unstructured::arbitrary_take_rest_iter`]
731
pub struct ArbitraryTakeRestIter<'a, ElementType> {
732
    u: Unstructured<'a>,
733
    _marker: PhantomData<ElementType>,
734
}
735
736
impl<'a, ElementType: Arbitrary<'a>> Iterator for ArbitraryTakeRestIter<'a, ElementType> {
737
    type Item = Result<ElementType>;
738
0
    fn next(&mut self) -> Option<Result<ElementType>> {
739
0
        let keep_going = self.u.arbitrary().unwrap_or(false);
740
0
        if keep_going {
741
0
            Some(Arbitrary::arbitrary(&mut self.u))
742
        } else {
743
0
            None
744
        }
745
0
    }
746
}
747
748
/// A trait that is implemented for all of the primitive integers:
749
///
750
/// * `u8`
751
/// * `u16`
752
/// * `u32`
753
/// * `u64`
754
/// * `u128`
755
/// * `usize`
756
/// * `i8`
757
/// * `i16`
758
/// * `i32`
759
/// * `i64`
760
/// * `i128`
761
/// * `isize`
762
///
763
/// Don't implement this trait yourself.
764
pub trait Int:
765
    Copy
766
    + std::fmt::Debug
767
    + PartialOrd
768
    + Ord
769
    + ops::Sub<Self, Output = Self>
770
    + ops::Rem<Self, Output = Self>
771
    + ops::Shr<Self, Output = Self>
772
    + ops::Shl<usize, Output = Self>
773
    + ops::BitOr<Self, Output = Self>
774
{
775
    #[doc(hidden)]
776
    type Unsigned: Int;
777
778
    #[doc(hidden)]
779
    const ZERO: Self;
780
781
    #[doc(hidden)]
782
    const ONE: Self;
783
784
    #[doc(hidden)]
785
    const MAX: Self;
786
787
    #[doc(hidden)]
788
    fn from_u8(b: u8) -> Self;
789
790
    #[doc(hidden)]
791
    fn from_usize(u: usize) -> Self;
792
793
    #[doc(hidden)]
794
    fn checked_add(self, rhs: Self) -> Option<Self>;
795
796
    #[doc(hidden)]
797
    fn wrapping_add(self, rhs: Self) -> Self;
798
799
    #[doc(hidden)]
800
    fn wrapping_sub(self, rhs: Self) -> Self;
801
802
    #[doc(hidden)]
803
    fn to_unsigned(self) -> Self::Unsigned;
804
805
    #[doc(hidden)]
806
    fn from_unsigned(unsigned: Self::Unsigned) -> Self;
807
}
808
809
macro_rules! impl_int {
810
    ( $( $ty:ty : $unsigned_ty: ty ; )* ) => {
811
        $(
812
            impl Int for $ty {
813
                type Unsigned = $unsigned_ty;
814
815
                const ZERO: Self = 0;
816
817
                const ONE: Self = 1;
818
819
                const MAX: Self = Self::MAX;
820
821
0
                fn from_u8(b: u8) -> Self {
822
0
                    b as Self
823
0
                }
Unexecuted instantiation: _RNvXs1_NtCsjLyxDhx7q6s_9arbitrary12unstructuredhNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs2_NtCsjLyxDhx7q6s_9arbitrary12unstructuredtNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs3_NtCsjLyxDhx7q6s_9arbitrary12unstructuredmNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs4_NtCsjLyxDhx7q6s_9arbitrary12unstructuredyNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs5_NtCsjLyxDhx7q6s_9arbitrary12unstructuredoNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs6_NtCsjLyxDhx7q6s_9arbitrary12unstructuredjNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs7_NtCsjLyxDhx7q6s_9arbitrary12unstructuredaNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs8_NtCsjLyxDhx7q6s_9arbitrary12unstructuredsNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs9_NtCsjLyxDhx7q6s_9arbitrary12unstructuredlNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXsa_NtCsjLyxDhx7q6s_9arbitrary12unstructuredxNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXsb_NtCsjLyxDhx7q6s_9arbitrary12unstructurednNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXsc_NtCsjLyxDhx7q6s_9arbitrary12unstructurediNtB5_3Int7from_u8B7_
824
825
0
                fn from_usize(u: usize) -> Self {
826
0
                    u as Self
827
0
                }
Unexecuted instantiation: _RNvXs1_NtCsjLyxDhx7q6s_9arbitrary12unstructuredhNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs2_NtCsjLyxDhx7q6s_9arbitrary12unstructuredtNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs3_NtCsjLyxDhx7q6s_9arbitrary12unstructuredmNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs4_NtCsjLyxDhx7q6s_9arbitrary12unstructuredyNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs5_NtCsjLyxDhx7q6s_9arbitrary12unstructuredoNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs6_NtCsjLyxDhx7q6s_9arbitrary12unstructuredjNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs7_NtCsjLyxDhx7q6s_9arbitrary12unstructuredaNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs8_NtCsjLyxDhx7q6s_9arbitrary12unstructuredsNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs9_NtCsjLyxDhx7q6s_9arbitrary12unstructuredlNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXsa_NtCsjLyxDhx7q6s_9arbitrary12unstructuredxNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXsb_NtCsjLyxDhx7q6s_9arbitrary12unstructurednNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXsc_NtCsjLyxDhx7q6s_9arbitrary12unstructurediNtB5_3Int10from_usizeB7_
828
829
0
                fn checked_add(self, rhs: Self) -> Option<Self> {
830
0
                    <$ty>::checked_add(self, rhs)
831
0
                }
Unexecuted instantiation: _RNvXs1_NtCsjLyxDhx7q6s_9arbitrary12unstructuredhNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXs2_NtCsjLyxDhx7q6s_9arbitrary12unstructuredtNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXs3_NtCsjLyxDhx7q6s_9arbitrary12unstructuredmNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXs4_NtCsjLyxDhx7q6s_9arbitrary12unstructuredyNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXs5_NtCsjLyxDhx7q6s_9arbitrary12unstructuredoNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXs6_NtCsjLyxDhx7q6s_9arbitrary12unstructuredjNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXs7_NtCsjLyxDhx7q6s_9arbitrary12unstructuredaNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXs8_NtCsjLyxDhx7q6s_9arbitrary12unstructuredsNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXs9_NtCsjLyxDhx7q6s_9arbitrary12unstructuredlNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXsa_NtCsjLyxDhx7q6s_9arbitrary12unstructuredxNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXsb_NtCsjLyxDhx7q6s_9arbitrary12unstructurednNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXsc_NtCsjLyxDhx7q6s_9arbitrary12unstructurediNtB5_3Int11checked_add
832
833
0
                fn wrapping_add(self, rhs: Self) -> Self {
834
0
                    <$ty>::wrapping_add(self, rhs)
835
0
                }
Unexecuted instantiation: _RNvXs1_NtCsjLyxDhx7q6s_9arbitrary12unstructuredhNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs2_NtCsjLyxDhx7q6s_9arbitrary12unstructuredtNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs3_NtCsjLyxDhx7q6s_9arbitrary12unstructuredmNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs4_NtCsjLyxDhx7q6s_9arbitrary12unstructuredyNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs5_NtCsjLyxDhx7q6s_9arbitrary12unstructuredoNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs6_NtCsjLyxDhx7q6s_9arbitrary12unstructuredjNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs7_NtCsjLyxDhx7q6s_9arbitrary12unstructuredaNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs8_NtCsjLyxDhx7q6s_9arbitrary12unstructuredsNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs9_NtCsjLyxDhx7q6s_9arbitrary12unstructuredlNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXsa_NtCsjLyxDhx7q6s_9arbitrary12unstructuredxNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXsb_NtCsjLyxDhx7q6s_9arbitrary12unstructurednNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXsc_NtCsjLyxDhx7q6s_9arbitrary12unstructurediNtB5_3Int12wrapping_addB7_
836
837
0
                fn wrapping_sub(self, rhs: Self) -> Self {
838
0
                    <$ty>::wrapping_sub(self, rhs)
839
0
                }
Unexecuted instantiation: _RNvXs1_NtCsjLyxDhx7q6s_9arbitrary12unstructuredhNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs2_NtCsjLyxDhx7q6s_9arbitrary12unstructuredtNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs3_NtCsjLyxDhx7q6s_9arbitrary12unstructuredmNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs4_NtCsjLyxDhx7q6s_9arbitrary12unstructuredyNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs5_NtCsjLyxDhx7q6s_9arbitrary12unstructuredoNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs6_NtCsjLyxDhx7q6s_9arbitrary12unstructuredjNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs7_NtCsjLyxDhx7q6s_9arbitrary12unstructuredaNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs8_NtCsjLyxDhx7q6s_9arbitrary12unstructuredsNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs9_NtCsjLyxDhx7q6s_9arbitrary12unstructuredlNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXsa_NtCsjLyxDhx7q6s_9arbitrary12unstructuredxNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXsb_NtCsjLyxDhx7q6s_9arbitrary12unstructurednNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXsc_NtCsjLyxDhx7q6s_9arbitrary12unstructurediNtB5_3Int12wrapping_subB7_
840
841
0
                fn to_unsigned(self) -> Self::Unsigned {
842
0
                    self as $unsigned_ty
843
0
                }
Unexecuted instantiation: _RNvXs1_NtCsjLyxDhx7q6s_9arbitrary12unstructuredhNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs2_NtCsjLyxDhx7q6s_9arbitrary12unstructuredtNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs3_NtCsjLyxDhx7q6s_9arbitrary12unstructuredmNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs4_NtCsjLyxDhx7q6s_9arbitrary12unstructuredyNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs5_NtCsjLyxDhx7q6s_9arbitrary12unstructuredoNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs6_NtCsjLyxDhx7q6s_9arbitrary12unstructuredjNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs7_NtCsjLyxDhx7q6s_9arbitrary12unstructuredaNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs8_NtCsjLyxDhx7q6s_9arbitrary12unstructuredsNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs9_NtCsjLyxDhx7q6s_9arbitrary12unstructuredlNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXsa_NtCsjLyxDhx7q6s_9arbitrary12unstructuredxNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXsb_NtCsjLyxDhx7q6s_9arbitrary12unstructurednNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXsc_NtCsjLyxDhx7q6s_9arbitrary12unstructurediNtB5_3Int11to_unsignedB7_
844
845
0
                fn from_unsigned(unsigned: $unsigned_ty) -> Self {
846
0
                    unsigned as Self
847
0
                }
Unexecuted instantiation: _RNvXs1_NtCsjLyxDhx7q6s_9arbitrary12unstructuredhNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs2_NtCsjLyxDhx7q6s_9arbitrary12unstructuredtNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs3_NtCsjLyxDhx7q6s_9arbitrary12unstructuredmNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs4_NtCsjLyxDhx7q6s_9arbitrary12unstructuredyNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs5_NtCsjLyxDhx7q6s_9arbitrary12unstructuredoNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs6_NtCsjLyxDhx7q6s_9arbitrary12unstructuredjNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs7_NtCsjLyxDhx7q6s_9arbitrary12unstructuredaNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs8_NtCsjLyxDhx7q6s_9arbitrary12unstructuredsNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs9_NtCsjLyxDhx7q6s_9arbitrary12unstructuredlNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXsa_NtCsjLyxDhx7q6s_9arbitrary12unstructuredxNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXsb_NtCsjLyxDhx7q6s_9arbitrary12unstructurednNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXsc_NtCsjLyxDhx7q6s_9arbitrary12unstructurediNtB5_3Int13from_unsignedB7_
848
            }
849
        )*
850
    }
851
}
852
853
impl_int! {
854
    u8: u8;
855
    u16: u16;
856
    u32: u32;
857
    u64: u64;
858
    u128: u128;
859
    usize: usize;
860
    i8: u8;
861
    i16: u16;
862
    i32: u32;
863
    i64: u64;
864
    i128: u128;
865
    isize: usize;
866
}
867
868
#[cfg(test)]
869
mod tests {
870
    use super::*;
871
872
    #[test]
873
    fn test_byte_size() {
874
        let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 6]);
875
        // Should take one byte off the end
876
        assert_eq!(u.arbitrary_byte_size().unwrap(), 6);
877
        assert_eq!(u.len(), 9);
878
        let mut v = vec![];
879
        v.resize(260, 0);
880
        v.push(1);
881
        v.push(4);
882
        let mut u = Unstructured::new(&v);
883
        // Should read two bytes off the end
884
        assert_eq!(u.arbitrary_byte_size().unwrap(), 0x104);
885
        assert_eq!(u.len(), 260);
886
    }
887
888
    #[test]
889
    fn int_in_range_of_one() {
890
        let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 6]);
891
        let x = u.int_in_range(0..=0).unwrap();
892
        assert_eq!(x, 0);
893
        let choice = *u.choose(&[42]).unwrap();
894
        assert_eq!(choice, 42)
895
    }
896
897
    #[test]
898
    fn int_in_range_uses_minimal_amount_of_bytes() {
899
        let mut u = Unstructured::new(&[1, 2]);
900
        assert_eq!(1, u.int_in_range::<u8>(0..=u8::MAX).unwrap());
901
        assert_eq!(u.len(), 1);
902
903
        let mut u = Unstructured::new(&[1, 2]);
904
        assert_eq!(1, u.int_in_range::<u32>(0..=u8::MAX as u32).unwrap());
905
        assert_eq!(u.len(), 1);
906
907
        let mut u = Unstructured::new(&[1]);
908
        assert_eq!(1, u.int_in_range::<u32>(0..=u8::MAX as u32 + 1).unwrap());
909
        assert!(u.is_empty());
910
    }
911
912
    #[test]
913
    fn int_in_range_in_bounds() {
914
        for input in u8::MIN..=u8::MAX {
915
            let input = [input];
916
917
            let mut u = Unstructured::new(&input);
918
            let x = u.int_in_range(1..=u8::MAX).unwrap();
919
            assert_ne!(x, 0);
920
921
            let mut u = Unstructured::new(&input);
922
            let x = u.int_in_range(0..=u8::MAX - 1).unwrap();
923
            assert_ne!(x, u8::MAX);
924
        }
925
    }
926
927
    #[test]
928
    fn int_in_range_covers_unsigned_range() {
929
        // Test that we generate all values within the range given to
930
        // `int_in_range`.
931
932
        let mut full = [false; u8::MAX as usize + 1];
933
        let mut no_zero = [false; u8::MAX as usize];
934
        let mut no_max = [false; u8::MAX as usize];
935
        let mut narrow = [false; 10];
936
937
        for input in u8::MIN..=u8::MAX {
938
            let input = [input];
939
940
            let mut u = Unstructured::new(&input);
941
            let x = u.int_in_range(0..=u8::MAX).unwrap();
942
            full[x as usize] = true;
943
944
            let mut u = Unstructured::new(&input);
945
            let x = u.int_in_range(1..=u8::MAX).unwrap();
946
            no_zero[x as usize - 1] = true;
947
948
            let mut u = Unstructured::new(&input);
949
            let x = u.int_in_range(0..=u8::MAX - 1).unwrap();
950
            no_max[x as usize] = true;
951
952
            let mut u = Unstructured::new(&input);
953
            let x = u.int_in_range(100..=109).unwrap();
954
            narrow[x as usize - 100] = true;
955
        }
956
957
        for (i, covered) in full.iter().enumerate() {
958
            assert!(covered, "full[{}] should have been generated", i);
959
        }
960
        for (i, covered) in no_zero.iter().enumerate() {
961
            assert!(covered, "no_zero[{}] should have been generated", i);
962
        }
963
        for (i, covered) in no_max.iter().enumerate() {
964
            assert!(covered, "no_max[{}] should have been generated", i);
965
        }
966
        for (i, covered) in narrow.iter().enumerate() {
967
            assert!(covered, "narrow[{}] should have been generated", i);
968
        }
969
    }
970
971
    #[test]
972
    fn int_in_range_covers_signed_range() {
973
        // Test that we generate all values within the range given to
974
        // `int_in_range`.
975
976
        let mut full = [false; u8::MAX as usize + 1];
977
        let mut no_min = [false; u8::MAX as usize];
978
        let mut no_max = [false; u8::MAX as usize];
979
        let mut narrow = [false; 21];
980
981
        let abs_i8_min: isize = 128;
982
983
        for input in 0..=u8::MAX {
984
            let input = [input];
985
986
            let mut u = Unstructured::new(&input);
987
            let x = u.int_in_range(i8::MIN..=i8::MAX).unwrap();
988
            full[(x as isize + abs_i8_min) as usize] = true;
989
990
            let mut u = Unstructured::new(&input);
991
            let x = u.int_in_range(i8::MIN + 1..=i8::MAX).unwrap();
992
            no_min[(x as isize + abs_i8_min - 1) as usize] = true;
993
994
            let mut u = Unstructured::new(&input);
995
            let x = u.int_in_range(i8::MIN..=i8::MAX - 1).unwrap();
996
            no_max[(x as isize + abs_i8_min) as usize] = true;
997
998
            let mut u = Unstructured::new(&input);
999
            let x = u.int_in_range(-10..=10).unwrap();
1000
            narrow[(x as isize + 10) as usize] = true;
1001
        }
1002
1003
        for (i, covered) in full.iter().enumerate() {
1004
            assert!(covered, "full[{}] should have been generated", i);
1005
        }
1006
        for (i, covered) in no_min.iter().enumerate() {
1007
            assert!(covered, "no_min[{}] should have been generated", i);
1008
        }
1009
        for (i, covered) in no_max.iter().enumerate() {
1010
            assert!(covered, "no_max[{}] should have been generated", i);
1011
        }
1012
        for (i, covered) in narrow.iter().enumerate() {
1013
            assert!(covered, "narrow[{}] should have been generated", i);
1014
        }
1015
    }
1016
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base16ct-0.2.0/src/display.rs
Line
Count
Source
1
use core::fmt;
2
3
/// `core::fmt` presenter for binary data encoded as hexadecimal (Base16).
4
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
5
pub struct HexDisplay<'a>(pub &'a [u8]);
6
7
impl fmt::Display for HexDisplay<'_> {
8
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9
0
        write!(f, "{:X}", self)
10
0
    }
11
}
12
13
impl fmt::UpperHex for HexDisplay<'_> {
14
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15
0
        let mut hex = [0u8; 2];
16
17
0
        for &byte in self.0 {
18
0
            f.write_str(crate::upper::encode_str(&[byte], &mut hex)?)?;
19
        }
20
21
0
        Ok(())
22
0
    }
23
}
24
25
impl fmt::LowerHex for HexDisplay<'_> {
26
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27
0
        let mut hex = [0u8; 2];
28
29
0
        for &byte in self.0 {
30
0
            f.write_str(crate::lower::encode_str(&[byte], &mut hex)?)?;
31
        }
32
33
0
        Ok(())
34
0
    }
35
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base16ct-0.2.0/src/error.rs
Line
Count
Source
1
use core::fmt;
2
3
/// Result type with the `base16ct` crate's [`Error`] type.
4
pub type Result<T> = core::result::Result<T, Error>;
5
6
/// Error type
7
#[derive(Clone, Eq, PartialEq, Debug)]
8
pub enum Error {
9
    /// Invalid encoding of provided Base16 string.
10
    InvalidEncoding,
11
12
    /// Insufficient output buffer length.
13
    InvalidLength,
14
}
15
16
impl fmt::Display for Error {
17
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18
0
        match self {
19
0
            Error::InvalidEncoding => f.write_str("invalid Base16 encoding"),
20
0
            Error::InvalidLength => f.write_str("invalid Base16 length"),
21
        }
22
0
    }
23
}
24
25
#[cfg(feature = "std")]
26
impl std::error::Error for Error {}
27
28
impl From<Error> for core::fmt::Error {
29
0
    fn from(_: Error) -> core::fmt::Error {
30
0
        core::fmt::Error::default()
31
0
    }
32
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base16ct-0.2.0/src/lib.rs
Line
Count
Source
1
#![no_std]
2
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3
#![doc(
4
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
5
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
6
)]
7
#![warn(
8
    clippy::mod_module_files,
9
    clippy::unwrap_used,
10
    missing_docs,
11
    rust_2018_idioms,
12
    unused_lifetimes,
13
    unused_qualifications
14
)]
15
16
//! Pure Rust implementation of Base16 ([RFC 4648], a.k.a. hex).
17
//!
18
//! Implements lower and upper case Base16 variants without data-dependent branches
19
//! or lookup  tables, thereby providing portable "best effort" constant-time
20
//! operation. Not constant-time with respect to message length (only data).
21
//!
22
//! Supports `no_std` environments and avoids heap allocations in the core API
23
//! (but also provides optional `alloc` support for convenience).
24
//!
25
//! Based on code from: <https://github.com/Sc00bz/ConstTimeEncoding/blob/master/hex.cpp>
26
//!
27
//! # Examples
28
//! ```
29
//! let lower_hex_str = "abcd1234";
30
//! let upper_hex_str = "ABCD1234";
31
//! let mixed_hex_str = "abCD1234";
32
//! let raw = b"\xab\xcd\x12\x34";
33
//!
34
//! let mut buf = [0u8; 16];
35
//! // length of return slice can be different from the input buffer!
36
//! let res = base16ct::lower::decode(lower_hex_str, &mut buf).unwrap();
37
//! assert_eq!(res, raw);
38
//! let res = base16ct::lower::encode(raw, &mut buf).unwrap();
39
//! assert_eq!(res, lower_hex_str.as_bytes());
40
//! // you also can use `encode_str` and `encode_string` to get
41
//! // `&str` and `String` respectively
42
//! let res: &str = base16ct::lower::encode_str(raw, &mut buf).unwrap();
43
//! assert_eq!(res, lower_hex_str);
44
//!
45
//! let res = base16ct::upper::decode(upper_hex_str, &mut buf).unwrap();
46
//! assert_eq!(res, raw);
47
//! let res = base16ct::upper::encode(raw, &mut buf).unwrap();
48
//! assert_eq!(res, upper_hex_str.as_bytes());
49
//!
50
//! // In cases when you don't know if input contains upper or lower
51
//! // hex-encoded value, then use functions from the `mixed` module
52
//! let res = base16ct::mixed::decode(lower_hex_str, &mut buf).unwrap();
53
//! assert_eq!(res, raw);
54
//! let res = base16ct::mixed::decode(upper_hex_str, &mut buf).unwrap();
55
//! assert_eq!(res, raw);
56
//! let res = base16ct::mixed::decode(mixed_hex_str, &mut buf).unwrap();
57
//! assert_eq!(res, raw);
58
//! ```
59
//!
60
//! [RFC 4648]: https://tools.ietf.org/html/rfc4648
61
62
#[cfg(feature = "alloc")]
63
#[macro_use]
64
extern crate alloc;
65
#[cfg(feature = "std")]
66
extern crate std;
67
68
/// Function for decoding and encoding lower Base16 (hex)
69
pub mod lower;
70
/// Function for decoding mixed Base16 (hex)
71
pub mod mixed;
72
/// Function for decoding and encoding upper Base16 (hex)
73
pub mod upper;
74
75
/// Display formatter for hex.
76
mod display;
77
/// Error types.
78
mod error;
79
80
pub use crate::{
81
    display::HexDisplay,
82
    error::{Error, Result},
83
};
84
85
#[cfg(feature = "alloc")]
86
use alloc::{string::String, vec::Vec};
87
88
/// Compute decoded length of the given hex-encoded input.
89
#[inline(always)]
90
pub fn decoded_len(bytes: &[u8]) -> Result<usize> {
91
    if bytes.len() & 1 == 0 {
92
        Ok(bytes.len() / 2)
93
    } else {
94
        Err(Error::InvalidLength)
95
    }
96
}
97
98
/// Get the length of Base16 (hex) produced by encoding the given bytes.
99
#[inline(always)]
100
0
pub fn encoded_len(bytes: &[u8]) -> usize {
101
0
    bytes.len() * 2
102
0
}
103
104
0
fn decode_inner<'a>(
105
0
    src: &[u8],
106
0
    dst: &'a mut [u8],
107
0
    decode_nibble: impl Fn(u8) -> u16,
108
0
) -> Result<&'a [u8]> {
109
0
    let dst = dst
110
0
        .get_mut(..decoded_len(src)?)
111
0
        .ok_or(Error::InvalidLength)?;
112
113
0
    let mut err: u16 = 0;
114
0
    for (src, dst) in src.chunks_exact(2).zip(dst.iter_mut()) {
115
0
        let byte = (decode_nibble(src[0]) << 4) | decode_nibble(src[1]);
116
0
        err |= byte >> 8;
117
0
        *dst = byte as u8;
118
0
    }
119
120
0
    match err {
121
0
        0 => Ok(dst),
122
0
        _ => Err(Error::InvalidEncoding),
123
    }
124
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base16ct-0.2.0/src/lower.rs
Line
Count
Source
1
use crate::{decode_inner, encoded_len, Error};
2
#[cfg(feature = "alloc")]
3
use crate::{decoded_len, String, Vec};
4
5
/// Decode a lower Base16 (hex) string into the provided destination buffer.
6
0
pub fn decode(src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], Error> {
7
0
    decode_inner(src.as_ref(), dst, decode_nibble)
8
0
}
9
10
/// Decode a lower Base16 (hex) string into a byte vector.
11
#[cfg(feature = "alloc")]
12
0
pub fn decode_vec(input: impl AsRef<[u8]>) -> Result<Vec<u8>, Error> {
13
0
    let mut output = vec![0u8; decoded_len(input.as_ref())?];
14
0
    decode(input, &mut output)?;
15
0
    Ok(output)
16
0
}
17
18
/// Encode the input byte slice as lower Base16.
19
///
20
/// Writes the result into the provided destination slice, returning an
21
/// ASCII-encoded lower Base16 (hex) string value.
22
0
pub fn encode<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a [u8], Error> {
23
0
    let dst = dst
24
0
        .get_mut(..encoded_len(src))
25
0
        .ok_or(Error::InvalidLength)?;
26
0
    for (src, dst) in src.iter().zip(dst.chunks_exact_mut(2)) {
27
0
        dst[0] = encode_nibble(src >> 4);
28
0
        dst[1] = encode_nibble(src & 0x0f);
29
0
    }
30
0
    Ok(dst)
31
0
}
32
33
/// Encode input byte slice into a [`&str`] containing lower Base16 (hex).
34
0
pub fn encode_str<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, Error> {
35
0
    encode(src, dst).map(|r| unsafe { core::str::from_utf8_unchecked(r) })
36
0
}
37
38
/// Encode input byte slice into a [`String`] containing lower Base16 (hex).
39
///
40
/// # Panics
41
/// If `input` length is greater than `usize::MAX/2`.
42
#[cfg(feature = "alloc")]
43
0
pub fn encode_string(input: &[u8]) -> String {
44
0
    let elen = encoded_len(input);
45
0
    let mut dst = vec![0u8; elen];
46
0
    let res = encode(input, &mut dst).expect("dst length is correct");
47
0
48
0
    debug_assert_eq!(elen, res.len());
49
0
    unsafe { String::from_utf8_unchecked(dst) }
50
0
}
51
52
/// Decode a single nibble of lower hex
53
#[inline(always)]
54
fn decode_nibble(src: u8) -> u16 {
55
    // 0-9  0x30-0x39
56
    // A-F  0x41-0x46 or a-f  0x61-0x66
57
    let byte = src as i16;
58
    let mut ret: i16 = -1;
59
60
    // 0-9  0x30-0x39
61
    // if (byte > 0x2f && byte < 0x3a) ret += byte - 0x30 + 1; // -47
62
    ret += (((0x2fi16 - byte) & (byte - 0x3a)) >> 8) & (byte - 47);
63
    // a-f  0x61-0x66
64
    // if (byte > 0x60 && byte < 0x67) ret += byte - 0x61 + 10 + 1; // -86
65
    ret += (((0x60i16 - byte) & (byte - 0x67)) >> 8) & (byte - 86);
66
67
    ret as u16
68
}
69
70
/// Encode a single nibble of hex
71
#[inline(always)]
72
0
fn encode_nibble(src: u8) -> u8 {
73
0
    let mut ret = src as i16 + 0x30;
74
0
    // 0-9  0x30-0x39
75
0
    // a-f  0x61-0x66
76
0
    ret += ((0x39i16 - ret) >> 8) & (0x61i16 - 0x3a);
77
0
    ret as u8
78
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base16ct-0.2.0/src/mixed.rs
Line
Count
Source
1
use crate::{decode_inner, Error};
2
#[cfg(feature = "alloc")]
3
use crate::{decoded_len, Vec};
4
5
/// Decode a mixed Base16 (hex) string into the provided destination buffer.
6
0
pub fn decode(src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], Error> {
7
0
    decode_inner(src.as_ref(), dst, decode_nibble)
8
0
}
9
10
/// Decode a mixed Base16 (hex) string into a byte vector.
11
#[cfg(feature = "alloc")]
12
0
pub fn decode_vec(input: impl AsRef<[u8]>) -> Result<Vec<u8>, Error> {
13
0
    let mut output = vec![0u8; decoded_len(input.as_ref())?];
14
0
    decode(input, &mut output)?;
15
0
    Ok(output)
16
0
}
17
18
/// Decode a single nibble of lower hex
19
#[inline(always)]
20
fn decode_nibble(src: u8) -> u16 {
21
    // 0-9  0x30-0x39
22
    // A-F  0x41-0x46 or a-f  0x61-0x66
23
    let byte = src as i16;
24
    let mut ret: i16 = -1;
25
26
    // 0-9  0x30-0x39
27
    // if (byte > 0x2f && byte < 0x3a) ret += byte - 0x30 + 1; // -47
28
    ret += (((0x2fi16 - byte) & (byte - 0x3a)) >> 8) & (byte - 47);
29
    // A-F  0x41-0x46
30
    // if (byte > 0x40 && byte < 0x47) ret += byte - 0x41 + 10 + 1; // -54
31
    ret += (((0x40i16 - byte) & (byte - 0x47)) >> 8) & (byte - 54);
32
    // a-f  0x61-0x66
33
    // if (byte > 0x60 && byte < 0x67) ret += byte - 0x61 + 10 + 1; // -86
34
    ret += (((0x60i16 - byte) & (byte - 0x67)) >> 8) & (byte - 86);
35
36
    ret as u16
37
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base16ct-0.2.0/src/upper.rs
Line
Count
Source
1
use crate::{decode_inner, encoded_len, Error};
2
#[cfg(feature = "alloc")]
3
use crate::{decoded_len, String, Vec};
4
5
/// Decode an upper Base16 (hex) string into the provided destination buffer.
6
0
pub fn decode(src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], Error> {
7
0
    decode_inner(src.as_ref(), dst, decode_nibble)
8
0
}
9
10
/// Decode an upper Base16 (hex) string into a byte vector.
11
#[cfg(feature = "alloc")]
12
0
pub fn decode_vec(input: impl AsRef<[u8]>) -> Result<Vec<u8>, Error> {
13
0
    let mut output = vec![0u8; decoded_len(input.as_ref())?];
14
0
    decode(input, &mut output)?;
15
0
    Ok(output)
16
0
}
17
18
/// Encode the input byte slice as upper Base16.
19
///
20
/// Writes the result into the provided destination slice, returning an
21
/// ASCII-encoded upper Base16 (hex) string value.
22
0
pub fn encode<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a [u8], Error> {
23
0
    let dst = dst
24
0
        .get_mut(..encoded_len(src))
25
0
        .ok_or(Error::InvalidLength)?;
26
0
    for (src, dst) in src.iter().zip(dst.chunks_exact_mut(2)) {
27
0
        dst[0] = encode_nibble(src >> 4);
28
0
        dst[1] = encode_nibble(src & 0x0f);
29
0
    }
30
0
    Ok(dst)
31
0
}
32
33
/// Encode input byte slice into a [`&str`] containing upper Base16 (hex).
34
0
pub fn encode_str<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, Error> {
35
0
    encode(src, dst).map(|r| unsafe { core::str::from_utf8_unchecked(r) })
36
0
}
37
38
/// Encode input byte slice into a [`String`] containing upper Base16 (hex).
39
///
40
/// # Panics
41
/// If `input` length is greater than `usize::MAX/2`.
42
#[cfg(feature = "alloc")]
43
0
pub fn encode_string(input: &[u8]) -> String {
44
0
    let elen = encoded_len(input);
45
0
    let mut dst = vec![0u8; elen];
46
0
    let res = encode(input, &mut dst).expect("dst length is correct");
47
0
48
0
    debug_assert_eq!(elen, res.len());
49
0
    unsafe { crate::String::from_utf8_unchecked(dst) }
50
0
}
51
52
/// Decode a single nibble of upper hex
53
#[inline(always)]
54
fn decode_nibble(src: u8) -> u16 {
55
    // 0-9  0x30-0x39
56
    // A-F  0x41-0x46 or a-f  0x61-0x66
57
    let byte = src as i16;
58
    let mut ret: i16 = -1;
59
60
    // 0-9  0x30-0x39
61
    // if (byte > 0x2f && byte < 0x3a) ret += byte - 0x30 + 1; // -47
62
    ret += (((0x2fi16 - byte) & (byte - 0x3a)) >> 8) & (byte - 47);
63
    // A-F  0x41-0x46
64
    // if (byte > 0x40 && byte < 0x47) ret += byte - 0x41 + 10 + 1; // -54
65
    ret += (((0x40i16 - byte) & (byte - 0x47)) >> 8) & (byte - 54);
66
67
    ret as u16
68
}
69
70
/// Encode a single nibble of hex
71
#[inline(always)]
72
0
fn encode_nibble(src: u8) -> u8 {
73
0
    let mut ret = src as i16 + 0x30;
74
0
    // 0-9  0x30-0x39
75
0
    // A-F  0x41-0x46
76
0
    ret += ((0x39i16 - ret) >> 8) & (0x41i16 - 0x3a);
77
0
    ret as u8
78
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64ct-1.6.0/src/alphabet.rs
Line
Count
Source
1
//! Base64 alphabets.
2
3
// TODO(tarcieri): explicitly checked/wrapped arithmetic
4
#![allow(clippy::integer_arithmetic)]
5
6
use core::{fmt::Debug, ops::RangeInclusive};
7
8
pub mod bcrypt;
9
pub mod crypt;
10
pub mod shacrypt;
11
pub mod standard;
12
pub mod url;
13
14
/// Core encoder/decoder functions for a particular Base64 alphabet.
15
pub trait Alphabet: 'static + Copy + Debug + Eq + Send + Sized + Sync {
16
    /// First character in this Base64 alphabet.
17
    const BASE: u8;
18
19
    /// Decoder passes
20
    const DECODER: &'static [DecodeStep];
21
22
    /// Encoder passes
23
    const ENCODER: &'static [EncodeStep];
24
25
    /// Is this encoding padded?
26
    const PADDED: bool;
27
28
    /// Unpadded equivalent of this alphabet.
29
    ///
30
    /// For alphabets that are unpadded to begin with, this should be `Self`.
31
    type Unpadded: Alphabet;
32
33
    /// Decode 3 bytes of a Base64 message.
34
    #[inline(always)]
35
0
    fn decode_3bytes(src: &[u8], dst: &mut [u8]) -> i16 {
36
0
        debug_assert_eq!(src.len(), 4);
37
0
        debug_assert!(dst.len() >= 3, "dst too short: {}", dst.len());
38
39
0
        let c0 = Self::decode_6bits(src[0]);
40
0
        let c1 = Self::decode_6bits(src[1]);
41
0
        let c2 = Self::decode_6bits(src[2]);
42
0
        let c3 = Self::decode_6bits(src[3]);
43
0
44
0
        dst[0] = ((c0 << 2) | (c1 >> 4)) as u8;
45
0
        dst[1] = ((c1 << 4) | (c2 >> 2)) as u8;
46
0
        dst[2] = ((c2 << 6) | c3) as u8;
47
0
48
0
        ((c0 | c1 | c2 | c3) >> 8) & 1
49
0
    }
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet8standard14Base64UnpaddedNtB6_8Alphabet13decode_3bytesCs7ONNNQjtL1v_11pem_rfc7468
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet8standard6Base64NtB6_8Alphabet13decode_3bytesCs7ONNNQjtL1v_11pem_rfc7468
50
51
    /// Decode 6-bits of a Base64 message.
52
0
    fn decode_6bits(src: u8) -> i16 {
53
0
        let mut ret: i16 = -1;
54
55
0
        for step in Self::DECODER {
56
0
            ret += match step {
57
0
                DecodeStep::Range(range, offset) => {
58
0
                    // Compute exclusive range from inclusive one
59
0
                    let start = *range.start() as i16 - 1;
60
0
                    let end = *range.end() as i16 + 1;
61
0
                    (((start - src as i16) & (src as i16 - end)) >> 8) & (src as i16 + *offset)
62
                }
63
0
                DecodeStep::Eq(value, offset) => {
64
0
                    let start = *value as i16 - 1;
65
0
                    let end = *value as i16 + 1;
66
0
                    (((start - src as i16) & (src as i16 - end)) >> 8) & *offset
67
                }
68
            };
69
        }
70
71
0
        ret
72
0
    }
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet3url17Base64UrlUnpaddedNtB6_8Alphabet12decode_6bitsB8_
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet3url9Base64UrlNtB6_8Alphabet12decode_6bitsB8_
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet5crypt11Base64CryptNtB6_8Alphabet12decode_6bitsB8_
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet6bcrypt12Base64BcryptNtB6_8Alphabet12decode_6bitsB8_
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet8shacrypt14Base64ShaCryptNtB6_8Alphabet12decode_6bitsB8_
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet8standard14Base64UnpaddedNtB6_8Alphabet12decode_6bitsB8_
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet8standard6Base64NtB6_8Alphabet12decode_6bitsB8_
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet8standard14Base64UnpaddedNtB6_8Alphabet12decode_6bitsCs7ONNNQjtL1v_11pem_rfc7468
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet8standard6Base64NtB6_8Alphabet12decode_6bitsCs7ONNNQjtL1v_11pem_rfc7468
73
74
    /// Encode 3-bytes of a Base64 message.
75
    #[inline(always)]
76
0
    fn encode_3bytes(src: &[u8], dst: &mut [u8]) {
77
0
        debug_assert_eq!(src.len(), 3);
78
0
        debug_assert!(dst.len() >= 4, "dst too short: {}", dst.len());
79
80
0
        let b0 = src[0] as i16;
81
0
        let b1 = src[1] as i16;
82
0
        let b2 = src[2] as i16;
83
0
84
0
        dst[0] = Self::encode_6bits(b0 >> 2);
85
0
        dst[1] = Self::encode_6bits(((b0 << 4) | (b1 >> 4)) & 63);
86
0
        dst[2] = Self::encode_6bits(((b1 << 2) | (b2 >> 6)) & 63);
87
0
        dst[3] = Self::encode_6bits(b2 & 63);
88
0
    }
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet8standard14Base64UnpaddedNtB6_8Alphabet13encode_3bytesCs7ONNNQjtL1v_11pem_rfc7468
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet8standard6Base64NtB6_8Alphabet13encode_3bytesCs7ONNNQjtL1v_11pem_rfc7468
89
90
    /// Encode 6-bits of a Base64 message.
91
    #[inline(always)]
92
0
    fn encode_6bits(src: i16) -> u8 {
93
0
        let mut diff = src + Self::BASE as i16;
94
95
0
        for &step in Self::ENCODER {
96
0
            diff += match step {
97
0
                EncodeStep::Apply(threshold, offset) => ((threshold as i16 - diff) >> 8) & offset,
98
0
                EncodeStep::Diff(threshold, offset) => ((threshold as i16 - src) >> 8) & offset,
99
            };
100
        }
101
102
0
        diff as u8
103
0
    }
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet8standard14Base64UnpaddedNtB6_8Alphabet12encode_6bitsCs7ONNNQjtL1v_11pem_rfc7468
Unexecuted instantiation: _RNvYNtNtNtCs2IUk8zOUKtU_8base64ct8alphabet8standard6Base64NtB6_8Alphabet12encode_6bitsCs7ONNNQjtL1v_11pem_rfc7468
104
}
105
106
/// Constant-time decoder step.
107
#[derive(Debug)]
108
pub enum DecodeStep {
109
    /// Match the given range, offsetting the input on match.
110
    Range(RangeInclusive<u8>, i16),
111
112
    /// Match the given value, returning the associated offset on match.
113
    Eq(u8, i16),
114
}
115
116
/// Constant-time encoder step.
117
#[derive(Copy, Clone, Debug)]
118
pub enum EncodeStep {
119
    /// Apply the given offset to the cumulative result on match.
120
    Apply(u8, i16),
121
122
    /// Compute a difference using the given offset on match.
123
    Diff(u8, i16),
124
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64ct-1.6.0/src/decoder.rs
Line
Count
Source
1
//! Buffered Base64 decoder.
2
3
use crate::{
4
    encoding,
5
    line_ending::{CHAR_CR, CHAR_LF},
6
    Encoding,
7
    Error::{self, InvalidLength},
8
    MIN_LINE_WIDTH,
9
};
10
use core::{cmp, marker::PhantomData};
11
12
#[cfg(feature = "alloc")]
13
use {alloc::vec::Vec, core::iter};
14
15
#[cfg(feature = "std")]
16
use std::io;
17
18
#[cfg(doc)]
19
use crate::{Base64, Base64Unpadded};
20
21
/// Stateful Base64 decoder with support for buffered, incremental decoding.
22
///
23
/// The `E` type parameter can be any type which impls [`Encoding`] such as
24
/// [`Base64`] or [`Base64Unpadded`].
25
#[derive(Clone)]
26
pub struct Decoder<'i, E: Encoding> {
27
    /// Current line being processed.
28
    line: Line<'i>,
29
30
    /// Base64 input data reader.
31
    line_reader: LineReader<'i>,
32
33
    /// Length of the remaining data after Base64 decoding.
34
    remaining_len: usize,
35
36
    /// Block buffer used for non-block-aligned data.
37
    block_buffer: BlockBuffer,
38
39
    /// Phantom parameter for the Base64 encoding in use.
40
    encoding: PhantomData<E>,
41
}
42
43
impl<'i, E: Encoding> Decoder<'i, E> {
44
    /// Create a new decoder for a byte slice containing contiguous
45
    /// (non-newline-delimited) Base64-encoded data.
46
    ///
47
    /// # Returns
48
    /// - `Ok(decoder)` on success.
49
    /// - `Err(Error::InvalidLength)` if the input buffer is empty.
50
0
    pub fn new(input: &'i [u8]) -> Result<Self, Error> {
51
0
        let line_reader = LineReader::new_unwrapped(input)?;
52
0
        let remaining_len = line_reader.decoded_len::<E>()?;
53
54
0
        Ok(Self {
55
0
            line: Line::default(),
56
0
            line_reader,
57
0
            remaining_len,
58
0
            block_buffer: BlockBuffer::default(),
59
0
            encoding: PhantomData,
60
0
        })
61
0
    }
62
63
    /// Create a new decoder for a byte slice containing Base64 which
64
    /// line wraps at the given line length.
65
    ///
66
    /// Trailing newlines are not supported and must be removed in advance.
67
    ///
68
    /// Newlines are handled according to what are roughly [RFC7468] conventions:
69
    ///
70
    /// ```text
71
    /// [parsers] MUST handle different newline conventions
72
    /// ```
73
    ///
74
    /// RFC7468 allows any of the following as newlines, and allows a mixture
75
    /// of different types of newlines:
76
    ///
77
    /// ```text
78
    /// eol        = CRLF / CR / LF
79
    /// ```
80
    ///
81
    /// # Returns
82
    /// - `Ok(decoder)` on success.
83
    /// - `Err(Error::InvalidLength)` if the input buffer is empty or the line
84
    ///   width is zero.
85
    ///
86
    /// [RFC7468]: https://datatracker.ietf.org/doc/html/rfc7468
87
0
    pub fn new_wrapped(input: &'i [u8], line_width: usize) -> Result<Self, Error> {
88
0
        let line_reader = LineReader::new_wrapped(input, line_width)?;
89
0
        let remaining_len = line_reader.decoded_len::<E>()?;
90
91
0
        Ok(Self {
92
0
            line: Line::default(),
93
0
            line_reader,
94
0
            remaining_len,
95
0
            block_buffer: BlockBuffer::default(),
96
0
            encoding: PhantomData,
97
0
        })
98
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderpE11new_wrappedB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderNtNtNtB4_8alphabet8standard6Base64E11new_wrappedCs7ONNNQjtL1v_11pem_rfc7468
99
100
    /// Fill the provided buffer with data decoded from Base64.
101
    ///
102
    /// Enough Base64 input data must remain to fill the entire buffer.
103
    ///
104
    /// # Returns
105
    /// - `Ok(bytes)` if the expected amount of data was read
106
    /// - `Err(Error::InvalidLength)` if the exact amount of data couldn't be read
107
0
    pub fn decode<'o>(&mut self, out: &'o mut [u8]) -> Result<&'o [u8], Error> {
108
0
        if self.is_finished() {
109
0
            return Err(InvalidLength);
110
0
        }
111
0
112
0
        let mut out_pos = 0;
113
114
0
        while out_pos < out.len() {
115
            // If there's data in the block buffer, use it
116
0
            if !self.block_buffer.is_empty() {
117
0
                let out_rem = out.len().checked_sub(out_pos).ok_or(InvalidLength)?;
118
0
                let bytes = self.block_buffer.take(out_rem)?;
119
0
                out[out_pos..][..bytes.len()].copy_from_slice(bytes);
120
0
                out_pos = out_pos.checked_add(bytes.len()).ok_or(InvalidLength)?;
121
0
            }
122
123
            // Advance the line reader if necessary
124
0
            if self.line.is_empty() && !self.line_reader.is_empty() {
125
0
                self.advance_line()?;
126
0
            }
127
128
            // Attempt to decode a stride of block-aligned data
129
0
            let in_blocks = self.line.len() / 4;
130
0
            let out_rem = out.len().checked_sub(out_pos).ok_or(InvalidLength)?;
131
0
            let out_blocks = out_rem / 3;
132
0
            let blocks = cmp::min(in_blocks, out_blocks);
133
0
            let in_aligned = self.line.take(blocks.checked_mul(4).ok_or(InvalidLength)?);
134
135
0
            if !in_aligned.is_empty() {
136
0
                let out_buf = &mut out[out_pos..][..blocks.checked_mul(3).ok_or(InvalidLength)?];
137
0
                let decoded_len = self.perform_decode(in_aligned, out_buf)?.len();
138
0
                out_pos = out_pos.checked_add(decoded_len).ok_or(InvalidLength)?;
139
0
            }
140
141
0
            if out_pos < out.len() {
142
0
                if self.is_finished() {
143
                    // If we're out of input then we've been requested to decode
144
                    // more data than is actually available.
145
0
                    return Err(InvalidLength);
146
                } else {
147
                    // If we still have data available but haven't completely
148
                    // filled the output slice, we're in a situation where
149
                    // either the input or output isn't block-aligned, so fill
150
                    // the internal block buffer.
151
0
                    self.fill_block_buffer()?;
152
                }
153
0
            }
154
        }
155
156
0
        self.remaining_len = self
157
0
            .remaining_len
158
0
            .checked_sub(out.len())
159
0
            .ok_or(InvalidLength)?;
160
161
0
        Ok(out)
162
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderpE6decodeB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderNtNtNtB4_8alphabet8standard6Base64E6decodeCs7ONNNQjtL1v_11pem_rfc7468
163
164
    /// Decode all remaining Base64 data, placing the result into `buf`.
165
    ///
166
    /// If successful, this function will return the total number of bytes
167
    /// decoded into `buf`.
168
    #[cfg(feature = "alloc")]
169
0
    pub fn decode_to_end<'o>(&mut self, buf: &'o mut Vec<u8>) -> Result<&'o [u8], Error> {
170
0
        let start_len = buf.len();
171
0
        let remaining_len = self.remaining_len();
172
0
        let total_len = start_len.checked_add(remaining_len).ok_or(InvalidLength)?;
173
174
0
        if total_len > buf.capacity() {
175
0
            buf.reserve(total_len.checked_sub(buf.capacity()).ok_or(InvalidLength)?);
176
0
        }
177
178
        // Append `decoded_len` zeroes to the vector
179
0
        buf.extend(iter::repeat(0).take(remaining_len));
180
0
        self.decode(&mut buf[start_len..])?;
181
0
        Ok(&buf[start_len..])
182
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderpE13decode_to_endB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderNtNtNtB4_8alphabet8standard6Base64E13decode_to_endCs7ONNNQjtL1v_11pem_rfc7468
183
184
    /// Get the length of the remaining data after Base64 decoding.
185
    ///
186
    /// Decreases every time data is decoded.
187
0
    pub fn remaining_len(&self) -> usize {
188
0
        self.remaining_len
189
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderpE13remaining_lenB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderNtNtNtB4_8alphabet8standard6Base64E13remaining_lenCscrZQdumITES_3der
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderNtNtNtB4_8alphabet8standard6Base64E13remaining_lenCs7ONNNQjtL1v_11pem_rfc7468
190
191
    /// Has all of the input data been decoded?
192
0
    pub fn is_finished(&self) -> bool {
193
0
        self.line.is_empty() && self.line_reader.is_empty() && self.block_buffer.is_empty()
194
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderpE11is_finishedB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderNtNtNtB4_8alphabet8standard6Base64E11is_finishedCs7ONNNQjtL1v_11pem_rfc7468
195
196
    /// Fill the block buffer with data.
197
0
    fn fill_block_buffer(&mut self) -> Result<(), Error> {
198
0
        let mut buf = [0u8; BlockBuffer::SIZE];
199
200
0
        let decoded = if self.line.len() < 4 && !self.line_reader.is_empty() {
201
            // Handle input block which is split across lines
202
0
            let mut tmp = [0u8; 4];
203
0
204
0
            // Copy remaining data in the line into tmp
205
0
            let line_end = self.line.take(4);
206
0
            tmp[..line_end.len()].copy_from_slice(line_end);
207
0
208
0
            // Advance the line and attempt to fill tmp
209
0
            self.advance_line()?;
210
0
            let len = 4usize.checked_sub(line_end.len()).ok_or(InvalidLength)?;
211
0
            let line_begin = self.line.take(len);
212
0
            tmp[line_end.len()..][..line_begin.len()].copy_from_slice(line_begin);
213
214
0
            let tmp_len = line_begin
215
0
                .len()
216
0
                .checked_add(line_end.len())
217
0
                .ok_or(InvalidLength)?;
218
219
0
            self.perform_decode(&tmp[..tmp_len], &mut buf)
220
        } else {
221
0
            let block = self.line.take(4);
222
0
            self.perform_decode(block, &mut buf)
223
0
        }?;
224
225
0
        self.block_buffer.fill(decoded)
226
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderpE17fill_block_bufferB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderNtNtNtB4_8alphabet8standard6Base64E17fill_block_bufferCs7ONNNQjtL1v_11pem_rfc7468
227
228
    /// Advance the internal buffer to the next line.
229
0
    fn advance_line(&mut self) -> Result<(), Error> {
230
0
        debug_assert!(self.line.is_empty(), "expected line buffer to be empty");
231
232
0
        if let Some(line) = self.line_reader.next().transpose()? {
233
0
            self.line = line;
234
0
            Ok(())
235
        } else {
236
0
            Err(InvalidLength)
237
        }
238
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderpE12advance_lineB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderNtNtNtB4_8alphabet8standard6Base64E12advance_lineCs7ONNNQjtL1v_11pem_rfc7468
239
240
    /// Perform Base64 decoding operation.
241
0
    fn perform_decode<'o>(&self, src: &[u8], dst: &'o mut [u8]) -> Result<&'o [u8], Error> {
242
0
        if self.is_finished() {
243
0
            E::decode(src, dst)
244
        } else {
245
0
            E::Unpadded::decode(src, dst)
246
        }
247
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderpE14perform_decodeB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7decoderINtB2_7DecoderNtNtNtB4_8alphabet8standard6Base64E14perform_decodeCs7ONNNQjtL1v_11pem_rfc7468
248
}
249
250
#[cfg(feature = "std")]
251
impl<'i, E: Encoding> io::Read for Decoder<'i, E> {
252
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
253
        if self.is_finished() {
254
            return Ok(0);
255
        }
256
        let slice = match buf.get_mut(..self.remaining_len()) {
257
            Some(bytes) => bytes,
258
            None => buf,
259
        };
260
261
        self.decode(slice)?;
262
        Ok(slice.len())
263
    }
264
265
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
266
        if self.is_finished() {
267
            return Ok(0);
268
        }
269
        Ok(self.decode_to_end(buf)?.len())
270
    }
271
272
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
273
        self.decode(buf)?;
274
        Ok(())
275
    }
276
}
277
278
/// Base64 decode buffer for a 1-block input.
279
///
280
/// This handles a partially decoded block of data, i.e. data which has been
281
/// decoded but not read.
282
#[derive(Clone, Default, Debug)]
283
struct BlockBuffer {
284
    /// 3 decoded bytes from a 4-byte Base64-encoded input.
285
    decoded: [u8; Self::SIZE],
286
287
    /// Length of the buffer.
288
    length: usize,
289
290
    /// Position within the buffer.
291
    position: usize,
292
}
293
294
impl BlockBuffer {
295
    /// Size of the buffer in bytes.
296
    const SIZE: usize = 3;
297
298
    /// Fill the buffer by decoding up to 3 bytes of decoded Base64 input.
299
0
    fn fill(&mut self, decoded_input: &[u8]) -> Result<(), Error> {
300
0
        debug_assert!(self.is_empty());
301
302
0
        if decoded_input.len() > Self::SIZE {
303
0
            return Err(InvalidLength);
304
0
        }
305
0
306
0
        self.position = 0;
307
0
        self.length = decoded_input.len();
308
0
        self.decoded[..decoded_input.len()].copy_from_slice(decoded_input);
309
0
        Ok(())
310
0
    }
311
312
    /// Take a specified number of bytes from the buffer.
313
    ///
314
    /// Returns as many bytes as possible, or an empty slice if the buffer has
315
    /// already been read to completion.
316
0
    fn take(&mut self, mut nbytes: usize) -> Result<&[u8], Error> {
317
0
        debug_assert!(self.position <= self.length);
318
0
        let start_pos = self.position;
319
0
        let remaining_len = self.length.checked_sub(start_pos).ok_or(InvalidLength)?;
320
321
0
        if nbytes > remaining_len {
322
0
            nbytes = remaining_len;
323
0
        }
324
325
0
        self.position = self.position.checked_add(nbytes).ok_or(InvalidLength)?;
326
0
        Ok(&self.decoded[start_pos..][..nbytes])
327
0
    }
328
329
    /// Have all of the bytes in this buffer been consumed?
330
0
    fn is_empty(&self) -> bool {
331
0
        self.position == self.length
332
0
    }
Unexecuted instantiation: _RNvMs_NtCs2IUk8zOUKtU_8base64ct7decoderNtB4_11BlockBuffer8is_emptyB6_
Unexecuted instantiation: _RNvMs_NtCs2IUk8zOUKtU_8base64ct7decoderNtB4_11BlockBuffer8is_emptyCs7ONNNQjtL1v_11pem_rfc7468
333
}
334
335
/// A single line of linewrapped data, providing a read buffer.
336
#[derive(Clone, Debug)]
337
pub struct Line<'i> {
338
    /// Remaining data in the line
339
    remaining: &'i [u8],
340
}
341
342
impl<'i> Default for Line<'i> {
343
0
    fn default() -> Self {
344
0
        Self::new(&[])
345
0
    }
Unexecuted instantiation: _RNvXs0_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_4LineNtNtCsbQ8arDwx5Xq_4core7default7Default7defaultB7_
Unexecuted instantiation: _RNvXs0_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_4LineNtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs7ONNNQjtL1v_11pem_rfc7468
346
}
347
348
impl<'i> Line<'i> {
349
    /// Create a new line which wraps the given input data.
350
0
    fn new(bytes: &'i [u8]) -> Self {
351
0
        Self { remaining: bytes }
352
0
    }
Unexecuted instantiation: _RNvMs1_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_4Line3newB7_
Unexecuted instantiation: _RNvMs1_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_4Line3newCs7ONNNQjtL1v_11pem_rfc7468
353
354
    /// Take up to `nbytes` from this line buffer.
355
0
    fn take(&mut self, nbytes: usize) -> &'i [u8] {
356
0
        let (bytes, rest) = if nbytes < self.remaining.len() {
357
0
            self.remaining.split_at(nbytes)
358
        } else {
359
0
            (self.remaining, [].as_ref())
360
        };
361
362
0
        self.remaining = rest;
363
0
        bytes
364
0
    }
365
366
    /// Slice off a tail of a given length.
367
0
    fn slice_tail(&self, nbytes: usize) -> Result<&'i [u8], Error> {
368
0
        let offset = self.len().checked_sub(nbytes).ok_or(InvalidLength)?;
369
0
        self.remaining.get(offset..).ok_or(InvalidLength)
370
0
    }
Unexecuted instantiation: _RNvMs1_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_4Line10slice_tailB7_
Unexecuted instantiation: _RNvMs1_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_4Line10slice_tailCs7ONNNQjtL1v_11pem_rfc7468
371
372
    /// Get the number of bytes remaining in this line.
373
0
    fn len(&self) -> usize {
374
0
        self.remaining.len()
375
0
    }
Unexecuted instantiation: _RNvMs1_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_4Line3lenB7_
Unexecuted instantiation: _RNvMs1_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_4Line3lenCs7ONNNQjtL1v_11pem_rfc7468
376
377
    /// Is the buffer for this line empty?
378
0
    fn is_empty(&self) -> bool {
379
0
        self.len() == 0
380
0
    }
Unexecuted instantiation: _RNvMs1_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_4Line8is_emptyB7_
Unexecuted instantiation: _RNvMs1_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_4Line8is_emptyCs7ONNNQjtL1v_11pem_rfc7468
381
382
    /// Trim the newline off the end of this line.
383
0
    fn trim_end(&self) -> Self {
384
0
        Line::new(match self.remaining {
385
0
            [line @ .., CHAR_CR, CHAR_LF] => line,
386
0
            [line @ .., CHAR_CR] => line,
387
0
            [line @ .., CHAR_LF] => line,
388
0
            line => line,
389
        })
390
0
    }
391
}
392
393
/// Iterator over multi-line Base64 input.
394
#[derive(Clone)]
395
struct LineReader<'i> {
396
    /// Remaining linewrapped data to be processed.
397
    remaining: &'i [u8],
398
399
    /// Line width.
400
    line_width: Option<usize>,
401
}
402
403
impl<'i> LineReader<'i> {
404
    /// Create a new reader which operates over continugous unwrapped data.
405
0
    fn new_unwrapped(bytes: &'i [u8]) -> Result<Self, Error> {
406
0
        if bytes.is_empty() {
407
0
            Err(InvalidLength)
408
        } else {
409
0
            Ok(Self {
410
0
                remaining: bytes,
411
0
                line_width: None,
412
0
            })
413
        }
414
0
    }
Unexecuted instantiation: _RNvMs2_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_10LineReader13new_unwrappedB7_
Unexecuted instantiation: _RNvMs2_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_10LineReader13new_unwrappedCs7ONNNQjtL1v_11pem_rfc7468
415
416
    /// Create a new reader which operates over linewrapped data.
417
0
    fn new_wrapped(bytes: &'i [u8], line_width: usize) -> Result<Self, Error> {
418
0
        if line_width < MIN_LINE_WIDTH {
419
0
            return Err(InvalidLength);
420
0
        }
421
422
0
        let mut reader = Self::new_unwrapped(bytes)?;
423
0
        reader.line_width = Some(line_width);
424
0
        Ok(reader)
425
0
    }
Unexecuted instantiation: _RNvMs2_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_10LineReader11new_wrappedB7_
Unexecuted instantiation: _RNvMs2_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_10LineReader11new_wrappedCs7ONNNQjtL1v_11pem_rfc7468
426
427
    /// Is this line reader empty?
428
0
    fn is_empty(&self) -> bool {
429
0
        self.remaining.is_empty()
430
0
    }
Unexecuted instantiation: _RNvMs2_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_10LineReader8is_emptyB7_
Unexecuted instantiation: _RNvMs2_NtCs2IUk8zOUKtU_8base64ct7decoderNtB5_10LineReader8is_emptyCs7ONNNQjtL1v_11pem_rfc7468
431
432
    /// Get the total length of the data decoded from this line reader.
433
0
    fn decoded_len<E: Encoding>(&self) -> Result<usize, Error> {
434
0
        let mut buffer = [0u8; 4];
435
0
        let mut lines = self.clone();
436
0
        let mut line = match lines.next().transpose()? {
437
0
            Some(l) => l,
438
0
            None => return Ok(0),
439
        };
440
0
        let mut base64_len = 0usize;
441
442
        loop {
443
0
            base64_len = base64_len.checked_add(line.len()).ok_or(InvalidLength)?;
444
445
0
            match lines.next().transpose()? {
446
0
                Some(l) => {
447
0
                    // Store the end of the line in the buffer so we can
448
0
                    // reassemble the last block to determine the real length
449
0
                    buffer.copy_from_slice(line.slice_tail(4)?);
450
451
0
                    line = l
452
                }
453
454
                // To compute an exact decoded length we need to decode the
455
                // last Base64 block and get the decoded length.
456
                //
457
                // This is what the somewhat complex code below is doing.
458
                None => {
459
                    // Compute number of bytes in the last block (may be unpadded)
460
0
                    let base64_last_block_len = match base64_len % 4 {
461
0
                        0 => 4,
462
0
                        n => n,
463
                    };
464
465
                    // Compute decoded length without the last block
466
0
                    let decoded_len = encoding::decoded_len(
467
0
                        base64_len
468
0
                            .checked_sub(base64_last_block_len)
469
0
                            .ok_or(InvalidLength)?,
470
                    );
471
472
                    // Compute the decoded length of the last block
473
0
                    let mut out = [0u8; 3];
474
0
                    let last_block_len = if line.len() < base64_last_block_len {
475
0
                        let buffered_part_len = base64_last_block_len
476
0
                            .checked_sub(line.len())
477
0
                            .ok_or(InvalidLength)?;
478
479
0
                        let offset = 4usize.checked_sub(buffered_part_len).ok_or(InvalidLength)?;
480
481
0
                        for i in 0..buffered_part_len {
482
0
                            buffer[i] = buffer[offset.checked_add(i).ok_or(InvalidLength)?];
483
                        }
484
485
0
                        buffer[buffered_part_len..][..line.len()].copy_from_slice(line.remaining);
486
0
                        let buffer_len = buffered_part_len
487
0
                            .checked_add(line.len())
488
0
                            .ok_or(InvalidLength)?;
489
490
0
                        E::decode(&buffer[..buffer_len], &mut out)?.len()
491
                    } else {
492
0
                        let last_block = line.slice_tail(base64_last_block_len)?;
493
0
                        E::decode(last_block, &mut out)?.len()
494
                    };
495
496
0
                    return decoded_len.checked_add(last_block_len).ok_or(InvalidLength);
497
                }
498
            }
499
        }
500
0
    }
Unexecuted instantiation: _RINvMs2_NtCs2IUk8zOUKtU_8base64ct7decoderNtB6_10LineReader11decoded_lenpEB8_
Unexecuted instantiation: _RINvMs2_NtCs2IUk8zOUKtU_8base64ct7decoderNtB6_10LineReader11decoded_lenNtNtNtB8_8alphabet8standard6Base64ECs7ONNNQjtL1v_11pem_rfc7468
501
}
502
503
impl<'i> Iterator for LineReader<'i> {
504
    type Item = Result<Line<'i>, Error>;
505
506
0
    fn next(&mut self) -> Option<Result<Line<'i>, Error>> {
507
0
        if let Some(line_width) = self.line_width {
508
0
            let rest = match self.remaining.get(line_width..) {
509
0
                None | Some([]) => {
510
0
                    if self.remaining.is_empty() {
511
0
                        return None;
512
                    } else {
513
0
                        let line = Line::new(self.remaining).trim_end();
514
0
                        self.remaining = &[];
515
0
                        return Some(Ok(line));
516
                    }
517
                }
518
0
                Some([CHAR_CR, CHAR_LF, rest @ ..]) => rest,
519
0
                Some([CHAR_CR, rest @ ..]) => rest,
520
0
                Some([CHAR_LF, rest @ ..]) => rest,
521
                _ => {
522
                    // Expected a leading newline
523
0
                    return Some(Err(Error::InvalidEncoding));
524
                }
525
            };
526
527
0
            let line = Line::new(&self.remaining[..line_width]);
528
0
            self.remaining = rest;
529
0
            Some(Ok(line))
530
0
        } else if !self.remaining.is_empty() {
531
0
            let line = Line::new(self.remaining).trim_end();
532
0
            self.remaining = b"";
533
0
534
0
            if line.is_empty() {
535
0
                None
536
            } else {
537
0
                Some(Ok(line))
538
            }
539
        } else {
540
0
            None
541
        }
542
0
    }
543
}
544
545
#[cfg(test)]
546
mod tests {
547
    use crate::{alphabet::Alphabet, test_vectors::*, Base64, Base64Unpadded, Decoder};
548
549
    #[cfg(feature = "std")]
550
    use {alloc::vec::Vec, std::io::Read};
551
552
    #[test]
553
    fn decode_padded() {
554
        decode_test(PADDED_BIN, || {
555
            Decoder::<Base64>::new(PADDED_BASE64.as_bytes()).unwrap()
556
        })
557
    }
558
559
    #[test]
560
    fn decode_unpadded() {
561
        decode_test(UNPADDED_BIN, || {
562
            Decoder::<Base64Unpadded>::new(UNPADDED_BASE64.as_bytes()).unwrap()
563
        })
564
    }
565
566
    #[test]
567
    fn decode_multiline_padded() {
568
        decode_test(MULTILINE_PADDED_BIN, || {
569
            Decoder::<Base64>::new_wrapped(MULTILINE_PADDED_BASE64.as_bytes(), 70).unwrap()
570
        })
571
    }
572
573
    #[test]
574
    fn decode_multiline_unpadded() {
575
        decode_test(MULTILINE_UNPADDED_BIN, || {
576
            Decoder::<Base64Unpadded>::new_wrapped(MULTILINE_UNPADDED_BASE64.as_bytes(), 70)
577
                .unwrap()
578
        })
579
    }
580
581
    #[cfg(feature = "std")]
582
    #[test]
583
    fn read_multiline_padded() {
584
        let mut decoder =
585
            Decoder::<Base64>::new_wrapped(MULTILINE_PADDED_BASE64.as_bytes(), 70).unwrap();
586
587
        let mut buf = Vec::new();
588
        let len = decoder.read_to_end(&mut buf).unwrap();
589
590
        assert_eq!(len, MULTILINE_PADDED_BIN.len());
591
        assert_eq!(buf.as_slice(), MULTILINE_PADDED_BIN);
592
    }
593
594
    /// Core functionality of a decoding test
595
    fn decode_test<'a, F, V>(expected: &[u8], f: F)
596
    where
597
        F: Fn() -> Decoder<'a, V>,
598
        V: Alphabet,
599
    {
600
        for chunk_size in 1..expected.len() {
601
            let mut decoder = f();
602
            let mut remaining_len = decoder.remaining_len();
603
            let mut buffer = [0u8; 1024];
604
605
            for chunk in expected.chunks(chunk_size) {
606
                assert!(!decoder.is_finished());
607
                let decoded = decoder.decode(&mut buffer[..chunk.len()]).unwrap();
608
                assert_eq!(chunk, decoded);
609
610
                remaining_len -= decoded.len();
611
                assert_eq!(remaining_len, decoder.remaining_len());
612
            }
613
614
            assert!(decoder.is_finished());
615
            assert_eq!(decoder.remaining_len(), 0);
616
        }
617
    }
618
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64ct-1.6.0/src/encoder.rs
Line
Count
Source
1
//! Buffered Base64 encoder.
2
3
use crate::{
4
    Encoding,
5
    Error::{self, InvalidLength},
6
    LineEnding, MIN_LINE_WIDTH,
7
};
8
use core::{cmp, marker::PhantomData, str};
9
10
#[cfg(feature = "std")]
11
use std::io;
12
13
#[cfg(doc)]
14
use crate::{Base64, Base64Unpadded};
15
16
/// Stateful Base64 encoder with support for buffered, incremental encoding.
17
///
18
/// The `E` type parameter can be any type which impls [`Encoding`] such as
19
/// [`Base64`] or [`Base64Unpadded`].
20
pub struct Encoder<'o, E: Encoding> {
21
    /// Output buffer.
22
    output: &'o mut [u8],
23
24
    /// Cursor within the output buffer.
25
    position: usize,
26
27
    /// Block buffer used for non-block-aligned data.
28
    block_buffer: BlockBuffer,
29
30
    /// Configuration and state for line-wrapping the output at a specified
31
    /// column.
32
    line_wrapper: Option<LineWrapper>,
33
34
    /// Phantom parameter for the Base64 encoding in use.
35
    encoding: PhantomData<E>,
36
}
37
38
impl<'o, E: Encoding> Encoder<'o, E> {
39
    /// Create a new encoder which writes output to the given byte slice.
40
    ///
41
    /// Output constructed using this method is not line-wrapped.
42
0
    pub fn new(output: &'o mut [u8]) -> Result<Self, Error> {
43
0
        if output.is_empty() {
44
0
            return Err(InvalidLength);
45
0
        }
46
0
47
0
        Ok(Self {
48
0
            output,
49
0
            position: 0,
50
0
            block_buffer: BlockBuffer::default(),
51
0
            line_wrapper: None,
52
0
            encoding: PhantomData,
53
0
        })
54
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderpE3newB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderNtNtNtB4_8alphabet8standard6Base64E3newCs7ONNNQjtL1v_11pem_rfc7468
55
56
    /// Create a new encoder which writes line-wrapped output to the given byte
57
    /// slice.
58
    ///
59
    /// Output will be wrapped at the specified interval, using the provided
60
    /// line ending. Use [`LineEnding::default()`] to use the conventional line
61
    /// ending for the target OS.
62
    ///
63
    /// Minimum allowed line width is 4.
64
0
    pub fn new_wrapped(
65
0
        output: &'o mut [u8],
66
0
        width: usize,
67
0
        ending: LineEnding,
68
0
    ) -> Result<Self, Error> {
69
0
        let mut encoder = Self::new(output)?;
70
0
        encoder.line_wrapper = Some(LineWrapper::new(width, ending)?);
71
0
        Ok(encoder)
72
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderpE11new_wrappedB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderNtNtNtB4_8alphabet8standard6Base64E11new_wrappedCs7ONNNQjtL1v_11pem_rfc7468
73
74
    /// Encode the provided buffer as Base64, writing it to the output buffer.
75
    ///
76
    /// # Returns
77
    /// - `Ok(bytes)` if the expected amount of data was read
78
    /// - `Err(Error::InvalidLength)` if there is insufficient space in the output buffer
79
0
    pub fn encode(&mut self, mut input: &[u8]) -> Result<(), Error> {
80
0
        // If there's data in the block buffer, fill it
81
0
        if !self.block_buffer.is_empty() {
82
0
            self.process_buffer(&mut input)?;
83
0
        }
84
85
0
        while !input.is_empty() {
86
            // Attempt to encode a stride of block-aligned data
87
0
            let in_blocks = input.len() / 3;
88
0
            let out_blocks = self.remaining().len() / 4;
89
0
            let mut blocks = cmp::min(in_blocks, out_blocks);
90
91
            // When line wrapping, cap the block-aligned stride at near/at line length
92
0
            if let Some(line_wrapper) = &self.line_wrapper {
93
0
                line_wrapper.wrap_blocks(&mut blocks)?;
94
0
            }
95
96
0
            if blocks > 0 {
97
0
                let len = blocks.checked_mul(3).ok_or(InvalidLength)?;
98
0
                let (in_aligned, in_rem) = input.split_at(len);
99
0
                input = in_rem;
100
0
                self.perform_encode(in_aligned)?;
101
0
            }
102
103
            // If there's remaining non-aligned data, fill the block buffer
104
0
            if !input.is_empty() {
105
0
                self.process_buffer(&mut input)?;
106
0
            }
107
        }
108
109
0
        Ok(())
110
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderpE6encodeB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderNtNtNtB4_8alphabet8standard6Base64E6encodeCs7ONNNQjtL1v_11pem_rfc7468
111
112
    /// Get the position inside of the output buffer where the write cursor
113
    /// is currently located.
114
0
    pub fn position(&self) -> usize {
115
0
        self.position
116
0
    }
117
118
    /// Finish encoding data, returning the resulting Base64 as a `str`.
119
0
    pub fn finish(self) -> Result<&'o str, Error> {
120
0
        self.finish_with_remaining().map(|(base64, _)| base64)
121
0
    }
122
123
    /// Finish encoding data, returning the resulting Base64 as a `str`
124
    /// along with the remaining space in the output buffer.
125
0
    pub fn finish_with_remaining(mut self) -> Result<(&'o str, &'o mut [u8]), Error> {
126
0
        if !self.block_buffer.is_empty() {
127
0
            let buffer_len = self.block_buffer.position;
128
0
            let block = self.block_buffer.bytes;
129
0
            self.perform_encode(&block[..buffer_len])?;
130
0
        }
131
132
0
        let (base64, remaining) = self.output.split_at_mut(self.position);
133
0
        Ok((str::from_utf8(base64)?, remaining))
134
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderpE21finish_with_remainingB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderNtNtNtB4_8alphabet8standard6Base64E21finish_with_remainingCs7ONNNQjtL1v_11pem_rfc7468
135
136
    /// Borrow the remaining data in the buffer.
137
0
    fn remaining(&mut self) -> &mut [u8] {
138
0
        &mut self.output[self.position..]
139
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderpE9remainingB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderNtNtNtB4_8alphabet8standard6Base64E9remainingCs7ONNNQjtL1v_11pem_rfc7468
140
141
    /// Fill the block buffer with data, consuming and encoding it when the
142
    /// buffer is full.
143
0
    fn process_buffer(&mut self, input: &mut &[u8]) -> Result<(), Error> {
144
0
        self.block_buffer.fill(input)?;
145
146
0
        if self.block_buffer.is_full() {
147
0
            let block = self.block_buffer.take();
148
0
            self.perform_encode(&block)?;
149
0
        }
150
151
0
        Ok(())
152
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderpE14process_bufferB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderNtNtNtB4_8alphabet8standard6Base64E14process_bufferCs7ONNNQjtL1v_11pem_rfc7468
153
154
    /// Perform Base64 encoding operation.
155
0
    fn perform_encode(&mut self, input: &[u8]) -> Result<usize, Error> {
156
0
        let mut len = E::encode(input, self.remaining())?.as_bytes().len();
157
158
        // Insert newline characters into the output as needed
159
0
        if let Some(line_wrapper) = &mut self.line_wrapper {
160
0
            line_wrapper.insert_newlines(&mut self.output[self.position..], &mut len)?;
161
0
        }
162
163
0
        self.position = self.position.checked_add(len).ok_or(InvalidLength)?;
164
0
        Ok(len)
165
0
    }
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderpE14perform_encodeB4_
Unexecuted instantiation: _RNvMNtCs2IUk8zOUKtU_8base64ct7encoderINtB2_7EncoderNtNtNtB4_8alphabet8standard6Base64E14perform_encodeCs7ONNNQjtL1v_11pem_rfc7468
166
}
167
168
#[cfg(feature = "std")]
169
impl<'o, E: Encoding> io::Write for Encoder<'o, E> {
170
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
171
        self.encode(buf)?;
172
        Ok(buf.len())
173
    }
174
175
    fn flush(&mut self) -> io::Result<()> {
176
        // TODO(tarcieri): return an error if there's still data remaining in the buffer?
177
        Ok(())
178
    }
179
}
180
181
/// Base64 encode buffer for a 1-block output.
182
///
183
/// This handles a partial block of data, i.e. data which hasn't been
184
#[derive(Clone, Default, Debug)]
185
struct BlockBuffer {
186
    /// 3 decoded bytes to be encoded to a 4-byte Base64-encoded input.
187
    bytes: [u8; Self::SIZE],
188
189
    /// Position within the buffer.
190
    position: usize,
191
}
192
193
impl BlockBuffer {
194
    /// Size of the buffer in bytes: 3-bytes of unencoded input which
195
    /// Base64 encode to 4-bytes of output.
196
    const SIZE: usize = 3;
197
198
    /// Fill the remaining space in the buffer with the input data.
199
0
    fn fill(&mut self, input: &mut &[u8]) -> Result<(), Error> {
200
0
        let remaining = Self::SIZE.checked_sub(self.position).ok_or(InvalidLength)?;
201
0
        let len = cmp::min(input.len(), remaining);
202
0
        self.bytes[self.position..][..len].copy_from_slice(&input[..len]);
203
0
        self.position = self.position.checked_add(len).ok_or(InvalidLength)?;
204
0
        *input = &input[len..];
205
0
        Ok(())
206
0
    }
207
208
    /// Take the output buffer, resetting the position to 0.
209
0
    fn take(&mut self) -> [u8; Self::SIZE] {
210
0
        debug_assert!(self.is_full());
211
0
        let result = self.bytes;
212
0
        *self = Default::default();
213
0
        result
214
0
    }
215
216
    /// Is the buffer empty?
217
0
    fn is_empty(&self) -> bool {
218
0
        self.position == 0
219
0
    }
Unexecuted instantiation: _RNvMs_NtCs2IUk8zOUKtU_8base64ct7encoderNtB4_11BlockBuffer8is_emptyB6_
Unexecuted instantiation: _RNvMs_NtCs2IUk8zOUKtU_8base64ct7encoderNtB4_11BlockBuffer8is_emptyCs7ONNNQjtL1v_11pem_rfc7468
220
221
    /// Is the buffer full?
222
0
    fn is_full(&self) -> bool {
223
0
        self.position == Self::SIZE
224
0
    }
Unexecuted instantiation: _RNvMs_NtCs2IUk8zOUKtU_8base64ct7encoderNtB4_11BlockBuffer7is_fullB6_
Unexecuted instantiation: _RNvMs_NtCs2IUk8zOUKtU_8base64ct7encoderNtB4_11BlockBuffer7is_fullCs7ONNNQjtL1v_11pem_rfc7468
225
}
226
227
/// Helper for wrapping Base64 at a given line width.
228
#[derive(Debug)]
229
struct LineWrapper {
230
    /// Number of bytes remaining in the current line.
231
    remaining: usize,
232
233
    /// Column at which Base64 should be wrapped.
234
    width: usize,
235
236
    /// Newline characters to use at the end of each line.
237
    ending: LineEnding,
238
}
239
240
impl LineWrapper {
241
    /// Create a new linewrapper.
242
0
    fn new(width: usize, ending: LineEnding) -> Result<Self, Error> {
243
0
        if width < MIN_LINE_WIDTH {
244
0
            return Err(InvalidLength);
245
0
        }
246
0
247
0
        Ok(Self {
248
0
            remaining: width,
249
0
            width,
250
0
            ending,
251
0
        })
252
0
    }
Unexecuted instantiation: _RNvMs0_NtCs2IUk8zOUKtU_8base64ct7encoderNtB5_11LineWrapper3newB7_
Unexecuted instantiation: _RNvMs0_NtCs2IUk8zOUKtU_8base64ct7encoderNtB5_11LineWrapper3newCs7ONNNQjtL1v_11pem_rfc7468
253
254
    /// Wrap the number of blocks to encode near/at EOL.
255
0
    fn wrap_blocks(&self, blocks: &mut usize) -> Result<(), Error> {
256
0
        if blocks.checked_mul(4).ok_or(InvalidLength)? >= self.remaining {
257
0
            *blocks = self.remaining / 4;
258
0
        }
259
260
0
        Ok(())
261
0
    }
262
263
    /// Insert newlines into the output buffer as needed.
264
0
    fn insert_newlines(&mut self, mut buffer: &mut [u8], len: &mut usize) -> Result<(), Error> {
265
0
        let mut buffer_len = *len;
266
0
267
0
        if buffer_len <= self.remaining {
268
0
            self.remaining = self
269
0
                .remaining
270
0
                .checked_sub(buffer_len)
271
0
                .ok_or(InvalidLength)?;
272
273
0
            return Ok(());
274
0
        }
275
0
276
0
        buffer = &mut buffer[self.remaining..];
277
0
        buffer_len = buffer_len
278
0
            .checked_sub(self.remaining)
279
0
            .ok_or(InvalidLength)?;
280
281
        // The `wrap_blocks` function should ensure the buffer is no larger than a Base64 block
282
0
        debug_assert!(buffer_len <= 4, "buffer too long: {}", buffer_len);
283
284
        // Ensure space in buffer to add newlines
285
0
        let buffer_end = buffer_len
286
0
            .checked_add(self.ending.len())
287
0
            .ok_or(InvalidLength)?;
288
289
0
        if buffer_end >= buffer.len() {
290
0
            return Err(InvalidLength);
291
0
        }
292
293
        // Shift the buffer contents to make space for the line ending
294
0
        for i in (0..buffer_len).rev() {
295
0
            buffer[i.checked_add(self.ending.len()).ok_or(InvalidLength)?] = buffer[i];
296
        }
297
298
0
        buffer[..self.ending.len()].copy_from_slice(self.ending.as_bytes());
299
0
        *len = (*len).checked_add(self.ending.len()).ok_or(InvalidLength)?;
300
0
        self.remaining = self.width.checked_sub(buffer_len).ok_or(InvalidLength)?;
301
302
0
        Ok(())
303
0
    }
304
}
305
306
#[cfg(test)]
307
mod tests {
308
    use crate::{alphabet::Alphabet, test_vectors::*, Base64, Base64Unpadded, Encoder, LineEnding};
309
310
    #[test]
311
    fn encode_padded() {
312
        encode_test::<Base64>(PADDED_BIN, PADDED_BASE64, None);
313
    }
314
315
    #[test]
316
    fn encode_unpadded() {
317
        encode_test::<Base64Unpadded>(UNPADDED_BIN, UNPADDED_BASE64, None);
318
    }
319
320
    #[test]
321
    fn encode_multiline_padded() {
322
        encode_test::<Base64>(MULTILINE_PADDED_BIN, MULTILINE_PADDED_BASE64, Some(70));
323
    }
324
325
    #[test]
326
    fn encode_multiline_unpadded() {
327
        encode_test::<Base64Unpadded>(MULTILINE_UNPADDED_BIN, MULTILINE_UNPADDED_BASE64, Some(70));
328
    }
329
330
    #[test]
331
    fn no_trailing_newline_when_aligned() {
332
        let mut buffer = [0u8; 64];
333
        let mut encoder = Encoder::<Base64>::new_wrapped(&mut buffer, 64, LineEnding::LF).unwrap();
334
        encoder.encode(&[0u8; 48]).unwrap();
335
336
        // Ensure no newline character is present in this case
337
        assert_eq!(
338
            "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
339
            encoder.finish().unwrap()
340
        );
341
    }
342
343
    /// Core functionality of an encoding test.
344
    fn encode_test<V: Alphabet>(input: &[u8], expected: &str, wrapped: Option<usize>) {
345
        let mut buffer = [0u8; 1024];
346
347
        for chunk_size in 1..input.len() {
348
            let mut encoder = match wrapped {
349
                Some(line_width) => {
350
                    Encoder::<V>::new_wrapped(&mut buffer, line_width, LineEnding::LF)
351
                }
352
                None => Encoder::<V>::new(&mut buffer),
353
            }
354
            .unwrap();
355
356
            for chunk in input.chunks(chunk_size) {
357
                encoder.encode(chunk).unwrap();
358
            }
359
360
            assert_eq!(expected, encoder.finish().unwrap());
361
        }
362
    }
363
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64ct-1.6.0/src/encoding.rs
Line
Count
Source
1
//! Base64 encodings
2
3
use crate::{
4
    alphabet::Alphabet,
5
    errors::{Error, InvalidEncodingError, InvalidLengthError},
6
};
7
use core::str;
8
9
#[cfg(feature = "alloc")]
10
use alloc::{string::String, vec::Vec};
11
12
#[cfg(doc)]
13
use crate::{Base64, Base64Bcrypt, Base64Crypt, Base64Unpadded, Base64Url, Base64UrlUnpadded};
14
15
/// Padding character
16
const PAD: u8 = b'=';
17
18
/// Base64 encoding trait.
19
///
20
/// This trait must be imported to make use of any Base64 alphabet defined
21
/// in this crate.
22
///
23
/// The following encoding types impl this trait:
24
///
25
/// - [`Base64`]: standard Base64 encoding with `=` padding.
26
/// - [`Base64Bcrypt`]: bcrypt Base64 encoding.
27
/// - [`Base64Crypt`]: `crypt(3)` Base64 encoding.
28
/// - [`Base64Unpadded`]: standard Base64 encoding *without* padding.
29
/// - [`Base64Url`]: URL-safe Base64 encoding with `=` padding.
30
/// - [`Base64UrlUnpadded`]: URL-safe Base64 encoding *without* padding.
31
pub trait Encoding: Alphabet {
32
    /// Decode a Base64 string into the provided destination buffer.
33
    fn decode(src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], Error>;
34
35
    /// Decode a Base64 string in-place.
36
    ///
37
    /// NOTE: this method does not (yet) validate that padding is well-formed,
38
    /// if the given Base64 encoding is padded.
39
    fn decode_in_place(buf: &mut [u8]) -> Result<&[u8], InvalidEncodingError>;
40
41
    /// Decode a Base64 string into a byte vector.
42
    #[cfg(feature = "alloc")]
43
    fn decode_vec(input: &str) -> Result<Vec<u8>, Error>;
44
45
    /// Encode the input byte slice as Base64.
46
    ///
47
    /// Writes the result into the provided destination slice, returning an
48
    /// ASCII-encoded Base64 string value.
49
    fn encode<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, InvalidLengthError>;
50
51
    /// Encode input byte slice into a [`String`] containing Base64.
52
    ///
53
    /// # Panics
54
    /// If `input` length is greater than `usize::MAX/4`.
55
    #[cfg(feature = "alloc")]
56
    fn encode_string(input: &[u8]) -> String;
57
58
    /// Get the length of Base64 produced by encoding the given bytes.
59
    ///
60
    /// WARNING: this function will return `0` for lengths greater than `usize::MAX/4`!
61
    fn encoded_len(bytes: &[u8]) -> usize;
62
}
63
64
impl<T: Alphabet> Encoding for T {
65
0
    fn decode(src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], Error> {
66
0
        let (src_unpadded, mut err) = if T::PADDED {
67
0
            let (unpadded_len, e) = decode_padding(src.as_ref())?;
68
0
            (&src.as_ref()[..unpadded_len], e)
69
        } else {
70
0
            (src.as_ref(), 0)
71
        };
72
73
0
        let dlen = decoded_len(src_unpadded.len());
74
0
75
0
        if dlen > dst.len() {
76
0
            return Err(Error::InvalidLength);
77
0
        }
78
0
79
0
        let dst = &mut dst[..dlen];
80
0
81
0
        let mut src_chunks = src_unpadded.chunks_exact(4);
82
0
        let mut dst_chunks = dst.chunks_exact_mut(3);
83
0
        for (s, d) in (&mut src_chunks).zip(&mut dst_chunks) {
84
0
            err |= Self::decode_3bytes(s, d);
85
0
        }
86
0
        let src_rem = src_chunks.remainder();
87
0
        let dst_rem = dst_chunks.into_remainder();
88
0
89
0
        err |= !(src_rem.is_empty() || src_rem.len() >= 2) as i16;
90
0
        let mut tmp_out = [0u8; 3];
91
0
        let mut tmp_in = [b'A'; 4];
92
0
        tmp_in[..src_rem.len()].copy_from_slice(src_rem);
93
0
        err |= Self::decode_3bytes(&tmp_in, &mut tmp_out);
94
0
        dst_rem.copy_from_slice(&tmp_out[..dst_rem.len()]);
95
0
96
0
        if err == 0 {
97
0
            validate_last_block::<T>(src.as_ref(), dst)?;
98
0
            Ok(dst)
99
        } else {
100
0
            Err(Error::InvalidEncoding)
101
        }
102
0
    }
Unexecuted instantiation: _RINvXININtCs2IUk8zOUKtU_8base64ct8encoding0pEpNtB6_8Encoding6decodepEB8_
Unexecuted instantiation: _RINvXNtCs2IUk8zOUKtU_8base64ct8encodingNtNtNtB5_8alphabet8standard14Base64UnpaddedNtB3_8Encoding6decodeRShECs7ONNNQjtL1v_11pem_rfc7468
Unexecuted instantiation: _RINvXNtCs2IUk8zOUKtU_8base64ct8encodingNtNtNtB5_8alphabet8standard6Base64NtB3_8Encoding6decodeRShECs7ONNNQjtL1v_11pem_rfc7468
103
104
    // TODO(tarcieri): explicitly checked/wrapped arithmetic
105
    #[allow(clippy::integer_arithmetic)]
106
0
    fn decode_in_place(mut buf: &mut [u8]) -> Result<&[u8], InvalidEncodingError> {
107
        // TODO: eliminate unsafe code when LLVM12 is stable
108
        // See: https://github.com/rust-lang/rust/issues/80963
109
0
        let mut err = if T::PADDED {
110
0
            let (unpadded_len, e) = decode_padding(buf)?;
111
0
            buf = &mut buf[..unpadded_len];
112
0
            e
113
        } else {
114
0
            0
115
        };
116
117
0
        let dlen = decoded_len(buf.len());
118
0
        let full_chunks = buf.len() / 4;
119
120
0
        for chunk in 0..full_chunks {
121
            // SAFETY: `p3` and `p4` point inside `buf`, while they may overlap,
122
            // read and write are clearly separated from each other and done via
123
            // raw pointers.
124
            #[allow(unsafe_code)]
125
            unsafe {
126
0
                debug_assert!(3 * chunk + 3 <= buf.len());
127
0
                debug_assert!(4 * chunk + 4 <= buf.len());
128
129
0
                let p3 = buf.as_mut_ptr().add(3 * chunk) as *mut [u8; 3];
130
0
                let p4 = buf.as_ptr().add(4 * chunk) as *const [u8; 4];
131
0
132
0
                let mut tmp_out = [0u8; 3];
133
0
                err |= Self::decode_3bytes(&*p4, &mut tmp_out);
134
0
                *p3 = tmp_out;
135
            }
136
        }
137
138
0
        let src_rem_pos = 4 * full_chunks;
139
0
        let src_rem_len = buf.len() - src_rem_pos;
140
0
        let dst_rem_pos = 3 * full_chunks;
141
0
        let dst_rem_len = dlen - dst_rem_pos;
142
0
143
0
        err |= !(src_rem_len == 0 || src_rem_len >= 2) as i16;
144
0
        let mut tmp_in = [b'A'; 4];
145
0
        tmp_in[..src_rem_len].copy_from_slice(&buf[src_rem_pos..]);
146
0
        let mut tmp_out = [0u8; 3];
147
0
148
0
        err |= Self::decode_3bytes(&tmp_in, &mut tmp_out);
149
0
150
0
        if err == 0 {
151
            // SAFETY: `dst_rem_len` is always smaller than 4, so we don't
152
            // read outside of `tmp_out`, write and the final slicing never go
153
            // outside of `buf`.
154
            #[allow(unsafe_code)]
155
            unsafe {
156
0
                debug_assert!(dst_rem_pos + dst_rem_len <= buf.len());
157
0
                debug_assert!(dst_rem_len <= tmp_out.len());
158
0
                debug_assert!(dlen <= buf.len());
159
160
0
                core::ptr::copy_nonoverlapping(
161
0
                    tmp_out.as_ptr(),
162
0
                    buf.as_mut_ptr().add(dst_rem_pos),
163
0
                    dst_rem_len,
164
0
                );
165
0
                Ok(buf.get_unchecked(..dlen))
166
            }
167
        } else {
168
0
            Err(InvalidEncodingError)
169
        }
170
0
    }
171
172
    #[cfg(feature = "alloc")]
173
0
    fn decode_vec(input: &str) -> Result<Vec<u8>, Error> {
174
0
        let mut output = vec![0u8; decoded_len(input.len())];
175
0
        let len = Self::decode(input, &mut output)?.len();
176
0
177
0
        if len <= output.len() {
178
0
            output.truncate(len);
179
0
            Ok(output)
180
        } else {
181
0
            Err(Error::InvalidLength)
182
        }
183
0
    }
184
185
0
    fn encode<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, InvalidLengthError> {
186
0
        let elen = match encoded_len_inner(src.len(), T::PADDED) {
187
0
            Some(v) => v,
188
0
            None => return Err(InvalidLengthError),
189
        };
190
191
0
        if elen > dst.len() {
192
0
            return Err(InvalidLengthError);
193
0
        }
194
0
195
0
        let dst = &mut dst[..elen];
196
0
197
0
        let mut src_chunks = src.chunks_exact(3);
198
0
        let mut dst_chunks = dst.chunks_exact_mut(4);
199
200
0
        for (s, d) in (&mut src_chunks).zip(&mut dst_chunks) {
201
0
            Self::encode_3bytes(s, d);
202
0
        }
203
204
0
        let src_rem = src_chunks.remainder();
205
0
206
0
        if T::PADDED {
207
0
            if let Some(dst_rem) = dst_chunks.next() {
208
0
                let mut tmp = [0u8; 3];
209
0
                tmp[..src_rem.len()].copy_from_slice(src_rem);
210
0
                Self::encode_3bytes(&tmp, dst_rem);
211
0
212
0
                let flag = src_rem.len() == 1;
213
0
                let mask = (flag as u8).wrapping_sub(1);
214
0
                dst_rem[2] = (dst_rem[2] & mask) | (PAD & !mask);
215
0
                dst_rem[3] = PAD;
216
0
            }
217
0
        } else {
218
0
            let dst_rem = dst_chunks.into_remainder();
219
0
220
0
            let mut tmp_in = [0u8; 3];
221
0
            let mut tmp_out = [0u8; 4];
222
0
            tmp_in[..src_rem.len()].copy_from_slice(src_rem);
223
0
            Self::encode_3bytes(&tmp_in, &mut tmp_out);
224
0
            dst_rem.copy_from_slice(&tmp_out[..dst_rem.len()]);
225
0
        }
226
227
0
        debug_assert!(str::from_utf8(dst).is_ok());
228
229
        // SAFETY: values written by `encode_3bytes` are valid one-byte UTF-8 chars
230
        #[allow(unsafe_code)]
231
0
        Ok(unsafe { str::from_utf8_unchecked(dst) })
232
0
    }
Unexecuted instantiation: _RNvXININtCs2IUk8zOUKtU_8base64ct8encoding0pEpNtB5_8Encoding6encodeB7_
Unexecuted instantiation: _RNvXNtCs2IUk8zOUKtU_8base64ct8encodingNtNtNtB4_8alphabet8standard14Base64UnpaddedNtB2_8Encoding6encodeCs7ONNNQjtL1v_11pem_rfc7468
Unexecuted instantiation: _RNvXNtCs2IUk8zOUKtU_8base64ct8encodingNtNtNtB4_8alphabet8standard6Base64NtB2_8Encoding6encodeCs7ONNNQjtL1v_11pem_rfc7468
233
234
    #[cfg(feature = "alloc")]
235
0
    fn encode_string(input: &[u8]) -> String {
236
0
        let elen = encoded_len_inner(input.len(), T::PADDED).expect("input is too big");
237
0
        let mut dst = vec![0u8; elen];
238
0
        let res = Self::encode(input, &mut dst).expect("encoding error");
239
0
240
0
        debug_assert_eq!(elen, res.len());
241
0
        debug_assert!(str::from_utf8(&dst).is_ok());
242
243
        // SAFETY: `dst` is fully written and contains only valid one-byte UTF-8 chars
244
        #[allow(unsafe_code)]
245
        unsafe {
246
0
            String::from_utf8_unchecked(dst)
247
0
        }
248
0
    }
249
250
0
    fn encoded_len(bytes: &[u8]) -> usize {
251
0
        encoded_len_inner(bytes.len(), T::PADDED).unwrap_or(0)
252
0
    }
Unexecuted instantiation: _RNvXININtCs2IUk8zOUKtU_8base64ct8encoding0pEpNtB5_8Encoding11encoded_lenB7_
Unexecuted instantiation: _RNvXNtCs2IUk8zOUKtU_8base64ct8encodingNtNtNtB4_8alphabet8standard6Base64NtB2_8Encoding11encoded_lenCs7ONNNQjtL1v_11pem_rfc7468
253
}
254
255
/// Validate padding is of the expected length compute unpadded length.
256
///
257
/// Note that this method does not explicitly check that the padded data
258
/// is valid in and of itself: that is performed by `validate_last_block` as a
259
/// final step.
260
///
261
/// Returns length-related errors eagerly as a [`Result`], and data-dependent
262
/// errors (i.e. malformed padding bytes) as `i16` to be combined with other
263
/// encoding-related errors prior to branching.
264
#[inline(always)]
265
0
pub(crate) fn decode_padding(input: &[u8]) -> Result<(usize, i16), InvalidEncodingError> {
266
0
    if input.len() % 4 != 0 {
267
0
        return Err(InvalidEncodingError);
268
0
    }
269
270
0
    let unpadded_len = match *input {
271
0
        [.., b0, b1] => is_pad_ct(b0)
272
0
            .checked_add(is_pad_ct(b1))
273
0
            .and_then(|len| len.try_into().ok())
Unexecuted instantiation: _RNCNvNtCs2IUk8zOUKtU_8base64ct8encoding14decode_padding0B5_
Unexecuted instantiation: _RNCNvNtCs2IUk8zOUKtU_8base64ct8encoding14decode_padding0Cs7ONNNQjtL1v_11pem_rfc7468
274
0
            .and_then(|len| input.len().checked_sub(len))
Unexecuted instantiation: _RNCNvNtCs2IUk8zOUKtU_8base64ct8encoding14decode_paddings_0B5_
Unexecuted instantiation: _RNCNvNtCs2IUk8zOUKtU_8base64ct8encoding14decode_paddings_0Cs7ONNNQjtL1v_11pem_rfc7468
275
0
            .ok_or(InvalidEncodingError)?,
276
0
        _ => input.len(),
277
    };
278
279
0
    let padding_len = input
280
0
        .len()
281
0
        .checked_sub(unpadded_len)
282
0
        .ok_or(InvalidEncodingError)?;
283
284
0
    let err = match *input {
285
0
        [.., b0] if padding_len == 1 => is_pad_ct(b0) ^ 1,
286
0
        [.., b0, b1] if padding_len == 2 => (is_pad_ct(b0) & is_pad_ct(b1)) ^ 1,
287
        _ => {
288
0
            if padding_len == 0 {
289
0
                0
290
            } else {
291
0
                return Err(InvalidEncodingError);
292
            }
293
        }
294
    };
295
296
0
    Ok((unpadded_len, err))
297
0
}
298
299
/// Validate that the last block of the decoded data round-trips back to the
300
/// encoded data.
301
0
fn validate_last_block<T: Alphabet>(encoded: &[u8], decoded: &[u8]) -> Result<(), Error> {
302
0
    if encoded.is_empty() && decoded.is_empty() {
303
0
        return Ok(());
304
0
    }
305
306
    // TODO(tarcieri): explicitly checked/wrapped arithmetic
307
    #[allow(clippy::integer_arithmetic)]
308
0
    fn last_block_start(bytes: &[u8], block_size: usize) -> usize {
309
0
        (bytes.len().saturating_sub(1) / block_size) * block_size
310
0
    }
311
312
0
    let enc_block = encoded
313
0
        .get(last_block_start(encoded, 4)..)
314
0
        .ok_or(Error::InvalidEncoding)?;
315
316
0
    let dec_block = decoded
317
0
        .get(last_block_start(decoded, 3)..)
318
0
        .ok_or(Error::InvalidEncoding)?;
319
320
    // Round-trip encode the decoded block
321
0
    let mut buf = [0u8; 4];
322
0
    let block = T::encode(dec_block, &mut buf)?;
323
324
    // Non-short-circuiting comparison of padding
325
    // TODO(tarcieri): better constant-time mechanisms (e.g. `subtle`)?
326
0
    if block
327
0
        .as_bytes()
328
0
        .iter()
329
0
        .zip(enc_block.iter())
330
0
        .fold(0, |acc, (a, b)| acc | (a ^ b))
Unexecuted instantiation: _RNCINvNtCs2IUk8zOUKtU_8base64ct8encoding19validate_last_blockpE0B6_
Unexecuted instantiation: _RNCINvNtCs2IUk8zOUKtU_8base64ct8encoding19validate_last_blockNtNtNtB6_8alphabet8standard14Base64UnpaddedE0Cs7ONNNQjtL1v_11pem_rfc7468
Unexecuted instantiation: _RNCINvNtCs2IUk8zOUKtU_8base64ct8encoding19validate_last_blockNtNtNtB6_8alphabet8standard6Base64E0Cs7ONNNQjtL1v_11pem_rfc7468
331
0
        == 0
332
    {
333
0
        Ok(())
334
    } else {
335
0
        Err(Error::InvalidEncoding)
336
    }
337
0
}
Unexecuted instantiation: _RINvNtCs2IUk8zOUKtU_8base64ct8encoding19validate_last_blockpEB4_
Unexecuted instantiation: _RINvNtCs2IUk8zOUKtU_8base64ct8encoding19validate_last_blockNtNtNtB4_8alphabet8standard14Base64UnpaddedECs7ONNNQjtL1v_11pem_rfc7468
Unexecuted instantiation: _RINvNtCs2IUk8zOUKtU_8base64ct8encoding19validate_last_blockNtNtNtB4_8alphabet8standard6Base64ECs7ONNNQjtL1v_11pem_rfc7468
338
339
/// Get the length of the output from decoding the provided *unpadded*
340
/// Base64-encoded input.
341
///
342
/// Note that this function does not fully validate the Base64 is well-formed
343
/// and may return incorrect results for malformed Base64.
344
// TODO(tarcieri): explicitly checked/wrapped arithmetic
345
#[allow(clippy::integer_arithmetic)]
346
#[inline(always)]
347
0
pub(crate) fn decoded_len(input_len: usize) -> usize {
348
0
    // overflow-proof computation of `(3*n)/4`
349
0
    let k = input_len / 4;
350
0
    let l = input_len - 4 * k;
351
0
    3 * k + (3 * l) / 4
352
0
}
353
354
/// Branchless match that a given byte is the `PAD` character
355
// TODO(tarcieri): explicitly checked/wrapped arithmetic
356
#[allow(clippy::integer_arithmetic)]
357
#[inline(always)]
358
0
fn is_pad_ct(input: u8) -> i16 {
359
0
    ((((PAD as i16 - 1) - input as i16) & (input as i16 - (PAD as i16 + 1))) >> 8) & 1
360
0
}
361
362
// TODO(tarcieri): explicitly checked/wrapped arithmetic
363
#[allow(clippy::integer_arithmetic)]
364
#[inline(always)]
365
0
const fn encoded_len_inner(n: usize, padded: bool) -> Option<usize> {
366
0
    match n.checked_mul(4) {
367
0
        Some(q) => {
368
0
            if padded {
369
0
                Some(((q / 3) + 3) & !3)
370
            } else {
371
0
                Some((q / 3) + (q % 3 != 0) as usize)
372
            }
373
        }
374
0
        None => None,
375
    }
376
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64ct-1.6.0/src/errors.rs
Line
Count
Source
1
//! Error types
2
3
use core::fmt;
4
5
const INVALID_ENCODING_MSG: &str = "invalid Base64 encoding";
6
const INVALID_LENGTH_MSG: &str = "invalid Base64 length";
7
8
/// Insufficient output buffer length.
9
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
10
pub struct InvalidLengthError;
11
12
impl fmt::Display for InvalidLengthError {
13
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
14
0
        f.write_str(INVALID_LENGTH_MSG)
15
0
    }
16
}
17
18
#[cfg(feature = "std")]
19
impl std::error::Error for InvalidLengthError {}
20
21
/// Invalid encoding of provided Base64 string.
22
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
23
pub struct InvalidEncodingError;
24
25
impl fmt::Display for InvalidEncodingError {
26
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
27
0
        f.write_str(INVALID_ENCODING_MSG)
28
0
    }
29
}
30
31
#[cfg(feature = "std")]
32
impl std::error::Error for InvalidEncodingError {}
33
34
/// Generic error, union of [`InvalidLengthError`] and [`InvalidEncodingError`].
35
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
36
pub enum Error {
37
    /// Invalid encoding of provided Base64 string.
38
    InvalidEncoding,
39
40
    /// Insufficient output buffer length.
41
    InvalidLength,
42
}
43
44
impl fmt::Display for Error {
45
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
46
0
        let s = match self {
47
0
            Self::InvalidEncoding => INVALID_ENCODING_MSG,
48
0
            Self::InvalidLength => INVALID_LENGTH_MSG,
49
        };
50
0
        f.write_str(s)
51
0
    }
52
}
53
54
impl From<InvalidEncodingError> for Error {
55
    #[inline]
56
0
    fn from(_: InvalidEncodingError) -> Error {
57
0
        Error::InvalidEncoding
58
0
    }
Unexecuted instantiation: _RNvXs1_NtCs2IUk8zOUKtU_8base64ct6errorsNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_20InvalidEncodingErrorE4fromB7_
Unexecuted instantiation: _RNvXs1_NtCs2IUk8zOUKtU_8base64ct6errorsNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_20InvalidEncodingErrorE4fromCs7ONNNQjtL1v_11pem_rfc7468
59
}
60
61
impl From<InvalidLengthError> for Error {
62
    #[inline]
63
0
    fn from(_: InvalidLengthError) -> Error {
64
0
        Error::InvalidLength
65
0
    }
Unexecuted instantiation: _RNvXs2_NtCs2IUk8zOUKtU_8base64ct6errorsNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_18InvalidLengthErrorE4fromB7_
Unexecuted instantiation: _RNvXs2_NtCs2IUk8zOUKtU_8base64ct6errorsNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_18InvalidLengthErrorE4fromCs7ONNNQjtL1v_11pem_rfc7468
66
}
67
68
impl From<core::str::Utf8Error> for Error {
69
    #[inline]
70
0
    fn from(_: core::str::Utf8Error) -> Error {
71
0
        Error::InvalidEncoding
72
0
    }
Unexecuted instantiation: _RNvXs3_NtCs2IUk8zOUKtU_8base64ct6errorsNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtNtBR_3str5error9Utf8ErrorE4fromB7_
Unexecuted instantiation: _RNvXs3_NtCs2IUk8zOUKtU_8base64ct6errorsNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtNtBR_3str5error9Utf8ErrorE4fromCs7ONNNQjtL1v_11pem_rfc7468
73
}
74
75
#[cfg(feature = "std")]
76
impl From<Error> for std::io::Error {
77
    fn from(err: Error) -> std::io::Error {
78
        // TODO(tarcieri): better customize `ErrorKind`?
79
        std::io::Error::new(std::io::ErrorKind::InvalidData, err)
80
    }
81
}
82
83
#[cfg(feature = "std")]
84
impl std::error::Error for Error {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64ct-1.6.0/src/line_ending.rs
Line
Count
Source
1
//! Line endings.
2
3
/// Carriage return
4
pub(crate) const CHAR_CR: u8 = 0x0d;
5
6
/// Line feed
7
pub(crate) const CHAR_LF: u8 = 0x0a;
8
9
/// Line endings: variants of newline characters that can be used with Base64.
10
///
11
/// Use [`LineEnding::default`] to get an appropriate line ending for the
12
/// current operating system.
13
#[allow(clippy::upper_case_acronyms)]
14
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
15
pub enum LineEnding {
16
    /// Carriage return: `\r` (Pre-OS X Macintosh)
17
    CR,
18
19
    /// Line feed: `\n` (Unix OSes)
20
    LF,
21
22
    /// Carriage return + line feed: `\r\n` (Windows)
23
    CRLF,
24
}
25
26
impl Default for LineEnding {
27
    // Default line ending matches conventions for target OS
28
    #[cfg(windows)]
29
    fn default() -> LineEnding {
30
        LineEnding::CRLF
31
    }
32
    #[cfg(not(windows))]
33
0
    fn default() -> LineEnding {
34
0
        LineEnding::LF
35
0
    }
36
}
37
38
#[allow(clippy::len_without_is_empty)]
39
impl LineEnding {
40
    /// Get the byte serialization of this [`LineEnding`].
41
0
    pub fn as_bytes(self) -> &'static [u8] {
42
0
        match self {
43
0
            LineEnding::CR => &[CHAR_CR],
44
0
            LineEnding::LF => &[CHAR_LF],
45
0
            LineEnding::CRLF => &[CHAR_CR, CHAR_LF],
46
        }
47
0
    }
Unexecuted instantiation: _RNvMs_NtCs2IUk8zOUKtU_8base64ct11line_endingNtB4_10LineEnding8as_bytesB6_
Unexecuted instantiation: _RNvMs_NtCs2IUk8zOUKtU_8base64ct11line_endingNtB4_10LineEnding8as_bytesCs7ONNNQjtL1v_11pem_rfc7468
48
49
    /// Get the encoded length of this [`LineEnding`].
50
0
    pub fn len(self) -> usize {
51
0
        self.as_bytes().len()
52
0
    }
Unexecuted instantiation: _RNvMs_NtCs2IUk8zOUKtU_8base64ct11line_endingNtB4_10LineEnding3lenB6_
Unexecuted instantiation: _RNvMs_NtCs2IUk8zOUKtU_8base64ct11line_endingNtB4_10LineEnding3lenCs7ONNNQjtL1v_11pem_rfc7468
53
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/block-buffer-0.10.4/src/lib.rs
Line
Count
Source
1
//! Fixed size buffer for block processing of data.
2
#![no_std]
3
#![doc(
4
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
5
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
6
)]
7
#![warn(missing_docs, rust_2018_idioms)]
8
9
pub use generic_array;
10
11
use core::{fmt, marker::PhantomData, slice};
12
use generic_array::{
13
    typenum::{IsLess, Le, NonZero, U256},
14
    ArrayLength, GenericArray,
15
};
16
17
mod sealed;
18
19
/// Block on which `BlockBuffer` operates.
20
pub type Block<BlockSize> = GenericArray<u8, BlockSize>;
21
22
/// Trait for buffer kinds.
23
pub trait BufferKind: sealed::Sealed {}
24
25
/// Eager block buffer kind, which guarantees that buffer position
26
/// always lies in the range of `0..BlockSize`.
27
#[derive(Copy, Clone, Debug, Default)]
28
pub struct Eager {}
29
30
/// Lazy block buffer kind, which guarantees that buffer position
31
/// always lies in the range of `0..=BlockSize`.
32
#[derive(Copy, Clone, Debug, Default)]
33
pub struct Lazy {}
34
35
impl BufferKind for Eager {}
36
impl BufferKind for Lazy {}
37
38
/// Eager block buffer.
39
pub type EagerBuffer<B> = BlockBuffer<B, Eager>;
40
/// Lazy block buffer.
41
pub type LazyBuffer<B> = BlockBuffer<B, Lazy>;
42
43
/// Block buffer error.
44
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
45
pub struct Error;
46
47
impl fmt::Display for Error {
48
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
49
0
        f.write_str("Block buffer error")
50
0
    }
51
}
52
53
/// Buffer for block processing of data.
54
#[derive(Debug)]
55
pub struct BlockBuffer<BlockSize, Kind>
56
where
57
    BlockSize: ArrayLength<u8> + IsLess<U256>,
58
    Le<BlockSize, U256>: NonZero,
59
    Kind: BufferKind,
60
{
61
    buffer: Block<BlockSize>,
62
    pos: u8,
63
    _pd: PhantomData<Kind>,
64
}
65
66
impl<BlockSize, Kind> Default for BlockBuffer<BlockSize, Kind>
67
where
68
    BlockSize: ArrayLength<u8> + IsLess<U256>,
69
    Le<BlockSize, U256>: NonZero,
70
    Kind: BufferKind,
71
{
72
9.63k
    fn default() -> Self {
73
9.63k
        if BlockSize::USIZE == 0 {
74
0
            panic!("Block size can not be equal to zero");
75
9.63k
        }
76
9.63k
        Self {
77
9.63k
            buffer: Default::default(),
78
9.63k
            pos: 0,
79
9.63k
            _pd: PhantomData,
80
9.63k
        }
81
9.63k
    }
Unexecuted instantiation: _RNvXINICsf9lUOpqAe5A_12block_buffers1_0ppEINtB5_11BlockBufferppENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultB5_
Unexecuted instantiation: _RNvXs1_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs1_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs2IvCg5PL8uK_11chia_traits
_RNvXs1_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs4RkbDk9WRL5_5clvmr
Line
Count
Source
72
9.63k
    fn default() -> Self {
73
9.63k
        if BlockSize::USIZE == 0 {
74
0
            panic!("Block size can not be equal to zero");
75
9.63k
        }
76
9.63k
        Self {
77
9.63k
            buffer: Default::default(),
78
9.63k
            pos: 0,
79
9.63k
            _pd: PhantomData,
80
9.63k
        }
81
9.63k
    }
Unexecuted instantiation: _RNvXs1_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCsjewTDwKBbyD_4k256
82
}
83
84
impl<BlockSize, Kind> Clone for BlockBuffer<BlockSize, Kind>
85
where
86
    BlockSize: ArrayLength<u8> + IsLess<U256>,
87
    Le<BlockSize, U256>: NonZero,
88
    Kind: BufferKind,
89
{
90
0
    fn clone(&self) -> Self {
91
0
        Self {
92
0
            buffer: self.buffer.clone(),
93
0
            pos: self.pos,
94
0
            _pd: PhantomData,
95
0
        }
96
0
    }
Unexecuted instantiation: _RNvXINICsf9lUOpqAe5A_12block_buffers2_0ppEINtB5_11BlockBufferppENtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB5_
Unexecuted instantiation: _RNvXs2_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerENtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneCs4RkbDk9WRL5_5clvmr
97
}
98
99
impl<BlockSize, Kind> BlockBuffer<BlockSize, Kind>
100
where
101
    BlockSize: ArrayLength<u8> + IsLess<U256>,
102
    Le<BlockSize, U256>: NonZero,
103
    Kind: BufferKind,
104
{
105
    /// Create new buffer from slice.
106
    ///
107
    /// # Panics
108
    /// If slice length is not valid for used buffer kind.
109
    #[inline(always)]
110
0
    pub fn new(buf: &[u8]) -> Self {
111
0
        Self::try_new(buf).unwrap()
112
0
    }
113
114
    /// Create new buffer from slice.
115
    ///
116
    /// Returns an error if slice length is not valid for used buffer kind.
117
    #[inline(always)]
118
0
    pub fn try_new(buf: &[u8]) -> Result<Self, Error> {
119
0
        if BlockSize::USIZE == 0 {
120
0
            panic!("Block size can not be equal to zero");
121
0
        }
122
0
        let pos = buf.len();
123
0
        if !Kind::invariant(pos, BlockSize::USIZE) {
124
0
            return Err(Error);
125
0
        }
126
0
        let mut buffer = Block::<BlockSize>::default();
127
0
        buffer[..pos].copy_from_slice(buf);
128
0
        Ok(Self {
129
0
            buffer,
130
0
            pos: pos as u8,
131
0
            _pd: PhantomData,
132
0
        })
133
0
    }
134
135
    /// Digest data in `input` in blocks of size `BlockSize` using
136
    /// the `compress` function, which accepts slice of blocks.
137
    #[inline]
138
29.0k
    pub fn digest_blocks(
139
29.0k
        &mut self,
140
29.0k
        mut input: &[u8],
141
29.0k
        mut compress: impl FnMut(&[Block<BlockSize>]),
142
29.0k
    ) {
143
29.0k
        let pos = self.get_pos();
144
29.0k
        // using `self.remaining()` for some reason
145
29.0k
        // prevents panic elimination
146
29.0k
        let rem = self.size() - pos;
147
29.0k
        let n = input.len();
148
29.0k
        // Note that checking condition `pos + n < BlockSize` is
149
29.0k
        // equivalent to checking `n < rem`, where `rem` is equal
150
29.0k
        // to `BlockSize - pos`. Using the latter allows us to work
151
29.0k
        // around compiler accounting for possible overflow of
152
29.0k
        // `pos + n` which results in it inserting unreachable
153
29.0k
        // panic branches. Using `unreachable_unchecked` in `get_pos`
154
29.0k
        // we convince compiler that `BlockSize - pos` never underflows.
155
29.0k
        if Kind::invariant(n, rem) {
156
            // double slicing allows to remove panic branches
157
19.5k
            self.buffer[pos..][..n].copy_from_slice(input);
158
19.5k
            self.set_pos_unchecked(pos + n);
159
19.5k
            return;
160
9.45k
        }
161
9.45k
        if pos != 0 {
162
6.53k
            let (left, right) = input.split_at(rem);
163
6.53k
            input = right;
164
6.53k
            self.buffer[pos..].copy_from_slice(left);
165
6.53k
            compress(slice::from_ref(&self.buffer));
166
6.53k
        }
167
168
9.45k
        let (blocks, leftover) = Kind::split_blocks(input);
169
9.45k
        if !blocks.is_empty() {
170
3.73k
            compress(blocks);
171
5.71k
        }
172
173
9.45k
        let n = leftover.len();
174
9.45k
        self.buffer[..n].copy_from_slice(leftover);
175
9.45k
        self.set_pos_unchecked(n);
176
29.0k
    }
Unexecuted instantiation: _RINvMs3_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferppE13digest_blockspEB6_
Unexecuted instantiation: _RINvMs3_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE13digest_blocksNCNvXs6_NtCsgFTejnltRzv_4hmac5optimINtB3o_8HmacCoreINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtB4a_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreB1s_NtB5O_9OidSha256EEENtB4a_15FixedOutputCore19finalize_fixed_core0ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMs3_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE13digest_blocksNCNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB3o_11CoreWrapperINtNtB3q_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreB1s_NtB5b_9OidSha256EENtB3s_6Update6update0ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMs3_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE13digest_blocksNCNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB3o_11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIB45_INtNtB3q_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreB1s_NtB5T_9OidSha256EEEENtB3s_6Update6update0ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMs3_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE13digest_blocksNCNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB3o_11CoreWrapperINtNtB3q_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreB1s_NtB5b_9OidSha256EENtB3s_6Update6update0ECs2IvCg5PL8uK_11chia_traits
_RINvMs3_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE13digest_blocksNCNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB3o_11CoreWrapperINtNtB3q_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreB1s_NtB5b_9OidSha256EENtB3s_6Update6update0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
138
29.0k
    pub fn digest_blocks(
139
29.0k
        &mut self,
140
29.0k
        mut input: &[u8],
141
29.0k
        mut compress: impl FnMut(&[Block<BlockSize>]),
142
29.0k
    ) {
143
29.0k
        let pos = self.get_pos();
144
29.0k
        // using `self.remaining()` for some reason
145
29.0k
        // prevents panic elimination
146
29.0k
        let rem = self.size() - pos;
147
29.0k
        let n = input.len();
148
29.0k
        // Note that checking condition `pos + n < BlockSize` is
149
29.0k
        // equivalent to checking `n < rem`, where `rem` is equal
150
29.0k
        // to `BlockSize - pos`. Using the latter allows us to work
151
29.0k
        // around compiler accounting for possible overflow of
152
29.0k
        // `pos + n` which results in it inserting unreachable
153
29.0k
        // panic branches. Using `unreachable_unchecked` in `get_pos`
154
29.0k
        // we convince compiler that `BlockSize - pos` never underflows.
155
29.0k
        if Kind::invariant(n, rem) {
156
            // double slicing allows to remove panic branches
157
19.5k
            self.buffer[pos..][..n].copy_from_slice(input);
158
19.5k
            self.set_pos_unchecked(pos + n);
159
19.5k
            return;
160
9.45k
        }
161
9.45k
        if pos != 0 {
162
6.53k
            let (left, right) = input.split_at(rem);
163
6.53k
            input = right;
164
6.53k
            self.buffer[pos..].copy_from_slice(left);
165
6.53k
            compress(slice::from_ref(&self.buffer));
166
6.53k
        }
167
168
9.45k
        let (blocks, leftover) = Kind::split_blocks(input);
169
9.45k
        if !blocks.is_empty() {
170
3.73k
            compress(blocks);
171
5.71k
        }
172
173
9.45k
        let n = leftover.len();
174
9.45k
        self.buffer[..n].copy_from_slice(leftover);
175
9.45k
        self.set_pos_unchecked(n);
176
29.0k
    }
Unexecuted instantiation: _RINvMs3_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE13digest_blocksNCNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB3o_11CoreWrapperINtNtB3q_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreB1s_NtB5b_9OidSha256EENtB3s_6Update6update0ECsjewTDwKBbyD_4k256
177
178
    /// Reset buffer by setting cursor position to zero.
179
    #[inline(always)]
180
0
    pub fn reset(&mut self) {
181
0
        self.set_pos_unchecked(0);
182
0
    }
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferppE5resetB5_
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE5resetCs568wuOlRYFZ_8chia_bls
183
184
    /// Pad remaining data with zeros and return resulting block.
185
    #[inline(always)]
186
0
    pub fn pad_with_zeros(&mut self) -> &mut Block<BlockSize> {
187
0
        let pos = self.get_pos();
188
0
        self.buffer[pos..].iter_mut().for_each(|b| *b = 0);
189
0
        self.set_pos_unchecked(0);
190
0
        &mut self.buffer
191
0
    }
192
193
    /// Return current cursor position.
194
    #[inline(always)]
195
48.2k
    pub fn get_pos(&self) -> usize {
196
48.2k
        let pos = self.pos as usize;
197
48.2k
        if !Kind::invariant(pos, BlockSize::USIZE) {
198
0
            debug_assert!(false);
199
            // SAFETY: `pos` never breaks the invariant
200
            unsafe {
201
0
                core::hint::unreachable_unchecked();
202
            }
203
48.2k
        }
204
48.2k
        pos
205
48.2k
    }
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferppE7get_posB5_
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE7get_posCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE7get_posCs2IvCg5PL8uK_11chia_traits
_RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE7get_posCs4RkbDk9WRL5_5clvmr
Line
Count
Source
195
48.2k
    pub fn get_pos(&self) -> usize {
196
48.2k
        let pos = self.pos as usize;
197
48.2k
        if !Kind::invariant(pos, BlockSize::USIZE) {
198
0
            debug_assert!(false);
199
            // SAFETY: `pos` never breaks the invariant
200
            unsafe {
201
0
                core::hint::unreachable_unchecked();
202
            }
203
48.2k
        }
204
48.2k
        pos
205
48.2k
    }
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE7get_posCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EB2j_ENtB5_5EagerE7get_posCs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE7get_posCs23lnNM1woOA_4sha2
206
207
    /// Return slice of data stored inside the buffer.
208
    #[inline(always)]
209
0
    pub fn get_data(&self) -> &[u8] {
210
0
        &self.buffer[..self.get_pos()]
211
0
    }
212
213
    /// Set buffer content and cursor position.
214
    ///
215
    /// # Panics
216
    /// If `pos` is bigger or equal to block size.
217
    #[inline]
218
0
    pub fn set(&mut self, buf: Block<BlockSize>, pos: usize) {
219
0
        assert!(Kind::invariant(pos, BlockSize::USIZE));
220
0
        self.buffer = buf;
221
0
        self.set_pos_unchecked(pos);
222
0
    }
223
224
    /// Return size of the internal buffer in bytes.
225
    #[inline(always)]
226
48.2k
    pub fn size(&self) -> usize {
227
48.2k
        BlockSize::USIZE
228
48.2k
    }
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferppE4sizeB5_
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE4sizeCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE4sizeCs2IvCg5PL8uK_11chia_traits
_RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE4sizeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
226
48.2k
    pub fn size(&self) -> usize {
227
48.2k
        BlockSize::USIZE
228
48.2k
    }
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE4sizeCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EB2j_ENtB5_5EagerE4sizeCs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE4sizeCs23lnNM1woOA_4sha2
229
230
    /// Return number of remaining bytes in the internal buffer.
231
    #[inline(always)]
232
0
    pub fn remaining(&self) -> usize {
233
0
        self.size() - self.get_pos()
234
0
    }
235
236
    #[inline(always)]
237
38.6k
    fn set_pos_unchecked(&mut self, pos: usize) {
238
38.6k
        debug_assert!(Kind::invariant(pos, BlockSize::USIZE));
239
38.6k
        self.pos = pos as u8;
240
38.6k
    }
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferppE17set_pos_uncheckedB5_
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE17set_pos_uncheckedCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE17set_pos_uncheckedCs2IvCg5PL8uK_11chia_traits
_RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE17set_pos_uncheckedCs4RkbDk9WRL5_5clvmr
Line
Count
Source
237
38.6k
    fn set_pos_unchecked(&mut self, pos: usize) {
238
38.6k
        debug_assert!(Kind::invariant(pos, BlockSize::USIZE));
239
38.6k
        self.pos = pos as u8;
240
38.6k
    }
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE17set_pos_uncheckedCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EB2j_ENtB5_5EagerE17set_pos_uncheckedCs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNvMs3_Csf9lUOpqAe5A_12block_bufferINtB5_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EB2f_ENtB5_5EagerE17set_pos_uncheckedCs23lnNM1woOA_4sha2
241
}
242
243
impl<BlockSize> BlockBuffer<BlockSize, Eager>
244
where
245
    BlockSize: ArrayLength<u8> + IsLess<U256>,
246
    Le<BlockSize, U256>: NonZero,
247
{
248
    /// Set `data` to generated blocks.
249
    #[inline]
250
0
    pub fn set_data(
251
0
        &mut self,
252
0
        mut data: &mut [u8],
253
0
        mut process_blocks: impl FnMut(&mut [Block<BlockSize>]),
254
0
    ) {
255
0
        let pos = self.get_pos();
256
0
        let r = self.remaining();
257
0
        let n = data.len();
258
0
        if pos != 0 {
259
0
            if n < r {
260
                // double slicing allows to remove panic branches
261
0
                data.copy_from_slice(&self.buffer[pos..][..n]);
262
0
                self.set_pos_unchecked(pos + n);
263
0
                return;
264
0
            }
265
0
            let (left, right) = data.split_at_mut(r);
266
0
            data = right;
267
0
            left.copy_from_slice(&self.buffer[pos..]);
268
0
        }
269
270
0
        let (blocks, leftover) = to_blocks_mut(data);
271
0
        process_blocks(blocks);
272
0
273
0
        let n = leftover.len();
274
0
        if n != 0 {
275
0
            let mut block = Default::default();
276
0
            process_blocks(slice::from_mut(&mut block));
277
0
            leftover.copy_from_slice(&block[..n]);
278
0
            self.buffer = block;
279
0
        }
280
0
        self.set_pos_unchecked(n);
281
0
    }
282
283
    /// Compress remaining data after padding it with `delim`, zeros and
284
    /// the `suffix` bytes. If there is not enough unused space, `compress`
285
    /// will be called twice.
286
    ///
287
    /// # Panics
288
    /// If suffix length is bigger than block size.
289
    #[inline(always)]
290
9.60k
    pub fn digest_pad(
291
9.60k
        &mut self,
292
9.60k
        delim: u8,
293
9.60k
        suffix: &[u8],
294
9.60k
        mut compress: impl FnMut(&Block<BlockSize>),
295
9.60k
    ) {
296
9.60k
        if suffix.len() > BlockSize::USIZE {
297
0
            panic!("suffix is too long");
298
9.60k
        }
299
9.60k
        let pos = self.get_pos();
300
9.60k
        self.buffer[pos] = delim;
301
402k
        for b in &mut self.buffer[pos + 1..] {
302
402k
            *b = 0;
303
402k
        }
304
305
9.60k
        let n = self.size() - suffix.len();
306
9.60k
        if self.size() - pos - 1 < suffix.len() {
307
341
            compress(&self.buffer);
308
341
            let mut block = Block::<BlockSize>::default();
309
341
            block[n..].copy_from_slice(suffix);
310
341
            compress(&block);
311
9.26k
        } else {
312
9.26k
            self.buffer[n..].copy_from_slice(suffix);
313
9.26k
            compress(&self.buffer);
314
9.26k
        }
315
9.60k
        self.set_pos_unchecked(0)
316
9.60k
    }
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferpNtB6_5EagerE10digest_padpEB6_
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE10digest_padNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB3l_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE10digest_padNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB3l_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0ECs2IvCg5PL8uK_11chia_traits
_RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE10digest_padNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB3l_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
290
9.60k
    pub fn digest_pad(
291
9.60k
        &mut self,
292
9.60k
        delim: u8,
293
9.60k
        suffix: &[u8],
294
9.60k
        mut compress: impl FnMut(&Block<BlockSize>),
295
9.60k
    ) {
296
9.60k
        if suffix.len() > BlockSize::USIZE {
297
0
            panic!("suffix is too long");
298
9.60k
        }
299
9.60k
        let pos = self.get_pos();
300
9.60k
        self.buffer[pos] = delim;
301
402k
        for b in &mut self.buffer[pos + 1..] {
302
402k
            *b = 0;
303
402k
        }
304
305
9.60k
        let n = self.size() - suffix.len();
306
9.60k
        if self.size() - pos - 1 < suffix.len() {
307
341
            compress(&self.buffer);
308
341
            let mut block = Block::<BlockSize>::default();
309
341
            block[n..].copy_from_slice(suffix);
310
341
            compress(&block);
311
9.26k
        } else {
312
9.26k
            self.buffer[n..].copy_from_slice(suffix);
313
9.26k
            compress(&self.buffer);
314
9.26k
        }
315
9.60k
        self.set_pos_unchecked(0)
316
9.60k
    }
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE10digest_padNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB3l_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0ECsjewTDwKBbyD_4k256
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB27_2B0EB2k_EB2k_EB2k_EB2k_EB2k_EB2k_ENtB6_5EagerE10digest_padNCNvXsb_NtCs23lnNM1woOA_4sha28core_apiNtB3u_13Sha512VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0EB3w_
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE10digest_padNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB3l_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0EB3n_
317
318
    /// Pad message with 0x80, zeros and 64-bit message length using
319
    /// big-endian byte order.
320
    #[inline]
321
9.60k
    pub fn len64_padding_be(&mut self, data_len: u64, compress: impl FnMut(&Block<BlockSize>)) {
322
9.60k
        self.digest_pad(0x80, &data_len.to_be_bytes(), compress);
323
9.60k
    }
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferpNtB6_5EagerE16len64_padding_bepEB6_
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE16len64_padding_beNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB3r_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE16len64_padding_beNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB3r_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0ECs2IvCg5PL8uK_11chia_traits
_RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE16len64_padding_beNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB3r_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
321
9.60k
    pub fn len64_padding_be(&mut self, data_len: u64, compress: impl FnMut(&Block<BlockSize>)) {
322
9.60k
        self.digest_pad(0x80, &data_len.to_be_bytes(), compress);
323
9.60k
    }
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE16len64_padding_beNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB3r_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0ECsjewTDwKBbyD_4k256
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB23_2B0EB2g_EB2g_EB2g_EB2g_EB2g_ENtB6_5EagerE16len64_padding_beNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB3r_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0EB3t_
324
325
    /// Pad message with 0x80, zeros and 64-bit message length using
326
    /// little-endian byte order.
327
    #[inline]
328
0
    pub fn len64_padding_le(&mut self, data_len: u64, compress: impl FnMut(&Block<BlockSize>)) {
329
0
        self.digest_pad(0x80, &data_len.to_le_bytes(), compress);
330
0
    }
331
332
    /// Pad message with 0x80, zeros and 128-bit message length using
333
    /// big-endian byte order.
334
    #[inline]
335
0
    pub fn len128_padding_be(&mut self, data_len: u128, compress: impl FnMut(&Block<BlockSize>)) {
336
0
        self.digest_pad(0x80, &data_len.to_be_bytes(), compress);
337
0
    }
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferpNtB6_5EagerE17len128_padding_bepEB6_
Unexecuted instantiation: _RINvMs4_Csf9lUOpqAe5A_12block_bufferINtB6_11BlockBufferINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBS_IBS_IBS_IBS_IBS_IBS_IBS_NtBU_5UTermNtNtBW_3bit2B1ENtB27_2B0EB2k_EB2k_EB2k_EB2k_EB2k_EB2k_ENtB6_5EagerE17len128_padding_beNCNvXsb_NtCs23lnNM1woOA_4sha28core_apiNtB3B_13Sha512VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0EB3D_
338
}
339
340
/// Split message into mutable slice of parallel blocks, blocks, and leftover bytes.
341
#[inline(always)]
342
0
fn to_blocks_mut<N: ArrayLength<u8>>(data: &mut [u8]) -> (&mut [Block<N>], &mut [u8]) {
343
0
    let nb = data.len() / N::USIZE;
344
0
    let (left, right) = data.split_at_mut(nb * N::USIZE);
345
0
    let p = left.as_mut_ptr() as *mut Block<N>;
346
0
    // SAFETY: we guarantee that `blocks` does not point outside of `data`, and `p` is valid for
347
0
    // mutation
348
0
    let blocks = unsafe { slice::from_raw_parts_mut(p, nb) };
349
0
    (blocks, right)
350
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/block-buffer-0.10.4/src/sealed.rs
Line
Count
Source
1
use super::{ArrayLength, Block};
2
use core::slice;
3
4
/// Sealed trait for buffer kinds.
5
pub trait Sealed {
6
    /// Invariant guaranteed by a buffer kind, i.e. with correct
7
    /// buffer code this function always returns true.
8
    fn invariant(pos: usize, block_size: usize) -> bool;
9
10
    /// Split input data into slice of blocks and tail.
11
    fn split_blocks<N: ArrayLength<u8>>(data: &[u8]) -> (&[Block<N>], &[u8]);
12
}
13
14
impl Sealed for super::Eager {
15
    #[inline(always)]
16
115k
    fn invariant(pos: usize, block_size: usize) -> bool {
17
115k
        pos < block_size
18
115k
    }
19
20
    #[inline(always)]
21
9.45k
    fn split_blocks<N: ArrayLength<u8>>(data: &[u8]) -> (&[Block<N>], &[u8]) {
22
9.45k
        let nb = data.len() / N::USIZE;
23
9.45k
        let blocks_len = nb * N::USIZE;
24
9.45k
        let tail_len = data.len() - blocks_len;
25
9.45k
        // SAFETY: we guarantee that created slices do not point
26
9.45k
        // outside of `data`
27
9.45k
        unsafe {
28
9.45k
            let blocks_ptr = data.as_ptr() as *const Block<N>;
29
9.45k
            let tail_ptr = data.as_ptr().add(blocks_len);
30
9.45k
            (
31
9.45k
                slice::from_raw_parts(blocks_ptr, nb),
32
9.45k
                slice::from_raw_parts(tail_ptr, tail_len),
33
9.45k
            )
34
9.45k
        }
35
9.45k
    }
Unexecuted instantiation: _RINvXNtCsf9lUOpqAe5A_12block_buffer6sealedNtB5_5EagerNtB3_6Sealed12split_blockspEB5_
Unexecuted instantiation: _RINvXNtCsf9lUOpqAe5A_12block_buffer6sealedNtB5_5EagerNtB3_6Sealed12split_blocksINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1g_IB1g_IB1g_IB1g_IB1g_IB1g_NtB1i_5UTermNtNtB1k_3bit2B1ENtB2y_2B0EB2M_EB2M_EB2M_EB2M_EB2M_EECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXNtCsf9lUOpqAe5A_12block_buffer6sealedNtB5_5EagerNtB3_6Sealed12split_blocksINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1g_IB1g_IB1g_IB1g_IB1g_IB1g_NtB1i_5UTermNtNtB1k_3bit2B1ENtB2y_2B0EB2M_EB2M_EB2M_EB2M_EB2M_EECs2IvCg5PL8uK_11chia_traits
_RINvXNtCsf9lUOpqAe5A_12block_buffer6sealedNtB5_5EagerNtB3_6Sealed12split_blocksINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1g_IB1g_IB1g_IB1g_IB1g_IB1g_NtB1i_5UTermNtNtB1k_3bit2B1ENtB2y_2B0EB2M_EB2M_EB2M_EB2M_EB2M_EECs4RkbDk9WRL5_5clvmr
Line
Count
Source
21
9.45k
    fn split_blocks<N: ArrayLength<u8>>(data: &[u8]) -> (&[Block<N>], &[u8]) {
22
9.45k
        let nb = data.len() / N::USIZE;
23
9.45k
        let blocks_len = nb * N::USIZE;
24
9.45k
        let tail_len = data.len() - blocks_len;
25
9.45k
        // SAFETY: we guarantee that created slices do not point
26
9.45k
        // outside of `data`
27
9.45k
        unsafe {
28
9.45k
            let blocks_ptr = data.as_ptr() as *const Block<N>;
29
9.45k
            let tail_ptr = data.as_ptr().add(blocks_len);
30
9.45k
            (
31
9.45k
                slice::from_raw_parts(blocks_ptr, nb),
32
9.45k
                slice::from_raw_parts(tail_ptr, tail_len),
33
9.45k
            )
34
9.45k
        }
35
9.45k
    }
Unexecuted instantiation: _RINvXNtCsf9lUOpqAe5A_12block_buffer6sealedNtB5_5EagerNtB3_6Sealed12split_blocksINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1g_IB1g_IB1g_IB1g_IB1g_IB1g_NtB1i_5UTermNtNtB1k_3bit2B1ENtB2y_2B0EB2M_EB2M_EB2M_EB2M_EB2M_EECsjewTDwKBbyD_4k256
36
}
37
38
impl Sealed for super::Lazy {
39
    #[inline(always)]
40
    fn invariant(pos: usize, block_size: usize) -> bool {
41
        pos <= block_size
42
    }
43
44
    #[inline(always)]
45
0
    fn split_blocks<N: ArrayLength<u8>>(data: &[u8]) -> (&[Block<N>], &[u8]) {
46
0
        if data.is_empty() {
47
0
            return (&[], &[]);
48
0
        }
49
0
        let (nb, tail_len) = if data.len() % N::USIZE == 0 {
50
0
            (data.len() / N::USIZE - 1, N::USIZE)
51
        } else {
52
0
            let nb = data.len() / N::USIZE;
53
0
            (nb, data.len() - nb * N::USIZE)
54
        };
55
0
        let blocks_len = nb * N::USIZE;
56
0
        // SAFETY: we guarantee that created slices do not point
57
0
        // outside of `data`
58
0
        unsafe {
59
0
            let blocks_ptr = data.as_ptr() as *const Block<N>;
60
0
            let tail_ptr = data.as_ptr().add(blocks_len);
61
0
            (
62
0
                slice::from_raw_parts(blocks_ptr, nb),
63
0
                slice::from_raw_parts(tail_ptr, tail_len),
64
0
            )
65
        }
66
0
    }
67
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/blst-0.3.12/src/bindings.rs
Line
Count
Source
1
/* automatically generated by rust-bindgen 0.65.1 */
2
3
#[repr(u32)]
4
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
5
pub enum BLST_ERROR {
6
    BLST_SUCCESS = 0,
7
    BLST_BAD_ENCODING = 1,
8
    BLST_POINT_NOT_ON_CURVE = 2,
9
    BLST_POINT_NOT_IN_GROUP = 3,
10
    BLST_AGGR_TYPE_MISMATCH = 4,
11
    BLST_VERIFY_FAIL = 5,
12
    BLST_PK_IS_INFINITY = 6,
13
    BLST_BAD_SCALAR = 7,
14
}
15
pub type byte = u8;
16
pub type limb_t = u64;
17
#[repr(C)]
18
0
#[derive(Debug, Default, Clone, PartialEq, Eq, Zeroize)]
Unexecuted instantiation: _RNvXsm_CscC7OSmV1s5f_4blstNtB5_11blst_scalarNtCs6qnKa1vNaZb_7zeroize7Zeroize7zeroize
Unexecuted instantiation: _RNvXsn_CscC7OSmV1s5f_4blstNtB5_11blst_scalarNtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4drop
19
#[zeroize(drop)]
20
pub struct blst_scalar {
21
    pub b: [byte; 32usize],
22
}
23
#[test]
24
fn bindgen_test_layout_blst_scalar() {
25
    const UNINIT: ::core::mem::MaybeUninit<blst_scalar> = ::core::mem::MaybeUninit::uninit();
26
    let ptr = UNINIT.as_ptr();
27
    assert_eq!(
28
        ::core::mem::size_of::<blst_scalar>(),
29
        32usize,
30
        concat!("Size of: ", stringify!(blst_scalar))
31
    );
32
    assert_eq!(
33
        ::core::mem::align_of::<blst_scalar>(),
34
        1usize,
35
        concat!("Alignment of ", stringify!(blst_scalar))
36
    );
37
    assert_eq!(
38
        unsafe { ::core::ptr::addr_of!((*ptr).b) as usize - ptr as usize },
39
        0usize,
40
        concat!(
41
            "Offset of field: ",
42
            stringify!(blst_scalar),
43
            "::",
44
            stringify!(b)
45
        )
46
    );
47
}
48
#[repr(C)]
49
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
50
pub struct blst_fr {
51
    pub l: [limb_t; 4usize],
52
}
53
#[test]
54
fn bindgen_test_layout_blst_fr() {
55
    const UNINIT: ::core::mem::MaybeUninit<blst_fr> = ::core::mem::MaybeUninit::uninit();
56
    let ptr = UNINIT.as_ptr();
57
    assert_eq!(
58
        ::core::mem::size_of::<blst_fr>(),
59
        32usize,
60
        concat!("Size of: ", stringify!(blst_fr))
61
    );
62
    assert_eq!(
63
        ::core::mem::align_of::<blst_fr>(),
64
        8usize,
65
        concat!("Alignment of ", stringify!(blst_fr))
66
    );
67
    assert_eq!(
68
        unsafe { ::core::ptr::addr_of!((*ptr).l) as usize - ptr as usize },
69
        0usize,
70
        concat!(
71
            "Offset of field: ",
72
            stringify!(blst_fr),
73
            "::",
74
            stringify!(l)
75
        )
76
    );
77
}
78
#[repr(C)]
79
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
80
pub struct blst_fp {
81
    pub l: [limb_t; 6usize],
82
}
83
#[test]
84
fn bindgen_test_layout_blst_fp() {
85
    const UNINIT: ::core::mem::MaybeUninit<blst_fp> = ::core::mem::MaybeUninit::uninit();
86
    let ptr = UNINIT.as_ptr();
87
    assert_eq!(
88
        ::core::mem::size_of::<blst_fp>(),
89
        48usize,
90
        concat!("Size of: ", stringify!(blst_fp))
91
    );
92
    assert_eq!(
93
        ::core::mem::align_of::<blst_fp>(),
94
        8usize,
95
        concat!("Alignment of ", stringify!(blst_fp))
96
    );
97
    assert_eq!(
98
        unsafe { ::core::ptr::addr_of!((*ptr).l) as usize - ptr as usize },
99
        0usize,
100
        concat!(
101
            "Offset of field: ",
102
            stringify!(blst_fp),
103
            "::",
104
            stringify!(l)
105
        )
106
    );
107
}
108
#[repr(C)]
109
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
110
pub struct blst_fp2 {
111
    pub fp: [blst_fp; 2usize],
112
}
113
#[test]
114
fn bindgen_test_layout_blst_fp2() {
115
    const UNINIT: ::core::mem::MaybeUninit<blst_fp2> = ::core::mem::MaybeUninit::uninit();
116
    let ptr = UNINIT.as_ptr();
117
    assert_eq!(
118
        ::core::mem::size_of::<blst_fp2>(),
119
        96usize,
120
        concat!("Size of: ", stringify!(blst_fp2))
121
    );
122
    assert_eq!(
123
        ::core::mem::align_of::<blst_fp2>(),
124
        8usize,
125
        concat!("Alignment of ", stringify!(blst_fp2))
126
    );
127
    assert_eq!(
128
        unsafe { ::core::ptr::addr_of!((*ptr).fp) as usize - ptr as usize },
129
        0usize,
130
        concat!(
131
            "Offset of field: ",
132
            stringify!(blst_fp2),
133
            "::",
134
            stringify!(fp)
135
        )
136
    );
137
}
138
#[repr(C)]
139
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
140
pub struct blst_fp6 {
141
    pub fp2: [blst_fp2; 3usize],
142
}
143
#[test]
144
fn bindgen_test_layout_blst_fp6() {
145
    const UNINIT: ::core::mem::MaybeUninit<blst_fp6> = ::core::mem::MaybeUninit::uninit();
146
    let ptr = UNINIT.as_ptr();
147
    assert_eq!(
148
        ::core::mem::size_of::<blst_fp6>(),
149
        288usize,
150
        concat!("Size of: ", stringify!(blst_fp6))
151
    );
152
    assert_eq!(
153
        ::core::mem::align_of::<blst_fp6>(),
154
        8usize,
155
        concat!("Alignment of ", stringify!(blst_fp6))
156
    );
157
    assert_eq!(
158
        unsafe { ::core::ptr::addr_of!((*ptr).fp2) as usize - ptr as usize },
159
        0usize,
160
        concat!(
161
            "Offset of field: ",
162
            stringify!(blst_fp6),
163
            "::",
164
            stringify!(fp2)
165
        )
166
    );
167
}
168
#[repr(C)]
169
#[derive(Debug, Copy, Clone, Eq)]
170
pub struct blst_fp12 {
171
    pub fp6: [blst_fp6; 2usize],
172
}
173
#[test]
174
fn bindgen_test_layout_blst_fp12() {
175
    const UNINIT: ::core::mem::MaybeUninit<blst_fp12> = ::core::mem::MaybeUninit::uninit();
176
    let ptr = UNINIT.as_ptr();
177
    assert_eq!(
178
        ::core::mem::size_of::<blst_fp12>(),
179
        576usize,
180
        concat!("Size of: ", stringify!(blst_fp12))
181
    );
182
    assert_eq!(
183
        ::core::mem::align_of::<blst_fp12>(),
184
        8usize,
185
        concat!("Alignment of ", stringify!(blst_fp12))
186
    );
187
    assert_eq!(
188
        unsafe { ::core::ptr::addr_of!((*ptr).fp6) as usize - ptr as usize },
189
        0usize,
190
        concat!(
191
            "Offset of field: ",
192
            stringify!(blst_fp12),
193
            "::",
194
            stringify!(fp6)
195
        )
196
    );
197
}
198
extern "C" {
199
    pub fn blst_scalar_from_uint32(out: *mut blst_scalar, a: *const u32);
200
}
201
extern "C" {
202
    pub fn blst_uint32_from_scalar(out: *mut u32, a: *const blst_scalar);
203
}
204
extern "C" {
205
    pub fn blst_scalar_from_uint64(out: *mut blst_scalar, a: *const u64);
206
}
207
extern "C" {
208
    pub fn blst_uint64_from_scalar(out: *mut u64, a: *const blst_scalar);
209
}
210
extern "C" {
211
    pub fn blst_scalar_from_bendian(out: *mut blst_scalar, a: *const byte);
212
}
213
extern "C" {
214
    pub fn blst_bendian_from_scalar(out: *mut byte, a: *const blst_scalar);
215
}
216
extern "C" {
217
    pub fn blst_scalar_from_lendian(out: *mut blst_scalar, a: *const byte);
218
}
219
extern "C" {
220
    pub fn blst_lendian_from_scalar(out: *mut byte, a: *const blst_scalar);
221
}
222
extern "C" {
223
    pub fn blst_scalar_fr_check(a: *const blst_scalar) -> bool;
224
}
225
extern "C" {
226
    pub fn blst_sk_check(a: *const blst_scalar) -> bool;
227
}
228
extern "C" {
229
    pub fn blst_sk_add_n_check(
230
        out: *mut blst_scalar,
231
        a: *const blst_scalar,
232
        b: *const blst_scalar,
233
    ) -> bool;
234
}
235
extern "C" {
236
    pub fn blst_sk_sub_n_check(
237
        out: *mut blst_scalar,
238
        a: *const blst_scalar,
239
        b: *const blst_scalar,
240
    ) -> bool;
241
}
242
extern "C" {
243
    pub fn blst_sk_mul_n_check(
244
        out: *mut blst_scalar,
245
        a: *const blst_scalar,
246
        b: *const blst_scalar,
247
    ) -> bool;
248
}
249
extern "C" {
250
    pub fn blst_sk_inverse(out: *mut blst_scalar, a: *const blst_scalar);
251
}
252
extern "C" {
253
    pub fn blst_scalar_from_le_bytes(out: *mut blst_scalar, in_: *const byte, len: usize) -> bool;
254
}
255
extern "C" {
256
    pub fn blst_scalar_from_be_bytes(out: *mut blst_scalar, in_: *const byte, len: usize) -> bool;
257
}
258
extern "C" {
259
    pub fn blst_fr_add(ret: *mut blst_fr, a: *const blst_fr, b: *const blst_fr);
260
}
261
extern "C" {
262
    pub fn blst_fr_sub(ret: *mut blst_fr, a: *const blst_fr, b: *const blst_fr);
263
}
264
extern "C" {
265
    pub fn blst_fr_mul_by_3(ret: *mut blst_fr, a: *const blst_fr);
266
}
267
extern "C" {
268
    pub fn blst_fr_lshift(ret: *mut blst_fr, a: *const blst_fr, count: usize);
269
}
270
extern "C" {
271
    pub fn blst_fr_rshift(ret: *mut blst_fr, a: *const blst_fr, count: usize);
272
}
273
extern "C" {
274
    pub fn blst_fr_mul(ret: *mut blst_fr, a: *const blst_fr, b: *const blst_fr);
275
}
276
extern "C" {
277
    pub fn blst_fr_sqr(ret: *mut blst_fr, a: *const blst_fr);
278
}
279
extern "C" {
280
    pub fn blst_fr_cneg(ret: *mut blst_fr, a: *const blst_fr, flag: bool);
281
}
282
extern "C" {
283
    pub fn blst_fr_eucl_inverse(ret: *mut blst_fr, a: *const blst_fr);
284
}
285
extern "C" {
286
    pub fn blst_fr_inverse(ret: *mut blst_fr, a: *const blst_fr);
287
}
288
extern "C" {
289
    pub fn blst_fr_from_uint64(ret: *mut blst_fr, a: *const u64);
290
}
291
extern "C" {
292
    pub fn blst_uint64_from_fr(ret: *mut u64, a: *const blst_fr);
293
}
294
extern "C" {
295
    pub fn blst_fr_from_scalar(ret: *mut blst_fr, a: *const blst_scalar);
296
}
297
extern "C" {
298
    pub fn blst_scalar_from_fr(ret: *mut blst_scalar, a: *const blst_fr);
299
}
300
extern "C" {
301
    pub fn blst_fp_add(ret: *mut blst_fp, a: *const blst_fp, b: *const blst_fp);
302
}
303
extern "C" {
304
    pub fn blst_fp_sub(ret: *mut blst_fp, a: *const blst_fp, b: *const blst_fp);
305
}
306
extern "C" {
307
    pub fn blst_fp_mul_by_3(ret: *mut blst_fp, a: *const blst_fp);
308
}
309
extern "C" {
310
    pub fn blst_fp_mul_by_8(ret: *mut blst_fp, a: *const blst_fp);
311
}
312
extern "C" {
313
    pub fn blst_fp_lshift(ret: *mut blst_fp, a: *const blst_fp, count: usize);
314
}
315
extern "C" {
316
    pub fn blst_fp_mul(ret: *mut blst_fp, a: *const blst_fp, b: *const blst_fp);
317
}
318
extern "C" {
319
    pub fn blst_fp_sqr(ret: *mut blst_fp, a: *const blst_fp);
320
}
321
extern "C" {
322
    pub fn blst_fp_cneg(ret: *mut blst_fp, a: *const blst_fp, flag: bool);
323
}
324
extern "C" {
325
    pub fn blst_fp_eucl_inverse(ret: *mut blst_fp, a: *const blst_fp);
326
}
327
extern "C" {
328
    pub fn blst_fp_inverse(ret: *mut blst_fp, a: *const blst_fp);
329
}
330
extern "C" {
331
    pub fn blst_fp_sqrt(ret: *mut blst_fp, a: *const blst_fp) -> bool;
332
}
333
extern "C" {
334
    pub fn blst_fp_from_uint32(ret: *mut blst_fp, a: *const u32);
335
}
336
extern "C" {
337
    pub fn blst_uint32_from_fp(ret: *mut u32, a: *const blst_fp);
338
}
339
extern "C" {
340
    pub fn blst_fp_from_uint64(ret: *mut blst_fp, a: *const u64);
341
}
342
extern "C" {
343
    pub fn blst_uint64_from_fp(ret: *mut u64, a: *const blst_fp);
344
}
345
extern "C" {
346
    pub fn blst_fp_from_bendian(ret: *mut blst_fp, a: *const byte);
347
}
348
extern "C" {
349
    pub fn blst_bendian_from_fp(ret: *mut byte, a: *const blst_fp);
350
}
351
extern "C" {
352
    pub fn blst_fp_from_lendian(ret: *mut blst_fp, a: *const byte);
353
}
354
extern "C" {
355
    pub fn blst_lendian_from_fp(ret: *mut byte, a: *const blst_fp);
356
}
357
extern "C" {
358
    pub fn blst_fp2_add(ret: *mut blst_fp2, a: *const blst_fp2, b: *const blst_fp2);
359
}
360
extern "C" {
361
    pub fn blst_fp2_sub(ret: *mut blst_fp2, a: *const blst_fp2, b: *const blst_fp2);
362
}
363
extern "C" {
364
    pub fn blst_fp2_mul_by_3(ret: *mut blst_fp2, a: *const blst_fp2);
365
}
366
extern "C" {
367
    pub fn blst_fp2_mul_by_8(ret: *mut blst_fp2, a: *const blst_fp2);
368
}
369
extern "C" {
370
    pub fn blst_fp2_lshift(ret: *mut blst_fp2, a: *const blst_fp2, count: usize);
371
}
372
extern "C" {
373
    pub fn blst_fp2_mul(ret: *mut blst_fp2, a: *const blst_fp2, b: *const blst_fp2);
374
}
375
extern "C" {
376
    pub fn blst_fp2_sqr(ret: *mut blst_fp2, a: *const blst_fp2);
377
}
378
extern "C" {
379
    pub fn blst_fp2_cneg(ret: *mut blst_fp2, a: *const blst_fp2, flag: bool);
380
}
381
extern "C" {
382
    pub fn blst_fp2_eucl_inverse(ret: *mut blst_fp2, a: *const blst_fp2);
383
}
384
extern "C" {
385
    pub fn blst_fp2_inverse(ret: *mut blst_fp2, a: *const blst_fp2);
386
}
387
extern "C" {
388
    pub fn blst_fp2_sqrt(ret: *mut blst_fp2, a: *const blst_fp2) -> bool;
389
}
390
extern "C" {
391
    pub fn blst_fp12_sqr(ret: *mut blst_fp12, a: *const blst_fp12);
392
}
393
extern "C" {
394
    pub fn blst_fp12_cyclotomic_sqr(ret: *mut blst_fp12, a: *const blst_fp12);
395
}
396
extern "C" {
397
    pub fn blst_fp12_mul(ret: *mut blst_fp12, a: *const blst_fp12, b: *const blst_fp12);
398
}
399
extern "C" {
400
    pub fn blst_fp12_mul_by_xy00z0(
401
        ret: *mut blst_fp12,
402
        a: *const blst_fp12,
403
        xy00z0: *const blst_fp6,
404
    );
405
}
406
extern "C" {
407
    pub fn blst_fp12_conjugate(a: *mut blst_fp12);
408
}
409
extern "C" {
410
    pub fn blst_fp12_inverse(ret: *mut blst_fp12, a: *const blst_fp12);
411
}
412
extern "C" {
413
    pub fn blst_fp12_frobenius_map(ret: *mut blst_fp12, a: *const blst_fp12, n: usize);
414
}
415
extern "C" {
416
    pub fn blst_fp12_is_equal(a: *const blst_fp12, b: *const blst_fp12) -> bool;
417
}
418
extern "C" {
419
    pub fn blst_fp12_is_one(a: *const blst_fp12) -> bool;
420
}
421
extern "C" {
422
    pub fn blst_fp12_in_group(a: *const blst_fp12) -> bool;
423
}
424
extern "C" {
425
    pub fn blst_fp12_one() -> *const blst_fp12;
426
}
427
#[repr(C)]
428
#[derive(Debug, Default, Copy, Clone, Eq)]
429
pub struct blst_p1 {
430
    pub x: blst_fp,
431
    pub y: blst_fp,
432
    pub z: blst_fp,
433
}
434
#[test]
435
fn bindgen_test_layout_blst_p1() {
436
    const UNINIT: ::core::mem::MaybeUninit<blst_p1> = ::core::mem::MaybeUninit::uninit();
437
    let ptr = UNINIT.as_ptr();
438
    assert_eq!(
439
        ::core::mem::size_of::<blst_p1>(),
440
        144usize,
441
        concat!("Size of: ", stringify!(blst_p1))
442
    );
443
    assert_eq!(
444
        ::core::mem::align_of::<blst_p1>(),
445
        8usize,
446
        concat!("Alignment of ", stringify!(blst_p1))
447
    );
448
    assert_eq!(
449
        unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize },
450
        0usize,
451
        concat!(
452
            "Offset of field: ",
453
            stringify!(blst_p1),
454
            "::",
455
            stringify!(x)
456
        )
457
    );
458
    assert_eq!(
459
        unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize },
460
        48usize,
461
        concat!(
462
            "Offset of field: ",
463
            stringify!(blst_p1),
464
            "::",
465
            stringify!(y)
466
        )
467
    );
468
    assert_eq!(
469
        unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize },
470
        96usize,
471
        concat!(
472
            "Offset of field: ",
473
            stringify!(blst_p1),
474
            "::",
475
            stringify!(z)
476
        )
477
    );
478
}
479
#[repr(C)]
480
#[derive(Debug, Default, Copy, Clone, Eq)]
481
pub struct blst_p1_affine {
482
    pub x: blst_fp,
483
    pub y: blst_fp,
484
}
485
#[test]
486
fn bindgen_test_layout_blst_p1_affine() {
487
    const UNINIT: ::core::mem::MaybeUninit<blst_p1_affine> = ::core::mem::MaybeUninit::uninit();
488
    let ptr = UNINIT.as_ptr();
489
    assert_eq!(
490
        ::core::mem::size_of::<blst_p1_affine>(),
491
        96usize,
492
        concat!("Size of: ", stringify!(blst_p1_affine))
493
    );
494
    assert_eq!(
495
        ::core::mem::align_of::<blst_p1_affine>(),
496
        8usize,
497
        concat!("Alignment of ", stringify!(blst_p1_affine))
498
    );
499
    assert_eq!(
500
        unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize },
501
        0usize,
502
        concat!(
503
            "Offset of field: ",
504
            stringify!(blst_p1_affine),
505
            "::",
506
            stringify!(x)
507
        )
508
    );
509
    assert_eq!(
510
        unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize },
511
        48usize,
512
        concat!(
513
            "Offset of field: ",
514
            stringify!(blst_p1_affine),
515
            "::",
516
            stringify!(y)
517
        )
518
    );
519
}
520
extern "C" {
521
    pub fn blst_p1_add(out: *mut blst_p1, a: *const blst_p1, b: *const blst_p1);
522
}
523
extern "C" {
524
    pub fn blst_p1_add_or_double(out: *mut blst_p1, a: *const blst_p1, b: *const blst_p1);
525
}
526
extern "C" {
527
    pub fn blst_p1_add_affine(out: *mut blst_p1, a: *const blst_p1, b: *const blst_p1_affine);
528
}
529
extern "C" {
530
    pub fn blst_p1_add_or_double_affine(
531
        out: *mut blst_p1,
532
        a: *const blst_p1,
533
        b: *const blst_p1_affine,
534
    );
535
}
536
extern "C" {
537
    pub fn blst_p1_double(out: *mut blst_p1, a: *const blst_p1);
538
}
539
extern "C" {
540
    pub fn blst_p1_mult(out: *mut blst_p1, p: *const blst_p1, scalar: *const byte, nbits: usize);
541
}
542
extern "C" {
543
    pub fn blst_p1_cneg(p: *mut blst_p1, cbit: bool);
544
}
545
extern "C" {
546
    pub fn blst_p1_to_affine(out: *mut blst_p1_affine, in_: *const blst_p1);
547
}
548
extern "C" {
549
    pub fn blst_p1_from_affine(out: *mut blst_p1, in_: *const blst_p1_affine);
550
}
551
extern "C" {
552
    pub fn blst_p1_on_curve(p: *const blst_p1) -> bool;
553
}
554
extern "C" {
555
    pub fn blst_p1_in_g1(p: *const blst_p1) -> bool;
556
}
557
extern "C" {
558
    pub fn blst_p1_is_equal(a: *const blst_p1, b: *const blst_p1) -> bool;
559
}
560
extern "C" {
561
    pub fn blst_p1_is_inf(a: *const blst_p1) -> bool;
562
}
563
extern "C" {
564
    pub fn blst_p1_generator() -> *const blst_p1;
565
}
566
extern "C" {
567
    pub fn blst_p1_affine_on_curve(p: *const blst_p1_affine) -> bool;
568
}
569
extern "C" {
570
    pub fn blst_p1_affine_in_g1(p: *const blst_p1_affine) -> bool;
571
}
572
extern "C" {
573
    pub fn blst_p1_affine_is_equal(a: *const blst_p1_affine, b: *const blst_p1_affine) -> bool;
574
}
575
extern "C" {
576
    pub fn blst_p1_affine_is_inf(a: *const blst_p1_affine) -> bool;
577
}
578
extern "C" {
579
    pub fn blst_p1_affine_generator() -> *const blst_p1_affine;
580
}
581
#[repr(C)]
582
#[derive(Debug, Default, Copy, Clone, Eq)]
583
pub struct blst_p2 {
584
    pub x: blst_fp2,
585
    pub y: blst_fp2,
586
    pub z: blst_fp2,
587
}
588
#[test]
589
fn bindgen_test_layout_blst_p2() {
590
    const UNINIT: ::core::mem::MaybeUninit<blst_p2> = ::core::mem::MaybeUninit::uninit();
591
    let ptr = UNINIT.as_ptr();
592
    assert_eq!(
593
        ::core::mem::size_of::<blst_p2>(),
594
        288usize,
595
        concat!("Size of: ", stringify!(blst_p2))
596
    );
597
    assert_eq!(
598
        ::core::mem::align_of::<blst_p2>(),
599
        8usize,
600
        concat!("Alignment of ", stringify!(blst_p2))
601
    );
602
    assert_eq!(
603
        unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize },
604
        0usize,
605
        concat!(
606
            "Offset of field: ",
607
            stringify!(blst_p2),
608
            "::",
609
            stringify!(x)
610
        )
611
    );
612
    assert_eq!(
613
        unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize },
614
        96usize,
615
        concat!(
616
            "Offset of field: ",
617
            stringify!(blst_p2),
618
            "::",
619
            stringify!(y)
620
        )
621
    );
622
    assert_eq!(
623
        unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize },
624
        192usize,
625
        concat!(
626
            "Offset of field: ",
627
            stringify!(blst_p2),
628
            "::",
629
            stringify!(z)
630
        )
631
    );
632
}
633
#[repr(C)]
634
#[derive(Debug, Default, Copy, Clone, Eq)]
635
pub struct blst_p2_affine {
636
    pub x: blst_fp2,
637
    pub y: blst_fp2,
638
}
639
#[test]
640
fn bindgen_test_layout_blst_p2_affine() {
641
    const UNINIT: ::core::mem::MaybeUninit<blst_p2_affine> = ::core::mem::MaybeUninit::uninit();
642
    let ptr = UNINIT.as_ptr();
643
    assert_eq!(
644
        ::core::mem::size_of::<blst_p2_affine>(),
645
        192usize,
646
        concat!("Size of: ", stringify!(blst_p2_affine))
647
    );
648
    assert_eq!(
649
        ::core::mem::align_of::<blst_p2_affine>(),
650
        8usize,
651
        concat!("Alignment of ", stringify!(blst_p2_affine))
652
    );
653
    assert_eq!(
654
        unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize },
655
        0usize,
656
        concat!(
657
            "Offset of field: ",
658
            stringify!(blst_p2_affine),
659
            "::",
660
            stringify!(x)
661
        )
662
    );
663
    assert_eq!(
664
        unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize },
665
        96usize,
666
        concat!(
667
            "Offset of field: ",
668
            stringify!(blst_p2_affine),
669
            "::",
670
            stringify!(y)
671
        )
672
    );
673
}
674
extern "C" {
675
    pub fn blst_p2_add(out: *mut blst_p2, a: *const blst_p2, b: *const blst_p2);
676
}
677
extern "C" {
678
    pub fn blst_p2_add_or_double(out: *mut blst_p2, a: *const blst_p2, b: *const blst_p2);
679
}
680
extern "C" {
681
    pub fn blst_p2_add_affine(out: *mut blst_p2, a: *const blst_p2, b: *const blst_p2_affine);
682
}
683
extern "C" {
684
    pub fn blst_p2_add_or_double_affine(
685
        out: *mut blst_p2,
686
        a: *const blst_p2,
687
        b: *const blst_p2_affine,
688
    );
689
}
690
extern "C" {
691
    pub fn blst_p2_double(out: *mut blst_p2, a: *const blst_p2);
692
}
693
extern "C" {
694
    pub fn blst_p2_mult(out: *mut blst_p2, p: *const blst_p2, scalar: *const byte, nbits: usize);
695
}
696
extern "C" {
697
    pub fn blst_p2_cneg(p: *mut blst_p2, cbit: bool);
698
}
699
extern "C" {
700
    pub fn blst_p2_to_affine(out: *mut blst_p2_affine, in_: *const blst_p2);
701
}
702
extern "C" {
703
    pub fn blst_p2_from_affine(out: *mut blst_p2, in_: *const blst_p2_affine);
704
}
705
extern "C" {
706
    pub fn blst_p2_on_curve(p: *const blst_p2) -> bool;
707
}
708
extern "C" {
709
    pub fn blst_p2_in_g2(p: *const blst_p2) -> bool;
710
}
711
extern "C" {
712
    pub fn blst_p2_is_equal(a: *const blst_p2, b: *const blst_p2) -> bool;
713
}
714
extern "C" {
715
    pub fn blst_p2_is_inf(a: *const blst_p2) -> bool;
716
}
717
extern "C" {
718
    pub fn blst_p2_generator() -> *const blst_p2;
719
}
720
extern "C" {
721
    pub fn blst_p2_affine_on_curve(p: *const blst_p2_affine) -> bool;
722
}
723
extern "C" {
724
    pub fn blst_p2_affine_in_g2(p: *const blst_p2_affine) -> bool;
725
}
726
extern "C" {
727
    pub fn blst_p2_affine_is_equal(a: *const blst_p2_affine, b: *const blst_p2_affine) -> bool;
728
}
729
extern "C" {
730
    pub fn blst_p2_affine_is_inf(a: *const blst_p2_affine) -> bool;
731
}
732
extern "C" {
733
    pub fn blst_p2_affine_generator() -> *const blst_p2_affine;
734
}
735
extern "C" {
736
    pub fn blst_p1s_to_affine(
737
        dst: *mut blst_p1_affine,
738
        points: *const *const blst_p1,
739
        npoints: usize,
740
    );
741
}
742
extern "C" {
743
    pub fn blst_p1s_add(ret: *mut blst_p1, points: *const *const blst_p1_affine, npoints: usize);
744
}
745
extern "C" {
746
    pub fn blst_p1s_mult_wbits_precompute_sizeof(wbits: usize, npoints: usize) -> usize;
747
}
748
extern "C" {
749
    pub fn blst_p1s_mult_wbits_precompute(
750
        table: *mut blst_p1_affine,
751
        wbits: usize,
752
        points: *const *const blst_p1_affine,
753
        npoints: usize,
754
    );
755
}
756
extern "C" {
757
    pub fn blst_p1s_mult_wbits_scratch_sizeof(npoints: usize) -> usize;
758
}
759
extern "C" {
760
    pub fn blst_p1s_mult_wbits(
761
        ret: *mut blst_p1,
762
        table: *const blst_p1_affine,
763
        wbits: usize,
764
        npoints: usize,
765
        scalars: *const *const byte,
766
        nbits: usize,
767
        scratch: *mut limb_t,
768
    );
769
}
770
extern "C" {
771
    pub fn blst_p1s_mult_pippenger_scratch_sizeof(npoints: usize) -> usize;
772
}
773
extern "C" {
774
    pub fn blst_p1s_mult_pippenger(
775
        ret: *mut blst_p1,
776
        points: *const *const blst_p1_affine,
777
        npoints: usize,
778
        scalars: *const *const byte,
779
        nbits: usize,
780
        scratch: *mut limb_t,
781
    );
782
}
783
extern "C" {
784
    pub fn blst_p1s_tile_pippenger(
785
        ret: *mut blst_p1,
786
        points: *const *const blst_p1_affine,
787
        npoints: usize,
788
        scalars: *const *const byte,
789
        nbits: usize,
790
        scratch: *mut limb_t,
791
        bit0: usize,
792
        window: usize,
793
    );
794
}
795
extern "C" {
796
    pub fn blst_p2s_to_affine(
797
        dst: *mut blst_p2_affine,
798
        points: *const *const blst_p2,
799
        npoints: usize,
800
    );
801
}
802
extern "C" {
803
    pub fn blst_p2s_add(ret: *mut blst_p2, points: *const *const blst_p2_affine, npoints: usize);
804
}
805
extern "C" {
806
    pub fn blst_p2s_mult_wbits_precompute_sizeof(wbits: usize, npoints: usize) -> usize;
807
}
808
extern "C" {
809
    pub fn blst_p2s_mult_wbits_precompute(
810
        table: *mut blst_p2_affine,
811
        wbits: usize,
812
        points: *const *const blst_p2_affine,
813
        npoints: usize,
814
    );
815
}
816
extern "C" {
817
    pub fn blst_p2s_mult_wbits_scratch_sizeof(npoints: usize) -> usize;
818
}
819
extern "C" {
820
    pub fn blst_p2s_mult_wbits(
821
        ret: *mut blst_p2,
822
        table: *const blst_p2_affine,
823
        wbits: usize,
824
        npoints: usize,
825
        scalars: *const *const byte,
826
        nbits: usize,
827
        scratch: *mut limb_t,
828
    );
829
}
830
extern "C" {
831
    pub fn blst_p2s_mult_pippenger_scratch_sizeof(npoints: usize) -> usize;
832
}
833
extern "C" {
834
    pub fn blst_p2s_mult_pippenger(
835
        ret: *mut blst_p2,
836
        points: *const *const blst_p2_affine,
837
        npoints: usize,
838
        scalars: *const *const byte,
839
        nbits: usize,
840
        scratch: *mut limb_t,
841
    );
842
}
843
extern "C" {
844
    pub fn blst_p2s_tile_pippenger(
845
        ret: *mut blst_p2,
846
        points: *const *const blst_p2_affine,
847
        npoints: usize,
848
        scalars: *const *const byte,
849
        nbits: usize,
850
        scratch: *mut limb_t,
851
        bit0: usize,
852
        window: usize,
853
    );
854
}
855
extern "C" {
856
    pub fn blst_map_to_g1(out: *mut blst_p1, u: *const blst_fp, v: *const blst_fp);
857
}
858
extern "C" {
859
    pub fn blst_map_to_g2(out: *mut blst_p2, u: *const blst_fp2, v: *const blst_fp2);
860
}
861
extern "C" {
862
    pub fn blst_encode_to_g1(
863
        out: *mut blst_p1,
864
        msg: *const byte,
865
        msg_len: usize,
866
        DST: *const byte,
867
        DST_len: usize,
868
        aug: *const byte,
869
        aug_len: usize,
870
    );
871
}
872
extern "C" {
873
    pub fn blst_hash_to_g1(
874
        out: *mut blst_p1,
875
        msg: *const byte,
876
        msg_len: usize,
877
        DST: *const byte,
878
        DST_len: usize,
879
        aug: *const byte,
880
        aug_len: usize,
881
    );
882
}
883
extern "C" {
884
    pub fn blst_encode_to_g2(
885
        out: *mut blst_p2,
886
        msg: *const byte,
887
        msg_len: usize,
888
        DST: *const byte,
889
        DST_len: usize,
890
        aug: *const byte,
891
        aug_len: usize,
892
    );
893
}
894
extern "C" {
895
    pub fn blst_hash_to_g2(
896
        out: *mut blst_p2,
897
        msg: *const byte,
898
        msg_len: usize,
899
        DST: *const byte,
900
        DST_len: usize,
901
        aug: *const byte,
902
        aug_len: usize,
903
    );
904
}
905
extern "C" {
906
    pub fn blst_p1_serialize(out: *mut byte, in_: *const blst_p1);
907
}
908
extern "C" {
909
    pub fn blst_p1_compress(out: *mut byte, in_: *const blst_p1);
910
}
911
extern "C" {
912
    pub fn blst_p1_affine_serialize(out: *mut byte, in_: *const blst_p1_affine);
913
}
914
extern "C" {
915
    pub fn blst_p1_affine_compress(out: *mut byte, in_: *const blst_p1_affine);
916
}
917
extern "C" {
918
    pub fn blst_p1_uncompress(out: *mut blst_p1_affine, in_: *const byte) -> BLST_ERROR;
919
}
920
extern "C" {
921
    pub fn blst_p1_deserialize(out: *mut blst_p1_affine, in_: *const byte) -> BLST_ERROR;
922
}
923
extern "C" {
924
    pub fn blst_p2_serialize(out: *mut byte, in_: *const blst_p2);
925
}
926
extern "C" {
927
    pub fn blst_p2_compress(out: *mut byte, in_: *const blst_p2);
928
}
929
extern "C" {
930
    pub fn blst_p2_affine_serialize(out: *mut byte, in_: *const blst_p2_affine);
931
}
932
extern "C" {
933
    pub fn blst_p2_affine_compress(out: *mut byte, in_: *const blst_p2_affine);
934
}
935
extern "C" {
936
    pub fn blst_p2_uncompress(out: *mut blst_p2_affine, in_: *const byte) -> BLST_ERROR;
937
}
938
extern "C" {
939
    pub fn blst_p2_deserialize(out: *mut blst_p2_affine, in_: *const byte) -> BLST_ERROR;
940
}
941
extern "C" {
942
    pub fn blst_keygen(
943
        out_SK: *mut blst_scalar,
944
        IKM: *const byte,
945
        IKM_len: usize,
946
        info: *const byte,
947
        info_len: usize,
948
    );
949
}
950
extern "C" {
951
    pub fn blst_sk_to_pk_in_g1(out_pk: *mut blst_p1, SK: *const blst_scalar);
952
}
953
extern "C" {
954
    pub fn blst_sign_pk_in_g1(out_sig: *mut blst_p2, hash: *const blst_p2, SK: *const blst_scalar);
955
}
956
extern "C" {
957
    pub fn blst_sk_to_pk_in_g2(out_pk: *mut blst_p2, SK: *const blst_scalar);
958
}
959
extern "C" {
960
    pub fn blst_sign_pk_in_g2(out_sig: *mut blst_p1, hash: *const blst_p1, SK: *const blst_scalar);
961
}
962
extern "C" {
963
    pub fn blst_miller_loop(
964
        ret: *mut blst_fp12,
965
        Q: *const blst_p2_affine,
966
        P: *const blst_p1_affine,
967
    );
968
}
969
extern "C" {
970
    pub fn blst_miller_loop_n(
971
        ret: *mut blst_fp12,
972
        Qs: *const *const blst_p2_affine,
973
        Ps: *const *const blst_p1_affine,
974
        n: usize,
975
    );
976
}
977
extern "C" {
978
    pub fn blst_final_exp(ret: *mut blst_fp12, f: *const blst_fp12);
979
}
980
extern "C" {
981
    pub fn blst_precompute_lines(Qlines: *mut blst_fp6, Q: *const blst_p2_affine);
982
}
983
extern "C" {
984
    pub fn blst_miller_loop_lines(
985
        ret: *mut blst_fp12,
986
        Qlines: *const blst_fp6,
987
        P: *const blst_p1_affine,
988
    );
989
}
990
extern "C" {
991
    pub fn blst_fp12_finalverify(gt1: *const blst_fp12, gt2: *const blst_fp12) -> bool;
992
}
993
#[repr(C)]
994
#[repr(align(1))]
995
#[derive(Debug, Default)]
996
pub struct blst_pairing {
997
    pub _bindgen_opaque_blob: [u8; 0usize],
998
}
999
#[test]
1000
fn bindgen_test_layout_blst_pairing() {
1001
    assert_eq!(
1002
        ::core::mem::size_of::<blst_pairing>(),
1003
        0usize,
1004
        concat!("Size of: ", stringify!(blst_pairing))
1005
    );
1006
    assert_eq!(
1007
        ::core::mem::align_of::<blst_pairing>(),
1008
        1usize,
1009
        concat!("Alignment of ", stringify!(blst_pairing))
1010
    );
1011
}
1012
extern "C" {
1013
    pub fn blst_pairing_sizeof() -> usize;
1014
}
1015
extern "C" {
1016
    pub fn blst_pairing_init(
1017
        new_ctx: *mut blst_pairing,
1018
        hash_or_encode: bool,
1019
        DST: *const byte,
1020
        DST_len: usize,
1021
    );
1022
}
1023
extern "C" {
1024
    pub fn blst_pairing_get_dst(ctx: *const blst_pairing) -> *const byte;
1025
}
1026
extern "C" {
1027
    pub fn blst_pairing_commit(ctx: *mut blst_pairing);
1028
}
1029
extern "C" {
1030
    pub fn blst_pairing_aggregate_pk_in_g2(
1031
        ctx: *mut blst_pairing,
1032
        PK: *const blst_p2_affine,
1033
        signature: *const blst_p1_affine,
1034
        msg: *const byte,
1035
        msg_len: usize,
1036
        aug: *const byte,
1037
        aug_len: usize,
1038
    ) -> BLST_ERROR;
1039
}
1040
extern "C" {
1041
    pub fn blst_pairing_chk_n_aggr_pk_in_g2(
1042
        ctx: *mut blst_pairing,
1043
        PK: *const blst_p2_affine,
1044
        pk_grpchk: bool,
1045
        signature: *const blst_p1_affine,
1046
        sig_grpchk: bool,
1047
        msg: *const byte,
1048
        msg_len: usize,
1049
        aug: *const byte,
1050
        aug_len: usize,
1051
    ) -> BLST_ERROR;
1052
}
1053
extern "C" {
1054
    pub fn blst_pairing_mul_n_aggregate_pk_in_g2(
1055
        ctx: *mut blst_pairing,
1056
        PK: *const blst_p2_affine,
1057
        sig: *const blst_p1_affine,
1058
        scalar: *const byte,
1059
        nbits: usize,
1060
        msg: *const byte,
1061
        msg_len: usize,
1062
        aug: *const byte,
1063
        aug_len: usize,
1064
    ) -> BLST_ERROR;
1065
}
1066
extern "C" {
1067
    pub fn blst_pairing_chk_n_mul_n_aggr_pk_in_g2(
1068
        ctx: *mut blst_pairing,
1069
        PK: *const blst_p2_affine,
1070
        pk_grpchk: bool,
1071
        sig: *const blst_p1_affine,
1072
        sig_grpchk: bool,
1073
        scalar: *const byte,
1074
        nbits: usize,
1075
        msg: *const byte,
1076
        msg_len: usize,
1077
        aug: *const byte,
1078
        aug_len: usize,
1079
    ) -> BLST_ERROR;
1080
}
1081
extern "C" {
1082
    pub fn blst_pairing_aggregate_pk_in_g1(
1083
        ctx: *mut blst_pairing,
1084
        PK: *const blst_p1_affine,
1085
        signature: *const blst_p2_affine,
1086
        msg: *const byte,
1087
        msg_len: usize,
1088
        aug: *const byte,
1089
        aug_len: usize,
1090
    ) -> BLST_ERROR;
1091
}
1092
extern "C" {
1093
    pub fn blst_pairing_chk_n_aggr_pk_in_g1(
1094
        ctx: *mut blst_pairing,
1095
        PK: *const blst_p1_affine,
1096
        pk_grpchk: bool,
1097
        signature: *const blst_p2_affine,
1098
        sig_grpchk: bool,
1099
        msg: *const byte,
1100
        msg_len: usize,
1101
        aug: *const byte,
1102
        aug_len: usize,
1103
    ) -> BLST_ERROR;
1104
}
1105
extern "C" {
1106
    pub fn blst_pairing_mul_n_aggregate_pk_in_g1(
1107
        ctx: *mut blst_pairing,
1108
        PK: *const blst_p1_affine,
1109
        sig: *const blst_p2_affine,
1110
        scalar: *const byte,
1111
        nbits: usize,
1112
        msg: *const byte,
1113
        msg_len: usize,
1114
        aug: *const byte,
1115
        aug_len: usize,
1116
    ) -> BLST_ERROR;
1117
}
1118
extern "C" {
1119
    pub fn blst_pairing_chk_n_mul_n_aggr_pk_in_g1(
1120
        ctx: *mut blst_pairing,
1121
        PK: *const blst_p1_affine,
1122
        pk_grpchk: bool,
1123
        sig: *const blst_p2_affine,
1124
        sig_grpchk: bool,
1125
        scalar: *const byte,
1126
        nbits: usize,
1127
        msg: *const byte,
1128
        msg_len: usize,
1129
        aug: *const byte,
1130
        aug_len: usize,
1131
    ) -> BLST_ERROR;
1132
}
1133
extern "C" {
1134
    pub fn blst_pairing_merge(ctx: *mut blst_pairing, ctx1: *const blst_pairing) -> BLST_ERROR;
1135
}
1136
extern "C" {
1137
    pub fn blst_pairing_finalverify(ctx: *const blst_pairing, gtsig: *const blst_fp12) -> bool;
1138
}
1139
extern "C" {
1140
    pub fn blst_aggregate_in_g1(
1141
        out: *mut blst_p1,
1142
        in_: *const blst_p1,
1143
        zwire: *const byte,
1144
    ) -> BLST_ERROR;
1145
}
1146
extern "C" {
1147
    pub fn blst_aggregate_in_g2(
1148
        out: *mut blst_p2,
1149
        in_: *const blst_p2,
1150
        zwire: *const byte,
1151
    ) -> BLST_ERROR;
1152
}
1153
extern "C" {
1154
    pub fn blst_aggregated_in_g1(out: *mut blst_fp12, signature: *const blst_p1_affine);
1155
}
1156
extern "C" {
1157
    pub fn blst_aggregated_in_g2(out: *mut blst_fp12, signature: *const blst_p2_affine);
1158
}
1159
extern "C" {
1160
    pub fn blst_core_verify_pk_in_g1(
1161
        pk: *const blst_p1_affine,
1162
        signature: *const blst_p2_affine,
1163
        hash_or_encode: bool,
1164
        msg: *const byte,
1165
        msg_len: usize,
1166
        DST: *const byte,
1167
        DST_len: usize,
1168
        aug: *const byte,
1169
        aug_len: usize,
1170
    ) -> BLST_ERROR;
1171
}
1172
extern "C" {
1173
    pub fn blst_core_verify_pk_in_g2(
1174
        pk: *const blst_p2_affine,
1175
        signature: *const blst_p1_affine,
1176
        hash_or_encode: bool,
1177
        msg: *const byte,
1178
        msg_len: usize,
1179
        DST: *const byte,
1180
        DST_len: usize,
1181
        aug: *const byte,
1182
        aug_len: usize,
1183
    ) -> BLST_ERROR;
1184
}
1185
extern "C" {
1186
    pub static BLS12_381_G1: blst_p1_affine;
1187
}
1188
extern "C" {
1189
    pub static BLS12_381_NEG_G1: blst_p1_affine;
1190
}
1191
extern "C" {
1192
    pub static BLS12_381_G2: blst_p2_affine;
1193
}
1194
extern "C" {
1195
    pub static BLS12_381_NEG_G2: blst_p2_affine;
1196
}
1197
extern "C" {
1198
    pub fn blst_fr_ct_bfly(x0: *mut blst_fr, x1: *mut blst_fr, twiddle: *const blst_fr);
1199
}
1200
extern "C" {
1201
    pub fn blst_fr_gs_bfly(x0: *mut blst_fr, x1: *mut blst_fr, twiddle: *const blst_fr);
1202
}
1203
extern "C" {
1204
    pub fn blst_fr_to(ret: *mut blst_fr, a: *const blst_fr);
1205
}
1206
extern "C" {
1207
    pub fn blst_fr_from(ret: *mut blst_fr, a: *const blst_fr);
1208
}
1209
extern "C" {
1210
    pub fn blst_fp_to(ret: *mut blst_fp, a: *const blst_fp);
1211
}
1212
extern "C" {
1213
    pub fn blst_fp_from(ret: *mut blst_fp, a: *const blst_fp);
1214
}
1215
extern "C" {
1216
    pub fn blst_fp_is_square(a: *const blst_fp) -> bool;
1217
}
1218
extern "C" {
1219
    pub fn blst_fp2_is_square(a: *const blst_fp2) -> bool;
1220
}
1221
extern "C" {
1222
    pub fn blst_p1_from_jacobian(out: *mut blst_p1, in_: *const blst_p1);
1223
}
1224
extern "C" {
1225
    pub fn blst_p2_from_jacobian(out: *mut blst_p2, in_: *const blst_p2);
1226
}
1227
extern "C" {
1228
    pub fn blst_sk_to_pk2_in_g1(
1229
        out: *mut byte,
1230
        out_pk: *mut blst_p1_affine,
1231
        SK: *const blst_scalar,
1232
    );
1233
}
1234
extern "C" {
1235
    pub fn blst_sign_pk2_in_g1(
1236
        out: *mut byte,
1237
        out_sig: *mut blst_p2_affine,
1238
        hash: *const blst_p2,
1239
        SK: *const blst_scalar,
1240
    );
1241
}
1242
extern "C" {
1243
    pub fn blst_sk_to_pk2_in_g2(
1244
        out: *mut byte,
1245
        out_pk: *mut blst_p2_affine,
1246
        SK: *const blst_scalar,
1247
    );
1248
}
1249
extern "C" {
1250
    pub fn blst_sign_pk2_in_g2(
1251
        out: *mut byte,
1252
        out_sig: *mut blst_p1_affine,
1253
        hash: *const blst_p1,
1254
        SK: *const blst_scalar,
1255
    );
1256
}
1257
#[repr(C)]
1258
#[repr(align(1))]
1259
#[derive(Debug, Default)]
1260
pub struct blst_uniq {
1261
    pub _bindgen_opaque_blob: [u8; 0usize],
1262
}
1263
#[test]
1264
fn bindgen_test_layout_blst_uniq() {
1265
    assert_eq!(
1266
        ::core::mem::size_of::<blst_uniq>(),
1267
        0usize,
1268
        concat!("Size of: ", stringify!(blst_uniq))
1269
    );
1270
    assert_eq!(
1271
        ::core::mem::align_of::<blst_uniq>(),
1272
        1usize,
1273
        concat!("Alignment of ", stringify!(blst_uniq))
1274
    );
1275
}
1276
extern "C" {
1277
    pub fn blst_uniq_sizeof(n_nodes: usize) -> usize;
1278
}
1279
extern "C" {
1280
    pub fn blst_uniq_init(tree: *mut blst_uniq);
1281
}
1282
extern "C" {
1283
    pub fn blst_uniq_test(tree: *mut blst_uniq, msg: *const byte, len: usize) -> bool;
1284
}
1285
extern "C" {
1286
    pub fn blst_expand_message_xmd(
1287
        out: *mut byte,
1288
        out_len: usize,
1289
        msg: *const byte,
1290
        msg_len: usize,
1291
        DST: *const byte,
1292
        DST_len: usize,
1293
    );
1294
}
1295
extern "C" {
1296
    pub fn blst_p1_unchecked_mult(
1297
        out: *mut blst_p1,
1298
        p: *const blst_p1,
1299
        scalar: *const byte,
1300
        nbits: usize,
1301
    );
1302
}
1303
extern "C" {
1304
    pub fn blst_p2_unchecked_mult(
1305
        out: *mut blst_p2,
1306
        p: *const blst_p2,
1307
        scalar: *const byte,
1308
        nbits: usize,
1309
    );
1310
}
1311
extern "C" {
1312
    pub fn blst_pairing_raw_aggregate(
1313
        ctx: *mut blst_pairing,
1314
        q: *const blst_p2_affine,
1315
        p: *const blst_p1_affine,
1316
    );
1317
}
1318
extern "C" {
1319
    pub fn blst_pairing_as_fp12(ctx: *mut blst_pairing) -> *mut blst_fp12;
1320
}
1321
extern "C" {
1322
    pub fn blst_bendian_from_fp12(out: *mut byte, a: *const blst_fp12);
1323
}
1324
extern "C" {
1325
    pub fn blst_keygen_v3(
1326
        out_SK: *mut blst_scalar,
1327
        IKM: *const byte,
1328
        IKM_len: usize,
1329
        info: *const byte,
1330
        info_len: usize,
1331
    );
1332
}
1333
extern "C" {
1334
    pub fn blst_keygen_v4_5(
1335
        out_SK: *mut blst_scalar,
1336
        IKM: *const byte,
1337
        IKM_len: usize,
1338
        salt: *const byte,
1339
        salt_len: usize,
1340
        info: *const byte,
1341
        info_len: usize,
1342
    );
1343
}
1344
extern "C" {
1345
    pub fn blst_keygen_v5(
1346
        out_SK: *mut blst_scalar,
1347
        IKM: *const byte,
1348
        IKM_len: usize,
1349
        salt: *const byte,
1350
        salt_len: usize,
1351
        info: *const byte,
1352
        info_len: usize,
1353
    );
1354
}
1355
extern "C" {
1356
    pub fn blst_derive_master_eip2333(out_SK: *mut blst_scalar, IKM: *const byte, IKM_len: usize);
1357
}
1358
extern "C" {
1359
    pub fn blst_derive_child_eip2333(
1360
        out_SK: *mut blst_scalar,
1361
        SK: *const blst_scalar,
1362
        child_index: u32,
1363
    );
1364
}
1365
extern "C" {
1366
    pub fn blst_scalar_from_hexascii(out: *mut blst_scalar, hex: *const byte);
1367
}
1368
extern "C" {
1369
    pub fn blst_fr_from_hexascii(ret: *mut blst_fr, hex: *const byte);
1370
}
1371
extern "C" {
1372
    pub fn blst_fp_from_hexascii(ret: *mut blst_fp, hex: *const byte);
1373
}
1374
extern "C" {
1375
    pub fn blst_p1_sizeof() -> usize;
1376
}
1377
extern "C" {
1378
    pub fn blst_p1_affine_sizeof() -> usize;
1379
}
1380
extern "C" {
1381
    pub fn blst_p2_sizeof() -> usize;
1382
}
1383
extern "C" {
1384
    pub fn blst_p2_affine_sizeof() -> usize;
1385
}
1386
extern "C" {
1387
    pub fn blst_fp12_sizeof() -> usize;
1388
}
1389
extern "C" {
1390
    pub fn blst_sha256(out: *mut byte, msg: *const byte, msg_len: usize);
1391
}
1392
#[test]
1393
fn bindgen_test_normal_types() {
1394
    // from "Rust for Rustaceans" by Jon Gjengset
1395
    fn is_normal<T: Sized + Send + Sync + Unpin>() {}
1396
    is_normal::<BLST_ERROR>();
1397
    is_normal::<blst_scalar>();
1398
    is_normal::<blst_fr>();
1399
    is_normal::<blst_fp>();
1400
    is_normal::<blst_fp2>();
1401
    is_normal::<blst_fp6>();
1402
    is_normal::<blst_fp12>();
1403
    is_normal::<blst_p1>();
1404
    is_normal::<blst_p1_affine>();
1405
    is_normal::<blst_p2>();
1406
    is_normal::<blst_p2_affine>();
1407
    is_normal::<blst_pairing>();
1408
    is_normal::<blst_uniq>();
1409
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/blst-0.3.12/src/lib.rs
Line
Count
Source
1
// Copyright Supranational LLC
2
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3
// SPDX-License-Identifier: Apache-2.0
4
5
#![cfg_attr(not(feature = "std"), no_std)]
6
#![allow(non_upper_case_globals)]
7
#![allow(non_camel_case_types)]
8
#![allow(non_snake_case)]
9
10
extern crate alloc;
11
12
use alloc::boxed::Box;
13
use alloc::vec;
14
use alloc::vec::Vec;
15
use core::any::Any;
16
use core::mem::MaybeUninit;
17
use core::ptr;
18
use zeroize::Zeroize;
19
20
#[cfg(feature = "std")]
21
use std::sync::{atomic::*, mpsc::channel, Arc};
22
23
#[cfg(feature = "serde")]
24
use serde::{Deserialize, Deserializer, Serialize, Serializer};
25
26
#[cfg(feature = "std")]
27
trait ThreadPoolExt {
28
    fn joined_execute<'any, F>(&self, job: F)
29
    where
30
        F: FnOnce() + Send + 'any;
31
}
32
33
#[cfg(all(not(feature = "no-threads"), feature = "std"))]
34
mod mt {
35
    use super::*;
36
    use core::mem::transmute;
37
    use std::sync::{Mutex, Once};
38
    use threadpool::ThreadPool;
39
40
0
    pub fn da_pool() -> ThreadPool {
41
        static INIT: Once = Once::new();
42
        static mut POOL: *const Mutex<ThreadPool> =
43
            0 as *const Mutex<ThreadPool>;
44
45
0
        INIT.call_once(|| {
46
0
            let pool = Mutex::new(ThreadPool::default());
47
0
            unsafe { POOL = transmute(Box::new(pool)) };
48
0
        });
49
0
        unsafe { (*POOL).lock().unwrap().clone() }
50
0
    }
51
52
    type Thunk<'any> = Box<dyn FnOnce() + Send + 'any>;
53
54
    impl ThreadPoolExt for ThreadPool {
55
0
        fn joined_execute<'scope, F>(&self, job: F)
56
0
        where
57
0
            F: FnOnce() + Send + 'scope,
58
0
        {
59
0
            // Bypass 'lifetime limitations by brute force. It works,
60
0
            // because we explicitly join the threads...
61
0
            self.execute(unsafe {
62
0
                transmute::<Thunk<'scope>, Thunk<'static>>(Box::new(job))
63
0
            })
64
0
        }
Unexecuted instantiation: _RINvXNtCscC7OSmV1s5f_4blst2mtNtCs4c1Xk16ziyI_10threadpool10ThreadPoolNtB5_13ThreadPoolExt14joined_executeNCNvMs6_B5_NtB5_9blst_fp1213miller_loop_n0EB5_
Unexecuted instantiation: _RINvXNtCscC7OSmV1s5f_4blst2mtNtCs4c1Xk16ziyI_10threadpool10ThreadPoolNtB5_13ThreadPoolExt14joined_executeNCNvMs3_NtB5_6min_pkNtB1N_9Signature16aggregate_verify0EB5_
Unexecuted instantiation: _RINvXNtCscC7OSmV1s5f_4blst2mtNtCs4c1Xk16ziyI_10threadpool10ThreadPoolNtB5_13ThreadPoolExt14joined_executeNCNvMs3_NtB5_6min_pkNtB1N_9Signature36verify_multiple_aggregate_signatures0EB5_
Unexecuted instantiation: _RINvXNtCscC7OSmV1s5f_4blst2mtNtCs4c1Xk16ziyI_10threadpool10ThreadPoolNtB5_13ThreadPoolExt14joined_executeNCNvMs3_NtB5_7min_sigNtB1N_9Signature16aggregate_verify0EB5_
Unexecuted instantiation: _RINvXNtCscC7OSmV1s5f_4blst2mtNtCs4c1Xk16ziyI_10threadpool10ThreadPoolNtB5_13ThreadPoolExt14joined_executeNCNvMs3_NtB5_7min_sigNtB1N_9Signature36verify_multiple_aggregate_signatures0EB5_
Unexecuted instantiation: _RINvXNtCscC7OSmV1s5f_4blst2mtNtCs4c1Xk16ziyI_10threadpool10ThreadPoolNtB5_13ThreadPoolExt14joined_executeNCNvMs1n_B5_NtB5_10p1_affines4from0EB5_
Unexecuted instantiation: _RINvXNtCscC7OSmV1s5f_4blst2mtNtCs4c1Xk16ziyI_10threadpool10ThreadPoolNtB5_13ThreadPoolExt14joined_executeNCNvXs1o_B5_SNtB5_14blst_p1_affineNtB5_10MultiPoint4mult0EB5_
Unexecuted instantiation: _RINvXNtCscC7OSmV1s5f_4blst2mtNtCs4c1Xk16ziyI_10threadpool10ThreadPoolNtB5_13ThreadPoolExt14joined_executeNCNvXs1o_B5_SNtB5_14blst_p1_affineNtB5_10MultiPoint3add0EB5_
Unexecuted instantiation: _RINvXNtCscC7OSmV1s5f_4blst2mtNtCs4c1Xk16ziyI_10threadpool10ThreadPoolNtB5_13ThreadPoolExt14joined_executeNCNvMs1r_B5_NtB5_10p2_affines4from0EB5_
Unexecuted instantiation: _RINvXNtCscC7OSmV1s5f_4blst2mtNtCs4c1Xk16ziyI_10threadpool10ThreadPoolNtB5_13ThreadPoolExt14joined_executeNCNvXs1s_B5_SNtB5_14blst_p2_affineNtB5_10MultiPoint4mult0EB5_
Unexecuted instantiation: _RINvXNtCscC7OSmV1s5f_4blst2mtNtCs4c1Xk16ziyI_10threadpool10ThreadPoolNtB5_13ThreadPoolExt14joined_executeNCNvXs1s_B5_SNtB5_14blst_p2_affineNtB5_10MultiPoint3add0EB5_
65
    }
66
}
67
68
#[cfg(all(feature = "no-threads", feature = "std"))]
69
mod mt {
70
    use super::*;
71
72
    pub struct EmptyPool {}
73
74
    pub fn da_pool() -> EmptyPool {
75
        EmptyPool {}
76
    }
77
78
    impl EmptyPool {
79
        pub fn max_count(&self) -> usize {
80
            1
81
        }
82
    }
83
84
    impl ThreadPoolExt for EmptyPool {
85
        fn joined_execute<'scope, F>(&self, job: F)
86
        where
87
            F: FnOnce() + Send + 'scope,
88
        {
89
            job()
90
        }
91
    }
92
}
93
94
include!("bindings.rs");
95
96
impl PartialEq for blst_p1 {
97
0
    fn eq(&self, other: &Self) -> bool {
98
0
        unsafe { blst_p1_is_equal(self, other) }
99
0
    }
100
}
101
102
impl PartialEq for blst_p1_affine {
103
0
    fn eq(&self, other: &Self) -> bool {
104
0
        unsafe { blst_p1_affine_is_equal(self, other) }
105
0
    }
106
}
107
108
impl PartialEq for blst_p2 {
109
0
    fn eq(&self, other: &Self) -> bool {
110
0
        unsafe { blst_p2_is_equal(self, other) }
111
0
    }
112
}
113
114
impl PartialEq for blst_p2_affine {
115
0
    fn eq(&self, other: &Self) -> bool {
116
0
        unsafe { blst_p2_affine_is_equal(self, other) }
117
0
    }
118
}
119
120
impl Default for blst_fp12 {
121
0
    fn default() -> Self {
122
0
        unsafe { *blst_fp12_one() }
123
0
    }
124
}
125
126
impl PartialEq for blst_fp12 {
127
0
    fn eq(&self, other: &Self) -> bool {
128
0
        unsafe { blst_fp12_is_equal(self, other) }
129
0
    }
130
}
131
132
impl core::ops::Mul for blst_fp12 {
133
    type Output = Self;
134
135
0
    fn mul(self, other: Self) -> Self {
136
0
        let mut out = MaybeUninit::<blst_fp12>::uninit();
137
0
        unsafe {
138
0
            blst_fp12_mul(out.as_mut_ptr(), &self, &other);
139
0
            out.assume_init()
140
0
        }
141
0
    }
142
}
143
144
impl core::ops::MulAssign for blst_fp12 {
145
0
    fn mul_assign(&mut self, other: Self) {
146
0
        unsafe { blst_fp12_mul(self, self, &other) }
147
0
    }
148
}
149
150
impl blst_fp12 {
151
0
    pub fn miller_loop(q: &blst_p2_affine, p: &blst_p1_affine) -> Self {
152
0
        let mut out = MaybeUninit::<blst_fp12>::uninit();
153
0
        unsafe {
154
0
            blst_miller_loop(out.as_mut_ptr(), q, p);
155
0
            out.assume_init()
156
0
        }
157
0
    }
158
159
    #[cfg(not(feature = "std"))]
160
    pub fn miller_loop_n(q: &[blst_p2_affine], p: &[blst_p1_affine]) -> Self {
161
        let n_elems = q.len();
162
        if n_elems != p.len() || n_elems == 0 {
163
            panic!("inputs' lengths mismatch");
164
        }
165
        let qs: [*const _; 2] = [&q[0], ptr::null()];
166
        let ps: [*const _; 2] = [&p[0], ptr::null()];
167
        let mut out = MaybeUninit::<blst_fp12>::uninit();
168
        unsafe {
169
            blst_miller_loop_n(out.as_mut_ptr(), &qs[0], &ps[0], n_elems);
170
            out.assume_init()
171
        }
172
    }
173
174
    #[cfg(feature = "std")]
175
0
    pub fn miller_loop_n(q: &[blst_p2_affine], p: &[blst_p1_affine]) -> Self {
176
0
        let n_elems = q.len();
177
0
        if n_elems != p.len() || n_elems == 0 {
178
0
            panic!("inputs' lengths mismatch");
179
0
        }
180
0
181
0
        let pool = mt::da_pool();
182
0
183
0
        let mut n_workers = pool.max_count();
184
0
        if n_workers == 1 {
185
0
            let qs: [*const _; 2] = [&q[0], ptr::null()];
186
0
            let ps: [*const _; 2] = [&p[0], ptr::null()];
187
0
            let mut out = MaybeUninit::<blst_fp12>::uninit();
188
0
            unsafe {
189
0
                blst_miller_loop_n(out.as_mut_ptr(), &qs[0], &ps[0], n_elems);
190
0
                return out.assume_init();
191
            }
192
0
        }
193
0
194
0
        let (tx, rx) = channel();
195
0
        let counter = Arc::new(AtomicUsize::new(0));
196
0
197
0
        let stride = core::cmp::min((n_elems + n_workers - 1) / n_workers, 16);
198
0
        n_workers = core::cmp::min((n_elems + stride - 1) / stride, n_workers);
199
0
        for _ in 0..n_workers {
200
0
            let tx = tx.clone();
201
0
            let counter = counter.clone();
202
0
203
0
            pool.joined_execute(move || {
204
0
                let mut acc = blst_fp12::default();
205
0
                let mut tmp = MaybeUninit::<blst_fp12>::uninit();
206
0
                let mut qs: [*const _; 2] = [ptr::null(), ptr::null()];
207
0
                let mut ps: [*const _; 2] = [ptr::null(), ptr::null()];
208
209
                loop {
210
0
                    let work = counter.fetch_add(stride, Ordering::Relaxed);
211
0
                    if work >= n_elems {
212
0
                        break;
213
0
                    }
214
0
                    let n = core::cmp::min(n_elems - work, stride);
215
0
                    qs[0] = &q[work];
216
0
                    ps[0] = &p[work];
217
0
                    unsafe {
218
0
                        blst_miller_loop_n(tmp.as_mut_ptr(), &qs[0], &ps[0], n);
219
0
                        acc *= tmp.assume_init();
220
0
                    }
221
                }
222
223
0
                tx.send(acc).expect("disaster");
224
0
            });
225
0
        }
226
227
0
        let mut acc = rx.recv().unwrap();
228
0
        for _ in 1..n_workers {
229
0
            acc *= rx.recv().unwrap();
230
0
        }
231
232
0
        acc
233
0
    }
234
235
0
    pub fn final_exp(&self) -> Self {
236
0
        let mut out = MaybeUninit::<blst_fp12>::uninit();
237
0
        unsafe {
238
0
            blst_final_exp(out.as_mut_ptr(), self);
239
0
            out.assume_init()
240
0
        }
241
0
    }
242
243
0
    pub fn in_group(&self) -> bool {
244
0
        unsafe { blst_fp12_in_group(self) }
245
0
    }
246
247
0
    pub fn finalverify(a: &Self, b: &Self) -> bool {
248
0
        unsafe { blst_fp12_finalverify(a, b) }
249
0
    }
250
251
0
    pub fn to_bendian(&self) -> [u8; 48 * 12] {
252
0
        let mut out = MaybeUninit::<[u8; 48 * 12]>::uninit();
253
0
        unsafe {
254
0
            blst_bendian_from_fp12(out.as_mut_ptr() as *mut u8, self);
255
0
            out.assume_init()
256
0
        }
257
0
    }
258
}
259
260
impl blst_scalar {
261
0
    pub fn hash_to(msg: &[u8], dst: &[u8]) -> Option<Self> {
262
0
        unsafe {
263
0
            let mut out = <Self>::default();
264
0
            let mut elem = [0u8; 48];
265
0
            blst_expand_message_xmd(
266
0
                elem.as_mut_ptr(),
267
0
                elem.len(),
268
0
                msg.as_ptr(),
269
0
                msg.len(),
270
0
                dst.as_ptr(),
271
0
                dst.len(),
272
0
            );
273
0
            if blst_scalar_from_be_bytes(&mut out, elem.as_ptr(), elem.len()) {
274
0
                Some(out)
275
            } else {
276
0
                None
277
            }
278
        }
279
0
    }
280
}
281
282
#[derive(Debug)]
283
pub struct Pairing {
284
    v: Box<[u64]>,
285
}
286
287
impl Pairing {
288
0
    pub fn new(hash_or_encode: bool, dst: &[u8]) -> Self {
289
0
        let v: Vec<u64> = vec![0; unsafe { blst_pairing_sizeof() } / 8];
290
0
        let mut obj = Self {
291
0
            v: v.into_boxed_slice(),
292
0
        };
293
0
        obj.init(hash_or_encode, dst);
294
0
        obj
295
0
    }
296
297
0
    pub fn init(&mut self, hash_or_encode: bool, dst: &[u8]) {
298
0
        unsafe {
299
0
            blst_pairing_init(
300
0
                self.ctx(),
301
0
                hash_or_encode,
302
0
                dst.as_ptr(),
303
0
                dst.len(),
304
0
            )
305
0
        }
306
0
    }
307
0
    fn ctx(&mut self) -> *mut blst_pairing {
308
0
        self.v.as_mut_ptr() as *mut blst_pairing
309
0
    }
310
0
    fn const_ctx(&self) -> *const blst_pairing {
311
0
        self.v.as_ptr() as *const blst_pairing
312
0
    }
313
314
0
    pub fn aggregate(
315
0
        &mut self,
316
0
        pk: &dyn Any,
317
0
        pk_validate: bool,
318
0
        sig: &dyn Any,
319
0
        sig_groupcheck: bool,
320
0
        msg: &[u8],
321
0
        aug: &[u8],
322
0
    ) -> BLST_ERROR {
323
0
        if pk.is::<blst_p1_affine>() {
324
            unsafe {
325
                blst_pairing_chk_n_aggr_pk_in_g1(
326
0
                    self.ctx(),
327
0
                    match pk.downcast_ref::<blst_p1_affine>() {
328
0
                        Some(pk) => pk,
329
0
                        None => ptr::null(),
330
                    },
331
0
                    pk_validate,
332
0
                    match sig.downcast_ref::<blst_p2_affine>() {
333
0
                        Some(sig) => sig,
334
0
                        None => ptr::null(),
335
                    },
336
0
                    sig_groupcheck,
337
0
                    msg.as_ptr(),
338
0
                    msg.len(),
339
0
                    aug.as_ptr(),
340
0
                    aug.len(),
341
                )
342
            }
343
0
        } else if pk.is::<blst_p2_affine>() {
344
            unsafe {
345
                blst_pairing_chk_n_aggr_pk_in_g2(
346
0
                    self.ctx(),
347
0
                    match pk.downcast_ref::<blst_p2_affine>() {
348
0
                        Some(pk) => pk,
349
0
                        None => ptr::null(),
350
                    },
351
0
                    pk_validate,
352
0
                    match sig.downcast_ref::<blst_p1_affine>() {
353
0
                        Some(sig) => sig,
354
0
                        None => ptr::null(),
355
                    },
356
0
                    sig_groupcheck,
357
0
                    msg.as_ptr(),
358
0
                    msg.len(),
359
0
                    aug.as_ptr(),
360
0
                    aug.len(),
361
                )
362
            }
363
        } else {
364
0
            panic!("whaaaa?")
365
        }
366
0
    }
367
368
    #[allow(clippy::too_many_arguments)]
369
0
    pub fn mul_n_aggregate(
370
0
        &mut self,
371
0
        pk: &dyn Any,
372
0
        pk_validate: bool,
373
0
        sig: &dyn Any,
374
0
        sig_groupcheck: bool,
375
0
        scalar: &[u8],
376
0
        nbits: usize,
377
0
        msg: &[u8],
378
0
        aug: &[u8],
379
0
    ) -> BLST_ERROR {
380
0
        if pk.is::<blst_p1_affine>() {
381
            unsafe {
382
                blst_pairing_chk_n_mul_n_aggr_pk_in_g1(
383
0
                    self.ctx(),
384
0
                    match pk.downcast_ref::<blst_p1_affine>() {
385
0
                        Some(pk) => pk,
386
0
                        None => ptr::null(),
387
                    },
388
0
                    pk_validate,
389
0
                    match sig.downcast_ref::<blst_p2_affine>() {
390
0
                        Some(sig) => sig,
391
0
                        None => ptr::null(),
392
                    },
393
0
                    sig_groupcheck,
394
0
                    scalar.as_ptr(),
395
0
                    nbits,
396
0
                    msg.as_ptr(),
397
0
                    msg.len(),
398
0
                    aug.as_ptr(),
399
0
                    aug.len(),
400
                )
401
            }
402
0
        } else if pk.is::<blst_p2_affine>() {
403
            unsafe {
404
                blst_pairing_chk_n_mul_n_aggr_pk_in_g2(
405
0
                    self.ctx(),
406
0
                    match pk.downcast_ref::<blst_p2_affine>() {
407
0
                        Some(pk) => pk,
408
0
                        None => ptr::null(),
409
                    },
410
0
                    pk_validate,
411
0
                    match sig.downcast_ref::<blst_p1_affine>() {
412
0
                        Some(sig) => sig,
413
0
                        None => ptr::null(),
414
                    },
415
0
                    sig_groupcheck,
416
0
                    scalar.as_ptr(),
417
0
                    nbits,
418
0
                    msg.as_ptr(),
419
0
                    msg.len(),
420
0
                    aug.as_ptr(),
421
0
                    aug.len(),
422
                )
423
            }
424
        } else {
425
0
            panic!("whaaaa?")
426
        }
427
0
    }
428
429
0
    pub fn aggregated(gtsig: &mut blst_fp12, sig: &dyn Any) {
430
0
        if sig.is::<blst_p1_affine>() {
431
            unsafe {
432
0
                blst_aggregated_in_g1(
433
0
                    gtsig,
434
0
                    sig.downcast_ref::<blst_p1_affine>().unwrap(),
435
0
                )
436
            }
437
0
        } else if sig.is::<blst_p2_affine>() {
438
            unsafe {
439
0
                blst_aggregated_in_g2(
440
0
                    gtsig,
441
0
                    sig.downcast_ref::<blst_p2_affine>().unwrap(),
442
0
                )
443
            }
444
        } else {
445
0
            panic!("whaaaa?")
446
        }
447
0
    }
448
449
0
    pub fn commit(&mut self) {
450
0
        unsafe { blst_pairing_commit(self.ctx()) }
451
0
    }
452
453
0
    pub fn merge(&mut self, ctx1: &Self) -> BLST_ERROR {
454
0
        unsafe { blst_pairing_merge(self.ctx(), ctx1.const_ctx()) }
455
0
    }
456
457
0
    pub fn finalverify(&self, gtsig: Option<&blst_fp12>) -> bool {
458
0
        unsafe {
459
0
            blst_pairing_finalverify(
460
0
                self.const_ctx(),
461
0
                match gtsig {
462
0
                    Some(gtsig) => gtsig,
463
0
                    None => ptr::null(),
464
                },
465
            )
466
        }
467
0
    }
468
469
0
    pub fn raw_aggregate(&mut self, q: &blst_p2_affine, p: &blst_p1_affine) {
470
0
        unsafe { blst_pairing_raw_aggregate(self.ctx(), q, p) }
471
0
    }
472
473
0
    pub fn as_fp12(&mut self) -> blst_fp12 {
474
0
        unsafe { *blst_pairing_as_fp12(self.ctx()) }
475
0
    }
476
}
477
478
0
pub fn uniq(msgs: &[&[u8]]) -> bool {
479
0
    let n_elems = msgs.len();
480
0
481
0
    if n_elems == 1 {
482
0
        return true;
483
0
    } else if n_elems == 2 {
484
0
        return msgs[0] != msgs[1];
485
0
    }
486
0
487
0
    let mut v: Vec<u64> = vec![0; unsafe { blst_uniq_sizeof(n_elems) } / 8];
488
0
    let ctx = v.as_mut_ptr() as *mut blst_uniq;
489
0
490
0
    unsafe { blst_uniq_init(ctx) };
491
492
0
    for msg in msgs.iter() {
493
0
        if !unsafe { blst_uniq_test(ctx, msg.as_ptr(), msg.len()) } {
494
0
            return false;
495
0
        }
496
    }
497
498
0
    true
499
0
}
500
501
#[cfg(feature = "std")]
502
0
pub fn print_bytes(bytes: &[u8], name: &str) {
503
0
    print!("{} ", name);
504
0
    for b in bytes.iter() {
505
0
        print!("{:02x}", b);
506
0
    }
507
0
    println!();
508
0
}
509
510
macro_rules! sig_variant_impl {
511
    (
512
        $name:expr,
513
        $pk:ty,
514
        $pk_aff:ty,
515
        $sig:ty,
516
        $sig_aff:ty,
517
        $sk_to_pk:ident,
518
        $hash_or_encode:expr,
519
        $hash_or_encode_to:ident,
520
        $sign:ident,
521
        $pk_eq:ident,
522
        $sig_eq:ident,
523
        $verify:ident,
524
        $pk_in_group:ident,
525
        $pk_to_aff:ident,
526
        $pk_from_aff:ident,
527
        $pk_ser:ident,
528
        $pk_comp:ident,
529
        $pk_deser:ident,
530
        $pk_uncomp:ident,
531
        $pk_comp_size:expr,
532
        $pk_ser_size:expr,
533
        $sig_in_group:ident,
534
        $sig_to_aff:ident,
535
        $sig_from_aff:ident,
536
        $sig_ser:ident,
537
        $sig_comp:ident,
538
        $sig_deser:ident,
539
        $sig_uncomp:ident,
540
        $sig_comp_size:expr,
541
        $sig_ser_size:expr,
542
        $pk_add_or_dbl:ident,
543
        $pk_add_or_dbl_aff:ident,
544
        $sig_add_or_dbl:ident,
545
        $sig_add_or_dbl_aff:ident,
546
        $pk_is_inf:ident,
547
        $sig_is_inf:ident,
548
        $sig_aggr_in_group:ident,
549
    ) => {
550
        /// Secret Key
551
0
        #[derive(Default, Debug, Clone, Zeroize)]
Unexecuted instantiation: _RNvXsa_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9SecretKeyNtCs6qnKa1vNaZb_7zeroize7Zeroize7zeroize
Unexecuted instantiation: _RNvXsb_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9SecretKeyNtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4drop
Unexecuted instantiation: _RNvXsa_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9SecretKeyNtCs6qnKa1vNaZb_7zeroize7Zeroize7zeroize
Unexecuted instantiation: _RNvXsb_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9SecretKeyNtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4drop
552
        #[zeroize(drop)]
553
        pub struct SecretKey {
554
            value: blst_scalar,
555
        }
556
557
        impl SecretKey {
558
            /// Deterministically generate a secret key from key material
559
0
            pub fn key_gen(
560
0
                ikm: &[u8],
561
0
                key_info: &[u8],
562
0
            ) -> Result<Self, BLST_ERROR> {
563
0
                if ikm.len() < 32 {
564
0
                    return Err(BLST_ERROR::BLST_BAD_ENCODING);
565
0
                }
566
0
                let mut sk = SecretKey::default();
567
0
                unsafe {
568
0
                    blst_keygen(
569
0
                        &mut sk.value,
570
0
                        ikm.as_ptr(),
571
0
                        ikm.len(),
572
0
                        key_info.as_ptr(),
573
0
                        key_info.len(),
574
0
                    );
575
0
                }
576
0
                Ok(sk)
577
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey7key_gen
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey7key_gen
578
579
0
            pub fn key_gen_v3(
580
0
                ikm: &[u8],
581
0
                key_info: &[u8],
582
0
            ) -> Result<Self, BLST_ERROR> {
583
0
                if ikm.len() < 32 {
584
0
                    return Err(BLST_ERROR::BLST_BAD_ENCODING);
585
0
                }
586
0
                let mut sk = SecretKey::default();
587
0
                unsafe {
588
0
                    blst_keygen_v3(
589
0
                        &mut sk.value,
590
0
                        ikm.as_ptr(),
591
0
                        ikm.len(),
592
0
                        key_info.as_ptr(),
593
0
                        key_info.len(),
594
0
                    );
595
0
                }
596
0
                Ok(sk)
597
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey10key_gen_v3
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey10key_gen_v3
598
599
0
            pub fn key_gen_v4_5(
600
0
                ikm: &[u8],
601
0
                salt: &[u8],
602
0
                info: &[u8],
603
0
            ) -> Result<Self, BLST_ERROR> {
604
0
                if ikm.len() < 32 {
605
0
                    return Err(BLST_ERROR::BLST_BAD_ENCODING);
606
0
                }
607
0
                let mut sk = SecretKey::default();
608
0
                unsafe {
609
0
                    blst_keygen_v4_5(
610
0
                        &mut sk.value,
611
0
                        ikm.as_ptr(),
612
0
                        ikm.len(),
613
0
                        salt.as_ptr(),
614
0
                        salt.len(),
615
0
                        info.as_ptr(),
616
0
                        info.len(),
617
0
                    );
618
0
                }
619
0
                Ok(sk)
620
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey12key_gen_v4_5
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey12key_gen_v4_5
621
622
0
            pub fn key_gen_v5(
623
0
                ikm: &[u8],
624
0
                salt: &[u8],
625
0
                info: &[u8],
626
0
            ) -> Result<Self, BLST_ERROR> {
627
0
                if ikm.len() < 32 {
628
0
                    return Err(BLST_ERROR::BLST_BAD_ENCODING);
629
0
                }
630
0
                let mut sk = SecretKey::default();
631
0
                unsafe {
632
0
                    blst_keygen_v5(
633
0
                        &mut sk.value,
634
0
                        ikm.as_ptr(),
635
0
                        ikm.len(),
636
0
                        salt.as_ptr(),
637
0
                        salt.len(),
638
0
                        info.as_ptr(),
639
0
                        info.len(),
640
0
                    );
641
0
                }
642
0
                Ok(sk)
643
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey10key_gen_v5
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey10key_gen_v5
644
645
0
            pub fn derive_master_eip2333(
646
0
                ikm: &[u8],
647
0
            ) -> Result<Self, BLST_ERROR> {
648
0
                if ikm.len() < 32 {
649
0
                    return Err(BLST_ERROR::BLST_BAD_ENCODING);
650
0
                }
651
0
                let mut sk = SecretKey::default();
652
0
                unsafe {
653
0
                    blst_derive_master_eip2333(
654
0
                        &mut sk.value,
655
0
                        ikm.as_ptr(),
656
0
                        ikm.len(),
657
0
                    );
658
0
                }
659
0
                Ok(sk)
660
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey21derive_master_eip2333
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey21derive_master_eip2333
661
662
0
            pub fn derive_child_eip2333(&self, child_index: u32) -> Self {
663
0
                let mut sk = SecretKey::default();
664
0
                unsafe {
665
0
                    blst_derive_child_eip2333(
666
0
                        &mut sk.value,
667
0
                        &self.value,
668
0
                        child_index,
669
0
                    );
670
0
                }
671
0
                sk
672
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey20derive_child_eip2333
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey20derive_child_eip2333
673
674
            // sk_to_pk
675
0
            pub fn sk_to_pk(&self) -> PublicKey {
676
0
                // TODO - would the user like the serialized/compressed pk as well?
677
0
                let mut pk_aff = PublicKey::default();
678
0
                //let mut pk_ser = [0u8; $pk_ser_size];
679
0
680
0
                unsafe {
681
0
                    $sk_to_pk(
682
0
                        //pk_ser.as_mut_ptr(),
683
0
                        ptr::null_mut(),
684
0
                        &mut pk_aff.point,
685
0
                        &self.value,
686
0
                    );
687
0
                }
688
0
                pk_aff
689
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey8sk_to_pk
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey8sk_to_pk
690
691
            // Sign
692
0
            pub fn sign(
693
0
                &self,
694
0
                msg: &[u8],
695
0
                dst: &[u8],
696
0
                aug: &[u8],
697
0
            ) -> Signature {
698
0
                // TODO - would the user like the serialized/compressed sig as well?
699
0
                let mut q = <$sig>::default();
700
0
                let mut sig_aff = <$sig_aff>::default();
701
0
                //let mut sig_ser = [0u8; $sig_ser_size];
702
0
                unsafe {
703
0
                    $hash_or_encode_to(
704
0
                        &mut q,
705
0
                        msg.as_ptr(),
706
0
                        msg.len(),
707
0
                        dst.as_ptr(),
708
0
                        dst.len(),
709
0
                        aug.as_ptr(),
710
0
                        aug.len(),
711
0
                    );
712
0
                    $sign(ptr::null_mut(), &mut sig_aff, &q, &self.value);
713
0
                }
714
0
                Signature { point: sig_aff }
715
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey4sign
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey4sign
716
717
            // TODO - formally speaking application is entitled to have
718
            // ultimate control over secret key storage, which means that
719
            // corresponding serialization/deserialization subroutines
720
            // should accept reference to where to store the result, as
721
            // opposite to returning one.
722
723
            // serialize
724
0
            pub fn serialize(&self) -> [u8; 32] {
725
0
                let mut sk_out = [0; 32];
726
0
                unsafe {
727
0
                    blst_bendian_from_scalar(sk_out.as_mut_ptr(), &self.value);
728
0
                }
729
0
                sk_out
730
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey9serialize
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey9serialize
731
732
            // deserialize
733
0
            pub fn deserialize(sk_in: &[u8]) -> Result<Self, BLST_ERROR> {
734
0
                let mut sk = blst_scalar::default();
735
0
                if sk_in.len() != 32 {
736
0
                    return Err(BLST_ERROR::BLST_BAD_ENCODING);
737
0
                }
738
0
                unsafe {
739
0
                    blst_scalar_from_bendian(&mut sk, sk_in.as_ptr());
740
0
                    if !blst_sk_check(&sk) {
741
0
                        return Err(BLST_ERROR::BLST_BAD_ENCODING);
742
0
                    }
743
0
                }
744
0
                Ok(Self { value: sk })
745
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey11deserialize
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey11deserialize
746
747
0
            pub fn to_bytes(&self) -> [u8; 32] {
748
0
                SecretKey::serialize(&self)
749
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey8to_bytes
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey8to_bytes
750
751
0
            pub fn from_bytes(sk_in: &[u8]) -> Result<Self, BLST_ERROR> {
752
0
                SecretKey::deserialize(sk_in)
753
0
            }
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst6min_pkNtB2_9SecretKey10from_bytes
Unexecuted instantiation: _RNvMNtCscC7OSmV1s5f_4blst7min_sigNtB2_9SecretKey10from_bytes
754
        }
755
756
        #[cfg(feature = "serde-secret")]
757
        impl Serialize for SecretKey {
758
            fn serialize<S: Serializer>(
759
                &self,
760
                ser: S,
761
            ) -> Result<S::Ok, S::Error> {
762
                let bytes = zeroize::Zeroizing::new(self.serialize());
763
                ser.serialize_bytes(bytes.as_ref())
764
            }
765
        }
766
767
        #[cfg(feature = "serde-secret")]
768
        impl<'de> Deserialize<'de> for SecretKey {
769
            fn deserialize<D: Deserializer<'de>>(
770
                deser: D,
771
            ) -> Result<Self, D::Error> {
772
                let bytes: &[u8] = Deserialize::deserialize(deser)?;
773
                Self::deserialize(bytes).map_err(|e| {
774
                    <D::Error as serde::de::Error>::custom(format!("{:?}", e))
775
                })
776
            }
777
        }
778
779
        #[derive(Default, Debug, Clone, Copy)]
780
        pub struct PublicKey {
781
            point: $pk_aff,
782
        }
783
784
        impl PublicKey {
785
            // Core operations
786
787
            // key_validate
788
0
            pub fn validate(&self) -> Result<(), BLST_ERROR> {
789
0
                unsafe {
790
0
                    if $pk_is_inf(&self.point) {
791
0
                        return Err(BLST_ERROR::BLST_PK_IS_INFINITY);
792
0
                    }
793
0
                    if !$pk_in_group(&self.point) {
794
0
                        return Err(BLST_ERROR::BLST_POINT_NOT_IN_GROUP);
795
0
                    }
796
0
                }
797
0
                Ok(())
798
0
            }
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst6min_pkNtB4_9PublicKey8validate
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst7min_sigNtB4_9PublicKey8validate
799
800
0
            pub fn key_validate(key: &[u8]) -> Result<Self, BLST_ERROR> {
801
0
                let pk = PublicKey::from_bytes(key)?;
802
0
                pk.validate()?;
803
0
                Ok(pk)
804
0
            }
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst6min_pkNtB4_9PublicKey12key_validate
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst7min_sigNtB4_9PublicKey12key_validate
805
806
0
            pub fn from_aggregate(agg_pk: &AggregatePublicKey) -> Self {
807
0
                let mut pk_aff = <$pk_aff>::default();
808
0
                unsafe {
809
0
                    $pk_to_aff(&mut pk_aff, &agg_pk.point);
810
0
                }
811
0
                Self { point: pk_aff }
812
0
            }
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst6min_pkNtB4_9PublicKey14from_aggregate
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst7min_sigNtB4_9PublicKey14from_aggregate
813
814
            // Serdes
815
816
0
            pub fn compress(&self) -> [u8; $pk_comp_size] {
817
0
                let mut pk_comp = [0u8; $pk_comp_size];
818
0
                unsafe {
819
0
                    $pk_comp(pk_comp.as_mut_ptr(), &self.point);
820
0
                }
821
0
                pk_comp
822
0
            }
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst6min_pkNtB4_9PublicKey8compress
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst7min_sigNtB4_9PublicKey8compress
823
824
0
            pub fn serialize(&self) -> [u8; $pk_ser_size] {
825
0
                let mut pk_out = [0u8; $pk_ser_size];
826
0
                unsafe {
827
0
                    $pk_ser(pk_out.as_mut_ptr(), &self.point);
828
0
                }
829
0
                pk_out
830
0
            }
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst6min_pkNtB4_9PublicKey9serialize
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst7min_sigNtB4_9PublicKey9serialize
831
832
0
            pub fn uncompress(pk_comp: &[u8]) -> Result<Self, BLST_ERROR> {
833
0
                if pk_comp.len() == $pk_comp_size && (pk_comp[0] & 0x80) != 0 {
834
0
                    let mut pk = <$pk_aff>::default();
835
0
                    let err = unsafe { $pk_uncomp(&mut pk, pk_comp.as_ptr()) };
836
0
                    if err != BLST_ERROR::BLST_SUCCESS {
837
0
                        return Err(err);
838
0
                    }
839
0
                    Ok(Self { point: pk })
840
                } else {
841
0
                    Err(BLST_ERROR::BLST_BAD_ENCODING)
842
                }
843
0
            }
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst6min_pkNtB4_9PublicKey10uncompress
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst7min_sigNtB4_9PublicKey10uncompress
844
845
0
            pub fn deserialize(pk_in: &[u8]) -> Result<Self, BLST_ERROR> {
846
0
                if (pk_in.len() == $pk_ser_size && (pk_in[0] & 0x80) == 0)
847
0
                    || (pk_in.len() == $pk_comp_size && (pk_in[0] & 0x80) != 0)
848
                {
849
0
                    let mut pk = <$pk_aff>::default();
850
0
                    let err = unsafe { $pk_deser(&mut pk, pk_in.as_ptr()) };
851
0
                    if err != BLST_ERROR::BLST_SUCCESS {
852
0
                        return Err(err);
853
0
                    }
854
0
                    Ok(Self { point: pk })
855
                } else {
856
0
                    Err(BLST_ERROR::BLST_BAD_ENCODING)
857
                }
858
0
            }
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst6min_pkNtB4_9PublicKey11deserialize
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst7min_sigNtB4_9PublicKey11deserialize
859
860
0
            pub fn from_bytes(pk_in: &[u8]) -> Result<Self, BLST_ERROR> {
861
0
                PublicKey::deserialize(pk_in)
862
0
            }
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst6min_pkNtB4_9PublicKey10from_bytes
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst7min_sigNtB4_9PublicKey10from_bytes
863
864
0
            pub fn to_bytes(&self) -> [u8; $pk_comp_size] {
865
0
                self.compress()
866
0
            }
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst6min_pkNtB4_9PublicKey8to_bytes
Unexecuted instantiation: _RNvMs_NtCscC7OSmV1s5f_4blst7min_sigNtB4_9PublicKey8to_bytes
867
        }
868
869
        // Trait for equality comparisons which are equivalence relations.
870
        //
871
        // This means, that in addition to a == b and a != b being strict
872
        // inverses, the equality must be reflexive, symmetric and transitive.
873
        impl Eq for PublicKey {}
874
875
        impl PartialEq for PublicKey {
876
0
            fn eq(&self, other: &Self) -> bool {
877
0
                unsafe { $pk_eq(&self.point, &other.point) }
878
0
            }
Unexecuted instantiation: _RNvXs1_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9PublicKeyNtNtCsbQ8arDwx5Xq_4core3cmp9PartialEq2eq
Unexecuted instantiation: _RNvXs1_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9PublicKeyNtNtCsbQ8arDwx5Xq_4core3cmp9PartialEq2eq
879
        }
880
881
        #[cfg(feature = "serde")]
882
        impl Serialize for PublicKey {
883
            fn serialize<S: Serializer>(
884
                &self,
885
                ser: S,
886
            ) -> Result<S::Ok, S::Error> {
887
                ser.serialize_bytes(&self.serialize())
888
            }
889
        }
890
891
        #[cfg(feature = "serde")]
892
        impl<'de> Deserialize<'de> for PublicKey {
893
            fn deserialize<D: Deserializer<'de>>(
894
                deser: D,
895
            ) -> Result<Self, D::Error> {
896
                let bytes: &[u8] = Deserialize::deserialize(deser)?;
897
                Self::deserialize(&bytes).map_err(|e| {
898
                    <D::Error as serde::de::Error>::custom(format!("{:?}", e))
899
                })
900
            }
901
        }
902
903
        #[derive(Debug, Clone, Copy)]
904
        pub struct AggregatePublicKey {
905
            point: $pk,
906
        }
907
908
        impl AggregatePublicKey {
909
0
            pub fn from_public_key(pk: &PublicKey) -> Self {
910
0
                let mut agg_pk = <$pk>::default();
911
0
                unsafe {
912
0
                    $pk_from_aff(&mut agg_pk, &pk.point);
913
0
                }
914
0
                Self { point: agg_pk }
915
0
            }
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregatePublicKey15from_public_key
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregatePublicKey15from_public_key
916
917
0
            pub fn to_public_key(&self) -> PublicKey {
918
0
                let mut pk = <$pk_aff>::default();
919
0
                unsafe {
920
0
                    $pk_to_aff(&mut pk, &self.point);
921
0
                }
922
0
                PublicKey { point: pk }
923
0
            }
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregatePublicKey13to_public_key
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregatePublicKey13to_public_key
924
925
            // Aggregate
926
0
            pub fn aggregate(
927
0
                pks: &[&PublicKey],
928
0
                pks_validate: bool,
929
0
            ) -> Result<Self, BLST_ERROR> {
930
0
                if pks.len() == 0 {
931
0
                    return Err(BLST_ERROR::BLST_AGGR_TYPE_MISMATCH);
932
0
                }
933
0
                if pks_validate {
934
0
                    pks[0].validate()?;
935
0
                }
936
0
                let mut agg_pk = AggregatePublicKey::from_public_key(pks[0]);
937
0
                for s in pks.iter().skip(1) {
938
0
                    if pks_validate {
939
0
                        s.validate()?;
940
0
                    }
941
0
                    unsafe {
942
0
                        $pk_add_or_dbl_aff(
943
0
                            &mut agg_pk.point,
944
0
                            &agg_pk.point,
945
0
                            &s.point,
946
0
                        );
947
0
                    }
948
                }
949
0
                Ok(agg_pk)
950
0
            }
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregatePublicKey9aggregate
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregatePublicKey9aggregate
951
952
0
            pub fn aggregate_serialized(
953
0
                pks: &[&[u8]],
954
0
                pks_validate: bool,
955
0
            ) -> Result<Self, BLST_ERROR> {
956
0
                // TODO - threading
957
0
                if pks.len() == 0 {
958
0
                    return Err(BLST_ERROR::BLST_AGGR_TYPE_MISMATCH);
959
0
                }
960
0
                let mut pk = if pks_validate {
961
0
                    PublicKey::key_validate(pks[0])?
962
                } else {
963
0
                    PublicKey::from_bytes(pks[0])?
964
                };
965
0
                let mut agg_pk = AggregatePublicKey::from_public_key(&pk);
966
0
                for s in pks.iter().skip(1) {
967
0
                    pk = if pks_validate {
968
0
                        PublicKey::key_validate(s)?
969
                    } else {
970
0
                        PublicKey::from_bytes(s)?
971
                    };
972
0
                    unsafe {
973
0
                        $pk_add_or_dbl_aff(
974
0
                            &mut agg_pk.point,
975
0
                            &agg_pk.point,
976
0
                            &pk.point,
977
0
                        );
978
0
                    }
979
                }
980
0
                Ok(agg_pk)
981
0
            }
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregatePublicKey20aggregate_serialized
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregatePublicKey20aggregate_serialized
982
983
0
            pub fn add_aggregate(&mut self, agg_pk: &AggregatePublicKey) {
984
0
                unsafe {
985
0
                    $pk_add_or_dbl(&mut self.point, &self.point, &agg_pk.point);
986
0
                }
987
0
            }
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregatePublicKey13add_aggregate
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregatePublicKey13add_aggregate
988
989
0
            pub fn add_public_key(
990
0
                &mut self,
991
0
                pk: &PublicKey,
992
0
                pk_validate: bool,
993
0
            ) -> Result<(), BLST_ERROR> {
994
0
                if pk_validate {
995
0
                    pk.validate()?;
996
0
                }
997
0
                unsafe {
998
0
                    $pk_add_or_dbl_aff(&mut self.point, &self.point, &pk.point);
999
0
                }
1000
0
                Ok(())
1001
0
            }
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregatePublicKey14add_public_key
Unexecuted instantiation: _RNvMs2_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregatePublicKey14add_public_key
1002
        }
1003
1004
        #[derive(Debug, Clone, Copy)]
1005
        pub struct Signature {
1006
            point: $sig_aff,
1007
        }
1008
1009
        impl Signature {
1010
            // sig_infcheck, check for infinity, is a way to avoid going
1011
            // into resource-consuming verification. Passing 'false' is
1012
            // always cryptographically safe, but application might want
1013
            // to guard against obviously bogus individual[!] signatures.
1014
0
            pub fn validate(
1015
0
                &self,
1016
0
                sig_infcheck: bool,
1017
0
            ) -> Result<(), BLST_ERROR> {
1018
0
                unsafe {
1019
0
                    if sig_infcheck && $sig_is_inf(&self.point) {
1020
0
                        return Err(BLST_ERROR::BLST_PK_IS_INFINITY);
1021
0
                    }
1022
0
                    if !$sig_in_group(&self.point) {
1023
0
                        return Err(BLST_ERROR::BLST_POINT_NOT_IN_GROUP);
1024
0
                    }
1025
0
                }
1026
0
                Ok(())
1027
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature8validate
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature8validate
1028
1029
0
            pub fn sig_validate(
1030
0
                sig: &[u8],
1031
0
                sig_infcheck: bool,
1032
0
            ) -> Result<Self, BLST_ERROR> {
1033
0
                let sig = Signature::from_bytes(sig)?;
1034
0
                sig.validate(sig_infcheck)?;
1035
0
                Ok(sig)
1036
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature12sig_validate
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature12sig_validate
1037
1038
            #[cfg(not(feature = "std"))]
1039
            pub fn verify(
1040
                &self,
1041
                sig_groupcheck: bool,
1042
                msg: &[u8],
1043
                dst: &[u8],
1044
                aug: &[u8],
1045
                pk: &PublicKey,
1046
                pk_validate: bool,
1047
            ) -> BLST_ERROR {
1048
                if sig_groupcheck {
1049
                    match self.validate(false) {
1050
                        Err(err) => return err,
1051
                        _ => (),
1052
                    }
1053
                }
1054
                if pk_validate {
1055
                    match pk.validate() {
1056
                        Err(err) => return err,
1057
                        _ => (),
1058
                    }
1059
                }
1060
                unsafe {
1061
                    $verify(
1062
                        &pk.point,
1063
                        &self.point,
1064
                        $hash_or_encode,
1065
                        msg.as_ptr(),
1066
                        msg.len(),
1067
                        dst.as_ptr(),
1068
                        dst.len(),
1069
                        aug.as_ptr(),
1070
                        aug.len(),
1071
                    )
1072
                }
1073
            }
1074
1075
            #[cfg(feature = "std")]
1076
0
            pub fn verify(
1077
0
                &self,
1078
0
                sig_groupcheck: bool,
1079
0
                msg: &[u8],
1080
0
                dst: &[u8],
1081
0
                aug: &[u8],
1082
0
                pk: &PublicKey,
1083
0
                pk_validate: bool,
1084
0
            ) -> BLST_ERROR {
1085
0
                let aug_msg = [aug, msg].concat();
1086
0
                self.aggregate_verify(
1087
0
                    sig_groupcheck,
1088
0
                    &[aug_msg.as_slice()],
1089
0
                    dst,
1090
0
                    &[pk],
1091
0
                    pk_validate,
1092
0
                )
1093
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature6verify
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature6verify
1094
1095
            #[cfg(feature = "std")]
1096
0
            pub fn aggregate_verify(
1097
0
                &self,
1098
0
                sig_groupcheck: bool,
1099
0
                msgs: &[&[u8]],
1100
0
                dst: &[u8],
1101
0
                pks: &[&PublicKey],
1102
0
                pks_validate: bool,
1103
0
            ) -> BLST_ERROR {
1104
0
                let n_elems = pks.len();
1105
0
                if n_elems == 0 || msgs.len() != n_elems {
1106
0
                    return BLST_ERROR::BLST_VERIFY_FAIL;
1107
0
                }
1108
0
1109
0
                // TODO - check msg uniqueness?
1110
0
1111
0
                let pool = mt::da_pool();
1112
0
                let (tx, rx) = channel();
1113
0
                let counter = Arc::new(AtomicUsize::new(0));
1114
0
                let valid = Arc::new(AtomicBool::new(true));
1115
0
1116
0
                let n_workers = core::cmp::min(pool.max_count(), n_elems);
1117
0
                for _ in 0..n_workers {
1118
0
                    let tx = tx.clone();
1119
0
                    let counter = counter.clone();
1120
0
                    let valid = valid.clone();
1121
0
1122
0
                    pool.joined_execute(move || {
1123
0
                        let mut pairing = Pairing::new($hash_or_encode, dst);
1124
1125
0
                        while valid.load(Ordering::Relaxed) {
1126
0
                            let work = counter.fetch_add(1, Ordering::Relaxed);
1127
0
                            if work >= n_elems {
1128
0
                                break;
1129
0
                            }
1130
0
                            if pairing.aggregate(
1131
0
                                &pks[work].point,
1132
0
                                pks_validate,
1133
0
                                &unsafe { ptr::null::<$sig_aff>().as_ref() },
1134
0
                                false,
1135
0
                                &msgs[work],
1136
0
                                &[],
1137
0
                            ) != BLST_ERROR::BLST_SUCCESS
1138
                            {
1139
0
                                valid.store(false, Ordering::Relaxed);
1140
0
                                break;
1141
0
                            }
1142
                        }
1143
0
                        if valid.load(Ordering::Relaxed) {
1144
0
                            pairing.commit();
1145
0
                        }
1146
0
                        tx.send(pairing).expect("disaster");
1147
0
                    });
Unexecuted instantiation: _RNCNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB7_9Signature16aggregate_verify0B9_
Unexecuted instantiation: _RNCNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB7_9Signature16aggregate_verify0B9_
1148
0
                }
1149
1150
0
                if sig_groupcheck && valid.load(Ordering::Relaxed) {
1151
0
                    match self.validate(false) {
1152
0
                        Err(_err) => valid.store(false, Ordering::Relaxed),
1153
0
                        _ => (),
1154
                    }
1155
0
                }
1156
1157
0
                let mut gtsig = blst_fp12::default();
1158
0
                if valid.load(Ordering::Relaxed) {
1159
0
                    Pairing::aggregated(&mut gtsig, &self.point);
1160
0
                }
1161
1162
0
                let mut acc = rx.recv().unwrap();
1163
0
                for _ in 1..n_workers {
1164
0
                    acc.merge(&rx.recv().unwrap());
1165
0
                }
1166
1167
0
                if valid.load(Ordering::Relaxed)
1168
0
                    && acc.finalverify(Some(&gtsig))
1169
                {
1170
0
                    BLST_ERROR::BLST_SUCCESS
1171
                } else {
1172
0
                    BLST_ERROR::BLST_VERIFY_FAIL
1173
                }
1174
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature16aggregate_verify
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature16aggregate_verify
1175
1176
            // pks are assumed to be verified for proof of possession,
1177
            // which implies that they are already group-checked
1178
            #[cfg(feature = "std")]
1179
0
            pub fn fast_aggregate_verify(
1180
0
                &self,
1181
0
                sig_groupcheck: bool,
1182
0
                msg: &[u8],
1183
0
                dst: &[u8],
1184
0
                pks: &[&PublicKey],
1185
0
            ) -> BLST_ERROR {
1186
0
                let agg_pk = match AggregatePublicKey::aggregate(pks, false) {
1187
0
                    Ok(agg_sig) => agg_sig,
1188
0
                    Err(err) => return err,
1189
                };
1190
0
                let pk = agg_pk.to_public_key();
1191
0
                self.aggregate_verify(
1192
0
                    sig_groupcheck,
1193
0
                    &[msg],
1194
0
                    dst,
1195
0
                    &[&pk],
1196
0
                    false,
1197
0
                )
1198
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature21fast_aggregate_verify
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature21fast_aggregate_verify
1199
1200
            #[cfg(feature = "std")]
1201
0
            pub fn fast_aggregate_verify_pre_aggregated(
1202
0
                &self,
1203
0
                sig_groupcheck: bool,
1204
0
                msg: &[u8],
1205
0
                dst: &[u8],
1206
0
                pk: &PublicKey,
1207
0
            ) -> BLST_ERROR {
1208
0
                self.aggregate_verify(sig_groupcheck, &[msg], dst, &[pk], false)
1209
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature36fast_aggregate_verify_pre_aggregated
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature36fast_aggregate_verify_pre_aggregated
1210
1211
            // https://ethresear.ch/t/fast-verification-of-multiple-bls-signatures/5407
1212
            #[cfg(feature = "std")]
1213
            #[allow(clippy::too_many_arguments)]
1214
0
            pub fn verify_multiple_aggregate_signatures(
1215
0
                msgs: &[&[u8]],
1216
0
                dst: &[u8],
1217
0
                pks: &[&PublicKey],
1218
0
                pks_validate: bool,
1219
0
                sigs: &[&Signature],
1220
0
                sigs_groupcheck: bool,
1221
0
                rands: &[blst_scalar],
1222
0
                rand_bits: usize,
1223
0
            ) -> BLST_ERROR {
1224
0
                let n_elems = pks.len();
1225
0
                if n_elems == 0
1226
0
                    || msgs.len() != n_elems
1227
0
                    || sigs.len() != n_elems
1228
0
                    || rands.len() != n_elems
1229
                {
1230
0
                    return BLST_ERROR::BLST_VERIFY_FAIL;
1231
0
                }
1232
0
1233
0
                // TODO - check msg uniqueness?
1234
0
1235
0
                let pool = mt::da_pool();
1236
0
                let (tx, rx) = channel();
1237
0
                let counter = Arc::new(AtomicUsize::new(0));
1238
0
                let valid = Arc::new(AtomicBool::new(true));
1239
0
1240
0
                let n_workers = core::cmp::min(pool.max_count(), n_elems);
1241
0
                for _ in 0..n_workers {
1242
0
                    let tx = tx.clone();
1243
0
                    let counter = counter.clone();
1244
0
                    let valid = valid.clone();
1245
0
1246
0
                    pool.joined_execute(move || {
1247
0
                        let mut pairing = Pairing::new($hash_or_encode, dst);
1248
1249
                        // TODO - engage multi-point mul-n-add for larger
1250
                        // amount of inputs...
1251
0
                        while valid.load(Ordering::Relaxed) {
1252
0
                            let work = counter.fetch_add(1, Ordering::Relaxed);
1253
0
                            if work >= n_elems {
1254
0
                                break;
1255
0
                            }
1256
0
1257
0
                            if pairing.mul_n_aggregate(
1258
0
                                &pks[work].point,
1259
0
                                pks_validate,
1260
0
                                &sigs[work].point,
1261
0
                                sigs_groupcheck,
1262
0
                                &rands[work].b,
1263
0
                                rand_bits,
1264
0
                                msgs[work],
1265
0
                                &[],
1266
0
                            ) != BLST_ERROR::BLST_SUCCESS
1267
                            {
1268
0
                                valid.store(false, Ordering::Relaxed);
1269
0
                                break;
1270
0
                            }
1271
                        }
1272
0
                        if valid.load(Ordering::Relaxed) {
1273
0
                            pairing.commit();
1274
0
                        }
1275
0
                        tx.send(pairing).expect("disaster");
1276
0
                    });
Unexecuted instantiation: _RNCNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB7_9Signature36verify_multiple_aggregate_signatures0B9_
Unexecuted instantiation: _RNCNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB7_9Signature36verify_multiple_aggregate_signatures0B9_
1277
0
                }
1278
1279
0
                let mut acc = rx.recv().unwrap();
1280
0
                for _ in 1..n_workers {
1281
0
                    acc.merge(&rx.recv().unwrap());
1282
0
                }
1283
1284
0
                if valid.load(Ordering::Relaxed) && acc.finalverify(None) {
1285
0
                    BLST_ERROR::BLST_SUCCESS
1286
                } else {
1287
0
                    BLST_ERROR::BLST_VERIFY_FAIL
1288
                }
1289
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature36verify_multiple_aggregate_signatures
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature36verify_multiple_aggregate_signatures
1290
1291
0
            pub fn from_aggregate(agg_sig: &AggregateSignature) -> Self {
1292
0
                let mut sig_aff = <$sig_aff>::default();
1293
0
                unsafe {
1294
0
                    $sig_to_aff(&mut sig_aff, &agg_sig.point);
1295
0
                }
1296
0
                Self { point: sig_aff }
1297
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature14from_aggregate
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature14from_aggregate
1298
1299
0
            pub fn compress(&self) -> [u8; $sig_comp_size] {
1300
0
                let mut sig_comp = [0; $sig_comp_size];
1301
0
                unsafe {
1302
0
                    $sig_comp(sig_comp.as_mut_ptr(), &self.point);
1303
0
                }
1304
0
                sig_comp
1305
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature8compress
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature8compress
1306
1307
0
            pub fn serialize(&self) -> [u8; $sig_ser_size] {
1308
0
                let mut sig_out = [0; $sig_ser_size];
1309
0
                unsafe {
1310
0
                    $sig_ser(sig_out.as_mut_ptr(), &self.point);
1311
0
                }
1312
0
                sig_out
1313
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature9serialize
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature9serialize
1314
1315
0
            pub fn uncompress(sig_comp: &[u8]) -> Result<Self, BLST_ERROR> {
1316
0
                if sig_comp.len() == $sig_comp_size && (sig_comp[0] & 0x80) != 0
1317
                {
1318
0
                    let mut sig = <$sig_aff>::default();
1319
0
                    let err =
1320
0
                        unsafe { $sig_uncomp(&mut sig, sig_comp.as_ptr()) };
1321
0
                    if err != BLST_ERROR::BLST_SUCCESS {
1322
0
                        return Err(err);
1323
0
                    }
1324
0
                    Ok(Self { point: sig })
1325
                } else {
1326
0
                    Err(BLST_ERROR::BLST_BAD_ENCODING)
1327
                }
1328
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature10uncompress
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature10uncompress
1329
1330
0
            pub fn deserialize(sig_in: &[u8]) -> Result<Self, BLST_ERROR> {
1331
0
                if (sig_in.len() == $sig_ser_size && (sig_in[0] & 0x80) == 0)
1332
0
                    || (sig_in.len() == $sig_comp_size
1333
0
                        && (sig_in[0] & 0x80) != 0)
1334
                {
1335
0
                    let mut sig = <$sig_aff>::default();
1336
0
                    let err = unsafe { $sig_deser(&mut sig, sig_in.as_ptr()) };
1337
0
                    if err != BLST_ERROR::BLST_SUCCESS {
1338
0
                        return Err(err);
1339
0
                    }
1340
0
                    Ok(Self { point: sig })
1341
                } else {
1342
0
                    Err(BLST_ERROR::BLST_BAD_ENCODING)
1343
                }
1344
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature11deserialize
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature11deserialize
1345
1346
0
            pub fn from_bytes(sig_in: &[u8]) -> Result<Self, BLST_ERROR> {
1347
0
                Signature::deserialize(sig_in)
1348
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature10from_bytes
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature10from_bytes
1349
1350
0
            pub fn to_bytes(&self) -> [u8; $sig_comp_size] {
1351
0
                self.compress()
1352
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature8to_bytes
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature8to_bytes
1353
1354
0
            pub fn subgroup_check(&self) -> bool {
1355
0
                unsafe { $sig_in_group(&self.point) }
1356
0
            }
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9Signature14subgroup_check
Unexecuted instantiation: _RNvMs3_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9Signature14subgroup_check
1357
        }
1358
1359
        // Trait for equality comparisons which are equivalence relations.
1360
        //
1361
        // This means, that in addition to a == b and a != b being strict
1362
        // inverses, the equality must be reflexive, symmetric and transitive.
1363
        impl Eq for Signature {}
1364
1365
        impl PartialEq for Signature {
1366
0
            fn eq(&self, other: &Self) -> bool {
1367
0
                unsafe { $sig_eq(&self.point, &other.point) }
1368
0
            }
Unexecuted instantiation: _RNvXs5_NtCscC7OSmV1s5f_4blst6min_pkNtB5_9SignatureNtNtCsbQ8arDwx5Xq_4core3cmp9PartialEq2eq
Unexecuted instantiation: _RNvXs5_NtCscC7OSmV1s5f_4blst7min_sigNtB5_9SignatureNtNtCsbQ8arDwx5Xq_4core3cmp9PartialEq2eq
1369
        }
1370
1371
        #[cfg(feature = "serde")]
1372
        impl Serialize for Signature {
1373
            fn serialize<S: Serializer>(
1374
                &self,
1375
                ser: S,
1376
            ) -> Result<S::Ok, S::Error> {
1377
                ser.serialize_bytes(&self.serialize())
1378
            }
1379
        }
1380
1381
        #[cfg(feature = "serde")]
1382
        impl<'de> Deserialize<'de> for Signature {
1383
            fn deserialize<D: Deserializer<'de>>(
1384
                deser: D,
1385
            ) -> Result<Self, D::Error> {
1386
                let bytes: &[u8] = Deserialize::deserialize(deser)?;
1387
                Self::deserialize(&bytes).map_err(|e| {
1388
                    <D::Error as serde::de::Error>::custom(format!("{:?}", e))
1389
                })
1390
            }
1391
        }
1392
1393
        #[derive(Debug, Clone, Copy)]
1394
        pub struct AggregateSignature {
1395
            point: $sig,
1396
        }
1397
1398
        impl AggregateSignature {
1399
0
            pub fn validate(&self) -> Result<(), BLST_ERROR> {
1400
0
                unsafe {
1401
0
                    if !$sig_aggr_in_group(&self.point) {
1402
0
                        return Err(BLST_ERROR::BLST_POINT_NOT_IN_GROUP);
1403
0
                    }
1404
0
                }
1405
0
                Ok(())
1406
0
            }
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregateSignature8validate
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregateSignature8validate
1407
1408
0
            pub fn from_signature(sig: &Signature) -> Self {
1409
0
                let mut agg_sig = <$sig>::default();
1410
0
                unsafe {
1411
0
                    $sig_from_aff(&mut agg_sig, &sig.point);
1412
0
                }
1413
0
                Self { point: agg_sig }
1414
0
            }
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregateSignature14from_signature
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregateSignature14from_signature
1415
1416
0
            pub fn to_signature(&self) -> Signature {
1417
0
                let mut sig = <$sig_aff>::default();
1418
0
                unsafe {
1419
0
                    $sig_to_aff(&mut sig, &self.point);
1420
0
                }
1421
0
                Signature { point: sig }
1422
0
            }
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregateSignature12to_signature
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregateSignature12to_signature
1423
1424
            // Aggregate
1425
0
            pub fn aggregate(
1426
0
                sigs: &[&Signature],
1427
0
                sigs_groupcheck: bool,
1428
0
            ) -> Result<Self, BLST_ERROR> {
1429
0
                if sigs.len() == 0 {
1430
0
                    return Err(BLST_ERROR::BLST_AGGR_TYPE_MISMATCH);
1431
0
                }
1432
0
                if sigs_groupcheck {
1433
                    // We can't actually judge if input is individual or
1434
                    // aggregated signature, so we can't enforce infinity
1435
                    // check.
1436
0
                    sigs[0].validate(false)?;
1437
0
                }
1438
0
                let mut agg_sig = AggregateSignature::from_signature(sigs[0]);
1439
0
                for s in sigs.iter().skip(1) {
1440
0
                    if sigs_groupcheck {
1441
0
                        s.validate(false)?;
1442
0
                    }
1443
0
                    unsafe {
1444
0
                        $sig_add_or_dbl_aff(
1445
0
                            &mut agg_sig.point,
1446
0
                            &agg_sig.point,
1447
0
                            &s.point,
1448
0
                        );
1449
0
                    }
1450
                }
1451
0
                Ok(agg_sig)
1452
0
            }
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregateSignature9aggregate
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregateSignature9aggregate
1453
1454
0
            pub fn aggregate_serialized(
1455
0
                sigs: &[&[u8]],
1456
0
                sigs_groupcheck: bool,
1457
0
            ) -> Result<Self, BLST_ERROR> {
1458
0
                // TODO - threading
1459
0
                if sigs.len() == 0 {
1460
0
                    return Err(BLST_ERROR::BLST_AGGR_TYPE_MISMATCH);
1461
0
                }
1462
0
                let mut sig = if sigs_groupcheck {
1463
0
                    Signature::sig_validate(sigs[0], false)?
1464
                } else {
1465
0
                    Signature::from_bytes(sigs[0])?
1466
                };
1467
0
                let mut agg_sig = AggregateSignature::from_signature(&sig);
1468
0
                for s in sigs.iter().skip(1) {
1469
0
                    sig = if sigs_groupcheck {
1470
0
                        Signature::sig_validate(s, false)?
1471
                    } else {
1472
0
                        Signature::from_bytes(s)?
1473
                    };
1474
0
                    unsafe {
1475
0
                        $sig_add_or_dbl_aff(
1476
0
                            &mut agg_sig.point,
1477
0
                            &agg_sig.point,
1478
0
                            &sig.point,
1479
0
                        );
1480
0
                    }
1481
                }
1482
0
                Ok(agg_sig)
1483
0
            }
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregateSignature20aggregate_serialized
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregateSignature20aggregate_serialized
1484
1485
0
            pub fn add_aggregate(&mut self, agg_sig: &AggregateSignature) {
1486
0
                unsafe {
1487
0
                    $sig_add_or_dbl(
1488
0
                        &mut self.point,
1489
0
                        &self.point,
1490
0
                        &agg_sig.point,
1491
0
                    );
1492
0
                }
1493
0
            }
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregateSignature13add_aggregate
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregateSignature13add_aggregate
1494
1495
0
            pub fn add_signature(
1496
0
                &mut self,
1497
0
                sig: &Signature,
1498
0
                sig_groupcheck: bool,
1499
0
            ) -> Result<(), BLST_ERROR> {
1500
0
                if sig_groupcheck {
1501
0
                    sig.validate(false)?;
1502
0
                }
1503
0
                unsafe {
1504
0
                    $sig_add_or_dbl_aff(
1505
0
                        &mut self.point,
1506
0
                        &self.point,
1507
0
                        &sig.point,
1508
0
                    );
1509
0
                }
1510
0
                Ok(())
1511
0
            }
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregateSignature13add_signature
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregateSignature13add_signature
1512
1513
0
            pub fn subgroup_check(&self) -> bool {
1514
0
                unsafe { $sig_aggr_in_group(&self.point) }
1515
0
            }
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst6min_pkNtB5_18AggregateSignature14subgroup_check
Unexecuted instantiation: _RNvMs6_NtCscC7OSmV1s5f_4blst7min_sigNtB5_18AggregateSignature14subgroup_check
1516
        }
1517
1518
        #[cfg(test)]
1519
        mod tests {
1520
            use super::*;
1521
            use rand::{RngCore, SeedableRng};
1522
            use rand_chacha::ChaCha20Rng;
1523
1524
            // Testing only - do not use for production
1525
            pub fn gen_random_key(
1526
                rng: &mut rand_chacha::ChaCha20Rng,
1527
            ) -> SecretKey {
1528
                let mut ikm = [0u8; 32];
1529
                rng.fill_bytes(&mut ikm);
1530
1531
                let mut sk = <blst_scalar>::default();
1532
                unsafe {
1533
                    blst_keygen(&mut sk, ikm.as_ptr(), 32, ptr::null(), 0);
1534
                }
1535
                SecretKey { value: sk }
1536
            }
1537
1538
            #[test]
1539
            fn test_sign_n_verify() {
1540
                let ikm: [u8; 32] = [
1541
                    0x93, 0xad, 0x7e, 0x65, 0xde, 0xad, 0x05, 0x2a, 0x08, 0x3a,
1542
                    0x91, 0x0c, 0x8b, 0x72, 0x85, 0x91, 0x46, 0x4c, 0xca, 0x56,
1543
                    0x60, 0x5b, 0xb0, 0x56, 0xed, 0xfe, 0x2b, 0x60, 0xa6, 0x3c,
1544
                    0x48, 0x99,
1545
                ];
1546
1547
                let sk = SecretKey::key_gen(&ikm, &[]).unwrap();
1548
                let pk = sk.sk_to_pk();
1549
1550
                let dst = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_";
1551
                let msg = b"hello foo";
1552
                let sig = sk.sign(msg, dst, &[]);
1553
1554
                let err = sig.verify(true, msg, dst, &[], &pk, true);
1555
                assert_eq!(err, BLST_ERROR::BLST_SUCCESS);
1556
            }
1557
1558
            #[test]
1559
            #[cfg(feature = "std")]
1560
            fn test_aggregate() {
1561
                let num_msgs = 10;
1562
                let dst = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_";
1563
1564
                let seed = [0u8; 32];
1565
                let mut rng = ChaCha20Rng::from_seed(seed);
1566
1567
                let sks: Vec<_> =
1568
                    (0..num_msgs).map(|_| gen_random_key(&mut rng)).collect();
1569
                let pks =
1570
                    sks.iter().map(|sk| sk.sk_to_pk()).collect::<Vec<_>>();
1571
                let pks_refs: Vec<&PublicKey> =
1572
                    pks.iter().map(|pk| pk).collect();
1573
                let pks_rev: Vec<&PublicKey> =
1574
                    pks.iter().rev().map(|pk| pk).collect();
1575
1576
                let pk_comp = pks[0].compress();
1577
                let pk_uncomp = PublicKey::uncompress(&pk_comp);
1578
                assert_eq!(pk_uncomp.is_ok(), true);
1579
1580
                let mut msgs: Vec<Vec<u8>> = vec![vec![]; num_msgs];
1581
                for i in 0..num_msgs {
1582
                    let msg_len = (rng.next_u64() & 0x3F) + 1;
1583
                    msgs[i] = vec![0u8; msg_len as usize];
1584
                    rng.fill_bytes(&mut msgs[i]);
1585
                }
1586
1587
                let msgs_refs: Vec<&[u8]> =
1588
                    msgs.iter().map(|m| m.as_slice()).collect();
1589
1590
                let sigs = sks
1591
                    .iter()
1592
                    .zip(msgs.iter())
1593
                    .map(|(sk, m)| (sk.sign(m, dst, &[])))
1594
                    .collect::<Vec<Signature>>();
1595
1596
                let mut errs = sigs
1597
                    .iter()
1598
                    .zip(msgs.iter())
1599
                    .zip(pks.iter())
1600
                    .map(|((s, m), pk)| (s.verify(true, m, dst, &[], pk, true)))
1601
                    .collect::<Vec<BLST_ERROR>>();
1602
                assert_eq!(errs, vec![BLST_ERROR::BLST_SUCCESS; num_msgs]);
1603
1604
                // Swap message/public key pairs to create bad signature
1605
                errs = sigs
1606
                    .iter()
1607
                    .zip(msgs.iter())
1608
                    .zip(pks.iter().rev())
1609
                    .map(|((s, m), pk)| (s.verify(true, m, dst, &[], pk, true)))
1610
                    .collect::<Vec<BLST_ERROR>>();
1611
                assert_ne!(errs, vec![BLST_ERROR::BLST_SUCCESS; num_msgs]);
1612
1613
                let sig_refs =
1614
                    sigs.iter().map(|s| s).collect::<Vec<&Signature>>();
1615
                let agg = match AggregateSignature::aggregate(&sig_refs, true) {
1616
                    Ok(agg) => agg,
1617
                    Err(err) => panic!("aggregate failure: {:?}", err),
1618
                };
1619
1620
                let agg_sig = agg.to_signature();
1621
                let mut result = agg_sig
1622
                    .aggregate_verify(false, &msgs_refs, dst, &pks_refs, false);
1623
                assert_eq!(result, BLST_ERROR::BLST_SUCCESS);
1624
1625
                // Swap message/public key pairs to create bad signature
1626
                result = agg_sig
1627
                    .aggregate_verify(false, &msgs_refs, dst, &pks_rev, false);
1628
                assert_ne!(result, BLST_ERROR::BLST_SUCCESS);
1629
            }
1630
1631
            #[test]
1632
            #[cfg(feature = "std")]
1633
            fn test_multiple_agg_sigs() {
1634
                let dst = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
1635
                let num_pks_per_sig = 10;
1636
                let num_sigs = 10;
1637
1638
                let seed = [0u8; 32];
1639
                let mut rng = ChaCha20Rng::from_seed(seed);
1640
1641
                let mut msgs: Vec<Vec<u8>> = vec![vec![]; num_sigs];
1642
                let mut sigs: Vec<Signature> = Vec::with_capacity(num_sigs);
1643
                let mut pks: Vec<PublicKey> = Vec::with_capacity(num_sigs);
1644
                let mut rands: Vec<blst_scalar> = Vec::with_capacity(num_sigs);
1645
                for i in 0..num_sigs {
1646
                    // Create public keys
1647
                    let sks_i: Vec<_> = (0..num_pks_per_sig)
1648
                        .map(|_| gen_random_key(&mut rng))
1649
                        .collect();
1650
1651
                    let pks_i = sks_i
1652
                        .iter()
1653
                        .map(|sk| sk.sk_to_pk())
1654
                        .collect::<Vec<_>>();
1655
                    let pks_refs_i: Vec<&PublicKey> =
1656
                        pks_i.iter().map(|pk| pk).collect();
1657
1658
                    // Create random message for pks to all sign
1659
                    let msg_len = (rng.next_u64() & 0x3F) + 1;
1660
                    msgs[i] = vec![0u8; msg_len as usize];
1661
                    rng.fill_bytes(&mut msgs[i]);
1662
1663
                    // Generate signature for each key pair
1664
                    let sigs_i = sks_i
1665
                        .iter()
1666
                        .map(|sk| sk.sign(&msgs[i], dst, &[]))
1667
                        .collect::<Vec<Signature>>();
1668
1669
                    // Test each current single signature
1670
                    let errs = sigs_i
1671
                        .iter()
1672
                        .zip(pks_i.iter())
1673
                        .map(|(s, pk)| {
1674
                            (s.verify(true, &msgs[i], dst, &[], pk, true))
1675
                        })
1676
                        .collect::<Vec<BLST_ERROR>>();
1677
                    assert_eq!(
1678
                        errs,
1679
                        vec![BLST_ERROR::BLST_SUCCESS; num_pks_per_sig]
1680
                    );
1681
1682
                    let sig_refs_i =
1683
                        sigs_i.iter().map(|s| s).collect::<Vec<&Signature>>();
1684
                    let agg_i =
1685
                        match AggregateSignature::aggregate(&sig_refs_i, false)
1686
                        {
1687
                            Ok(agg_i) => agg_i,
1688
                            Err(err) => panic!("aggregate failure: {:?}", err),
1689
                        };
1690
1691
                    // Test current aggregate signature
1692
                    sigs.push(agg_i.to_signature());
1693
                    let mut result = sigs[i].fast_aggregate_verify(
1694
                        false,
1695
                        &msgs[i],
1696
                        dst,
1697
                        &pks_refs_i,
1698
                    );
1699
                    assert_eq!(result, BLST_ERROR::BLST_SUCCESS);
1700
1701
                    // negative test
1702
                    if i != 0 {
1703
                        result = sigs[i - 1].fast_aggregate_verify(
1704
                            false,
1705
                            &msgs[i],
1706
                            dst,
1707
                            &pks_refs_i,
1708
                        );
1709
                        assert_ne!(result, BLST_ERROR::BLST_SUCCESS);
1710
                    }
1711
1712
                    // aggregate public keys and push into vec
1713
                    let agg_pk_i =
1714
                        match AggregatePublicKey::aggregate(&pks_refs_i, false)
1715
                        {
1716
                            Ok(agg_pk_i) => agg_pk_i,
1717
                            Err(err) => panic!("aggregate failure: {:?}", err),
1718
                        };
1719
                    pks.push(agg_pk_i.to_public_key());
1720
1721
                    // Test current aggregate signature with aggregated pks
1722
                    result = sigs[i].fast_aggregate_verify_pre_aggregated(
1723
                        false, &msgs[i], dst, &pks[i],
1724
                    );
1725
                    assert_eq!(result, BLST_ERROR::BLST_SUCCESS);
1726
1727
                    // negative test
1728
                    if i != 0 {
1729
                        result = sigs[i - 1]
1730
                            .fast_aggregate_verify_pre_aggregated(
1731
                                false, &msgs[i], dst, &pks[i],
1732
                            );
1733
                        assert_ne!(result, BLST_ERROR::BLST_SUCCESS);
1734
                    }
1735
1736
                    // create random values
1737
                    let mut vals = [0u64; 4];
1738
                    vals[0] = rng.next_u64();
1739
                    while vals[0] == 0 {
1740
                        // Reject zero as it is used for multiplication.
1741
                        vals[0] = rng.next_u64();
1742
                    }
1743
                    let mut rand_i = MaybeUninit::<blst_scalar>::uninit();
1744
                    unsafe {
1745
                        blst_scalar_from_uint64(
1746
                            rand_i.as_mut_ptr(),
1747
                            vals.as_ptr(),
1748
                        );
1749
                        rands.push(rand_i.assume_init());
1750
                    }
1751
                }
1752
1753
                let msgs_refs: Vec<&[u8]> =
1754
                    msgs.iter().map(|m| m.as_slice()).collect();
1755
                let sig_refs =
1756
                    sigs.iter().map(|s| s).collect::<Vec<&Signature>>();
1757
                let pks_refs: Vec<&PublicKey> =
1758
                    pks.iter().map(|pk| pk).collect();
1759
1760
                let msgs_rev: Vec<&[u8]> =
1761
                    msgs.iter().rev().map(|m| m.as_slice()).collect();
1762
                let sig_rev =
1763
                    sigs.iter().rev().map(|s| s).collect::<Vec<&Signature>>();
1764
                let pks_rev: Vec<&PublicKey> =
1765
                    pks.iter().rev().map(|pk| pk).collect();
1766
1767
                let mut result =
1768
                    Signature::verify_multiple_aggregate_signatures(
1769
                        &msgs_refs, dst, &pks_refs, false, &sig_refs, true,
1770
                        &rands, 64,
1771
                    );
1772
                assert_eq!(result, BLST_ERROR::BLST_SUCCESS);
1773
1774
                // negative tests (use reverse msgs, pks, and sigs)
1775
                result = Signature::verify_multiple_aggregate_signatures(
1776
                    &msgs_rev, dst, &pks_refs, false, &sig_refs, true, &rands,
1777
                    64,
1778
                );
1779
                assert_ne!(result, BLST_ERROR::BLST_SUCCESS);
1780
1781
                result = Signature::verify_multiple_aggregate_signatures(
1782
                    &msgs_refs, dst, &pks_rev, false, &sig_refs, true, &rands,
1783
                    64,
1784
                );
1785
                assert_ne!(result, BLST_ERROR::BLST_SUCCESS);
1786
1787
                result = Signature::verify_multiple_aggregate_signatures(
1788
                    &msgs_refs, dst, &pks_refs, false, &sig_rev, true, &rands,
1789
                    64,
1790
                );
1791
                assert_ne!(result, BLST_ERROR::BLST_SUCCESS);
1792
            }
1793
1794
            #[test]
1795
            fn test_serialization() {
1796
                let seed = [0u8; 32];
1797
                let mut rng = ChaCha20Rng::from_seed(seed);
1798
1799
                let sk = gen_random_key(&mut rng);
1800
                let sk2 = gen_random_key(&mut rng);
1801
1802
                let pk = sk.sk_to_pk();
1803
                let pk_comp = pk.compress();
1804
                let pk_ser = pk.serialize();
1805
1806
                let pk_uncomp = PublicKey::uncompress(&pk_comp);
1807
                assert_eq!(pk_uncomp.is_ok(), true);
1808
                assert_eq!(pk_uncomp.unwrap(), pk);
1809
1810
                let pk_deser = PublicKey::deserialize(&pk_ser);
1811
                assert_eq!(pk_deser.is_ok(), true);
1812
                assert_eq!(pk_deser.unwrap(), pk);
1813
1814
                let pk2 = sk2.sk_to_pk();
1815
                let pk_comp2 = pk2.compress();
1816
                let pk_ser2 = pk2.serialize();
1817
1818
                let pk_uncomp2 = PublicKey::uncompress(&pk_comp2);
1819
                assert_eq!(pk_uncomp2.is_ok(), true);
1820
                assert_eq!(pk_uncomp2.unwrap(), pk2);
1821
1822
                let pk_deser2 = PublicKey::deserialize(&pk_ser2);
1823
                assert_eq!(pk_deser2.is_ok(), true);
1824
                assert_eq!(pk_deser2.unwrap(), pk2);
1825
1826
                assert_ne!(pk, pk2);
1827
                assert_ne!(pk_uncomp.unwrap(), pk2);
1828
                assert_ne!(pk_deser.unwrap(), pk2);
1829
                assert_ne!(pk_uncomp2.unwrap(), pk);
1830
                assert_ne!(pk_deser2.unwrap(), pk);
1831
            }
1832
1833
            #[cfg(feature = "serde")]
1834
            #[test]
1835
            fn test_serde() {
1836
                let seed = [0u8; 32];
1837
                let mut rng = ChaCha20Rng::from_seed(seed);
1838
1839
                // generate a sk, pk, and sig, and make sure it signs
1840
                let sk = gen_random_key(&mut rng);
1841
                let pk = sk.sk_to_pk();
1842
                let sig = sk.sign(b"asdf", b"qwer", b"zxcv");
1843
                assert_eq!(
1844
                    sig.verify(true, b"asdf", b"qwer", b"zxcv", &pk, true),
1845
                    BLST_ERROR::BLST_SUCCESS
1846
                );
1847
1848
                // roundtrip through serde
1849
                let pk_ser =
1850
                    rmp_serde::encode::to_vec_named(&pk).expect("ser pk");
1851
                let sig_ser =
1852
                    rmp_serde::encode::to_vec_named(&sig).expect("ser sig");
1853
                let pk_des: PublicKey =
1854
                    rmp_serde::decode::from_slice(&pk_ser).expect("des pk");
1855
                let sig_des: Signature =
1856
                    rmp_serde::decode::from_slice(&sig_ser).expect("des sig");
1857
1858
                // check that we got back the right things
1859
                assert_eq!(pk, pk_des);
1860
                assert_eq!(sig, sig_des);
1861
                assert_eq!(
1862
                    sig.verify(true, b"asdf", b"qwer", b"zxcv", &pk_des, true),
1863
                    BLST_ERROR::BLST_SUCCESS
1864
                );
1865
                assert_eq!(
1866
                    sig_des.verify(true, b"asdf", b"qwer", b"zxcv", &pk, true),
1867
                    BLST_ERROR::BLST_SUCCESS
1868
                );
1869
                assert_eq!(sk.sign(b"asdf", b"qwer", b"zxcv"), sig_des);
1870
1871
                #[cfg(feature = "serde-secret")]
1872
                if true {
1873
                    let sk_ser =
1874
                        rmp_serde::encode::to_vec_named(&sk).expect("ser sk");
1875
                    let sk_des: SecretKey =
1876
                        rmp_serde::decode::from_slice(&sk_ser).expect("des sk");
1877
                    // BLS signatures are deterministic, so this establishes
1878
                    // that sk == sk_des
1879
                    assert_eq!(sk_des.sign(b"asdf", b"qwer", b"zxcv"), sig);
1880
                }
1881
            }
1882
        }
1883
    };
1884
}
1885
1886
pub mod min_pk {
1887
    use super::*;
1888
1889
    sig_variant_impl!(
1890
        "MinPk",
1891
        blst_p1,
1892
        blst_p1_affine,
1893
        blst_p2,
1894
        blst_p2_affine,
1895
        blst_sk_to_pk2_in_g1,
1896
        true,
1897
        blst_hash_to_g2,
1898
        blst_sign_pk2_in_g1,
1899
        blst_p1_affine_is_equal,
1900
        blst_p2_affine_is_equal,
1901
        blst_core_verify_pk_in_g1,
1902
        blst_p1_affine_in_g1,
1903
        blst_p1_to_affine,
1904
        blst_p1_from_affine,
1905
        blst_p1_affine_serialize,
1906
        blst_p1_affine_compress,
1907
        blst_p1_deserialize,
1908
        blst_p1_uncompress,
1909
        48,
1910
        96,
1911
        blst_p2_affine_in_g2,
1912
        blst_p2_to_affine,
1913
        blst_p2_from_affine,
1914
        blst_p2_affine_serialize,
1915
        blst_p2_affine_compress,
1916
        blst_p2_deserialize,
1917
        blst_p2_uncompress,
1918
        96,
1919
        192,
1920
        blst_p1_add_or_double,
1921
        blst_p1_add_or_double_affine,
1922
        blst_p2_add_or_double,
1923
        blst_p2_add_or_double_affine,
1924
        blst_p1_affine_is_inf,
1925
        blst_p2_affine_is_inf,
1926
        blst_p2_in_g2,
1927
    );
1928
}
1929
1930
pub mod min_sig {
1931
    use super::*;
1932
1933
    sig_variant_impl!(
1934
        "MinSig",
1935
        blst_p2,
1936
        blst_p2_affine,
1937
        blst_p1,
1938
        blst_p1_affine,
1939
        blst_sk_to_pk2_in_g2,
1940
        true,
1941
        blst_hash_to_g1,
1942
        blst_sign_pk2_in_g2,
1943
        blst_p2_affine_is_equal,
1944
        blst_p1_affine_is_equal,
1945
        blst_core_verify_pk_in_g2,
1946
        blst_p2_affine_in_g2,
1947
        blst_p2_to_affine,
1948
        blst_p2_from_affine,
1949
        blst_p2_affine_serialize,
1950
        blst_p2_affine_compress,
1951
        blst_p2_deserialize,
1952
        blst_p2_uncompress,
1953
        96,
1954
        192,
1955
        blst_p1_affine_in_g1,
1956
        blst_p1_to_affine,
1957
        blst_p1_from_affine,
1958
        blst_p1_affine_serialize,
1959
        blst_p1_affine_compress,
1960
        blst_p1_deserialize,
1961
        blst_p1_uncompress,
1962
        48,
1963
        96,
1964
        blst_p2_add_or_double,
1965
        blst_p2_add_or_double_affine,
1966
        blst_p1_add_or_double,
1967
        blst_p1_add_or_double_affine,
1968
        blst_p2_affine_is_inf,
1969
        blst_p1_affine_is_inf,
1970
        blst_p1_in_g1,
1971
    );
1972
}
1973
1974
pub trait MultiPoint {
1975
    type Output;
1976
1977
    fn mult(&self, scalars: &[u8], nbits: usize) -> Self::Output;
1978
    fn add(&self) -> Self::Output;
1979
}
1980
1981
#[cfg(feature = "std")]
1982
include!("pippenger.rs");
1983
1984
#[cfg(not(feature = "std"))]
1985
include!("pippenger-no_std.rs");
1986
1987
#[cfg(test)]
1988
mod fp12_test {
1989
    use super::*;
1990
    use rand::{RngCore, SeedableRng};
1991
    use rand_chacha::ChaCha20Rng;
1992
1993
    #[test]
1994
    fn miller_loop_n() {
1995
        const npoints: usize = 97;
1996
        const nbits: usize = 64;
1997
        const nbytes: usize = (nbits + 7) / 8;
1998
1999
        let mut scalars = Box::new([0u8; nbytes * npoints]);
2000
        ChaCha20Rng::from_entropy().fill_bytes(scalars.as_mut());
2001
2002
        let mut p1s: Vec<blst_p1> = Vec::with_capacity(npoints);
2003
        let mut p2s: Vec<blst_p2> = Vec::with_capacity(npoints);
2004
2005
        unsafe {
2006
            p1s.set_len(npoints);
2007
            p2s.set_len(npoints);
2008
2009
            for i in 0..npoints {
2010
                blst_p1_mult(
2011
                    &mut p1s[i],
2012
                    blst_p1_generator(),
2013
                    &scalars[i * nbytes],
2014
                    32,
2015
                );
2016
                blst_p2_mult(
2017
                    &mut p2s[i],
2018
                    blst_p2_generator(),
2019
                    &scalars[i * nbytes + 4],
2020
                    32,
2021
                );
2022
            }
2023
        }
2024
2025
        let ps = p1_affines::from(&p1s);
2026
        let qs = p2_affines::from(&p2s);
2027
2028
        let mut naive = blst_fp12::default();
2029
        for i in 0..npoints {
2030
            naive *= blst_fp12::miller_loop(&qs[i], &ps[i]);
2031
        }
2032
2033
        assert_eq!(
2034
            naive,
2035
            blst_fp12::miller_loop_n(qs.as_slice(), ps.as_slice())
2036
        );
2037
    }
2038
}
2039
2040
#[cfg(test)]
2041
mod sk_test {
2042
    use super::*;
2043
    use rand::{RngCore, SeedableRng};
2044
    use rand_chacha::ChaCha20Rng;
2045
2046
    #[test]
2047
    fn inverse() {
2048
        let mut bytes = [0u8; 64];
2049
        ChaCha20Rng::from_entropy().fill_bytes(bytes.as_mut());
2050
2051
        let mut sk = blst_scalar::default();
2052
        let mut p1 = blst_p1::default();
2053
        let mut p2 = blst_p2::default();
2054
2055
        unsafe {
2056
            blst_scalar_from_be_bytes(&mut sk, bytes.as_ptr(), bytes.len());
2057
2058
            blst_p1_mult(&mut p1, blst_p1_generator(), sk.b.as_ptr(), 255);
2059
            blst_sk_inverse(&mut sk, &sk);
2060
            blst_p1_mult(&mut p1, &p1, sk.b.as_ptr(), 255);
2061
2062
            blst_p2_mult(&mut p2, blst_p2_generator(), sk.b.as_ptr(), 255);
2063
            blst_sk_inverse(&mut sk, &sk);
2064
            blst_p2_mult(&mut p2, &p2, sk.b.as_ptr(), 255);
2065
        }
2066
2067
        assert_eq!(p1, unsafe { *blst_p1_generator() });
2068
        assert_eq!(p2, unsafe { *blst_p2_generator() });
2069
    }
2070
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/blst-0.3.12/src/pippenger.rs
Line
Count
Source
1
// Copyright Supranational LLC
2
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3
// SPDX-License-Identifier: Apache-2.0
4
5
use core::num::Wrapping;
6
use core::ops::{Index, IndexMut};
7
use core::slice::SliceIndex;
8
use std::sync::Barrier;
9
10
struct tile {
11
    x: usize,
12
    dx: usize,
13
    y: usize,
14
    dy: usize,
15
}
16
17
// Minimalist core::cell::Cell stand-in, but with Sync marker, which
18
// makes it possible to pass it to multiple threads. It works, because
19
// *here* each Cell is written only once and by just one thread.
20
#[repr(transparent)]
21
struct Cell<T: ?Sized> {
22
    value: T,
23
}
24
unsafe impl<T: ?Sized + Sync> Sync for Cell<T> {}
25
impl<T> Cell<T> {
26
0
    pub fn as_ptr(&self) -> *mut T {
27
0
        &self.value as *const T as *mut T
28
0
    }
Unexecuted instantiation: _RNvMs1k_CscC7OSmV1s5f_4blstINtB6_4CellNtB6_7blst_p1E6as_ptrB6_
Unexecuted instantiation: _RNvMs1k_CscC7OSmV1s5f_4blstINtB6_4CellNtB6_7blst_p2E6as_ptrB6_
29
}
30
31
macro_rules! pippenger_mult_impl {
32
    (
33
        $points:ident,
34
        $point:ty,
35
        $point_affine:ty,
36
        $to_affines:ident,
37
        $scratch_sizeof:ident,
38
        $multi_scalar_mult:ident,
39
        $tile_mult:ident,
40
        $add_or_double:ident,
41
        $double:ident,
42
        $test_mod:ident,
43
        $generator:ident,
44
        $mult:ident,
45
        $add:ident,
46
    ) => {
47
        pub struct $points {
48
            points: Vec<$point_affine>,
49
        }
50
51
        impl<I: SliceIndex<[$point_affine]>> Index<I> for $points {
52
            type Output = I::Output;
53
54
            #[inline]
55
0
            fn index(&self, i: I) -> &Self::Output {
56
0
                &self.points[i]
57
0
            }
Unexecuted instantiation: _RNvXINICscC7OSmV1s5f_4blsts1l_0pENtB5_10p1_affinesINtNtNtCsbQ8arDwx5Xq_4core3ops5index5IndexpE5indexB5_
Unexecuted instantiation: _RNvXINICscC7OSmV1s5f_4blsts1p_0pENtB5_10p2_affinesINtNtNtCsbQ8arDwx5Xq_4core3ops5index5IndexpE5indexB5_
58
        }
59
        impl<I: SliceIndex<[$point_affine]>> IndexMut<I> for $points {
60
            #[inline]
61
0
            fn index_mut(&mut self, i: I) -> &mut Self::Output {
62
0
                &mut self.points[i]
63
0
            }
Unexecuted instantiation: _RNvXINICscC7OSmV1s5f_4blsts1m_0pENtB5_10p1_affinesINtNtNtCsbQ8arDwx5Xq_4core3ops5index8IndexMutpE9index_mutB5_
Unexecuted instantiation: _RNvXINICscC7OSmV1s5f_4blsts1q_0pENtB5_10p2_affinesINtNtNtCsbQ8arDwx5Xq_4core3ops5index8IndexMutpE9index_mutB5_
64
        }
65
66
        impl $points {
67
            #[inline]
68
0
            pub fn as_slice(&self) -> &[$point_affine] {
69
0
                self.points.as_slice()
70
0
            }
Unexecuted instantiation: _RNvMs1n_CscC7OSmV1s5f_4blstNtB6_10p1_affines8as_sliceB6_
Unexecuted instantiation: _RNvMs1r_CscC7OSmV1s5f_4blstNtB6_10p2_affines8as_sliceB6_
71
72
0
            pub fn from(points: &[$point]) -> Self {
73
0
                let npoints = points.len();
74
0
                let mut ret = Self {
75
0
                    points: Vec::with_capacity(npoints),
76
0
                };
77
0
                unsafe { ret.points.set_len(npoints) };
78
0
79
0
                let pool = mt::da_pool();
80
0
                let ncpus = pool.max_count();
81
0
                if ncpus < 2 || npoints < 768 {
82
0
                    let p: [*const $point; 2] = [&points[0], ptr::null()];
83
0
                    unsafe { $to_affines(&mut ret.points[0], &p[0], npoints) };
84
0
                    return ret;
85
0
                }
86
0
87
0
                let mut nslices = (npoints + 511) / 512;
88
0
                nslices = core::cmp::min(nslices, ncpus);
89
0
                let wg = Arc::new((Barrier::new(2), AtomicUsize::new(nslices)));
90
0
91
0
                let (mut delta, mut rem) =
92
0
                    (npoints / nslices + 1, Wrapping(npoints % nslices));
93
0
                let mut x = 0usize;
94
0
                while x < npoints {
95
0
                    let out = &mut ret.points[x];
96
0
                    let inp = &points[x];
97
0
98
0
                    delta -= (rem == Wrapping(0)) as usize;
99
0
                    rem -= Wrapping(1);
100
0
                    x += delta;
101
0
102
0
                    let wg = wg.clone();
103
0
                    pool.joined_execute(move || {
104
0
                        let p: [*const $point; 2] = [inp, ptr::null()];
105
0
                        unsafe { $to_affines(out, &p[0], delta) };
106
0
                        if wg.1.fetch_sub(1, Ordering::AcqRel) == 1 {
107
0
                            wg.0.wait();
108
0
                        }
109
0
                    });
Unexecuted instantiation: _RNCNvMs1n_CscC7OSmV1s5f_4blstNtB8_10p1_affines4from0B8_
Unexecuted instantiation: _RNCNvMs1r_CscC7OSmV1s5f_4blstNtB8_10p2_affines4from0B8_
110
0
                }
111
0
                wg.0.wait();
112
0
113
0
                ret
114
0
            }
Unexecuted instantiation: _RNvMs1n_CscC7OSmV1s5f_4blstNtB6_10p1_affines4from
Unexecuted instantiation: _RNvMs1r_CscC7OSmV1s5f_4blstNtB6_10p2_affines4from
115
116
            #[inline]
117
0
            pub fn mult(&self, scalars: &[u8], nbits: usize) -> $point {
118
0
                self.as_slice().mult(scalars, nbits)
119
0
            }
Unexecuted instantiation: _RNvMs1n_CscC7OSmV1s5f_4blstNtB6_10p1_affines4multB6_
Unexecuted instantiation: _RNvMs1r_CscC7OSmV1s5f_4blstNtB6_10p2_affines4multB6_
120
121
            #[inline]
122
0
            pub fn add(&self) -> $point {
123
0
                self.as_slice().add()
124
0
            }
Unexecuted instantiation: _RNvMs1n_CscC7OSmV1s5f_4blstNtB6_10p1_affines3addB6_
Unexecuted instantiation: _RNvMs1r_CscC7OSmV1s5f_4blstNtB6_10p2_affines3addB6_
125
        }
126
127
        impl MultiPoint for [$point_affine] {
128
            type Output = $point;
129
130
0
            fn mult(&self, scalars: &[u8], nbits: usize) -> $point {
131
0
                let npoints = self.len();
132
0
                let nbytes = (nbits + 7) / 8;
133
0
134
0
                if scalars.len() < nbytes * npoints {
135
0
                    panic!("scalars length mismatch");
136
0
                }
137
0
138
0
                let pool = mt::da_pool();
139
0
                let ncpus = pool.max_count();
140
0
                if ncpus < 2 || npoints < 32 {
141
0
                    let p: [*const $point_affine; 2] = [&self[0], ptr::null()];
142
0
                    let s: [*const u8; 2] = [&scalars[0], ptr::null()];
143
0
144
0
                    unsafe {
145
0
                        let mut scratch: Vec<u64> =
146
0
                            Vec::with_capacity($scratch_sizeof(npoints) / 8);
147
0
                        #[allow(clippy::uninit_vec)]
148
0
                        scratch.set_len(scratch.capacity());
149
0
                        let mut ret = <$point>::default();
150
0
                        $multi_scalar_mult(
151
0
                            &mut ret,
152
0
                            &p[0],
153
0
                            npoints,
154
0
                            &s[0],
155
0
                            nbits,
156
0
                            &mut scratch[0],
157
0
                        );
158
0
                        return ret;
159
                    }
160
0
                }
161
0
162
0
                let (nx, ny, window) =
163
0
                    breakdown(nbits, pippenger_window_size(npoints), ncpus);
164
0
165
0
                // |grid[]| holds "coordinates" and place for result
166
0
                let mut grid: Vec<(tile, Cell<$point>)> =
167
0
                    Vec::with_capacity(nx * ny);
168
0
                #[allow(clippy::uninit_vec)]
169
0
                unsafe { grid.set_len(grid.capacity()) };
170
0
                let dx = npoints / nx;
171
0
                let mut y = window * (ny - 1);
172
0
                let mut total = 0usize;
173
174
0
                while total < nx {
175
0
                    grid[total].0.x = total * dx;
176
0
                    grid[total].0.dx = dx;
177
0
                    grid[total].0.y = y;
178
0
                    grid[total].0.dy = nbits - y;
179
0
                    total += 1;
180
0
                }
181
0
                grid[total - 1].0.dx = npoints - grid[total - 1].0.x;
182
0
                while y != 0 {
183
0
                    y -= window;
184
0
                    for i in 0..nx {
185
0
                        grid[total].0.x = grid[i].0.x;
186
0
                        grid[total].0.dx = grid[i].0.dx;
187
0
                        grid[total].0.y = y;
188
0
                        grid[total].0.dy = window;
189
0
                        total += 1;
190
0
                    }
191
                }
192
0
                let grid = &grid[..];
193
0
194
0
                let points = &self[..];
195
0
                let sz = unsafe { $scratch_sizeof(0) / 8 };
196
0
197
0
                let mut row_sync: Vec<AtomicUsize> = Vec::with_capacity(ny);
198
0
                row_sync.resize_with(ny, Default::default);
199
0
                let row_sync = Arc::new(row_sync);
200
0
                let counter = Arc::new(AtomicUsize::new(0));
201
0
                let (tx, rx) = channel();
202
0
                let n_workers = core::cmp::min(ncpus, total);
203
0
                for _ in 0..n_workers {
204
0
                    let tx = tx.clone();
205
0
                    let counter = counter.clone();
206
0
                    let row_sync = row_sync.clone();
207
0
208
0
                    pool.joined_execute(move || {
209
0
                        let mut scratch = vec![0u64; sz << (window - 1)];
210
0
                        let mut p: [*const $point_affine; 2] =
211
0
                            [ptr::null(), ptr::null()];
212
0
                        let mut s: [*const u8; 2] = [ptr::null(), ptr::null()];
213
214
                        loop {
215
0
                            let work = counter.fetch_add(1, Ordering::Relaxed);
216
0
                            if work >= total {
217
0
                                break;
218
0
                            }
219
0
                            let x = grid[work].0.x;
220
0
                            let y = grid[work].0.y;
221
0
222
0
                            p[0] = &points[x];
223
0
                            s[0] = &scalars[x * nbytes];
224
0
                            unsafe {
225
0
                                $tile_mult(
226
0
                                    grid[work].1.as_ptr(),
227
0
                                    &p[0],
228
0
                                    grid[work].0.dx,
229
0
                                    &s[0],
230
0
                                    nbits,
231
0
                                    &mut scratch[0],
232
0
                                    y,
233
0
                                    window,
234
0
                                );
235
0
                            }
236
0
                            if row_sync[y / window]
237
0
                                .fetch_add(1, Ordering::AcqRel)
238
0
                                == nx - 1
239
0
                            {
240
0
                                tx.send(y).expect("disaster");
241
0
                            }
242
                        }
243
0
                    });
Unexecuted instantiation: _RNCNvXs1o_CscC7OSmV1s5f_4blstSNtB8_14blst_p1_affineNtB8_10MultiPoint4mult0B8_
Unexecuted instantiation: _RNCNvXs1s_CscC7OSmV1s5f_4blstSNtB8_14blst_p2_affineNtB8_10MultiPoint4mult0B8_
244
0
                }
245
246
0
                let mut ret = <$point>::default();
247
0
                let mut rows = vec![false; ny];
248
0
                let mut row = 0usize;
249
0
                for _ in 0..ny {
250
0
                    let mut y = rx.recv().unwrap();
251
0
                    rows[y / window] = true;
252
0
                    while grid[row].0.y == y {
253
0
                        while row < total && grid[row].0.y == y {
254
0
                            unsafe {
255
0
                                $add_or_double(
256
0
                                    &mut ret,
257
0
                                    &ret,
258
0
                                    grid[row].1.as_ptr(),
259
0
                                );
260
0
                            }
261
0
                            row += 1;
262
0
                        }
263
0
                        if y == 0 {
264
0
                            break;
265
0
                        }
266
0
                        for _ in 0..window {
267
0
                            unsafe { $double(&mut ret, &ret) };
268
0
                        }
269
0
                        y -= window;
270
0
                        if !rows[y / window] {
271
0
                            break;
272
0
                        }
273
                    }
274
                }
275
0
                ret
276
0
            }
Unexecuted instantiation: _RNvXs1o_CscC7OSmV1s5f_4blstSNtB6_14blst_p1_affineNtB6_10MultiPoint4mult
Unexecuted instantiation: _RNvXs1s_CscC7OSmV1s5f_4blstSNtB6_14blst_p2_affineNtB6_10MultiPoint4mult
277
278
0
            fn add(&self) -> $point {
279
0
                let npoints = self.len();
280
0
281
0
                let pool = mt::da_pool();
282
0
                let ncpus = pool.max_count();
283
0
                if ncpus < 2 || npoints < 384 {
284
0
                    let p: [*const _; 2] = [&self[0], ptr::null()];
285
0
                    let mut ret = <$point>::default();
286
0
                    unsafe { $add(&mut ret, &p[0], npoints) };
287
0
                    return ret;
288
0
                }
289
0
290
0
                let (tx, rx) = channel();
291
0
                let counter = Arc::new(AtomicUsize::new(0));
292
0
                let nchunks = (npoints + 255) / 256;
293
0
                let chunk = npoints / nchunks + 1;
294
0
295
0
                let n_workers = core::cmp::min(ncpus, nchunks);
296
0
                for _ in 0..n_workers {
297
0
                    let tx = tx.clone();
298
0
                    let counter = counter.clone();
299
0
300
0
                    pool.joined_execute(move || {
301
0
                        let mut acc = <$point>::default();
302
0
                        let mut chunk = chunk;
303
0
                        let mut p: [*const _; 2] = [ptr::null(), ptr::null()];
304
305
                        loop {
306
0
                            let work =
307
0
                                counter.fetch_add(chunk, Ordering::Relaxed);
308
0
                            if work >= npoints {
309
0
                                break;
310
0
                            }
311
0
                            p[0] = &self[work];
312
0
                            if work + chunk > npoints {
313
0
                                chunk = npoints - work;
314
0
                            }
315
0
                            unsafe {
316
0
                                let mut t = MaybeUninit::<$point>::uninit();
317
0
                                $add(t.as_mut_ptr(), &p[0], chunk);
318
0
                                $add_or_double(&mut acc, &acc, t.as_ptr());
319
0
                            };
320
                        }
321
0
                        tx.send(acc).expect("disaster");
322
0
                    });
Unexecuted instantiation: _RNCNvXs1o_CscC7OSmV1s5f_4blstSNtB8_14blst_p1_affineNtB8_10MultiPoint3add0B8_
Unexecuted instantiation: _RNCNvXs1s_CscC7OSmV1s5f_4blstSNtB8_14blst_p2_affineNtB8_10MultiPoint3add0B8_
323
0
                }
324
325
0
                let mut ret = rx.recv().unwrap();
326
0
                for _ in 1..n_workers {
327
0
                    unsafe {
328
0
                        $add_or_double(&mut ret, &ret, &rx.recv().unwrap())
329
0
                    };
330
0
                }
331
332
0
                ret
333
0
            }
Unexecuted instantiation: _RNvXs1o_CscC7OSmV1s5f_4blstSNtB6_14blst_p1_affineNtB6_10MultiPoint3add
Unexecuted instantiation: _RNvXs1s_CscC7OSmV1s5f_4blstSNtB6_14blst_p2_affineNtB6_10MultiPoint3add
334
        }
335
336
        #[cfg(test)]
337
        pippenger_test_mod!(
338
            $test_mod,
339
            $points,
340
            $point,
341
            $add_or_double,
342
            $generator,
343
            $mult,
344
        );
345
    };
346
}
347
348
#[cfg(test)]
349
include!("pippenger-test_mod.rs");
350
351
pippenger_mult_impl!(
352
    p1_affines,
353
    blst_p1,
354
    blst_p1_affine,
355
    blst_p1s_to_affine,
356
    blst_p1s_mult_pippenger_scratch_sizeof,
357
    blst_p1s_mult_pippenger,
358
    blst_p1s_tile_pippenger,
359
    blst_p1_add_or_double,
360
    blst_p1_double,
361
    p1_multi_point,
362
    blst_p1_generator,
363
    blst_p1_mult,
364
    blst_p1s_add,
365
);
366
367
pippenger_mult_impl!(
368
    p2_affines,
369
    blst_p2,
370
    blst_p2_affine,
371
    blst_p2s_to_affine,
372
    blst_p2s_mult_pippenger_scratch_sizeof,
373
    blst_p2s_mult_pippenger,
374
    blst_p2s_tile_pippenger,
375
    blst_p2_add_or_double,
376
    blst_p2_double,
377
    p2_multi_point,
378
    blst_p2_generator,
379
    blst_p2_mult,
380
    blst_p2s_add,
381
);
382
383
0
fn num_bits(l: usize) -> usize {
384
0
    8 * core::mem::size_of_val(&l) - l.leading_zeros() as usize
385
0
}
386
387
0
fn breakdown(
388
0
    nbits: usize,
389
0
    window: usize,
390
0
    ncpus: usize,
391
0
) -> (usize, usize, usize) {
392
0
    let mut nx: usize;
393
0
    let mut wnd: usize;
394
0
395
0
    if nbits > window * ncpus {
396
0
        nx = 1;
397
0
        wnd = num_bits(ncpus / 4);
398
0
        if (window + wnd) > 18 {
399
0
            wnd = window - wnd;
400
0
        } else {
401
0
            wnd = (nbits / window + ncpus - 1) / ncpus;
402
0
            if (nbits / (window + 1) + ncpus - 1) / ncpus < wnd {
403
0
                wnd = window + 1;
404
0
            } else {
405
0
                wnd = window;
406
0
            }
407
        }
408
    } else {
409
0
        nx = 2;
410
0
        wnd = window - 2;
411
0
        while (nbits / wnd + 1) * nx < ncpus {
412
0
            nx += 1;
413
0
            wnd = window - num_bits(3 * nx / 2);
414
0
        }
415
0
        nx -= 1;
416
0
        wnd = window - num_bits(3 * nx / 2);
417
    }
418
0
    let ny = nbits / wnd + 1;
419
0
    wnd = nbits / ny + 1;
420
0
421
0
    (nx, ny, wnd)
422
0
}
423
424
0
fn pippenger_window_size(npoints: usize) -> usize {
425
0
    let wbits = num_bits(npoints);
426
0
427
0
    if wbits > 13 {
428
0
        return wbits - 4;
429
0
    }
430
0
    if wbits > 5 {
431
0
        return wbits - 3;
432
0
    }
433
0
    2
434
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chia-bls-0.10.0/src/bls_cache.rs
Line
Count
Source
1
use std::borrow::Borrow;
2
use std::num::NonZeroUsize;
3
4
use lru::LruCache;
5
use sha2::{Digest, Sha256};
6
7
use crate::{aggregate_verify_gt, hash_to_g2};
8
use crate::{GTElement, PublicKey, Signature};
9
10
/// This is a cache of pairings of public keys and their corresponding message.
11
/// It accelerates aggregate verification when some public keys have already
12
/// been paired, and found in the cache.
13
/// We use it to cache pairings when validating transactions inserted into the
14
/// mempool, as many of those transactions are likely to show up in a full block
15
/// later. This makes it a lot cheaper to validate the full block.
16
/// However, validating a signature where we have no cached GT elements, the
17
/// aggregate_verify() primitive is faster. When long-syncing, that's
18
/// preferable.
19
#[cfg_attr(feature = "py-bindings", pyo3::pyclass(name = "BLSCache"))]
20
#[derive(Debug, Clone)]
21
pub struct BlsCache {
22
    // sha256(pubkey + message) -> GTElement
23
    cache: LruCache<[u8; 32], GTElement>,
24
}
25
26
impl Default for BlsCache {
27
0
    fn default() -> Self {
28
0
        Self::new(NonZeroUsize::new(50000).unwrap())
29
0
    }
30
}
31
32
impl BlsCache {
33
0
    pub fn new(cache_size: NonZeroUsize) -> Self {
34
0
        Self {
35
0
            cache: LruCache::new(cache_size),
36
0
        }
37
0
    }
38
39
0
    pub fn len(&self) -> usize {
40
0
        self.cache.len()
41
0
    }
42
43
0
    pub fn is_empty(&self) -> bool {
44
0
        self.cache.is_empty()
45
0
    }
46
47
0
    pub fn aggregate_verify(
48
0
        &mut self,
49
0
        pks: impl IntoIterator<Item = impl Borrow<PublicKey>>,
50
0
        msgs: impl IntoIterator<Item = impl AsRef<[u8]>>,
51
0
        sig: &Signature,
52
0
    ) -> bool {
53
0
        let iter = pks.into_iter().zip(msgs).map(|(pk, msg)| -> GTElement {
54
0
            // Hash pubkey + message
55
0
            let mut hasher = Sha256::new();
56
0
            hasher.update(pk.borrow().to_bytes());
57
0
            hasher.update(msg.as_ref());
58
0
            let hash: [u8; 32] = hasher.finalize().into();
59
60
            // If the pairing is in the cache, we don't need to recalculate it.
61
0
            if let Some(pairing) = self.cache.get(&hash).cloned() {
62
0
                return pairing;
63
0
            }
64
0
65
0
            // Otherwise, we need to calculate the pairing and add it to the cache.
66
0
            let mut aug_msg = pk.borrow().to_bytes().to_vec();
67
0
            aug_msg.extend_from_slice(msg.as_ref());
68
0
            let aug_hash = hash_to_g2(&aug_msg);
69
0
70
0
            let mut hasher = Sha256::new();
71
0
            hasher.update(&aug_msg);
72
0
            let hash: [u8; 32] = hasher.finalize().into();
73
0
74
0
            let pairing = aug_hash.pair(pk.borrow());
75
0
            self.cache.put(hash, pairing.clone());
76
0
            pairing
77
0
        });
78
0
79
0
        aggregate_verify_gt(sig, iter)
80
0
    }
81
}
82
83
#[cfg(feature = "py-bindings")]
84
mod python {
85
    use super::*;
86
87
    use pyo3::{
88
        exceptions::PyValueError,
89
        pybacked::PyBackedBytes,
90
        pymethods,
91
        types::{PyAnyMethods, PyList},
92
        Bound, PyObject, PyResult,
93
    };
94
95
    #[pymethods]
96
    impl BlsCache {
97
        #[new]
98
        #[pyo3(signature = (size=None))]
99
        pub fn init(size: Option<u32>) -> PyResult<Self> {
100
            let Some(size) = size else {
101
                return Ok(Self::default());
102
            };
103
104
            let Some(size) = NonZeroUsize::new(size as usize) else {
105
                return Err(PyValueError::new_err(
106
                    "Cannot have a cache size less than one.",
107
                ));
108
            };
109
110
            Ok(Self::new(size))
111
        }
112
113
        #[pyo3(name = "aggregate_verify")]
114
        pub fn py_aggregate_verify(
115
            &mut self,
116
            pks: &Bound<'_, PyList>,
117
            msgs: &Bound<'_, PyList>,
118
            sig: &Signature,
119
        ) -> PyResult<bool> {
120
            let pks = pks
121
                .iter()?
122
                .map(|item| item?.extract())
123
                .collect::<PyResult<Vec<PublicKey>>>()?;
124
125
            let msgs = msgs
126
                .iter()?
127
                .map(|item| item?.extract())
128
                .collect::<PyResult<Vec<PyBackedBytes>>>()?;
129
130
            Ok(self.aggregate_verify(pks, msgs, sig))
131
        }
132
133
        #[pyo3(name = "len")]
134
        pub fn py_len(&self) -> PyResult<usize> {
135
            Ok(self.len())
136
        }
137
138
        #[pyo3(name = "items")]
139
        pub fn py_items(&self, py: pyo3::Python<'_>) -> PyResult<PyObject> {
140
            use pyo3::prelude::*;
141
            use pyo3::types::PyBytes;
142
            let ret = PyList::empty_bound(py);
143
            for (key, value) in &self.cache {
144
                ret.append((
145
                    PyBytes::new_bound(py, key),
146
                    PyBytes::new_bound(py, &value.to_bytes()),
147
                ))?;
148
            }
149
            Ok(ret.into())
150
        }
151
152
        #[pyo3(name = "update")]
153
        pub fn py_update(&mut self, other: &Bound<'_, PyList>) -> PyResult<()> {
154
            for item in other.borrow().iter()? {
155
                let (key, value): (Vec<u8>, Vec<u8>) = item?.extract()?;
156
                self.cache.put(
157
                    key.try_into()
158
                        .map_err(|_| PyValueError::new_err("invalid key"))?,
159
                    GTElement::from_bytes(
160
                        (&value[..])
161
                            .try_into()
162
                            .map_err(|_| PyValueError::new_err("invalid GTElement"))?,
163
                    ),
164
                );
165
            }
166
            Ok(())
167
        }
168
    }
169
}
170
171
#[cfg(test)]
172
pub mod tests {
173
    use super::*;
174
175
    use crate::sign;
176
    use crate::SecretKey;
177
178
    #[test]
179
    fn test_aggregate_verify() {
180
        let mut bls_cache = BlsCache::default();
181
182
        let sk = SecretKey::from_seed(&[0; 32]);
183
        let pk = sk.public_key();
184
        let msg = [106; 32];
185
186
        let sig = sign(&sk, msg);
187
        let pk_list = [pk];
188
        let msg_list = [msg];
189
190
        // Before we cache anything, it should be empty.
191
        assert!(bls_cache.is_empty());
192
193
        // Verify the signature and add to the cache.
194
        assert!(bls_cache.aggregate_verify(pk_list, msg_list, &sig));
195
        assert_eq!(bls_cache.len(), 1);
196
197
        // Now that it's cached, it shouldn't cache it again.
198
        assert!(bls_cache.aggregate_verify(pk_list, msg_list, &sig));
199
        assert_eq!(bls_cache.len(), 1);
200
    }
201
202
    #[test]
203
    fn test_cache() {
204
        let mut bls_cache = BlsCache::default();
205
206
        let sk1 = SecretKey::from_seed(&[0; 32]);
207
        let pk1 = sk1.public_key();
208
        let msg1 = [106; 32];
209
210
        let mut agg_sig = sign(&sk1, msg1);
211
        let mut pk_list = vec![pk1];
212
        let mut msg_list = vec![msg1];
213
214
        // Before we cache anything, it should be empty.
215
        assert!(bls_cache.is_empty());
216
217
        // Add the first signature to cache.
218
        assert!(bls_cache.aggregate_verify(&pk_list, &msg_list, &agg_sig));
219
        assert_eq!(bls_cache.len(), 1);
220
221
        // Try with the first key message pair in the cache but not the second.
222
        let sk2 = SecretKey::from_seed(&[1; 32]);
223
        let pk2 = sk2.public_key();
224
        let msg2 = [107; 32];
225
226
        agg_sig += &sign(&sk2, msg2);
227
        pk_list.push(pk2);
228
        msg_list.push(msg2);
229
230
        assert!(bls_cache.aggregate_verify(&pk_list, &msg_list, &agg_sig));
231
        assert_eq!(bls_cache.len(), 2);
232
233
        // Try reusing a public key.
234
        let msg3 = [108; 32];
235
236
        agg_sig += &sign(&sk2, msg3);
237
        pk_list.push(pk2);
238
        msg_list.push(msg3);
239
240
        // Verify this signature and add to the cache as well (since it's still a different aggregate).
241
        assert!(bls_cache.aggregate_verify(pk_list, msg_list, &agg_sig));
242
        assert_eq!(bls_cache.len(), 3);
243
    }
244
245
    #[test]
246
    fn test_cache_limit() {
247
        // The cache is limited to only 3 items.
248
        let mut bls_cache = BlsCache::new(NonZeroUsize::new(3).unwrap());
249
250
        // Before we cache anything, it should be empty.
251
        assert!(bls_cache.is_empty());
252
253
        // Create 5 pubkey message pairs.
254
        for i in 1..=5 {
255
            let sk = SecretKey::from_seed(&[i; 32]);
256
            let pk = sk.public_key();
257
            let msg = [106; 32];
258
259
            let sig = sign(&sk, msg);
260
            let pk_list = [pk];
261
            let msg_list = [msg];
262
263
            // Add to cache by validating them one at a time.
264
            assert!(bls_cache.aggregate_verify(pk_list.iter(), msg_list.iter(), &sig));
265
        }
266
267
        // The cache should be full now.
268
        assert_eq!(bls_cache.cache.len(), 3);
269
270
        // Recreate first key.
271
        let sk = SecretKey::from_seed(&[1; 32]);
272
        let pk = sk.public_key();
273
        let msg = [106; 32];
274
275
        let aug_msg = [&pk.to_bytes(), msg.as_ref()].concat();
276
277
        let mut hasher = Sha256::new();
278
        hasher.update(aug_msg);
279
        let hash: [u8; 32] = hasher.finalize().into();
280
281
        // The first key should have been removed, since it's the oldest that's been accessed.
282
        assert!(!bls_cache.cache.contains(&hash));
283
    }
284
285
    #[test]
286
    fn test_empty_sig() {
287
        let mut bls_cache = BlsCache::default();
288
289
        let pks: [&PublicKey; 0] = [];
290
        let msgs: [&[u8]; 0] = [];
291
292
        assert!(bls_cache.aggregate_verify(pks, msgs, &Signature::default()));
293
    }
294
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chia-bls-0.10.0/src/derive_keys.rs
Line
Count
Source
1
use crate::secret_key::SecretKey;
2
3
pub trait DerivableKey {
4
    #[must_use]
5
    fn derive_unhardened(&self, idx: u32) -> Self;
6
}
7
8
0
fn derive_path_unhardened<Key: DerivableKey>(key: &Key, path: &[u32]) -> Key {
9
0
    let mut derived = key.derive_unhardened(path[0]);
10
0
    for idx in &path[1..] {
11
0
        derived = derived.derive_unhardened(*idx);
12
0
    }
13
0
    derived
14
0
}
15
16
0
fn derive_path_hardened(key: &SecretKey, path: &[u32]) -> SecretKey {
17
0
    let mut derived = key.derive_hardened(path[0]);
18
0
    for idx in &path[1..] {
19
0
        derived = derived.derive_hardened(*idx);
20
0
    }
21
0
    derived
22
0
}
23
24
0
pub fn master_to_wallet_unhardened_intermediate<Key: DerivableKey>(key: &Key) -> Key {
25
0
    derive_path_unhardened(key, &[12381_u32, 8444, 2])
26
0
}
27
28
0
pub fn master_to_wallet_unhardened<Key: DerivableKey>(key: &Key, idx: u32) -> Key {
29
0
    derive_path_unhardened(key, &[12381_u32, 8444, 2, idx])
30
0
}
31
32
0
pub fn master_to_wallet_hardened_intermediate(key: &SecretKey) -> SecretKey {
33
0
    derive_path_hardened(key, &[12381_u32, 8444, 2])
34
0
}
35
36
0
pub fn master_to_wallet_hardened(key: &SecretKey, idx: u32) -> SecretKey {
37
0
    derive_path_hardened(key, &[12381_u32, 8444, 2, idx])
38
0
}
39
40
0
pub fn master_to_pool_singleton(key: &SecretKey, pool_wallet_idx: u32) -> SecretKey {
41
0
    derive_path_hardened(key, &[12381_u32, 8444, 5, pool_wallet_idx])
42
0
}
43
44
/// # Panics
45
///
46
/// Panics if `pool_wallet_idx` or `idx` is greater than or equal to 10000.
47
0
pub fn master_to_pool_authentication(key: &SecretKey, pool_wallet_idx: u32, idx: u32) -> SecretKey {
48
0
    assert!(pool_wallet_idx < 10000);
49
0
    assert!(idx < 10000);
50
0
    derive_path_hardened(key, &[12381_u32, 8444, 6, pool_wallet_idx * 10000 + idx])
51
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chia-bls-0.10.0/src/error.rs
Line
Count
Source
1
use blst::BLST_ERROR;
2
use thiserror::Error;
3
4
0
#[derive(Debug, Clone, PartialEq, Eq, Error)]
5
pub enum Error {
6
    #[error("SecretKey byte data must be less than the group order")]
7
    SecretKeyGroupOrder,
8
    #[error("Given G1 infinity element must be canonical")]
9
    G1NotCanonical,
10
    #[error("Given G1 non-infinity element must start with 0b10")]
11
    G1InfinityInvalidBits,
12
    #[error("G1 non-infinity element can't have only zeros")]
13
    G1InfinityNotZero,
14
    #[error("PublicKey is invalid (BLST ERROR: {0:?})")]
15
    InvalidPublicKey(BLST_ERROR),
16
    #[error("Signature is invalid (BLST ERROR: {0:?})")]
17
    InvalidSignature(BLST_ERROR),
18
}
19
20
pub type Result<T> = std::result::Result<T, Error>;
21
22
impl From<Error> for chia_traits::Error {
23
0
    fn from(err: Error) -> chia_traits::Error {
24
0
        chia_traits::Error::Custom(format!("{err}"))
25
0
    }
26
}
27
28
#[cfg(feature = "py-bindings")]
29
mod pybindings {
30
    use super::*;
31
32
    use pyo3::{exceptions::PyValueError, PyErr};
33
34
    impl From<Error> for PyErr {
35
        fn from(err: Error) -> PyErr {
36
            PyValueError::new_err(format!("BLS Error {err:?}"))
37
        }
38
    }
39
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chia-bls-0.10.0/src/gtelement.rs
Line
Count
Source
1
use blst::*;
2
use chia_traits::chia_error::Result;
3
use chia_traits::{read_bytes, Streamable};
4
use sha2::{Digest, Sha256};
5
use std::fmt;
6
use std::hash::{Hash, Hasher};
7
use std::io::Cursor;
8
use std::mem::MaybeUninit;
9
use std::ops::{Mul, MulAssign};
10
11
#[cfg_attr(
12
    feature = "py-bindings",
13
    pyo3::pyclass,
14
    derive(chia_py_streamable_macro::PyStreamable)
15
)]
16
#[derive(Clone)]
17
pub struct GTElement(pub(crate) blst_fp12);
18
19
impl GTElement {
20
    const SIZE: usize = std::mem::size_of::<blst_fp12>();
21
22
0
    pub fn from_bytes(bytes: &[u8; Self::SIZE]) -> Self {
23
0
        let gt = unsafe {
24
0
            let mut gt = MaybeUninit::<blst_fp12>::uninit();
25
0
            std::ptr::copy_nonoverlapping(bytes.as_ptr(), gt.as_mut_ptr().cast::<u8>(), Self::SIZE);
26
0
            gt.assume_init()
27
0
        };
28
0
        Self(gt)
29
0
    }
30
31
0
    pub fn to_bytes(&self) -> [u8; Self::SIZE] {
32
0
        unsafe {
33
0
            let mut bytes = MaybeUninit::<[u8; Self::SIZE]>::uninit();
34
0
            let buf: *const blst_fp12 = &self.0;
35
0
            std::ptr::copy_nonoverlapping(
36
0
                buf.cast::<u8>(),
37
0
                bytes.as_mut_ptr().cast::<u8>(),
38
0
                Self::SIZE,
39
0
            );
40
0
            bytes.assume_init()
41
0
        }
42
0
    }
43
}
44
45
impl PartialEq for GTElement {
46
0
    fn eq(&self, other: &Self) -> bool {
47
0
        unsafe { blst_fp12_is_equal(&self.0, &other.0) }
48
0
    }
49
}
50
impl Eq for GTElement {}
51
52
impl Hash for GTElement {
53
0
    fn hash<H: Hasher>(&self, state: &mut H) {
54
0
        state.write(&self.to_bytes());
55
0
    }
56
}
57
58
impl MulAssign<&GTElement> for GTElement {
59
0
    fn mul_assign(&mut self, rhs: &GTElement) {
60
0
        unsafe {
61
0
            blst_fp12_mul(&mut self.0, &self.0, &rhs.0);
62
0
        }
63
0
    }
64
}
65
66
impl Mul<&GTElement> for &GTElement {
67
    type Output = GTElement;
68
0
    fn mul(self, rhs: &GTElement) -> GTElement {
69
0
        let gt = unsafe {
70
0
            let mut gt = MaybeUninit::<blst_fp12>::uninit();
71
0
            blst_fp12_mul(gt.as_mut_ptr(), &self.0, &rhs.0);
72
0
            gt.assume_init()
73
0
        };
74
0
        GTElement(gt)
75
0
    }
76
}
77
78
impl fmt::Debug for GTElement {
79
0
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
80
0
        formatter.write_fmt(format_args!(
81
0
            "<GTElement {}>",
82
0
            &hex::encode(self.to_bytes())
83
0
        ))
84
0
    }
85
}
86
87
impl Streamable for GTElement {
88
0
    fn update_digest(&self, digest: &mut Sha256) {
89
0
        digest.update(self.to_bytes());
90
0
    }
91
92
0
    fn stream(&self, out: &mut Vec<u8>) -> Result<()> {
93
0
        out.extend_from_slice(&self.to_bytes());
94
0
        Ok(())
95
0
    }
96
97
0
    fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> Result<Self> {
98
0
        Ok(GTElement::from_bytes(
99
0
            read_bytes(input, Self::SIZE)?.try_into().unwrap(),
100
        ))
101
0
    }
Unexecuted instantiation: _RINvXs5_NtCs568wuOlRYFZ_8chia_bls9gtelementNtB6_9GTElementNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXs5_NtCs568wuOlRYFZ_8chia_bls9gtelementNtB6_9GTElementNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable5parseKb1_EB8_
102
}
103
104
#[cfg(feature = "py-bindings")]
105
mod pybindings {
106
    use super::*;
107
108
    use chia_traits::{FromJsonDict, ToJsonDict};
109
    use pyo3::{exceptions::PyValueError, prelude::*};
110
111
    #[pymethods]
112
    impl GTElement {
113
        #[classattr]
114
        #[pyo3(name = "SIZE")]
115
        const PY_SIZE: usize = Self::SIZE;
116
117
        fn __str__(&self) -> String {
118
            hex::encode(self.to_bytes())
119
        }
120
121
        #[must_use]
122
        pub fn __mul__(&self, rhs: &Self) -> Self {
123
            let mut ret = self.clone();
124
            ret *= rhs;
125
            ret
126
        }
127
128
        pub fn __imul__(&mut self, rhs: &Self) {
129
            *self *= rhs;
130
        }
131
    }
132
133
    impl ToJsonDict for GTElement {
134
        fn to_json_dict(&self, py: Python<'_>) -> PyResult<PyObject> {
135
            let bytes = self.to_bytes();
136
            Ok(hex::encode(bytes).into_py(py))
137
        }
138
    }
139
140
    impl FromJsonDict for GTElement {
141
        fn from_json_dict(o: &Bound<'_, PyAny>) -> PyResult<Self> {
142
            let s: String = o.extract()?;
143
            if !s.starts_with("0x") {
144
                return Err(PyValueError::new_err(
145
                    "bytes object is expected to start with 0x",
146
                ));
147
            }
148
            let s = &s[2..];
149
            let buf = match hex::decode(s) {
150
                Err(_) => {
151
                    return Err(PyValueError::new_err("invalid hex"));
152
                }
153
                Ok(v) => v,
154
            };
155
            if buf.len() != Self::SIZE {
156
                return Err(PyValueError::new_err(format!(
157
                    "GTElement, invalid length {} expected {}",
158
                    buf.len(),
159
                    Self::SIZE
160
                )));
161
            }
162
            Ok(Self::from_bytes(buf.as_slice().try_into().unwrap()))
163
        }
164
    }
165
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chia-bls-0.10.0/src/public_key.rs
Line
Count
Source
1
use crate::secret_key::is_all_zero;
2
use crate::{DerivableKey, Error, Result};
3
4
use blst::*;
5
use chia_traits::{read_bytes, Streamable};
6
use sha2::{digest::FixedOutput, Digest, Sha256};
7
use std::fmt;
8
use std::hash::{Hash, Hasher};
9
use std::io::Cursor;
10
use std::mem::MaybeUninit;
11
use std::ops::{Add, AddAssign, Neg, SubAssign};
12
13
#[cfg_attr(
14
    feature = "py-bindings",
15
    pyo3::pyclass(name = "G1Element"),
16
    derive(chia_py_streamable_macro::PyStreamable)
17
)]
18
#[derive(Clone, Copy, Default)]
19
pub struct PublicKey(pub(crate) blst_p1);
20
21
#[cfg(feature = "arbitrary")]
22
impl<'a> arbitrary::Arbitrary<'a> for PublicKey {
23
    fn arbitrary(_u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
24
        // placeholder
25
        Ok(Self::default())
26
    }
27
}
28
29
impl PublicKey {
30
36.5k
    pub fn from_bytes_unchecked(bytes: &[u8; 48]) -> Result<Self> {
31
36.5k
        // check if the element is canonical
32
36.5k
        // the first 3 bits have special meaning
33
36.5k
        let zeros_only = is_all_zero(&bytes[1..]);
34
36.5k
35
36.5k
        if (bytes[0] & 0xc0) == 0xc0 {
36
            // enforce that infinity must be 0xc0000..00
37
12.1k
            if bytes[0] != 0xc0 || !zeros_only {
38
72
                return Err(Error::G1NotCanonical);
39
12.0k
            }
40
12.0k
            // return infinity element (point all zero)
41
12.0k
            return Ok(Self::default());
42
24.4k
        }
43
24.4k
44
24.4k
        if (bytes[0] & 0xc0) != 0x80 {
45
10
            return Err(Error::G1InfinityInvalidBits);
46
24.3k
        }
47
24.3k
        if zeros_only {
48
10
            return Err(Error::G1InfinityNotZero);
49
24.3k
        }
50
51
24.3k
        let p1 = unsafe {
52
24.3k
            let mut p1_affine = MaybeUninit::<blst_p1_affine>::uninit();
53
24.3k
            let ret = blst_p1_uncompress(p1_affine.as_mut_ptr(), bytes.as_ptr());
54
24.3k
            if ret != BLST_ERROR::BLST_SUCCESS {
55
44
                return Err(Error::InvalidPublicKey(ret));
56
24.3k
            }
57
24.3k
            let mut p1 = MaybeUninit::<blst_p1>::uninit();
58
24.3k
            blst_p1_from_affine(p1.as_mut_ptr(), &p1_affine.assume_init());
59
24.3k
            p1.assume_init()
60
24.3k
        };
61
24.3k
        Ok(Self(p1))
62
36.5k
    }
63
64
0
    pub fn generator() -> Self {
65
0
        let p1 = unsafe { *blst_p1_generator() };
66
0
        Self(p1)
67
0
    }
68
69
    // Creates a G1 point by multiplying the generator by the specified scalar.
70
    // This is the same as creating a private key from the scalar, and then get
71
    // the corresponding public key
72
3.32k
    pub fn from_integer(int_bytes: &[u8]) -> Self {
73
3.32k
        let p1 = unsafe {
74
3.32k
            let mut scalar = MaybeUninit::<blst_scalar>::uninit();
75
3.32k
            blst_scalar_from_be_bytes(scalar.as_mut_ptr(), int_bytes.as_ptr(), int_bytes.len());
76
3.32k
            let mut p1 = MaybeUninit::<blst_p1>::uninit();
77
3.32k
            blst_p1_mult(
78
3.32k
                p1.as_mut_ptr(),
79
3.32k
                blst_p1_generator(),
80
3.32k
                scalar.as_ptr().cast::<u8>(),
81
3.32k
                256,
82
3.32k
            );
83
3.32k
            p1.assume_init()
84
3.32k
        };
85
3.32k
        Self(p1)
86
3.32k
    }
87
88
36.5k
    pub fn from_bytes(bytes: &[u8; 48]) -> Result<Self> {
89
36.5k
        let ret = Self::from_bytes_unchecked(bytes)?;
90
36.4k
        if ret.is_valid() {
91
36.3k
            Ok(ret)
92
        } else {
93
68
            Err(Error::InvalidPublicKey(BLST_ERROR::BLST_POINT_NOT_ON_CURVE))
94
        }
95
36.5k
    }
96
97
0
    pub fn from_uncompressed(buf: &[u8; 96]) -> Result<Self> {
98
0
        let p1 = unsafe {
99
0
            let mut p1_affine = MaybeUninit::<blst_p1_affine>::uninit();
100
0
            let ret = blst_p1_deserialize(p1_affine.as_mut_ptr(), buf.as_ptr());
101
0
            if ret != BLST_ERROR::BLST_SUCCESS {
102
0
                return Err(Error::InvalidSignature(ret));
103
0
            }
104
0
            let mut p1 = MaybeUninit::<blst_p1>::uninit();
105
0
            blst_p1_from_affine(p1.as_mut_ptr(), &p1_affine.assume_init());
106
0
            p1.assume_init()
107
0
        };
108
0
        Ok(Self(p1))
109
0
    }
110
111
32.3k
    pub fn to_bytes(&self) -> [u8; 48] {
112
32.3k
        unsafe {
113
32.3k
            let mut bytes = MaybeUninit::<[u8; 48]>::uninit();
114
32.3k
            blst_p1_compress(bytes.as_mut_ptr().cast::<u8>(), &self.0);
115
32.3k
            bytes.assume_init()
116
32.3k
        }
117
32.3k
    }
118
119
42.3k
    pub fn is_valid(&self) -> bool {
120
42.3k
        // Infinity was considered a valid G1Element in older Relic versions
121
42.3k
        // For historical compatibililty this behavior is maintained.
122
42.3k
        unsafe { blst_p1_is_inf(&self.0) || blst_p1_in_g1(&self.0) }
123
42.3k
    }
124
125
0
    pub fn is_inf(&self) -> bool {
126
0
        unsafe { blst_p1_is_inf(&self.0) }
127
0
    }
128
129
0
    pub fn negate(&mut self) {
130
0
        unsafe {
131
0
            blst_p1_cneg(&mut self.0, true);
132
0
        }
133
0
    }
134
135
5.37k
    pub fn scalar_multiply(&mut self, int_bytes: &[u8]) {
136
5.37k
        unsafe {
137
5.37k
            let mut scalar = MaybeUninit::<blst_scalar>::uninit();
138
5.37k
            blst_scalar_from_be_bytes(scalar.as_mut_ptr(), int_bytes.as_ptr(), int_bytes.len());
139
5.37k
            blst_p1_mult(&mut self.0, &self.0, scalar.as_ptr().cast::<u8>(), 256);
140
5.37k
        }
141
5.37k
    }
142
143
0
    pub fn get_fingerprint(&self) -> u32 {
144
0
        let mut hasher = Sha256::new();
145
0
        hasher.update(self.to_bytes());
146
0
        let hash: [u8; 32] = hasher.finalize_fixed().into();
147
0
        u32::from_be_bytes(hash[0..4].try_into().unwrap())
148
0
    }
149
}
150
151
impl PartialEq for PublicKey {
152
0
    fn eq(&self, other: &Self) -> bool {
153
0
        unsafe { blst_p1_is_equal(&self.0, &other.0) }
154
0
    }
155
}
156
impl Eq for PublicKey {}
157
158
impl Streamable for PublicKey {
159
0
    fn update_digest(&self, digest: &mut Sha256) {
160
0
        digest.update(self.to_bytes());
161
0
    }
162
163
0
    fn stream(&self, out: &mut Vec<u8>) -> chia_traits::Result<()> {
164
0
        out.extend_from_slice(&self.to_bytes());
165
0
        Ok(())
166
0
    }
167
168
0
    fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> chia_traits::Result<Self> {
169
0
        let input = read_bytes(input, 48)?.try_into().unwrap();
170
0
        if TRUSTED {
171
0
            Ok(Self::from_bytes_unchecked(input)?)
172
        } else {
173
0
            Ok(Self::from_bytes(input)?)
174
        }
175
0
    }
Unexecuted instantiation: _RINvXs1_NtCs568wuOlRYFZ_8chia_bls10public_keyNtB6_9PublicKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXs1_NtCs568wuOlRYFZ_8chia_bls10public_keyNtB6_9PublicKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable5parseKb1_EB8_
176
}
177
178
impl Hash for PublicKey {
179
0
    fn hash<H: Hasher>(&self, state: &mut H) {
180
0
        state.write(&self.to_bytes());
181
0
    }
182
}
183
184
impl Neg for PublicKey {
185
    type Output = PublicKey;
186
0
    fn neg(mut self) -> Self::Output {
187
0
        self.negate();
188
0
        self
189
0
    }
190
}
191
192
impl Neg for &PublicKey {
193
    type Output = PublicKey;
194
0
    fn neg(self) -> Self::Output {
195
0
        let mut ret = *self;
196
0
        ret.negate();
197
0
        ret
198
0
    }
199
}
200
201
impl AddAssign<&PublicKey> for PublicKey {
202
18.0k
    fn add_assign(&mut self, rhs: &PublicKey) {
203
18.0k
        unsafe {
204
18.0k
            blst_p1_add_or_double(&mut self.0, &self.0, &rhs.0);
205
18.0k
        }
206
18.0k
    }
207
}
208
209
impl SubAssign<&PublicKey> for PublicKey {
210
1.94k
    fn sub_assign(&mut self, rhs: &PublicKey) {
211
1.94k
        unsafe {
212
1.94k
            let mut neg = *rhs;
213
1.94k
            blst_p1_cneg(&mut neg.0, true);
214
1.94k
            blst_p1_add_or_double(&mut self.0, &self.0, &neg.0);
215
1.94k
        }
216
1.94k
    }
217
}
218
219
impl Add<&PublicKey> for &PublicKey {
220
    type Output = PublicKey;
221
0
    fn add(self, rhs: &PublicKey) -> PublicKey {
222
0
        let p1 = unsafe {
223
0
            let mut ret = MaybeUninit::<blst_p1>::uninit();
224
0
            blst_p1_add_or_double(ret.as_mut_ptr(), &self.0, &rhs.0);
225
0
            ret.assume_init()
226
0
        };
227
0
        PublicKey(p1)
228
0
    }
229
}
230
231
impl Add<&PublicKey> for PublicKey {
232
    type Output = PublicKey;
233
0
    fn add(mut self, rhs: &PublicKey) -> PublicKey {
234
0
        unsafe {
235
0
            blst_p1_add_or_double(&mut self.0, &self.0, &rhs.0);
236
0
            self
237
0
        }
238
0
    }
239
}
240
241
impl fmt::Debug for PublicKey {
242
0
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
243
0
        formatter.write_fmt(format_args!(
244
0
            "<G1Element {}>",
245
0
            &hex::encode(self.to_bytes())
246
0
        ))
247
0
    }
248
}
249
250
impl DerivableKey for PublicKey {
251
0
    fn derive_unhardened(&self, idx: u32) -> Self {
252
0
        let mut hasher = Sha256::new();
253
0
        hasher.update(self.to_bytes());
254
0
        hasher.update(idx.to_be_bytes());
255
0
        let digest: [u8; 32] = hasher.finalize_fixed().into();
256
0
257
0
        let p1 = unsafe {
258
0
            let mut nonce = MaybeUninit::<blst_scalar>::uninit();
259
0
            blst_scalar_from_lendian(nonce.as_mut_ptr(), digest.as_ptr());
260
0
            let mut bte = MaybeUninit::<[u8; 48]>::uninit();
261
0
            blst_bendian_from_scalar(bte.as_mut_ptr().cast::<u8>(), nonce.as_ptr());
262
0
            let mut p1 = MaybeUninit::<blst_p1>::uninit();
263
0
            blst_p1_mult(
264
0
                p1.as_mut_ptr(),
265
0
                blst_p1_generator(),
266
0
                bte.as_ptr().cast::<u8>(),
267
0
                256,
268
0
            );
269
0
            blst_p1_add(p1.as_mut_ptr(), p1.as_mut_ptr(), &self.0);
270
0
            p1.assume_init()
271
0
        };
272
0
        PublicKey(p1)
273
0
    }
274
}
275
276
pub const DST: &[u8] = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_";
277
278
0
pub fn hash_to_g1(msg: &[u8]) -> PublicKey {
279
0
    hash_to_g1_with_dst(msg, DST)
280
0
}
281
282
4.41k
pub fn hash_to_g1_with_dst(msg: &[u8], dst: &[u8]) -> PublicKey {
283
4.41k
    let p1 = unsafe {
284
4.41k
        let mut p1 = MaybeUninit::<blst_p1>::uninit();
285
4.41k
        blst_hash_to_g1(
286
4.41k
            p1.as_mut_ptr(),
287
4.41k
            msg.as_ptr(),
288
4.41k
            msg.len(),
289
4.41k
            dst.as_ptr(),
290
4.41k
            dst.len(),
291
4.41k
            std::ptr::null(),
292
4.41k
            0,
293
4.41k
        );
294
4.41k
        p1.assume_init()
295
4.41k
    };
296
4.41k
    PublicKey(p1)
297
4.41k
}
298
299
#[cfg(feature = "py-bindings")]
300
mod pybindings {
301
    use super::*;
302
303
    use crate::{parse_hex::parse_hex_string, GTElement, Signature};
304
305
    use chia_traits::{FromJsonDict, ToJsonDict};
306
    use pyo3::prelude::*;
307
308
    #[pymethods]
309
    impl PublicKey {
310
        #[classattr]
311
        const SIZE: usize = 48;
312
313
        #[new]
314
        pub fn init() -> Self {
315
            Self::default()
316
        }
317
318
        #[staticmethod]
319
        #[pyo3(name = "generator")]
320
        pub fn py_generator() -> Self {
321
            Self::generator()
322
        }
323
324
        pub fn pair(&self, other: &Signature) -> GTElement {
325
            other.pair(self)
326
        }
327
328
        #[pyo3(name = "get_fingerprint")]
329
        pub fn py_get_fingerprint(&self) -> u32 {
330
            self.get_fingerprint()
331
        }
332
333
        fn __str__(&self) -> String {
334
            hex::encode(self.to_bytes())
335
        }
336
337
        #[must_use]
338
        pub fn __add__(&self, rhs: &Self) -> Self {
339
            self + rhs
340
        }
341
342
        pub fn __iadd__(&mut self, rhs: &Self) {
343
            *self += rhs;
344
        }
345
    }
346
347
    impl ToJsonDict for PublicKey {
348
        fn to_json_dict(&self, py: Python<'_>) -> PyResult<PyObject> {
349
            let bytes = self.to_bytes();
350
            Ok(("0x".to_string() + &hex::encode(bytes)).into_py(py))
351
        }
352
    }
353
354
    impl FromJsonDict for PublicKey {
355
        fn from_json_dict(o: &Bound<'_, PyAny>) -> PyResult<Self> {
356
            Ok(Self::from_bytes(
357
                parse_hex_string(o, 48, "PublicKey")?
358
                    .as_slice()
359
                    .try_into()
360
                    .unwrap(),
361
            )?)
362
        }
363
    }
364
}
365
366
#[cfg(test)]
367
mod tests {
368
    use super::*;
369
    use crate::SecretKey;
370
    use hex::FromHex;
371
    use rand::rngs::StdRng;
372
    use rand::{Rng, SeedableRng};
373
    use rstest::rstest;
374
375
    #[test]
376
    fn test_derive_unhardened() {
377
        let sk_hex = "52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb";
378
        let sk = SecretKey::from_bytes(&<[u8; 32]>::from_hex(sk_hex).unwrap()).unwrap();
379
        let pk = sk.public_key();
380
381
        // make sure deriving the secret keys produce the same public keys as
382
        // deriving the public key
383
        for idx in 0..4_usize {
384
            let derived_sk = sk.derive_unhardened(idx as u32);
385
            let derived_pk = pk.derive_unhardened(idx as u32);
386
            assert_eq!(derived_pk.to_bytes(), derived_sk.public_key().to_bytes());
387
        }
388
    }
389
390
    #[test]
391
    fn test_from_bytes() {
392
        let mut rng = StdRng::seed_from_u64(1337);
393
        let mut data = [0u8; 48];
394
        for _i in 0..50 {
395
            rng.fill(data.as_mut_slice());
396
            // clear the bits that mean infinity
397
            data[0] = 0x80;
398
            // just any random bytes are not a valid key and should fail
399
            match PublicKey::from_bytes(&data) {
400
                Err(Error::InvalidPublicKey(err)) => {
401
                    assert!([
402
                        BLST_ERROR::BLST_BAD_ENCODING,
403
                        BLST_ERROR::BLST_POINT_NOT_ON_CURVE
404
                    ]
405
                    .contains(&err));
406
                }
407
                Err(e) => {
408
                    panic!("unexpected error from_bytes(): {e}");
409
                }
410
                Ok(v) => {
411
                    panic!("unexpected value from_bytes(): {v:?}");
412
                }
413
            }
414
        }
415
    }
416
417
    #[rstest]
418
    #[case("c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", Error::G1NotCanonical)]
419
    #[case("c08000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Error::G1NotCanonical)]
420
    #[case("c80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Error::G1NotCanonical)]
421
    #[case("e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Error::G1NotCanonical)]
422
    #[case("d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Error::G1NotCanonical)]
423
    #[case("800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Error::G1InfinityNotZero)]
424
    #[case("400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Error::G1InfinityInvalidBits)]
425
    fn test_from_bytes_failures(#[case] input: &str, #[case()] error: Error) {
426
        let bytes: [u8; 48] = hex::decode(input).unwrap().try_into().unwrap();
427
        assert_eq!(PublicKey::from_bytes(&bytes).unwrap_err(), error);
428
    }
429
430
    #[test]
431
    fn test_from_bytes_infinity() {
432
        let bytes: [u8; 48] = hex::decode("c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap().try_into().unwrap();
433
        let pk = PublicKey::from_bytes(&bytes).unwrap();
434
        assert_eq!(pk, PublicKey::default());
435
    }
436
437
    #[test]
438
    fn test_get_fingerprint() {
439
        let bytes: [u8; 48] = hex::decode("997cc43ed8788f841fcf3071f6f212b89ba494b6ebaf1bda88c3f9de9d968a61f3b7284a5ee13889399ca71a026549a2")
440
        .unwrap()
441
        .as_slice()
442
        .try_into()
443
        .unwrap();
444
        let pk = PublicKey::from_bytes(&bytes).unwrap();
445
        assert_eq!(pk.get_fingerprint(), 651_010_559);
446
    }
447
448
    #[test]
449
    fn test_aggregate_pubkey() {
450
        // from blspy import PrivateKey
451
        // from blspy import AugSchemeMPL
452
        // sk = PrivateKey.from_bytes(bytes.fromhex("52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb"))
453
        // pk = sk.get_g1()
454
        // pk + pk
455
        // <G1Element b1b8033286299e7f238aede0d3fea48d133a1e233139085f72c102c2e6cc1f8a4ea64ed2838c10bbd2ef8f78ef271bf3>
456
        // pk + pk + pk
457
        // <G1Element a8bc2047d90c04a12e8c38050ec0feb4417b4d5689165cd2cea8a7903aad1778e36548a46d427b5ec571364515e456d6>
458
459
        let sk_hex = "52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb";
460
        let sk = SecretKey::from_bytes(&<[u8; 32]>::from_hex(sk_hex).unwrap()).unwrap();
461
        let pk = sk.public_key();
462
        let pk2 = &pk + &pk;
463
        let pk3 = &pk + &pk + &pk;
464
465
        assert_eq!(pk2, PublicKey::from_bytes(&<[u8; 48]>::from_hex("b1b8033286299e7f238aede0d3fea48d133a1e233139085f72c102c2e6cc1f8a4ea64ed2838c10bbd2ef8f78ef271bf3").unwrap()).unwrap());
466
        assert_eq!(pk3, PublicKey::from_bytes(&<[u8; 48]>::from_hex("a8bc2047d90c04a12e8c38050ec0feb4417b4d5689165cd2cea8a7903aad1778e36548a46d427b5ec571364515e456d6").unwrap()).unwrap());
467
    }
468
469
    #[test]
470
    fn test_roundtrip() {
471
        let mut rng = StdRng::seed_from_u64(1337);
472
        let mut data = [0u8; 32];
473
        for _i in 0..50 {
474
            rng.fill(data.as_mut_slice());
475
            let sk = SecretKey::from_seed(&data);
476
            let pk = sk.public_key();
477
            let bytes = pk.to_bytes();
478
            let pk2 = PublicKey::from_bytes(&bytes).unwrap();
479
            assert_eq!(pk, pk2);
480
        }
481
    }
482
483
    #[test]
484
    fn test_default_is_valid() {
485
        let pk = PublicKey::default();
486
        assert!(pk.is_valid());
487
    }
488
489
    #[test]
490
    fn test_infinity_is_valid() {
491
        let mut data = [0u8; 48];
492
        data[0] = 0xc0;
493
        let pk = PublicKey::from_bytes(&data).unwrap();
494
        assert!(pk.is_valid());
495
    }
496
497
    #[test]
498
    fn test_is_valid() {
499
        let mut rng = StdRng::seed_from_u64(1337);
500
        let mut data = [0u8; 32];
501
        for _i in 0..50 {
502
            rng.fill(data.as_mut_slice());
503
            let sk = SecretKey::from_seed(&data);
504
            let pk = sk.public_key();
505
            assert!(pk.is_valid());
506
        }
507
    }
508
509
    #[test]
510
    fn test_default_is_inf() {
511
        let pk = PublicKey::default();
512
        assert!(pk.is_inf());
513
    }
514
515
    #[test]
516
    fn test_infinity() {
517
        let mut data = [0u8; 48];
518
        data[0] = 0xc0;
519
        let pk = PublicKey::from_bytes(&data).unwrap();
520
        assert!(pk.is_inf());
521
    }
522
523
    #[test]
524
    fn test_is_inf() {
525
        let mut rng = StdRng::seed_from_u64(1337);
526
        let mut data = [0u8; 32];
527
        for _i in 0..500 {
528
            rng.fill(data.as_mut_slice());
529
            let sk = SecretKey::from_seed(&data);
530
            let pk = sk.public_key();
531
            assert!(!pk.is_inf());
532
        }
533
    }
534
535
    #[test]
536
    fn test_hash() {
537
        fn hash<T: Hash>(v: T) -> u64 {
538
            use std::collections::hash_map::DefaultHasher;
539
            let mut h = DefaultHasher::new();
540
            v.hash(&mut h);
541
            h.finish()
542
        }
543
544
        let mut rng = StdRng::seed_from_u64(1337);
545
        let mut data = [0u8; 32];
546
        rng.fill(data.as_mut_slice());
547
548
        let sk = SecretKey::from_seed(&data);
549
        let pk1 = sk.public_key();
550
        let pk2 = pk1.derive_unhardened(1);
551
        let pk3 = pk1.derive_unhardened(2);
552
553
        assert!(hash(pk2) != hash(pk3));
554
        assert!(hash(pk1.derive_unhardened(42)) == hash(pk1.derive_unhardened(42)));
555
    }
556
557
    #[test]
558
    fn test_debug() {
559
        let mut data = [0u8; 48];
560
        data[0] = 0xc0;
561
        let pk = PublicKey::from_bytes(&data).unwrap();
562
        assert_eq!(
563
            format!("{pk:?}"),
564
            format!("<G1Element {}>", hex::encode(data))
565
        );
566
    }
567
568
    #[test]
569
    fn test_generator() {
570
        assert_eq!(
571
            hex::encode(PublicKey::generator().to_bytes()),
572
            "97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"
573
        );
574
    }
575
576
    #[test]
577
    fn test_from_integer() {
578
        let mut rng = StdRng::seed_from_u64(1337);
579
        let mut data = [0u8; 32];
580
        for _i in 0..50 {
581
            // this integer may not exceed the group order, so leave the top
582
            // byte as 0
583
            rng.fill(&mut data[1..]);
584
585
            let g1 = PublicKey::from_integer(&data);
586
            let expected_g1 = SecretKey::from_bytes(&data)
587
                .expect("invalid public key")
588
                .public_key();
589
            assert_eq!(g1, expected_g1);
590
        }
591
    }
592
593
    // test cases from zksnark test in chia_rs
594
    #[rstest]
595
    #[case("06f6ba2972ab1c83718d747b2d55cca96d08729b1ea5a3ab3479b8efe2d455885abf65f58d1507d7f260cd2a4687db821171c9d8dc5c0f5c3c4fd64b26cf93ff28b2e683c409fb374c4e26cc548c6f7cef891e60b55e6115bb38bbe97822e4d4", "a6f6ba2972ab1c83718d747b2d55cca96d08729b1ea5a3ab3479b8efe2d455885abf65f58d1507d7f260cd2a4687db82")]
596
    #[case("127271e81a1cb5c08a68694fcd5bd52f475d545edd4fbd49b9f6ec402ee1973f9f4102bf3bfccdcbf1b2f862af89a1340d40795c1c09d1e10b1acfa0f3a97a71bf29c11665743fa8d30e57e450b8762959571d6f6d253b236931b93cf634e7cf", "b27271e81a1cb5c08a68694fcd5bd52f475d545edd4fbd49b9f6ec402ee1973f9f4102bf3bfccdcbf1b2f862af89a134")]
597
    #[case("0fe94ac2d68d39d9207ea0cae4bb2177f7352bd754173ed27bd13b4c156f77f8885458886ee9fbd212719f27a96397c110fa7b4f898b1c45c2e82c5d46b52bdad95cae8299d4fd4556ae02baf20a5ec989fc62f28c8b6b3df6dc696f2afb6e20", "afe94ac2d68d39d9207ea0cae4bb2177f7352bd754173ed27bd13b4c156f77f8885458886ee9fbd212719f27a96397c1")]
598
    #[case("13aedc305adfdbc854aa105c41085618484858e6baa276b176fd89415021f7a0c75ff4f9ec39f482f142f1b54c11144815e519df6f71b1db46c83b1d2bdf381fc974059f3ccd87ed5259221dc37c50c3be407b58990d14b6d5bb79dad9ab8c42", "b3aedc305adfdbc854aa105c41085618484858e6baa276b176fd89415021f7a0c75ff4f9ec39f482f142f1b54c111448")]
599
    fn test_from_uncompressed(#[case] input: &str, #[case] expect: &str) {
600
        let input = hex::decode(input).unwrap();
601
        let g1 = PublicKey::from_uncompressed(input.as_slice().try_into().unwrap()).unwrap();
602
        let compressed = g1.to_bytes();
603
        assert_eq!(hex::encode(compressed), expect);
604
    }
605
606
    #[test]
607
    fn test_negate_roundtrip() {
608
        let mut rng = StdRng::seed_from_u64(1337);
609
        let mut data = [0u8; 32];
610
        for _i in 0..50 {
611
            // this integer may not exceed the group order, so leave the top
612
            // byte as 0
613
            rng.fill(&mut data[1..]);
614
615
            let g1 = PublicKey::from_integer(&data);
616
            let mut g1_neg = g1;
617
            g1_neg.negate();
618
            assert!(g1_neg != g1);
619
620
            g1_neg.negate();
621
            assert!(g1_neg == g1);
622
        }
623
    }
624
625
    #[test]
626
    fn test_negate_infinity() {
627
        let g1 = PublicKey::default();
628
        let mut g1_neg = g1;
629
        // negate on infinity is a no-op
630
        g1_neg.negate();
631
        assert!(g1_neg == g1);
632
    }
633
634
    #[test]
635
    fn test_negate() {
636
        let mut rng = StdRng::seed_from_u64(1337);
637
        let mut data = [0u8; 32];
638
        for _i in 0..50 {
639
            // this integer may not exceed the group order, so leave the top
640
            // byte as 0
641
            rng.fill(&mut data[1..]);
642
643
            let g1 = PublicKey::from_integer(&data);
644
            let mut g1_neg = g1;
645
            g1_neg.negate();
646
647
            let mut g1_double = g1;
648
            // adding the negative undoes adding the positive
649
            g1_double += &g1;
650
            assert!(g1_double != g1);
651
            g1_double += &g1_neg;
652
            assert!(g1_double == g1);
653
        }
654
    }
655
656
    #[test]
657
    fn test_scalar_multiply() {
658
        let mut rng = StdRng::seed_from_u64(1337);
659
        let mut data = [0u8; 32];
660
        for _i in 0..50 {
661
            // this integer may not exceed the group order, so leave the top
662
            // byte as 0
663
            rng.fill(&mut data[1..]);
664
665
            let mut g1 = PublicKey::from_integer(&data);
666
            let mut g1_double = g1;
667
            g1_double += &g1;
668
            assert!(g1_double != g1);
669
            // scalar multiply by 2 is the same as adding oneself
670
            g1.scalar_multiply(&[2]);
671
            assert!(g1_double == g1);
672
        }
673
    }
674
675
    #[test]
676
    fn test_hash_to_g1_different_dst() {
677
        const DEFAULT_DST: &[u8] = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_";
678
        const CUSTOM_DST: &[u8] = b"foobar";
679
680
        let mut rng = StdRng::seed_from_u64(1337);
681
        let mut msg = [0u8; 32];
682
        for _i in 0..50 {
683
            rng.fill(&mut msg);
684
            let default_hash = hash_to_g1(&msg);
685
            assert_eq!(default_hash, hash_to_g1_with_dst(&msg, DEFAULT_DST));
686
            assert!(default_hash != hash_to_g1_with_dst(&msg, CUSTOM_DST));
687
        }
688
    }
689
690
    // test cases from clvm_rs
691
    #[rstest]
692
    #[case("abcdef0123456789", "88e7302bf1fa8fcdecfb96f6b81475c3564d3bcaf552ccb338b1c48b9ba18ab7195c5067fe94fb216478188c0a3bef4a")]
693
    fn test_hash_to_g1(#[case] input: &str, #[case] expect: &str) {
694
        let g1 = hash_to_g1(input.as_bytes());
695
        assert_eq!(hex::encode(g1.to_bytes()), expect);
696
    }
697
698
    // test cases from clvm_rs
699
    #[rstest]
700
    #[case("abcdef0123456789", "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_", "8dd8e3a9197ddefdc25dde980d219004d6aa130d1af9b1808f8b2b004ae94484ac62a08a739ec7843388019a79c437b0")]
701
    #[case("abcdef0123456789", "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_", "88e7302bf1fa8fcdecfb96f6b81475c3564d3bcaf552ccb338b1c48b9ba18ab7195c5067fe94fb216478188c0a3bef4a")]
702
    fn test_hash_to_g1_with_dst(#[case] input: &str, #[case] dst: &str, #[case] expect: &str) {
703
        let g1 = hash_to_g1_with_dst(input.as_bytes(), dst.as_bytes());
704
        assert_eq!(hex::encode(g1.to_bytes()), expect);
705
    }
706
}
707
708
#[cfg(test)]
709
#[cfg(feature = "py-bindings")]
710
mod pytests {
711
    use super::*;
712
    use crate::SecretKey;
713
    use pyo3::{IntoPy, Python};
714
    use rand::rngs::StdRng;
715
    use rand::{Rng, SeedableRng};
716
    use rstest::rstest;
717
718
    #[test]
719
    fn test_json_dict_roundtrip() {
720
        pyo3::prepare_freethreaded_python();
721
        let mut rng = StdRng::seed_from_u64(1337);
722
        let mut data = [0u8; 32];
723
        for _i in 0..50 {
724
            rng.fill(data.as_mut_slice());
725
            let sk = SecretKey::from_seed(&data);
726
            let pk = sk.public_key();
727
            Python::with_gil(|py| {
728
                let string = pk.to_json_dict(py).expect("to_json_dict");
729
                let pk2 = PublicKey::from_json_dict(string.bind(py)).unwrap();
730
                assert_eq!(pk, pk2);
731
            });
732
        }
733
    }
734
735
    #[rstest]
736
    #[case("0x000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e", "PublicKey, invalid length 47 expected 48")]
737
    #[case("0x000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f00", "PublicKey, invalid length 49 expected 48")]
738
    #[case("000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e", "PublicKey, invalid length 47 expected 48")]
739
    #[case("000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f00", "PublicKey, invalid length 49 expected 48")]
740
    #[case("0x00r102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f", "invalid hex")]
741
    fn test_json_dict(#[case] input: &str, #[case] msg: &str) {
742
        pyo3::prepare_freethreaded_python();
743
        Python::with_gil(|py| {
744
            let err =
745
                PublicKey::from_json_dict(input.to_string().into_py(py).bind(py)).unwrap_err();
746
            assert_eq!(err.value_bound(py).to_string(), msg.to_string());
747
        });
748
    }
749
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chia-bls-0.10.0/src/secret_key.rs
Line
Count
Source
1
use crate::{DerivableKey, Error, PublicKey, Result};
2
use blst::*;
3
use chia_traits::{read_bytes, Streamable};
4
use hkdf::HkdfExtract;
5
use sha2::{Digest, Sha256};
6
use std::fmt;
7
use std::hash::{Hash, Hasher};
8
use std::io::Cursor;
9
use std::mem::MaybeUninit;
10
use std::ops::{Add, AddAssign};
11
12
#[cfg_attr(
13
    feature = "py-bindings",
14
    pyo3::pyclass(frozen, name = "PrivateKey"),
15
    derive(chia_py_streamable_macro::PyStreamable)
16
)]
17
#[derive(PartialEq, Eq, Clone)]
18
pub struct SecretKey(pub(crate) blst_scalar);
19
20
#[cfg(feature = "arbitrary")]
21
impl<'a> arbitrary::Arbitrary<'a> for SecretKey {
22
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
23
        let mut seed = [0_u8; 32];
24
        let _ = u.fill_buffer(seed.as_mut_slice());
25
        Ok(Self::from_seed(&seed))
26
    }
27
}
28
29
0
fn flip_bits(input: [u8; 32]) -> [u8; 32] {
30
0
    let mut ret = [0; 32];
31
0
    for i in 0..32 {
32
0
        ret[i] = input[i] ^ 0xff;
33
0
    }
34
0
    ret
35
0
}
36
37
0
fn ikm_to_lamport_sk(ikm: &[u8; 32], salt: [u8; 4]) -> [u8; 255 * 32] {
38
0
    let mut extracter = HkdfExtract::<Sha256>::new(Some(&salt));
39
0
    extracter.input_ikm(ikm);
40
0
    let (_, h) = extracter.finalize();
41
0
42
0
    let mut output = [0_u8; 255 * 32];
43
0
    h.expand(&[], &mut output).unwrap();
44
0
    output
45
0
}
46
47
0
fn to_lamport_pk(ikm: [u8; 32], idx: u32) -> [u8; 32] {
48
0
    let not_ikm = flip_bits(ikm);
49
0
    let salt = idx.to_be_bytes();
50
0
51
0
    let mut lamport0 = ikm_to_lamport_sk(&ikm, salt);
52
0
    let mut lamport1 = ikm_to_lamport_sk(&not_ikm, salt);
53
54
0
    for i in (0..32 * 255).step_by(32) {
55
0
        let hash = sha256(&lamport0[i..i + 32]);
56
0
        lamport0[i..i + 32].copy_from_slice(&hash);
57
0
    }
58
0
    for i in (0..32 * 255).step_by(32) {
59
0
        let hash = sha256(&lamport1[i..i + 32]);
60
0
        lamport1[i..i + 32].copy_from_slice(&hash);
61
0
    }
62
63
0
    let mut hasher = Sha256::new();
64
0
    hasher.update(lamport0);
65
0
    hasher.update(lamport1);
66
0
    hasher.finalize().into()
67
0
}
68
69
0
fn sha256(bytes: &[u8]) -> [u8; 32] {
70
0
    let mut hasher = Sha256::new();
71
0
    hasher.update(bytes);
72
0
    hasher.finalize().into()
73
0
}
74
75
36.5k
pub fn is_all_zero(buf: &[u8]) -> bool {
76
36.5k
    let (prefix, aligned, suffix) = unsafe { buf.align_to::<u128>() };
77
36.5k
78
205k
    prefix.iter().all(|&x| x == 0)
79
12.1k
        && suffix.iter().all(|&x| x == 0)
80
24.2k
        && aligned.iter().all(|&x| x == 0)
81
36.5k
}
82
83
impl SecretKey {
84
    /// # Panics
85
    ///
86
    /// Panics if the seed produces an invalid SecretKey.
87
    #[must_use]
88
0
    pub fn from_seed(seed: &[u8]) -> Self {
89
0
        // described here:
90
0
        // https://eips.ethereum.org/EIPS/eip-2333#derive_master_sk
91
0
        assert!(seed.len() >= 32);
92
93
0
        let bytes = unsafe {
94
0
            let mut scalar = MaybeUninit::<blst_scalar>::uninit();
95
0
            blst_keygen_v3(
96
0
                scalar.as_mut_ptr(),
97
0
                seed.as_ptr(),
98
0
                seed.len(),
99
0
                std::ptr::null(),
100
0
                0,
101
0
            );
102
0
            let mut bytes = MaybeUninit::<[u8; 32]>::uninit();
103
0
            blst_bendian_from_scalar(bytes.as_mut_ptr().cast::<u8>(), &scalar.assume_init());
104
0
            bytes.assume_init()
105
0
        };
106
0
        Self::from_bytes(&bytes).expect("from_seed")
107
0
    }
108
109
0
    pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self> {
110
0
        let pk = unsafe {
111
0
            let mut pk = MaybeUninit::<blst_scalar>::uninit();
112
0
            blst_scalar_from_bendian(pk.as_mut_ptr(), bytes.as_ptr());
113
0
            pk.assume_init()
114
0
        };
115
0
116
0
        if is_all_zero(bytes) {
117
            // don't check anything else, we allow zero private key
118
0
            return Ok(Self(pk));
119
0
        }
120
0
121
0
        if unsafe { !blst_sk_check(&pk) } {
122
0
            return Err(Error::SecretKeyGroupOrder);
123
0
        }
124
0
125
0
        Ok(Self(pk))
126
0
    }
127
128
0
    pub fn to_bytes(&self) -> [u8; 32] {
129
0
        unsafe {
130
0
            let mut bytes = MaybeUninit::<[u8; 32]>::uninit();
131
0
            blst_bendian_from_scalar(bytes.as_mut_ptr().cast::<u8>(), &self.0);
132
0
            bytes.assume_init()
133
0
        }
134
0
    }
135
136
0
    pub fn public_key(&self) -> PublicKey {
137
0
        let p1 = unsafe {
138
0
            let mut p1 = MaybeUninit::<blst_p1>::uninit();
139
0
            blst_sk_to_pk_in_g1(p1.as_mut_ptr(), &self.0);
140
0
            p1.assume_init()
141
0
        };
142
0
        PublicKey(p1)
143
0
    }
144
145
    #[must_use]
146
0
    pub fn derive_hardened(&self, idx: u32) -> SecretKey {
147
0
        // described here:
148
0
        // https://eips.ethereum.org/EIPS/eip-2333#derive_child_sk
149
0
        SecretKey::from_seed(to_lamport_pk(self.to_bytes(), idx).as_slice())
150
0
    }
151
}
152
153
impl Streamable for SecretKey {
154
0
    fn update_digest(&self, digest: &mut Sha256) {
155
0
        digest.update(self.to_bytes());
156
0
    }
157
158
0
    fn stream(&self, out: &mut Vec<u8>) -> chia_traits::chia_error::Result<()> {
159
0
        out.extend_from_slice(&self.to_bytes());
160
0
        Ok(())
161
0
    }
162
163
0
    fn parse<const TRUSTED: bool>(
164
0
        input: &mut Cursor<&[u8]>,
165
0
    ) -> chia_traits::chia_error::Result<Self> {
166
0
        Ok(Self::from_bytes(
167
0
            read_bytes(input, 32)?.try_into().unwrap(),
168
0
        )?)
169
0
    }
Unexecuted instantiation: _RINvXs_NtCs568wuOlRYFZ_8chia_bls10secret_keyNtB5_9SecretKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable5parseKb0_EB7_
Unexecuted instantiation: _RINvXs_NtCs568wuOlRYFZ_8chia_bls10secret_keyNtB5_9SecretKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable5parseKb1_EB7_
170
}
171
172
impl Hash for SecretKey {
173
0
    fn hash<H: Hasher>(&self, state: &mut H) {
174
0
        state.write(&self.to_bytes());
175
0
    }
176
}
177
178
impl Add<&SecretKey> for &SecretKey {
179
    type Output = SecretKey;
180
0
    fn add(self, rhs: &SecretKey) -> SecretKey {
181
0
        let scalar = unsafe {
182
0
            let mut ret = MaybeUninit::<blst_scalar>::uninit();
183
0
            blst_sk_add_n_check(ret.as_mut_ptr(), &self.0, &rhs.0);
184
0
            ret.assume_init()
185
0
        };
186
0
        SecretKey(scalar)
187
0
    }
188
}
189
190
impl Add<&SecretKey> for SecretKey {
191
    type Output = SecretKey;
192
0
    fn add(mut self, rhs: &SecretKey) -> SecretKey {
193
0
        unsafe {
194
0
            blst_sk_add_n_check(&mut self.0, &self.0, &rhs.0);
195
0
            self
196
0
        }
197
0
    }
198
}
199
200
impl AddAssign<&SecretKey> for SecretKey {
201
0
    fn add_assign(&mut self, rhs: &SecretKey) {
202
0
        unsafe {
203
0
            blst_sk_add_n_check(&mut self.0, &self.0, &rhs.0);
204
0
        }
205
0
    }
206
}
207
208
impl fmt::Debug for SecretKey {
209
0
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
210
0
        formatter.write_fmt(format_args!(
211
0
            "<PrivateKey {}>",
212
0
            &hex::encode(self.to_bytes())
213
0
        ))
214
0
    }
215
}
216
217
impl DerivableKey for SecretKey {
218
0
    fn derive_unhardened(&self, idx: u32) -> Self {
219
0
        let pk = self.public_key();
220
0
221
0
        let mut hasher = Sha256::new();
222
0
        hasher.update(pk.to_bytes());
223
0
        hasher.update(idx.to_be_bytes());
224
0
        let digest = hasher.finalize();
225
226
0
        let scalar = unsafe {
227
0
            let mut scalar = MaybeUninit::<blst_scalar>::uninit();
228
0
            let success =
229
0
                blst_scalar_from_be_bytes(scalar.as_mut_ptr(), digest.as_ptr(), digest.len());
230
0
            assert!(success);
231
0
            let success = blst_sk_add_n_check(scalar.as_mut_ptr(), scalar.as_ptr(), &self.0);
232
0
            assert!(success);
233
0
            scalar.assume_init()
234
0
        };
235
0
        Self(scalar)
236
0
    }
237
}
238
239
#[cfg(feature = "py-bindings")]
240
mod pybindings {
241
    use super::*;
242
243
    use crate::{parse_hex::parse_hex_string, PublicKey, Signature};
244
245
    use chia_traits::{FromJsonDict, ToJsonDict};
246
    use pyo3::prelude::*;
247
248
    #[pymethods]
249
    impl SecretKey {
250
        #[classattr]
251
        const PRIVATE_KEY_SIZE: usize = 32;
252
253
        pub fn sign_g2(&self, msg: &[u8]) -> Signature {
254
            crate::sign(self, msg)
255
        }
256
257
        pub fn get_g1(&self) -> PublicKey {
258
            self.public_key()
259
        }
260
261
        fn __str__(&self) -> String {
262
            hex::encode(self.to_bytes())
263
        }
264
    }
265
266
    impl ToJsonDict for SecretKey {
267
        fn to_json_dict(&self, py: Python<'_>) -> PyResult<PyObject> {
268
            let bytes = self.to_bytes();
269
            Ok(("0x".to_string() + &hex::encode(bytes)).into_py(py))
270
        }
271
    }
272
273
    impl FromJsonDict for SecretKey {
274
        fn from_json_dict(o: &Bound<'_, PyAny>) -> PyResult<Self> {
275
            Ok(Self::from_bytes(
276
                parse_hex_string(o, 32, "PrivateKey")?
277
                    .as_slice()
278
                    .try_into()
279
                    .unwrap(),
280
            )?)
281
        }
282
    }
283
}
284
285
#[cfg(test)]
286
mod tests {
287
    use super::*;
288
    use hex::FromHex;
289
    use rand::rngs::StdRng;
290
    use rand::{Rng, SeedableRng};
291
292
    #[test]
293
    fn test_make_key() {
294
        // test vectors from:
295
        // from chia.util.keychain import KeyDataSecrets
296
        // print(KeyDataSecrets.from_mnemonic(phrase)["privatekey"])
297
298
        // (seed, secret-key)
299
        let test_cases = &[
300
        ("fc795be0c3f18c50dddb34e72179dc597d64055497ecc1e69e2e56a5409651bc139aae8070d4df0ea14d8d2a518a9a00bb1cc6e92e053fe34051f6821df9164c",
301
            "52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb"),
302
        ("b873212f885ccffbf4692afcb84bc2e55886de2dfa07d90f5c3c239abc31c0a6ce047e30fd8bf6a281e71389aa82d73df74c7bbfb3b06b4639a5cee775cccd3c",
303
            "35d65c35d926f62ba2dd128754ddb556edb4e2c926237ab9e02a23e7b3533613"),
304
        ("3e066d7dee2dbf8fcd3fe240a3975658ca118a8f6f4ca81cf99104944604b05a5090a79d99e545704b914ca0397fedb82fd00fd6a72098703709c891a065ee49",
305
            "59095c391107936599b7ee6f09067979b321932bd62e23c7f53ed5fb19f851f6")
306
    ];
307
308
        for (seed, sk) in test_cases {
309
            assert_eq!(
310
                SecretKey::from_seed(&<[u8; 64]>::from_hex(seed).unwrap())
311
                    .to_bytes()
312
                    .to_vec(),
313
                Vec::<u8>::from_hex(sk).unwrap()
314
            );
315
        }
316
    }
317
318
    #[test]
319
    fn test_derive_unhardened() {
320
        // test vectors from:
321
        // from blspy import AugSchemeMPL
322
        // from blspy import PrivateKey
323
        // sk = PrivateKey.from_bytes(bytes.fromhex("52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb"))
324
        // AugSchemeMPL.derive_child_sk_unhardened(sk, 0)
325
        // AugSchemeMPL.derive_child_sk_unhardened(sk, 1)
326
        // AugSchemeMPL.derive_child_sk_unhardened(sk, 2)
327
        // AugSchemeMPL.derive_child_sk_unhardened(sk, 3)
328
        // <PrivateKey 399638f99d446500f3c3a363f24c2b0634ad7caf646f503455093f35f29290bd>
329
        // <PrivateKey 3dcb4098ad925d8940e2f516d2d5a4dbab393db928a8c6cb06b93066a09a843a>
330
        // <PrivateKey 13115c8fb68a3d667938dac2ffc6b867a4a0f216bbb228aa43d6bdde14245575>
331
        // <PrivateKey 52e7e9f2fb51f2c5705aea8e11ac82737b95e664ae578f015af22031d956f92b>
332
333
        let sk_hex = "52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb";
334
        let derived_hex = [
335
            "399638f99d446500f3c3a363f24c2b0634ad7caf646f503455093f35f29290bd",
336
            "3dcb4098ad925d8940e2f516d2d5a4dbab393db928a8c6cb06b93066a09a843a",
337
            "13115c8fb68a3d667938dac2ffc6b867a4a0f216bbb228aa43d6bdde14245575",
338
            "52e7e9f2fb51f2c5705aea8e11ac82737b95e664ae578f015af22031d956f92b",
339
        ];
340
        let sk = SecretKey::from_bytes(&<[u8; 32]>::from_hex(sk_hex).unwrap()).unwrap();
341
342
        for (i, hex) in derived_hex.iter().enumerate() {
343
            let derived = sk.derive_unhardened(i as u32);
344
            assert_eq!(derived.to_bytes(), <[u8; 32]>::from_hex(hex).unwrap());
345
        }
346
    }
347
348
    #[test]
349
    fn test_public_key() {
350
        // test vectors from:
351
        // from blspy import PrivateKey
352
        // from blspy import AugSchemeMPL
353
        // sk = PrivateKey.from_bytes(bytes.fromhex("52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb"))
354
        // for i in [100, 52312, 352350, 316]:
355
        //         sk0 = AugSchemeMPL.derive_child_sk_unhardened(sk, i)
356
        //         print(bytes(sk0).hex())
357
        //         print(bytes(sk0.get_g1()).hex())
358
359
        // secret key, public key
360
        let test_cases = [
361
        ("5aac8405befe4cb3748a67177c56df26355f1f98d979afdb0b2f97858d2f71c3",
362
        "b9de000821a610ef644d160c810e35113742ff498002c2deccd8f1a349e423047e9b3fc17ebfc733dbee8fd902ba2961"),
363
        ("23f1fb291d3bd7434282578b842d5ea4785994bb89bd2c94896d1b4be6c70ba2",
364
        "96f304a5885e67abdeab5e1ed0576780a1368777ea7760124834529e8694a1837a20ffea107b9769c4f92a1f6c167e69"),
365
        ("2bc1d6d6efe58d365c29ccb7ad12c8457c0eec70a29003073692ac4cb1cd7ba2",
366
        "b10568446def64b17fc9b6d614ae036deaac3f2d654e12e45ea04b19208246e0d760e8826426e97f9f0666b7ce340d75"),
367
        ("2bfc8672d859700e30aa6c8edc24a8ce9e6dc53bb1ef936f82de722847d05b9e",
368
        "9641472acbd6af7e5313d2500791b87117612af43eef929cf7975aaaa5a203a32698a8ef53763a84d90ad3f00b86ad66"),
369
        ("3311f883dad1e39c52bf82d5870d05371c0b1200576287b5160808f55568151b",
370
        "928ea102b5a3e3efe4f4c240d3458a568dfeb505e02901a85ed70a384944b0c08c703a35245322709921b8f2b7f5e54a"),
371
        ];
372
373
        for (sk_hex, pk_hex) in test_cases {
374
            let sk = SecretKey::from_bytes(&<[u8; 32]>::from_hex(sk_hex).unwrap()).unwrap();
375
            let pk = sk.public_key();
376
            assert_eq!(
377
                pk,
378
                PublicKey::from_bytes(&<[u8; 48]>::from_hex(pk_hex).unwrap()).unwrap()
379
            );
380
        }
381
    }
382
383
    #[test]
384
    fn test_derive_hardened() {
385
        // test vectors from:
386
        // from blspy import AugSchemeMPL
387
        // from blspy import PrivateKey
388
        // sk = PrivateKey.from_bytes(bytes.fromhex("52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb"))
389
        // AugSchemeMPL.derive_child_sk(sk, 0)
390
        // AugSchemeMPL.derive_child_sk(sk, 1)
391
        // AugSchemeMPL.derive_child_sk(sk, 2)
392
        // AugSchemeMPL.derive_child_sk(sk, 3)
393
        // <PrivateKey 05eccb2d70e814f51a30d8b9965505605c677afa97228fa2419db583a8121db9>
394
        // <PrivateKey 612ae96bdce2e9bc01693ac579918fbb559e04ec365cce9b66bb80e328f62c46>
395
        // <PrivateKey 5df14a0a34fd6c30a80136d4103f0a93422ce82d5c537bebbecbc56e19fee5b9>
396
        // <PrivateKey 3ea55db88d9a6bf5f1d9c9de072e3c9a56b13f4156d72fca7880cd39b4bd4fdc>
397
398
        let sk_hex = "52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb";
399
        let derived_hex = [
400
            "05eccb2d70e814f51a30d8b9965505605c677afa97228fa2419db583a8121db9",
401
            "612ae96bdce2e9bc01693ac579918fbb559e04ec365cce9b66bb80e328f62c46",
402
            "5df14a0a34fd6c30a80136d4103f0a93422ce82d5c537bebbecbc56e19fee5b9",
403
            "3ea55db88d9a6bf5f1d9c9de072e3c9a56b13f4156d72fca7880cd39b4bd4fdc",
404
        ];
405
        let sk = SecretKey::from_bytes(&<[u8; 32]>::from_hex(sk_hex).unwrap()).unwrap();
406
407
        for (i, hex) in derived_hex.iter().enumerate() {
408
            let derived = sk.derive_hardened(i as u32);
409
            assert_eq!(derived.to_bytes(), <[u8; 32]>::from_hex(hex).unwrap());
410
        }
411
    }
412
413
    #[test]
414
    fn test_debug() {
415
        let sk_hex = "52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb";
416
        let sk = SecretKey::from_bytes(&<[u8; 32]>::from_hex(sk_hex).unwrap()).unwrap();
417
        assert_eq!(format!("{sk:?}"), format!("<PrivateKey {sk_hex}>"));
418
    }
419
420
    #[test]
421
    fn test_hash() {
422
        fn hash<T: Hash>(v: &T) -> u64 {
423
            use std::collections::hash_map::DefaultHasher;
424
            let mut h = DefaultHasher::new();
425
            v.hash(&mut h);
426
            h.finish()
427
        }
428
429
        let mut rng = StdRng::seed_from_u64(1337);
430
        let mut data = [0u8; 32];
431
        rng.fill(data.as_mut_slice());
432
433
        let sk1 = SecretKey::from_seed(&data);
434
        let sk2 = SecretKey::from_seed(&data);
435
436
        rng.fill(data.as_mut_slice());
437
        let sk3 = SecretKey::from_seed(&data);
438
439
        assert!(hash(&sk1) == hash(&sk2));
440
        assert!(hash(&sk1) != hash(&sk3));
441
    }
442
443
    #[test]
444
    fn test_from_bytes() {
445
        let mut rng = StdRng::seed_from_u64(1337);
446
        let mut data = [0u8; 32];
447
        for _i in 0..50 {
448
            rng.fill(data.as_mut_slice());
449
            // make the bytes exceed q
450
            data[0] |= 0x80;
451
            // just any random bytes are not a valid key and should fail
452
            assert_eq!(
453
                SecretKey::from_bytes(&data).unwrap_err(),
454
                Error::SecretKeyGroupOrder
455
            );
456
        }
457
    }
458
459
    #[test]
460
    fn test_from_bytes_zero() {
461
        let data = [0u8; 32];
462
        let _sk = SecretKey::from_bytes(&data).unwrap();
463
    }
464
465
    #[test]
466
    fn test_aggregate_secret_key() {
467
        let sk_hex = "5aac8405befe4cb3748a67177c56df26355f1f98d979afdb0b2f97858d2f71c3";
468
        let sk = SecretKey::from_bytes(&<[u8; 32]>::from_hex(sk_hex).unwrap()).unwrap();
469
        let sk2 = &sk + &sk;
470
        let sk3 = &sk + &sk + &sk;
471
472
        assert_eq!(
473
            sk2,
474
            SecretKey::from_bytes(
475
                &<[u8; 32]>::from_hex(
476
                    "416b60b8545f1c1eb5daf626ef0be64717009b2eb2f503b7165f2f0c1a5ee385"
477
                )
478
                .unwrap()
479
            )
480
            .unwrap()
481
        );
482
483
        assert_eq!(
484
            sk3,
485
            SecretKey::from_bytes(
486
                &<[u8; 32]>::from_hex(
487
                    "282a3d6ae9bfeb89f72b853661c0ed67f8a216c48c705793218ec692a78e5547"
488
                )
489
                .unwrap()
490
            )
491
            .unwrap()
492
        );
493
    }
494
495
    #[test]
496
    fn test_roundtrip() {
497
        let mut rng = StdRng::seed_from_u64(1337);
498
        let mut data = [0u8; 32];
499
        for _i in 0..50 {
500
            rng.fill(data.as_mut_slice());
501
            let sk = SecretKey::from_seed(&data);
502
            let bytes = sk.to_bytes();
503
            let sk2 = SecretKey::from_bytes(&bytes).unwrap();
504
            assert_eq!(sk, sk2);
505
            assert_eq!(sk.public_key(), sk2.public_key());
506
        }
507
    }
508
}
509
510
#[cfg(test)]
511
#[cfg(feature = "py-bindings")]
512
mod pytests {
513
    use super::*;
514
    use pyo3::{IntoPy, Python};
515
    use rand::rngs::StdRng;
516
    use rand::{Rng, SeedableRng};
517
    use rstest::rstest;
518
519
    #[test]
520
    fn test_json_dict_roundtrip() {
521
        pyo3::prepare_freethreaded_python();
522
        let mut rng = StdRng::seed_from_u64(1337);
523
        let mut data = [0u8; 32];
524
        for _i in 0..50 {
525
            rng.fill(data.as_mut_slice());
526
            let sk = SecretKey::from_seed(&data);
527
            Python::with_gil(|py| {
528
                let string = sk.to_json_dict(py).expect("to_json_dict");
529
                let sk2 = SecretKey::from_json_dict(string.bind(py)).unwrap();
530
                assert_eq!(sk, sk2);
531
                assert_eq!(sk.public_key(), sk2.public_key());
532
            });
533
        }
534
    }
535
536
    #[rstest]
537
    #[case(
538
        "0x000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e",
539
        "PrivateKey, invalid length 31 expected 32"
540
    )]
541
    #[case(
542
        "0x000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f00",
543
        "PrivateKey, invalid length 33 expected 32"
544
    )]
545
    #[case(
546
        "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f00",
547
        "PrivateKey, invalid length 33 expected 32"
548
    )]
549
    #[case(
550
        "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e",
551
        "PrivateKey, invalid length 31 expected 32"
552
    )]
553
    #[case(
554
        "0r0102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f",
555
        "invalid hex"
556
    )]
557
    fn test_json_dict(#[case] input: &str, #[case] msg: &str) {
558
        pyo3::prepare_freethreaded_python();
559
        Python::with_gil(|py| {
560
            let err =
561
                SecretKey::from_json_dict(input.to_string().into_py(py).bind(py)).unwrap_err();
562
            assert_eq!(err.value_bound(py).to_string(), msg.to_string());
563
        });
564
    }
565
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chia-bls-0.10.0/src/signature.rs
Line
Count
Source
1
use crate::{Error, GTElement, PublicKey, Result, SecretKey};
2
use blst::*;
3
use chia_traits::{read_bytes, Streamable};
4
use sha2::{Digest, Sha256};
5
use std::borrow::Borrow;
6
use std::fmt;
7
use std::hash::{Hash, Hasher};
8
use std::io::Cursor;
9
use std::mem::MaybeUninit;
10
use std::ops::{Add, AddAssign, Neg, SubAssign};
11
12
// we use the augmented scheme
13
pub const DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_";
14
15
#[cfg_attr(
16
    feature = "py-bindings",
17
    pyo3::pyclass(name = "G2Element"),
18
    derive(chia_py_streamable_macro::PyStreamable)
19
)]
20
#[derive(Clone, Default)]
21
pub struct Signature(pub(crate) blst_p2);
22
23
#[cfg(feature = "arbitrary")]
24
impl<'a> arbitrary::Arbitrary<'a> for Signature {
25
    fn arbitrary(_u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
26
        // placeholder
27
        Ok(Self::default())
28
    }
29
}
30
31
impl Signature {
32
19.6k
    pub fn from_bytes_unchecked(buf: &[u8; 96]) -> Result<Self> {
33
19.5k
        let p2 = unsafe {
34
19.6k
            let mut p2_affine = MaybeUninit::<blst_p2_affine>::uninit();
35
19.6k
            let ret = blst_p2_uncompress(p2_affine.as_mut_ptr(), buf.as_ptr());
36
19.6k
            if ret != BLST_ERROR::BLST_SUCCESS {
37
123
                return Err(Error::InvalidSignature(ret));
38
19.5k
            }
39
19.5k
            let mut p2 = MaybeUninit::<blst_p2>::uninit();
40
19.5k
            blst_p2_from_affine(p2.as_mut_ptr(), &p2_affine.assume_init());
41
19.5k
            p2.assume_init()
42
19.5k
        };
43
19.5k
        Ok(Self(p2))
44
19.6k
    }
45
46
19.6k
    pub fn from_bytes(buf: &[u8; 96]) -> Result<Self> {
47
19.6k
        let ret = Self::from_bytes_unchecked(buf)?;
48
19.5k
        if ret.is_valid() {
49
19.4k
            Ok(ret)
50
        } else {
51
46
            Err(Error::InvalidSignature(BLST_ERROR::BLST_POINT_NOT_ON_CURVE))
52
        }
53
19.6k
    }
54
55
0
    pub fn from_uncompressed(buf: &[u8; 192]) -> Result<Self> {
56
0
        let p2 = unsafe {
57
0
            let mut p2_affine = MaybeUninit::<blst_p2_affine>::uninit();
58
0
            let ret = blst_p2_deserialize(p2_affine.as_mut_ptr(), buf.as_ptr());
59
0
            if ret != BLST_ERROR::BLST_SUCCESS {
60
0
                return Err(Error::InvalidSignature(ret));
61
0
            }
62
0
            let mut p2 = MaybeUninit::<blst_p2>::uninit();
63
0
            blst_p2_from_affine(p2.as_mut_ptr(), &p2_affine.assume_init());
64
0
            p2.assume_init()
65
0
        };
66
0
        Ok(Self(p2))
67
0
    }
68
69
14.4k
    pub fn to_bytes(&self) -> [u8; 96] {
70
14.4k
        unsafe {
71
14.4k
            let mut bytes = MaybeUninit::<[u8; 96]>::uninit();
72
14.4k
            blst_p2_compress(bytes.as_mut_ptr().cast::<u8>(), &self.0);
73
14.4k
            bytes.assume_init()
74
14.4k
        }
75
14.4k
    }
76
77
0
    pub fn generator() -> Self {
78
0
        unsafe { Self(*blst_p2_generator()) }
79
0
    }
80
81
0
    pub fn aggregate(&mut self, sig: &Signature) {
82
0
        unsafe {
83
0
            blst_p2_add_or_double(&mut self.0, &self.0, &sig.0);
84
0
        }
85
0
    }
86
87
24.3k
    pub fn is_valid(&self) -> bool {
88
24.3k
        // Infinity was considered a valid G2Element in older Relic versions
89
24.3k
        // For historical compatibililty this behavior is maintained.
90
24.3k
        unsafe { blst_p2_is_inf(&self.0) || blst_p2_in_g2(&self.0) }
91
24.3k
    }
92
93
0
    pub fn negate(&mut self) {
94
0
        unsafe {
95
0
            blst_p2_cneg(&mut self.0, true);
96
0
        }
97
0
    }
98
99
5.38k
    pub fn scalar_multiply(&mut self, int_bytes: &[u8]) {
100
5.38k
        unsafe {
101
5.38k
            let mut scalar = MaybeUninit::<blst_scalar>::uninit();
102
5.38k
            blst_scalar_from_be_bytes(scalar.as_mut_ptr(), int_bytes.as_ptr(), int_bytes.len());
103
5.38k
            blst_p2_mult(&mut self.0, &self.0, scalar.as_ptr().cast::<u8>(), 256);
104
5.38k
        }
105
5.38k
    }
106
107
0
    pub fn pair(&self, other: &PublicKey) -> GTElement {
108
0
        let ans = unsafe {
109
0
            let mut ans = MaybeUninit::<blst_fp12>::uninit();
110
0
            let mut aff1 = MaybeUninit::<blst_p1_affine>::uninit();
111
0
            let mut aff2 = MaybeUninit::<blst_p2_affine>::uninit();
112
0
113
0
            blst_p1_to_affine(aff1.as_mut_ptr(), &other.0);
114
0
            blst_p2_to_affine(aff2.as_mut_ptr(), &self.0);
115
0
116
0
            blst_miller_loop(ans.as_mut_ptr(), &aff2.assume_init(), &aff1.assume_init());
117
0
            blst_final_exp(ans.as_mut_ptr(), ans.as_ptr());
118
0
            ans.assume_init()
119
0
        };
120
0
        GTElement(ans)
121
0
    }
122
}
123
124
impl Streamable for Signature {
125
0
    fn update_digest(&self, digest: &mut Sha256) {
126
0
        digest.update(self.to_bytes());
127
0
    }
128
129
0
    fn stream(&self, out: &mut Vec<u8>) -> chia_traits::chia_error::Result<()> {
130
0
        out.extend_from_slice(&self.to_bytes());
131
0
        Ok(())
132
0
    }
133
134
0
    fn parse<const TRUSTED: bool>(
135
0
        input: &mut Cursor<&[u8]>,
136
0
    ) -> chia_traits::chia_error::Result<Self> {
137
0
        let input = read_bytes(input, 96)?.try_into().unwrap();
138
0
        if TRUSTED {
139
0
            Ok(Self::from_bytes_unchecked(input)?)
140
        } else {
141
0
            Ok(Self::from_bytes(input)?)
142
        }
143
0
    }
Unexecuted instantiation: _RINvXs_NtCs568wuOlRYFZ_8chia_bls9signatureNtB5_9SignatureNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable5parseKb0_EB7_
Unexecuted instantiation: _RINvXs_NtCs568wuOlRYFZ_8chia_bls9signatureNtB5_9SignatureNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable5parseKb1_EB7_
144
}
145
146
impl PartialEq for Signature {
147
722
    fn eq(&self, other: &Self) -> bool {
148
722
        unsafe { blst_p2_is_equal(&self.0, &other.0) }
149
722
    }
150
}
151
impl Eq for Signature {}
152
153
impl Hash for Signature {
154
0
    fn hash<H: Hasher>(&self, state: &mut H) {
155
0
        state.write(&self.to_bytes());
156
0
    }
157
}
158
159
impl fmt::Debug for Signature {
160
0
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
161
0
        formatter.write_fmt(format_args!(
162
0
            "<G2Element {}>",
163
0
            &hex::encode(self.to_bytes())
164
0
        ))
165
0
    }
166
}
167
168
impl AddAssign<&Signature> for Signature {
169
3.82k
    fn add_assign(&mut self, rhs: &Signature) {
170
3.82k
        unsafe {
171
3.82k
            blst_p2_add_or_double(&mut self.0, &self.0, &rhs.0);
172
3.82k
        }
173
3.82k
    }
174
}
175
176
impl Neg for Signature {
177
    type Output = Signature;
178
0
    fn neg(mut self) -> Self::Output {
179
0
        self.negate();
180
0
        self
181
0
    }
182
}
183
184
impl Neg for &Signature {
185
    type Output = Signature;
186
0
    fn neg(self) -> Self::Output {
187
0
        let mut ret = self.clone();
188
0
        ret.negate();
189
0
        ret
190
0
    }
191
}
192
193
impl SubAssign<&Signature> for Signature {
194
1.88k
    fn sub_assign(&mut self, rhs: &Signature) {
195
1.88k
        unsafe {
196
1.88k
            let mut neg = rhs.clone();
197
1.88k
            blst_p2_cneg(&mut neg.0, true);
198
1.88k
            blst_p2_add_or_double(&mut self.0, &self.0, &neg.0);
199
1.88k
        }
200
1.88k
    }
201
}
202
203
impl Add<&Signature> for Signature {
204
    type Output = Signature;
205
0
    fn add(mut self, rhs: &Signature) -> Signature {
206
0
        unsafe {
207
0
            blst_p2_add_or_double(&mut self.0, &self.0, &rhs.0);
208
0
            self
209
0
        }
210
0
    }
211
}
212
213
impl Add<&Signature> for &Signature {
214
    type Output = Signature;
215
0
    fn add(self, rhs: &Signature) -> Signature {
216
0
        let p1 = unsafe {
217
0
            let mut ret = MaybeUninit::<blst_p2>::uninit();
218
0
            blst_p2_add_or_double(ret.as_mut_ptr(), &self.0, &rhs.0);
219
0
            ret.assume_init()
220
0
        };
221
0
        Signature(p1)
222
0
    }
223
}
224
225
// validate a series of public keys (G1 points) and G2 points. These points are
226
// paired and the resulting GT points are multiplied. If the resulting GT point
227
// is the identity, the function returns true, otherwise false. To validate an
228
// aggregate signature, include the G1 generator and the signature as one of the
229
// pairs.
230
20
pub fn aggregate_pairing<G1: Borrow<PublicKey>, G2: Borrow<Signature>, I>(data: I) -> bool
231
20
where
232
20
    I: IntoIterator<Item = (G1, G2)>,
233
20
{
234
20
    let mut data = data.into_iter().peekable();
235
20
    if data.peek().is_none() {
236
20
        return true;
237
0
    }
238
0
239
0
    let mut v: Vec<u64> = vec![0; unsafe { blst_pairing_sizeof() } / 8];
240
0
    let ctx = unsafe {
241
0
        let ctx = v.as_mut_slice().as_mut_ptr().cast::<blst_pairing>();
242
0
        blst_pairing_init(
243
0
            ctx,
244
0
            true, // hash
245
0
            DST.as_ptr(),
246
0
            DST.len(),
247
0
        );
248
0
        ctx
249
    };
250
251
0
    for (g1, g2) in data {
252
0
        if !g1.borrow().is_valid() {
253
0
            return false;
254
0
        }
255
0
        if !g2.borrow().is_valid() {
256
0
            return false;
257
0
        }
258
0
259
0
        let g1_affine = unsafe {
260
0
            let mut g1_affine = MaybeUninit::<blst_p1_affine>::uninit();
261
0
            blst_p1_to_affine(g1_affine.as_mut_ptr(), &g1.borrow().0);
262
0
            g1_affine.assume_init()
263
0
        };
264
0
265
0
        let g2_affine = unsafe {
266
0
            let mut g2_affine = MaybeUninit::<blst_p2_affine>::uninit();
267
0
            blst_p2_to_affine(g2_affine.as_mut_ptr(), &g2.borrow().0);
268
0
            g2_affine.assume_init()
269
0
        };
270
0
271
0
        unsafe {
272
0
            blst_pairing_raw_aggregate(ctx, &g2_affine, &g1_affine);
273
0
        }
274
    }
275
276
    unsafe {
277
0
        blst_pairing_commit(ctx);
278
0
        blst_pairing_finalverify(ctx, std::ptr::null())
279
    }
280
20
}
Unexecuted instantiation: _RINvNtCs568wuOlRYFZ_8chia_bls9signature17aggregate_pairingpppEB4_
_RINvNtCs568wuOlRYFZ_8chia_bls9signature17aggregate_pairingNtNtB4_10public_key9PublicKeyNtB2_9SignatureINtNtCsiBl6Lc3cFal_5alloc3vec3VecTBU_B1n_EEECs4RkbDk9WRL5_5clvmr
Line
Count
Source
230
20
pub fn aggregate_pairing<G1: Borrow<PublicKey>, G2: Borrow<Signature>, I>(data: I) -> bool
231
20
where
232
20
    I: IntoIterator<Item = (G1, G2)>,
233
20
{
234
20
    let mut data = data.into_iter().peekable();
235
20
    if data.peek().is_none() {
236
20
        return true;
237
0
    }
238
0
239
0
    let mut v: Vec<u64> = vec![0; unsafe { blst_pairing_sizeof() } / 8];
240
0
    let ctx = unsafe {
241
0
        let ctx = v.as_mut_slice().as_mut_ptr().cast::<blst_pairing>();
242
0
        blst_pairing_init(
243
0
            ctx,
244
0
            true, // hash
245
0
            DST.as_ptr(),
246
0
            DST.len(),
247
0
        );
248
0
        ctx
249
    };
250
251
0
    for (g1, g2) in data {
252
0
        if !g1.borrow().is_valid() {
253
0
            return false;
254
0
        }
255
0
        if !g2.borrow().is_valid() {
256
0
            return false;
257
0
        }
258
0
259
0
        let g1_affine = unsafe {
260
0
            let mut g1_affine = MaybeUninit::<blst_p1_affine>::uninit();
261
0
            blst_p1_to_affine(g1_affine.as_mut_ptr(), &g1.borrow().0);
262
0
            g1_affine.assume_init()
263
0
        };
264
0
265
0
        let g2_affine = unsafe {
266
0
            let mut g2_affine = MaybeUninit::<blst_p2_affine>::uninit();
267
0
            blst_p2_to_affine(g2_affine.as_mut_ptr(), &g2.borrow().0);
268
0
            g2_affine.assume_init()
269
0
        };
270
0
271
0
        unsafe {
272
0
            blst_pairing_raw_aggregate(ctx, &g2_affine, &g1_affine);
273
0
        }
274
    }
275
276
    unsafe {
277
0
        blst_pairing_commit(ctx);
278
0
        blst_pairing_finalverify(ctx, std::ptr::null())
279
    }
280
20
}
281
282
0
pub fn hash_to_g2(msg: &[u8]) -> Signature {
283
0
    hash_to_g2_with_dst(msg, DST)
284
0
}
285
286
4.12k
pub fn hash_to_g2_with_dst(msg: &[u8], dst: &[u8]) -> Signature {
287
4.12k
    let p2 = unsafe {
288
4.12k
        let mut p2 = MaybeUninit::<blst_p2>::uninit();
289
4.12k
        blst_hash_to_g2(
290
4.12k
            p2.as_mut_ptr(),
291
4.12k
            msg.as_ptr(),
292
4.12k
            msg.len(),
293
4.12k
            dst.as_ptr(),
294
4.12k
            dst.len(),
295
4.12k
            std::ptr::null(),
296
4.12k
            0,
297
4.12k
        );
298
4.12k
        p2.assume_init()
299
4.12k
    };
300
4.12k
    Signature(p2)
301
4.12k
}
302
303
// aggregate the signatures into a single one. It can then be validated using
304
// aggregate_verify()
305
0
pub fn aggregate<Sig: Borrow<Signature>, I>(sigs: I) -> Signature
306
0
where
307
0
    I: IntoIterator<Item = Sig>,
308
0
{
309
0
    let mut ret = Signature::default();
310
311
0
    for s in sigs {
312
0
        ret.aggregate(s.borrow());
313
0
    }
314
0
    ret
315
0
}
316
317
// verify a signature given a single public key and message using the augmented
318
// scheme, i.e. the public key is pre-pended to the message before hashed to G2.
319
0
pub fn verify<Msg: AsRef<[u8]>>(sig: &Signature, key: &PublicKey, msg: Msg) -> bool {
320
0
    unsafe {
321
0
        let mut pubkey_affine = MaybeUninit::<blst_p1_affine>::uninit();
322
0
        let mut sig_affine = MaybeUninit::<blst_p2_affine>::uninit();
323
0
324
0
        blst_p1_to_affine(pubkey_affine.as_mut_ptr(), &key.0);
325
0
        blst_p2_to_affine(sig_affine.as_mut_ptr(), &sig.0);
326
0
327
0
        let mut augmented_msg = key.to_bytes().to_vec();
328
0
        augmented_msg.extend_from_slice(msg.as_ref());
329
0
330
0
        let err = blst_core_verify_pk_in_g1(
331
0
            &pubkey_affine.assume_init(),
332
0
            &sig_affine.assume_init(),
333
0
            true, // hash
334
0
            augmented_msg.as_ptr(),
335
0
            augmented_msg.len(),
336
0
            DST.as_ptr(),
337
0
            DST.len(),
338
0
            std::ptr::null(),
339
0
            0,
340
0
        );
341
0
342
0
        err == BLST_ERROR::BLST_SUCCESS
343
0
    }
344
0
}
345
346
// verify an aggregate signature given all public keys and messages.
347
// Messages will been augmented with the public key.
348
// returns true if the signature is valid.
349
4.85k
pub fn aggregate_verify<Pk: Borrow<PublicKey>, Msg: Borrow<[u8]>, I>(
350
4.85k
    sig: &Signature,
351
4.85k
    data: I,
352
4.85k
) -> bool
353
4.85k
where
354
4.85k
    I: IntoIterator<Item = (Pk, Msg)>,
355
4.85k
{
356
4.85k
    if !sig.is_valid() {
357
0
        return false;
358
4.85k
    }
359
4.85k
360
4.85k
    let mut data = data.into_iter().peekable();
361
4.85k
    if data.peek().is_none() {
362
722
        return *sig == Signature::default();
363
4.13k
    }
364
4.13k
365
4.13k
    let sig_gt = unsafe {
366
4.13k
        let mut sig_affine = MaybeUninit::<blst_p2_affine>::uninit();
367
4.13k
        let mut sig_gt = MaybeUninit::<blst_fp12>::uninit();
368
4.13k
        blst_p2_to_affine(sig_affine.as_mut_ptr(), &sig.0);
369
4.13k
        blst_aggregated_in_g2(sig_gt.as_mut_ptr(), sig_affine.as_ptr());
370
4.13k
        sig_gt.assume_init()
371
4.13k
    };
372
4.13k
373
4.13k
    let mut v: Vec<u64> = vec![0; unsafe { blst_pairing_sizeof() } / 8];
374
4.13k
    let ctx = unsafe {
375
4.13k
        let ctx = v.as_mut_ptr().cast::<blst_pairing>();
376
4.13k
        blst_pairing_init(
377
4.13k
            ctx,
378
4.13k
            true, // hash
379
4.13k
            DST.as_ptr(),
380
4.13k
            DST.len(),
381
4.13k
        );
382
4.13k
        ctx
383
4.13k
    };
384
4.13k
385
4.13k
    let mut aug_msg = Vec::<u8>::new();
386
8.11k
    for (pk, msg) in data {
387
5.96k
        if !pk.borrow().is_valid() {
388
0
            return false;
389
5.96k
        }
390
5.96k
391
5.96k
        let pk_affine = unsafe {
392
5.96k
            let mut pk_affine = MaybeUninit::<blst_p1_affine>::uninit();
393
5.96k
            blst_p1_to_affine(pk_affine.as_mut_ptr(), &pk.borrow().0);
394
5.96k
            pk_affine.assume_init()
395
5.96k
        };
396
5.96k
397
5.96k
        aug_msg.clear();
398
5.96k
        aug_msg.extend_from_slice(&pk.borrow().to_bytes());
399
5.96k
        aug_msg.extend_from_slice(msg.borrow());
400
5.96k
401
5.96k
        let err = unsafe {
402
5.96k
            blst_pairing_aggregate_pk_in_g1(
403
5.96k
                ctx,
404
5.96k
                &pk_affine,
405
5.96k
                std::ptr::null(),
406
5.96k
                aug_msg.as_ptr(),
407
5.96k
                aug_msg.len(),
408
5.96k
                std::ptr::null(),
409
5.96k
                0,
410
5.96k
            )
411
5.96k
        };
412
5.96k
413
5.96k
        if err != BLST_ERROR::BLST_SUCCESS {
414
1.98k
            return false;
415
3.98k
        }
416
    }
417
418
    unsafe {
419
2.14k
        blst_pairing_commit(ctx);
420
2.14k
        blst_pairing_finalverify(ctx, &sig_gt)
421
    }
422
4.85k
}
Unexecuted instantiation: _RINvNtCs568wuOlRYFZ_8chia_bls9signature16aggregate_verifypppEB4_
_RINvNtCs568wuOlRYFZ_8chia_bls9signature16aggregate_verifyNtNtB4_10public_key9PublicKeyNtNtCs4RkbDk9WRL5_5clvmr9allocator4AtomINtNtCsiBl6Lc3cFal_5alloc3vec3VecTBT_B1m_EEEB1q_
Line
Count
Source
349
4.85k
pub fn aggregate_verify<Pk: Borrow<PublicKey>, Msg: Borrow<[u8]>, I>(
350
4.85k
    sig: &Signature,
351
4.85k
    data: I,
352
4.85k
) -> bool
353
4.85k
where
354
4.85k
    I: IntoIterator<Item = (Pk, Msg)>,
355
4.85k
{
356
4.85k
    if !sig.is_valid() {
357
0
        return false;
358
4.85k
    }
359
4.85k
360
4.85k
    let mut data = data.into_iter().peekable();
361
4.85k
    if data.peek().is_none() {
362
722
        return *sig == Signature::default();
363
4.13k
    }
364
4.13k
365
4.13k
    let sig_gt = unsafe {
366
4.13k
        let mut sig_affine = MaybeUninit::<blst_p2_affine>::uninit();
367
4.13k
        let mut sig_gt = MaybeUninit::<blst_fp12>::uninit();
368
4.13k
        blst_p2_to_affine(sig_affine.as_mut_ptr(), &sig.0);
369
4.13k
        blst_aggregated_in_g2(sig_gt.as_mut_ptr(), sig_affine.as_ptr());
370
4.13k
        sig_gt.assume_init()
371
4.13k
    };
372
4.13k
373
4.13k
    let mut v: Vec<u64> = vec![0; unsafe { blst_pairing_sizeof() } / 8];
374
4.13k
    let ctx = unsafe {
375
4.13k
        let ctx = v.as_mut_ptr().cast::<blst_pairing>();
376
4.13k
        blst_pairing_init(
377
4.13k
            ctx,
378
4.13k
            true, // hash
379
4.13k
            DST.as_ptr(),
380
4.13k
            DST.len(),
381
4.13k
        );
382
4.13k
        ctx
383
4.13k
    };
384
4.13k
385
4.13k
    let mut aug_msg = Vec::<u8>::new();
386
8.11k
    for (pk, msg) in data {
387
5.96k
        if !pk.borrow().is_valid() {
388
0
            return false;
389
5.96k
        }
390
5.96k
391
5.96k
        let pk_affine = unsafe {
392
5.96k
            let mut pk_affine = MaybeUninit::<blst_p1_affine>::uninit();
393
5.96k
            blst_p1_to_affine(pk_affine.as_mut_ptr(), &pk.borrow().0);
394
5.96k
            pk_affine.assume_init()
395
5.96k
        };
396
5.96k
397
5.96k
        aug_msg.clear();
398
5.96k
        aug_msg.extend_from_slice(&pk.borrow().to_bytes());
399
5.96k
        aug_msg.extend_from_slice(msg.borrow());
400
5.96k
401
5.96k
        let err = unsafe {
402
5.96k
            blst_pairing_aggregate_pk_in_g1(
403
5.96k
                ctx,
404
5.96k
                &pk_affine,
405
5.96k
                std::ptr::null(),
406
5.96k
                aug_msg.as_ptr(),
407
5.96k
                aug_msg.len(),
408
5.96k
                std::ptr::null(),
409
5.96k
                0,
410
5.96k
            )
411
5.96k
        };
412
5.96k
413
5.96k
        if err != BLST_ERROR::BLST_SUCCESS {
414
1.98k
            return false;
415
3.98k
        }
416
    }
417
418
    unsafe {
419
2.14k
        blst_pairing_commit(ctx);
420
2.14k
        blst_pairing_finalverify(ctx, &sig_gt)
421
    }
422
4.85k
}
423
424
// verify an aggregate signature by pre-paired public keys and messages.
425
// Messages having been augmented and hashed to G2 and then paired with the G1
426
// public key.
427
// returns true if the signature is valid.
428
0
pub fn aggregate_verify_gt<Gt: Borrow<GTElement>, I>(sig: &Signature, data: I) -> bool
429
0
where
430
0
    I: IntoIterator<Item = Gt>,
431
0
{
432
0
    if !sig.is_valid() {
433
0
        return false;
434
0
    }
435
0
436
0
    let mut data = data.into_iter();
437
0
    let Some(agg) = data.next() else {
438
0
        return *sig == Signature::default();
439
    };
440
441
0
    let mut agg = agg.borrow().clone();
442
0
    for gt in data {
443
0
        agg *= gt.borrow();
444
0
    }
445
446
0
    agg == sig.pair(&PublicKey::generator())
447
0
}
448
449
// Signs msg using sk without augmenting the message with the public key. This
450
// function is used when the caller augments the message with some other public
451
// key
452
0
pub fn sign_raw<Msg: AsRef<[u8]>>(sk: &SecretKey, msg: Msg) -> Signature {
453
0
    let p2 = unsafe {
454
0
        let mut p2 = MaybeUninit::<blst_p2>::uninit();
455
0
        blst_hash_to_g2(
456
0
            p2.as_mut_ptr(),
457
0
            msg.as_ref().as_ptr(),
458
0
            msg.as_ref().len(),
459
0
            DST.as_ptr(),
460
0
            DST.len(),
461
0
            std::ptr::null(),
462
0
            0,
463
0
        );
464
0
        blst_sign_pk_in_g1(p2.as_mut_ptr(), p2.as_ptr(), &sk.0);
465
0
        p2.assume_init()
466
0
    };
467
0
    Signature(p2)
468
0
}
469
470
// Signs msg using sk using the augmented scheme, meaning the public key is
471
// pre-pended to msg befire signing.
472
0
pub fn sign<Msg: AsRef<[u8]>>(sk: &SecretKey, msg: Msg) -> Signature {
473
0
    let mut aug_msg = sk.public_key().to_bytes().to_vec();
474
0
    aug_msg.extend_from_slice(msg.as_ref());
475
0
    sign_raw(sk, aug_msg)
476
0
}
477
478
#[cfg(feature = "py-bindings")]
479
mod pybindings {
480
    use super::*;
481
482
    use crate::parse_hex::parse_hex_string;
483
484
    use chia_traits::{FromJsonDict, ToJsonDict};
485
    use pyo3::prelude::*;
486
487
    #[pymethods]
488
    impl Signature {
489
        #[classattr]
490
        const SIZE: usize = 96;
491
492
        #[new]
493
        pub fn init() -> Self {
494
            Self::default()
495
        }
496
497
        #[pyo3(name = "pair")]
498
        pub fn py_pair(&self, other: &PublicKey) -> GTElement {
499
            self.pair(other)
500
        }
501
502
        #[staticmethod]
503
        #[pyo3(name = "generator")]
504
        pub fn py_generator() -> Self {
505
            Self::generator()
506
        }
507
508
        fn __str__(&self) -> String {
509
            hex::encode(self.to_bytes())
510
        }
511
512
        #[must_use]
513
        pub fn __add__(&self, rhs: &Self) -> Self {
514
            self + rhs
515
        }
516
517
        pub fn __iadd__(&mut self, rhs: &Self) {
518
            *self += rhs;
519
        }
520
    }
521
522
    impl ToJsonDict for Signature {
523
        fn to_json_dict(&self, py: Python<'_>) -> PyResult<PyObject> {
524
            let bytes = self.to_bytes();
525
            Ok(("0x".to_string() + &hex::encode(bytes)).into_py(py))
526
        }
527
    }
528
529
    impl FromJsonDict for Signature {
530
        fn from_json_dict(o: &Bound<'_, PyAny>) -> PyResult<Self> {
531
            Ok(Self::from_bytes(
532
                parse_hex_string(o, 96, "Signature")?
533
                    .as_slice()
534
                    .try_into()
535
                    .unwrap(),
536
            )?)
537
        }
538
    }
539
}
540
541
#[cfg(test)]
542
mod tests {
543
    use super::*;
544
    use hex::FromHex;
545
    use rand::rngs::StdRng;
546
    use rand::{Rng, SeedableRng};
547
    use rstest::rstest;
548
549
    #[test]
550
    fn test_from_bytes() {
551
        let mut rng = StdRng::seed_from_u64(1337);
552
        let mut data = [0u8; 96];
553
        for _i in 0..50 {
554
            rng.fill(data.as_mut_slice());
555
            // just any random bytes are not a valid signature and should fail
556
            match Signature::from_bytes(&data) {
557
                Err(Error::InvalidSignature(err)) => {
558
                    assert!([
559
                        BLST_ERROR::BLST_BAD_ENCODING,
560
                        BLST_ERROR::BLST_POINT_NOT_ON_CURVE
561
                    ]
562
                    .contains(&err));
563
                }
564
                Err(e) => {
565
                    panic!("unexpected error from_bytes(): {e}");
566
                }
567
                Ok(v) => {
568
                    panic!("unexpected value from_bytes(): {v:?}");
569
                }
570
            }
571
        }
572
    }
573
574
    #[test]
575
    fn test_default_is_valid() {
576
        let sig = Signature::default();
577
        assert!(sig.is_valid());
578
    }
579
580
    #[test]
581
    fn test_infinity_is_valid() {
582
        let mut data = [0u8; 96];
583
        data[0] = 0xc0;
584
        let sig = Signature::from_bytes(&data).unwrap();
585
        assert!(sig.is_valid());
586
    }
587
588
    #[test]
589
    fn test_is_valid() {
590
        let mut rng = StdRng::seed_from_u64(1337);
591
        let mut data = [0u8; 32];
592
        let msg = [0u8; 32];
593
        for _i in 0..50 {
594
            rng.fill(data.as_mut_slice());
595
            let sk = SecretKey::from_seed(&data);
596
            let sig = sign(&sk, msg);
597
            assert!(sig.is_valid());
598
        }
599
    }
600
601
    #[test]
602
    fn test_roundtrip() {
603
        let mut rng = StdRng::seed_from_u64(1337);
604
        let mut data = [0u8; 32];
605
        let mut msg = [0u8; 32];
606
        rng.fill(msg.as_mut_slice());
607
        for _i in 0..50 {
608
            rng.fill(data.as_mut_slice());
609
            let sk = SecretKey::from_seed(&data);
610
            let sig = sign(&sk, msg);
611
            let bytes = sig.to_bytes();
612
            let sig2 = Signature::from_bytes(&bytes).unwrap();
613
            assert_eq!(sig, sig2);
614
        }
615
    }
616
617
    #[test]
618
    fn test_random_verify() {
619
        let mut rng = StdRng::seed_from_u64(1337);
620
        let mut data = [0u8; 32];
621
        let mut msg = [0u8; 32];
622
        rng.fill(msg.as_mut_slice());
623
        for _i in 0..20 {
624
            rng.fill(data.as_mut_slice());
625
            let sk = SecretKey::from_seed(&data);
626
            let pk = sk.public_key();
627
            let sig = sign(&sk, msg);
628
            assert!(verify(&sig, &pk, msg));
629
630
            let bytes = sig.to_bytes();
631
            let sig2 = Signature::from_bytes(&bytes).unwrap();
632
            assert!(verify(&sig2, &pk, msg));
633
        }
634
    }
635
636
    #[test]
637
    fn test_verify() {
638
        // test case from:
639
        // from blspy import PrivateKey
640
        // from blspy import AugSchemeMPL
641
        // sk = PrivateKey.from_bytes(bytes.fromhex("52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb"))
642
        // data = b"foobar"
643
        // print(AugSchemeMPL.sign(sk, data))
644
        let msg = b"foobar";
645
        let sk = SecretKey::from_bytes(
646
            &<[u8; 32]>::from_hex(
647
                "52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb",
648
            )
649
            .unwrap(),
650
        )
651
        .unwrap();
652
653
        let sig = sign(&sk, msg);
654
        assert!(verify(&sig, &sk.public_key(), msg));
655
656
        assert_eq!(sig.to_bytes(), <[u8; 96]>::from_hex("b45825c0ee7759945c0189b4c38b7e54231ebadc83a851bec3bb7cf954a124ae0cc8e8e5146558332ea152f63bf8846e04826185ef60e817f271f8d500126561319203f9acb95809ed20c193757233454be1562a5870570941a84605bd2c9c9a").unwrap());
657
    }
658
659
    fn aug_msg_to_g2(pk: &PublicKey, msg: &[u8]) -> Signature {
660
        let mut augmented = pk.to_bytes().to_vec();
661
        augmented.extend_from_slice(msg);
662
        hash_to_g2(augmented.as_slice())
663
    }
664
665
    #[test]
666
    fn test_aggregate_signature() {
667
        // from blspy import PrivateKey
668
        // from blspy import AugSchemeMPL
669
        // sk = PrivateKey.from_bytes(bytes.fromhex("52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb"))
670
        // data = b"foobar"
671
        // sk0 = AugSchemeMPL.derive_child_sk(sk, 0)
672
        // sk1 = AugSchemeMPL.derive_child_sk(sk, 1)
673
        // sk2 = AugSchemeMPL.derive_child_sk(sk, 2)
674
        // sk3 = AugSchemeMPL.derive_child_sk(sk, 3)
675
676
        // sig0 = AugSchemeMPL.sign(sk0, data)
677
        // sig1 = AugSchemeMPL.sign(sk1, data)
678
        // sig2 = AugSchemeMPL.sign(sk2, data)
679
        // sig3 = AugSchemeMPL.sign(sk3, data)
680
681
        // agg = AugSchemeMPL.aggregate([sig0, sig1, sig2, sig3])
682
683
        // 87bce2c588f4257e2792d929834548c7d3af679272cb4f8e1d24cf4bf584dd287aa1d9f5e53a86f288190db45e1d100d0a5e936079a66a709b5f35394cf7d52f49dd963284cb5241055d54f8cf48f61bc1037d21cae6c025a7ea5e9f4d289a18
684
685
        let sk_hex = "52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb";
686
        let sk = SecretKey::from_bytes(&<[u8; 32]>::from_hex(sk_hex).unwrap()).unwrap();
687
        let msg = b"foobar";
688
        let mut agg1 = Signature::default();
689
        let mut agg2 = Signature::default();
690
        let mut sigs = Vec::<Signature>::new();
691
        let mut data = Vec::<(PublicKey, &[u8])>::new();
692
        let mut pairs = Vec::<(PublicKey, Signature)>::new();
693
        for idx in 0..4 {
694
            let derived = sk.derive_hardened(idx as u32);
695
            let pk = derived.public_key();
696
            data.push((pk, msg));
697
            let sig = sign(&derived, msg);
698
            agg1.aggregate(&sig);
699
            agg2 += &sig;
700
            sigs.push(sig);
701
            pairs.push((pk, aug_msg_to_g2(&pk, msg)));
702
        }
703
        let agg3 = aggregate(&sigs);
704
        let agg4 = &sigs[0] + &sigs[1] + &sigs[2] + &sigs[3];
705
706
        assert_eq!(agg1.to_bytes(), <[u8; 96]>::from_hex("87bce2c588f4257e2792d929834548c7d3af679272cb4f8e1d24cf4bf584dd287aa1d9f5e53a86f288190db45e1d100d0a5e936079a66a709b5f35394cf7d52f49dd963284cb5241055d54f8cf48f61bc1037d21cae6c025a7ea5e9f4d289a18").unwrap());
707
        assert_eq!(agg1, agg2);
708
        assert_eq!(agg1, agg3);
709
        assert_eq!(agg1, agg4);
710
711
        // ensure the aggregate signature verifies OK
712
        assert!(aggregate_verify(&agg1, data.clone()));
713
        assert!(aggregate_verify(&agg2, data.clone()));
714
        assert!(aggregate_verify(&agg3, data.clone()));
715
        assert!(aggregate_verify(&agg4, data.clone()));
716
717
        pairs.push((-PublicKey::generator(), agg1));
718
        assert!(aggregate_pairing(pairs.clone()));
719
        // order does not matter
720
        assert!(aggregate_pairing(pairs.into_iter().rev()));
721
    }
722
723
    #[rstest]
724
    fn test_aggregate_gt_signature(#[values(0, 1, 2, 3, 4, 5, 100)] num_keys: usize) {
725
        let sk_hex = "52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb";
726
        let sk = SecretKey::from_bytes(&<[u8; 32]>::from_hex(sk_hex).unwrap()).unwrap();
727
        let msg = b"foobar";
728
        let mut agg = Signature::default();
729
        let mut gts = Vec::<GTElement>::new();
730
        let mut pks = Vec::<PublicKey>::new();
731
        for idx in 0..num_keys {
732
            let derived = sk.derive_hardened(idx as u32);
733
            let pk = derived.public_key();
734
            let sig = sign(&derived, msg);
735
            agg.aggregate(&sig);
736
            gts.push(aug_msg_to_g2(&pk, msg).pair(&pk));
737
            pks.push(pk);
738
        }
739
740
        assert!(aggregate_verify_gt(&agg, &gts));
741
        assert!(aggregate_verify(&agg, pks.iter().map(|pk| (pk, &msg[..]))));
742
743
        // the order of the GTElements does not matter
744
        for _ in 0..num_keys {
745
            gts.rotate_right(1);
746
            pks.rotate_right(1);
747
            assert!(aggregate_verify_gt(&agg, &gts));
748
            assert!(aggregate_verify(&agg, pks.iter().map(|pk| (pk, &msg[..]))));
749
        }
750
        for _ in 0..num_keys {
751
            gts.rotate_right(1);
752
            pks.rotate_right(1);
753
            assert!(!aggregate_verify_gt(&agg, &gts[1..]));
754
            assert!(!aggregate_verify(
755
                &agg,
756
                pks[1..].iter().map(|pk| (pk, &msg[..]))
757
            ));
758
        }
759
    }
760
761
    #[test]
762
    fn test_aggregate_duplicate_signature() {
763
        let sk_hex = "52d75c4707e39595b27314547f9723e5530c01198af3fc5849d9a7af65631efb";
764
        let sk = SecretKey::from_bytes(&<[u8; 32]>::from_hex(sk_hex).unwrap()).unwrap();
765
        let msg = b"foobar";
766
        let mut agg = Signature::default();
767
        let mut data = Vec::<(PublicKey, &[u8])>::new();
768
        let mut pairs = Vec::<(PublicKey, Signature)>::new();
769
        for _idx in 0..2 {
770
            let pk = sk.public_key();
771
            data.push((pk, msg));
772
            agg.aggregate(&sign(&sk, *msg));
773
774
            pairs.push((pk, aug_msg_to_g2(&pk, msg)));
775
        }
776
777
        assert_eq!(agg.to_bytes(), <[u8; 96]>::from_hex("a1cca6540a4a06d096cb5b5fc76af5fd099476e70b623b8c6e4cf02ffde94fc0f75f4e17c67a9e350940893306798a3519368b02dc3464b7270ea4ca233cfa85a38da9e25c9314e81270b54d1e773a2ec5c3e14c62dac7abdebe52f4688310d3").unwrap());
778
779
        assert!(aggregate_verify(&agg, data));
780
781
        pairs.push((-PublicKey::generator(), agg));
782
        assert!(aggregate_pairing(pairs.clone()));
783
        // order does not matter
784
        assert!(aggregate_pairing(pairs.into_iter().rev()));
785
    }
786
787
    #[cfg(test)]
788
    fn random_sk<R: Rng>(rng: &mut R) -> SecretKey {
789
        let mut data = [0u8; 64];
790
        rng.fill(data.as_mut_slice());
791
        SecretKey::from_seed(&data)
792
    }
793
794
    #[test]
795
    fn test_aggregate_signature_separate_msg() {
796
        let mut rng = StdRng::seed_from_u64(1337);
797
        let sk = [random_sk(&mut rng), random_sk(&mut rng)];
798
        let pk = [sk[0].public_key(), sk[1].public_key()];
799
        let msg: [&'static [u8]; 2] = [b"foo", b"foobar"];
800
        let sig = [sign(&sk[0], msg[0]), sign(&sk[1], msg[1])];
801
        let mut agg = Signature::default();
802
        agg.aggregate(&sig[0]);
803
        agg.aggregate(&sig[1]);
804
805
        assert!(aggregate_verify(&agg, pk.iter().zip(msg)));
806
        // order does not matter
807
        assert!(aggregate_verify(&agg, pk.iter().zip(msg).rev()));
808
    }
809
810
    #[test]
811
    fn test_aggregate_signature_identity() {
812
        // when verifying 0 messages, an identity signature is considered valid
813
        let empty = Vec::<(PublicKey, &[u8])>::new();
814
        assert!(aggregate_verify(&Signature::default(), empty));
815
816
        let pairs = vec![(-PublicKey::generator(), Signature::default())];
817
        assert!(aggregate_pairing(pairs));
818
    }
819
820
    #[test]
821
    fn test_invalid_aggregate_signature() {
822
        let mut rng = StdRng::seed_from_u64(1337);
823
        let sk = [random_sk(&mut rng), random_sk(&mut rng)];
824
        let pk = [sk[0].public_key(), sk[1].public_key()];
825
        let msg: [&'static [u8]; 2] = [b"foo", b"foobar"];
826
        let sig = [sign(&sk[0], msg[0]), sign(&sk[1], msg[1])];
827
        let g2s = [aug_msg_to_g2(&pk[0], msg[0]), aug_msg_to_g2(&pk[1], msg[1])];
828
        let mut agg = Signature::default();
829
        agg.aggregate(&sig[0]);
830
        agg.aggregate(&sig[1]);
831
832
        assert!(!aggregate_verify(&agg, [(&pk[0], msg[0])]));
833
        assert!(!aggregate_verify(&agg, [(&pk[1], msg[1])]));
834
        // public keys mixed with the wrong message
835
        assert!(!aggregate_verify(
836
            &agg,
837
            [(&pk[0], msg[1]), (&pk[1], msg[0])]
838
        ));
839
        assert!(!aggregate_verify(
840
            &agg,
841
            [(&pk[1], msg[0]), (&pk[0], msg[1])]
842
        ));
843
844
        let gen_sig = (&-PublicKey::generator(), agg);
845
        assert!(!aggregate_pairing([
846
            (&pk[0], g2s[0].clone()),
847
            gen_sig.clone()
848
        ]));
849
        assert!(!aggregate_pairing([
850
            (&pk[1], g2s[1].clone()),
851
            gen_sig.clone()
852
        ]));
853
        // public keys mixed with the wrong message
854
        assert!(!aggregate_pairing([
855
            (&pk[0], g2s[1].clone()),
856
            (&pk[1], g2s[0].clone()),
857
            gen_sig.clone()
858
        ]));
859
        assert!(!aggregate_pairing([
860
            (&pk[1], g2s[0].clone()),
861
            (&pk[0], g2s[1].clone()),
862
            gen_sig.clone()
863
        ]));
864
    }
865
866
    #[test]
867
    fn test_vector_2_aggregate_of_aggregates() {
868
        // test case from: bls-signatures/src/test.cpp
869
        // "Chia test vector 2 (Augmented, aggregate of aggregates)"
870
        let message1 = [1_u8, 2, 3, 40];
871
        let message2 = [5_u8, 6, 70, 201];
872
        let message3 = [9_u8, 10, 11, 12, 13];
873
        let message4 = [15_u8, 63, 244, 92, 0, 1];
874
875
        let sk1 = SecretKey::from_seed(&[2_u8; 32]);
876
        let sk2 = SecretKey::from_seed(&[3_u8; 32]);
877
878
        let pk1 = sk1.public_key();
879
        let pk2 = sk2.public_key();
880
881
        let sig1 = sign(&sk1, message1);
882
        let sig2 = sign(&sk2, message2);
883
        let sig3 = sign(&sk2, message1);
884
        let sig4 = sign(&sk1, message3);
885
        let sig5 = sign(&sk1, message1);
886
        let sig6 = sign(&sk1, message4);
887
888
        let agg_sig_l = aggregate([sig1, sig2]);
889
        let agg_sig_r = aggregate([sig3, sig4, sig5]);
890
        let aggsig = aggregate([agg_sig_l, agg_sig_r, sig6]);
891
892
        assert!(aggregate_verify(
893
            &aggsig,
894
            [
895
                (&pk1, message1.as_ref()),
896
                (&pk2, message2.as_ref()),
897
                (&pk2, message1.as_ref()),
898
                (&pk1, message3.as_ref()),
899
                (&pk1, message1.as_ref()),
900
                (&pk1, message4.as_ref())
901
            ]
902
        ));
903
904
        assert_eq!(
905
            aggsig.to_bytes(),
906
            <[u8; 96]>::from_hex(
907
                "a1d5360dcb418d33b29b90b912b4accde535cf0e52caf467a005dc632d9f7af44b6c4e9acd4\
908
            6eac218b28cdb07a3e3bc087df1cd1e3213aa4e11322a3ff3847bbba0b2fd19ddc25ca964871\
909
            997b9bceeab37a4c2565876da19382ea32a962200"
910
            )
911
            .unwrap()
912
        );
913
    }
914
915
    #[test]
916
    fn test_signature_zero_key() {
917
        // test case from: bls-signatures/src/test.cpp
918
        // "Should sign with the zero key"
919
        let sk = SecretKey::from_bytes(&[0; 32]).unwrap();
920
        assert_eq!(sign(&sk, [1_u8, 2, 3]), Signature::default());
921
    }
922
923
    #[test]
924
    fn test_aggregate_many_g2_elements_diff_message() {
925
        // test case from: bls-signatures/src/test.cpp
926
        // "Should Aug aggregate many G2Elements, diff message"
927
928
        let mut rng = StdRng::seed_from_u64(1337);
929
930
        let mut pairs = Vec::<(PublicKey, Vec<u8>)>::new();
931
        let mut sigs = Vec::<Signature>::new();
932
933
        for i in 0..80 {
934
            let message = vec![0_u8, 100, 2, 45, 64, 12, 12, 63, i];
935
            let sk = random_sk(&mut rng);
936
            let sig = sign(&sk, &message);
937
            pairs.push((sk.public_key(), message));
938
            sigs.push(sig);
939
        }
940
941
        let aggsig = aggregate(sigs);
942
943
        assert!(aggregate_verify(&aggsig, pairs));
944
    }
945
946
    #[test]
947
    fn test_aggregate_identity() {
948
        // test case from: bls-signatures/src/test.cpp
949
        // "Aggregate Verification of zero items with infinity should pass"
950
        let sig = Signature::default();
951
        let aggsig = aggregate([&sig]);
952
        assert_eq!(aggsig, sig);
953
        assert_eq!(aggsig, Signature::default());
954
955
        let pairs: [(&PublicKey, &[u8]); 0] = [];
956
        assert!(aggregate_verify(&aggsig, pairs));
957
    }
958
959
    #[test]
960
    fn test_aggregate_multiple_levels_degenerate() {
961
        // test case from: bls-signatures/src/test.cpp
962
        // "Should aggregate with multiple levels, degenerate"
963
964
        let mut rng = StdRng::seed_from_u64(1337);
965
966
        let message1 = [100_u8, 2, 254, 88, 90, 45, 23];
967
        let sk1 = random_sk(&mut rng);
968
        let pk1 = sk1.public_key();
969
        let mut agg_sig = sign(&sk1, message1);
970
        let mut pairs: Vec<(PublicKey, &[u8])> = vec![(pk1, &message1)];
971
972
        for _i in 0..10 {
973
            let sk = random_sk(&mut rng);
974
            let pk = sk.public_key();
975
            pairs.push((pk, &message1));
976
            let sig = sign(&sk, message1);
977
            agg_sig.aggregate(&sig);
978
        }
979
        assert!(aggregate_verify(&agg_sig, pairs));
980
    }
981
982
    #[test]
983
    fn test_aggregate_multiple_levels_different_messages() {
984
        // test case from: bls-signatures/src/test.cpp
985
        // "Should aggregate with multiple levels, different messages"
986
987
        let mut rng = StdRng::seed_from_u64(1337);
988
989
        let message1 = [100_u8, 2, 254, 88, 90, 45, 23];
990
        let message2 = [192_u8, 29, 2, 0, 0, 45, 23];
991
        let message3 = [52_u8, 29, 2, 0, 0, 45, 102];
992
        let message4 = [99_u8, 29, 2, 0, 0, 45, 222];
993
994
        let sk1 = random_sk(&mut rng);
995
        let sk2 = random_sk(&mut rng);
996
997
        let pk1 = sk1.public_key();
998
        let pk2 = sk2.public_key();
999
1000
        let sig1 = sign(&sk1, message1);
1001
        let sig2 = sign(&sk2, message2);
1002
        let sig3 = sign(&sk2, message3);
1003
        let sig4 = sign(&sk1, message4);
1004
1005
        let agg_sig_l = aggregate([sig1, sig2]);
1006
        let agg_sig_r = aggregate([sig3, sig4]);
1007
        let agg_sig = aggregate([agg_sig_l, agg_sig_r]);
1008
1009
        let all_pairs: [(&PublicKey, &[u8]); 4] = [
1010
            (&pk1, &message1),
1011
            (&pk2, &message2),
1012
            (&pk2, &message3),
1013
            (&pk1, &message4),
1014
        ];
1015
        assert!(aggregate_verify(&agg_sig, all_pairs));
1016
    }
1017
1018
    #[test]
1019
    fn test_aug_scheme() {
1020
        // test case from: bls-signatures/src/test.cpp
1021
        // "Aug Scheme"
1022
1023
        let msg1 = [7_u8, 8, 9];
1024
        let msg2 = [10_u8, 11, 12];
1025
1026
        let sk1 = SecretKey::from_seed(&[4_u8; 32]);
1027
        let pk1 = sk1.public_key();
1028
        let pk1v = pk1.to_bytes();
1029
        let sig1 = sign(&sk1, msg1);
1030
        let sig1v = sig1.to_bytes();
1031
1032
        assert!(verify(&sig1, &pk1, msg1));
1033
        assert!(verify(
1034
            &Signature::from_bytes(&sig1v).unwrap(),
1035
            &PublicKey::from_bytes(&pk1v).unwrap(),
1036
            msg1
1037
        ));
1038
1039
        let sk2 = SecretKey::from_seed(&[5_u8; 32]);
1040
        let pk2 = sk2.public_key();
1041
        let pk2v = pk2.to_bytes();
1042
        let sig2 = sign(&sk2, msg2);
1043
        let sig2v = sig2.to_bytes();
1044
1045
        assert!(verify(&sig2, &pk2, msg2));
1046
        assert!(verify(
1047
            &Signature::from_bytes(&sig2v).unwrap(),
1048
            &PublicKey::from_bytes(&pk2v).unwrap(),
1049
            msg2
1050
        ));
1051
1052
        // Wrong G2Element
1053
        assert!(!verify(&sig2, &pk1, msg1));
1054
        assert!(!verify(
1055
            &Signature::from_bytes(&sig2v).unwrap(),
1056
            &PublicKey::from_bytes(&pk1v).unwrap(),
1057
            msg1
1058
        ));
1059
        // Wrong msg
1060
        assert!(!verify(&sig1, &pk1, msg2));
1061
        assert!(!verify(
1062
            &Signature::from_bytes(&sig1v).unwrap(),
1063
            &PublicKey::from_bytes(&pk1v).unwrap(),
1064
            msg2
1065
        ));
1066
        // Wrong pk
1067
        assert!(!verify(&sig1, &pk2, msg1));
1068
        assert!(!verify(
1069
            &Signature::from_bytes(&sig1v).unwrap(),
1070
            &PublicKey::from_bytes(&pk2v).unwrap(),
1071
            msg1
1072
        ));
1073
1074
        let aggsig = aggregate([sig1, sig2]);
1075
        let aggsigv = aggsig.to_bytes();
1076
        let pairs: [(&PublicKey, &[u8]); 2] = [(&pk1, &msg1), (&pk2, &msg2)];
1077
        assert!(aggregate_verify(&aggsig, pairs));
1078
        assert!(aggregate_verify(
1079
            &Signature::from_bytes(&aggsigv).unwrap(),
1080
            pairs
1081
        ));
1082
    }
1083
1084
    #[test]
1085
    fn test_hash() {
1086
        fn hash<T: Hash>(v: T) -> u64 {
1087
            use std::collections::hash_map::DefaultHasher;
1088
            let mut h = DefaultHasher::new();
1089
            v.hash(&mut h);
1090
            h.finish()
1091
        }
1092
1093
        let mut rng = StdRng::seed_from_u64(1337);
1094
        let mut data = [0u8; 32];
1095
        rng.fill(data.as_mut_slice());
1096
        let sk = SecretKey::from_seed(&data);
1097
        let sig1 = sign(&sk, [0, 1, 2]);
1098
        let sig2 = sign(&sk, [0, 1, 2, 3]);
1099
1100
        assert!(hash(sig1) != hash(sig2));
1101
        assert_eq!(hash(sign(&sk, [0, 1, 2])), hash(sign(&sk, [0, 1, 2])));
1102
    }
1103
1104
    #[test]
1105
    fn test_debug() {
1106
        let mut data = [0u8; 96];
1107
        data[0] = 0xc0;
1108
        let sig = Signature::from_bytes(&data).unwrap();
1109
        assert_eq!(
1110
            format!("{sig:?}"),
1111
            format!("<G2Element {}>", hex::encode(data))
1112
        );
1113
    }
1114
1115
    #[test]
1116
    fn test_generator() {
1117
        assert_eq!(
1118
        hex::encode(Signature::generator().to_bytes()),
1119
        "93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8"
1120
        );
1121
    }
1122
1123
    // test cases from zksnark test in chia_rs
1124
    #[rstest]
1125
    #[case("0a7ecb9c6d6f0af8d922c9b348d686f7f827c5f5d7a53036e5dd6c4cfe088806375d730251df57c03b0eaa41ca2a9cc51817cfd6118c065e9b337e42a6b66621e2ffa79f576ae57dcb4916459b0131d42383b790a4f60c5aeb339b61a78d85a808b73e0701084dc16b5d7aa8c2f5385f83a217bc29934d0d02c51365410232e3c0288438e3110aa6e8cdef7bd32c46d60d0104952aaa0f0545cbe1548b70eed8b543ce19ede34cc51a387d092221417db0253f4651666b17303e225eac706107", "8a7ecb9c6d6f0af8d922c9b348d686f7f827c5f5d7a53036e5dd6c4cfe088806375d730251df57c03b0eaa41ca2a9cc51817cfd6118c065e9b337e42a6b66621e2ffa79f576ae57dcb4916459b0131d42383b790a4f60c5aeb339b61a78d85a8")]
1126
    #[case("13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801", "93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8")]
1127
    #[case("140acf170629d78244fb753f05fb79578add9217add53996d5de7c3005880c0dea903f851d6be749ebfb81c9721871370ef60428444d76f4ff81515628a4eb63e72c3cd7651a23c4eca109d1d88fec5a53626b36c76407926f308366b5ded1b219a481d87c6f87a4021fa8aa32851874f01b3eb011f6ed69c7884717fb0f5239bdc7310c2bc287659cd4a93976deaac20f4a21f0b004c767be4a21f36861616a5399b3e27431dc8133f325603230eaf1debdce8077105ab46baafa4836842305", "b40acf170629d78244fb753f05fb79578add9217add53996d5de7c3005880c0dea903f851d6be749ebfb81c9721871370ef60428444d76f4ff81515628a4eb63e72c3cd7651a23c4eca109d1d88fec5a53626b36c76407926f308366b5ded1b2")]
1128
    fn test_from_uncompressed(#[case] input: &str, #[case] expect: &str) {
1129
        let input = hex::decode(input).unwrap();
1130
        let g2 = Signature::from_uncompressed(input.as_slice().try_into().unwrap()).unwrap();
1131
        let compressed = g2.to_bytes();
1132
        assert_eq!(hex::encode(compressed), expect);
1133
    }
1134
1135
    #[test]
1136
    fn test_negate_roundtrip() {
1137
        let mut rng = StdRng::seed_from_u64(1337);
1138
        let mut data = [0u8; 32];
1139
        let mut msg = [0u8; 32];
1140
        rng.fill(msg.as_mut_slice());
1141
        for _i in 0..50 {
1142
            rng.fill(data.as_mut_slice());
1143
            let sk = SecretKey::from_seed(&data);
1144
            let g2 = sign(&sk, msg);
1145
1146
            let mut g2_neg = g2.clone();
1147
            g2_neg.negate();
1148
            assert!(g2_neg != g2);
1149
1150
            g2_neg.negate();
1151
            assert!(g2_neg == g2);
1152
        }
1153
    }
1154
1155
    #[test]
1156
    fn test_negate_infinity() {
1157
        let g2 = Signature::default();
1158
        let mut g2_neg = g2.clone();
1159
        // negate on infinity is a no-op
1160
        g2_neg.negate();
1161
        assert!(g2_neg == g2);
1162
    }
1163
1164
    #[test]
1165
    fn test_negate() {
1166
        let mut rng = StdRng::seed_from_u64(1337);
1167
        let mut data = [0u8; 32];
1168
        let mut msg = [0u8; 32];
1169
        rng.fill(msg.as_mut_slice());
1170
        for _i in 0..50 {
1171
            rng.fill(data.as_mut_slice());
1172
            let sk = SecretKey::from_seed(&data);
1173
            let g2 = sign(&sk, msg);
1174
            let mut g2_neg = g2.clone();
1175
            g2_neg.negate();
1176
1177
            let mut g2_double = g2.clone();
1178
            // adding the negative undoes adding the positive
1179
            g2_double += &g2;
1180
            assert!(g2_double != g2);
1181
            g2_double += &g2_neg;
1182
            assert!(g2_double == g2);
1183
        }
1184
    }
1185
1186
    #[test]
1187
    fn test_scalar_multiply() {
1188
        let mut rng = StdRng::seed_from_u64(1337);
1189
        let mut data = [0u8; 32];
1190
        let mut msg = [0u8; 32];
1191
        rng.fill(msg.as_mut_slice());
1192
        for _i in 0..50 {
1193
            rng.fill(data.as_mut_slice());
1194
            let sk = SecretKey::from_seed(&data);
1195
            let mut g2 = sign(&sk, msg);
1196
            let mut g2_double = g2.clone();
1197
            g2_double += &g2;
1198
            assert!(g2_double != g2);
1199
            // scalar multiply by 2 is the same as adding oneself
1200
            g2.scalar_multiply(&[2]);
1201
            assert!(g2_double == g2);
1202
        }
1203
    }
1204
1205
    #[test]
1206
    fn test_hash_to_g2_different_dst() {
1207
        const DEFAULT_DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_";
1208
        const CUSTOM_DST: &[u8] = b"foobar";
1209
1210
        let mut rng = StdRng::seed_from_u64(1337);
1211
        let mut msg = [0u8; 32];
1212
        for _i in 0..50 {
1213
            rng.fill(&mut msg);
1214
            let default_hash = hash_to_g2(&msg);
1215
            assert_eq!(default_hash, hash_to_g2_with_dst(&msg, DEFAULT_DST));
1216
            assert!(default_hash != hash_to_g2_with_dst(&msg, CUSTOM_DST));
1217
        }
1218
    }
1219
1220
    // test cases from clvm_rs
1221
    #[rstest]
1222
    #[case("abcdef0123456789", "92596412844e12c4733b5a6bfc5727cde4c20b345665d2de99de163266f3ba6a944c6c0fdd9d9fe57b9a4acb769bf3780456f8aab4cd41a70836dba57a5278a85fbd18eb96a2b56cfbda853186c9d190c43e63bc3e6a181aed692e97bbdb1944")]
1223
    fn test_hash_to_g2(#[case] input: &str, #[case] expect: &str) {
1224
        let g2 = hash_to_g2(input.as_bytes());
1225
        assert_eq!(hex::encode(g2.to_bytes()), expect);
1226
    }
1227
1228
    // test cases from clvm_rs
1229
    #[rstest]
1230
    #[case("abcdef0123456789", "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_", "8ee1ff66094b8975401c86ad424076d97fed9c2025db5f9dfde6ed455c7bff34b55e96379c1f9ee3c173633587f425e50aed3e807c6c7cd7bed35d40542eee99891955b2ea5321ebde37172e2c01155138494c2d725b03c02765828679bf011e")]
1231
    #[case("abcdef0123456789", "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_", "92596412844e12c4733b5a6bfc5727cde4c20b345665d2de99de163266f3ba6a944c6c0fdd9d9fe57b9a4acb769bf3780456f8aab4cd41a70836dba57a5278a85fbd18eb96a2b56cfbda853186c9d190c43e63bc3e6a181aed692e97bbdb1944")]
1232
    fn test_hash_to_g2_with_dst(#[case] input: &str, #[case] dst: &str, #[case] expect: &str) {
1233
        let g2 = hash_to_g2_with_dst(input.as_bytes(), dst.as_bytes());
1234
        assert_eq!(hex::encode(g2.to_bytes()), expect);
1235
    }
1236
}
1237
1238
#[cfg(test)]
1239
#[cfg(feature = "py-bindings")]
1240
mod pytests {
1241
    use super::*;
1242
1243
    use pyo3::{IntoPy, Python};
1244
    use rand::rngs::StdRng;
1245
    use rand::{Rng, SeedableRng};
1246
    use rstest::rstest;
1247
1248
    #[test]
1249
    fn test_json_dict_roundtrip() {
1250
        pyo3::prepare_freethreaded_python();
1251
        let mut rng = StdRng::seed_from_u64(1337);
1252
        let mut data = [0u8; 32];
1253
        let mut msg = [0u8; 10];
1254
        for _i in 0..50 {
1255
            rng.fill(data.as_mut_slice());
1256
            rng.fill(msg.as_mut_slice());
1257
            let sk = SecretKey::from_seed(&data);
1258
            let sig = sign(&sk, msg);
1259
            Python::with_gil(|py| {
1260
                let string = sig.to_json_dict(py).expect("to_json_dict");
1261
                let sig2 = Signature::from_json_dict(string.bind(py)).unwrap();
1262
                assert_eq!(sig, sig2);
1263
            });
1264
        }
1265
    }
1266
1267
    #[rstest]
1268
    #[case("0x000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0ff000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e", "Signature, invalid length 95 expected 96")]
1269
    #[case("0x000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0ff000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f00", "Signature, invalid length 97 expected 96")]
1270
    #[case("000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0ff000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e", "Signature, invalid length 95 expected 96")]
1271
    #[case("000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0ff000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f00", "Signature, invalid length 97 expected 96")]
1272
    #[case("00r102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0ff000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f", "invalid hex")]
1273
    fn test_json_dict(#[case] input: &str, #[case] msg: &str) {
1274
        pyo3::prepare_freethreaded_python();
1275
        Python::with_gil(|py| {
1276
            let err =
1277
                Signature::from_json_dict(input.to_string().into_py(py).bind(py)).unwrap_err();
1278
            assert_eq!(err.value_bound(py).to_string(), msg.to_string());
1279
        });
1280
    }
1281
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chia-traits-0.10.0/src/chia_error.rs
Line
Count
Source
1
use thiserror::Error;
2
3
0
#[derive(Debug, PartialEq, Eq, Clone, Error)]
4
pub enum Error {
5
    #[error("invalid bool encoding")]
6
    InvalidBool,
7
    #[error("invalid optional encoding")]
8
    InvalidOptional,
9
    #[error("unexpected end of buffer")]
10
    EndOfBuffer,
11
    #[error("invalid string encoding")]
12
    InvalidString,
13
    #[error("input buffer too large")]
14
    InputTooLarge,
15
    #[error("sequence too large")]
16
    SequenceTooLarge,
17
    #[error("invalid enum value")]
18
    InvalidEnum,
19
    #[error("invalid CLVM serialization")]
20
    InvalidClvm,
21
    #[error("{0}")]
22
    Custom(String),
23
}
24
25
pub type Result<T> = std::result::Result<T, Error>;
26
27
#[cfg(feature = "py-bindings")]
28
impl From<Error> for pyo3::PyErr {
29
    fn from(err: Error) -> pyo3::PyErr {
30
        pyo3::exceptions::PyValueError::new_err(err.to_string())
31
    }
32
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chia-traits-0.10.0/src/streamable.rs
Line
Count
Source
1
use crate::chia_error::{Error, Result};
2
use sha2::{Digest, Sha256};
3
use std::io::Cursor;
4
use std::mem;
5
6
0
pub fn read_bytes<'a>(input: &'a mut Cursor<&[u8]>, len: usize) -> Result<&'a [u8]> {
7
0
    let pos = input.position();
8
0
    let buf: &'a [u8] = &input.get_ref()[pos as usize..];
9
0
    if buf.len() < len {
10
0
        Err(Error::EndOfBuffer)
11
    } else {
12
0
        let ret = &buf[..len];
13
0
        input.set_position(pos + len as u64);
14
0
        Ok(ret)
15
    }
16
0
}
17
18
#[test]
19
fn test_read_bytes() {
20
    let mut input = Cursor::<&[u8]>::new(&[0_u8, 1, 2, 3, 4]);
21
    assert_eq!(read_bytes(&mut input, 1).unwrap(), [0_u8]);
22
    assert_eq!(read_bytes(&mut input, 1).unwrap(), [1_u8]);
23
    assert_eq!(read_bytes(&mut input, 1).unwrap(), [2_u8]);
24
    assert_eq!(read_bytes(&mut input, 1).unwrap(), [3_u8]);
25
    assert_eq!(read_bytes(&mut input, 1).unwrap(), [4_u8]);
26
    assert_eq!(read_bytes(&mut input, 1).unwrap_err(), Error::EndOfBuffer);
27
}
28
29
pub trait Streamable {
30
    fn update_digest(&self, digest: &mut Sha256);
31
    fn stream(&self, out: &mut Vec<u8>) -> Result<()>;
32
    fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> Result<Self>
33
    where
34
        Self: Sized;
35
36
    // convenience functions for the top-level Streamable object
37
    // these are meant to be used by *users* of streamable objects
38
    // whereas the above functions are meant to be implemented by *implementers*
39
    // of streamable types
40
0
    fn to_bytes(&self) -> Result<Vec<u8>> {
41
0
        let mut ret = Vec::<u8>::new();
42
0
        self.stream(&mut ret)?;
43
0
        Ok(ret)
44
0
    }
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls10public_key9PublicKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls10secret_key9SecretKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls9signature9SignatureNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB6_
Unexecuted instantiation: _RNvYNtNtCsiBl6Lc3cFal_5alloc6string6StringNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesBI_
Unexecuted instantiation: _RNvYaNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
Unexecuted instantiation: _RNvYbNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
Unexecuted instantiation: _RNvYhNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
Unexecuted instantiation: _RNvYlNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
Unexecuted instantiation: _RNvYmNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
Unexecuted instantiation: _RNvYnNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
Unexecuted instantiation: _RNvYoNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
Unexecuted instantiation: _RNvYsNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
Unexecuted instantiation: _RNvYtNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
Unexecuted instantiation: _RNvYuNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
Unexecuted instantiation: _RNvYxNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
Unexecuted instantiation: _RNvYyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable8to_bytesB7_
45
0
    fn from_bytes(bytes: &[u8]) -> Result<Self>
46
0
    where
47
0
        Self: Sized,
48
0
    {
49
0
        let mut cursor = Cursor::new(bytes);
50
0
        let ret = Self::parse::<false>(&mut cursor)?;
51
0
        if cursor.position() == bytes.len() as u64 {
52
0
            Ok(ret)
53
        } else {
54
0
            Err(Error::InputTooLarge)
55
        }
56
0
    }
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls10public_key9PublicKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls10secret_key9SecretKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls9signature9SignatureNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB6_
Unexecuted instantiation: _RNvYNtNtCsiBl6Lc3cFal_5alloc6string6StringNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesBI_
Unexecuted instantiation: _RNvYaNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
Unexecuted instantiation: _RNvYbNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
Unexecuted instantiation: _RNvYhNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
Unexecuted instantiation: _RNvYlNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
Unexecuted instantiation: _RNvYmNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
Unexecuted instantiation: _RNvYnNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
Unexecuted instantiation: _RNvYoNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
Unexecuted instantiation: _RNvYsNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
Unexecuted instantiation: _RNvYtNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
Unexecuted instantiation: _RNvYuNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
Unexecuted instantiation: _RNvYxNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
Unexecuted instantiation: _RNvYyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable10from_bytesB7_
57
0
    fn from_bytes_unchecked(bytes: &[u8]) -> Result<Self>
58
0
    where
59
0
        Self: Sized,
60
0
    {
61
0
        let mut cursor = Cursor::new(bytes);
62
0
        let ret = Self::parse::<true>(&mut cursor)?;
63
0
        if cursor.position() == bytes.len() as u64 {
64
0
            Ok(ret)
65
        } else {
66
0
            Err(Error::InputTooLarge)
67
        }
68
0
    }
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls10public_key9PublicKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls10secret_key9SecretKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls9signature9SignatureNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB6_
Unexecuted instantiation: _RNvYNtNtCsiBl6Lc3cFal_5alloc6string6StringNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedBI_
Unexecuted instantiation: _RNvYaNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
Unexecuted instantiation: _RNvYbNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
Unexecuted instantiation: _RNvYhNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
Unexecuted instantiation: _RNvYlNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
Unexecuted instantiation: _RNvYmNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
Unexecuted instantiation: _RNvYnNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
Unexecuted instantiation: _RNvYoNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
Unexecuted instantiation: _RNvYsNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
Unexecuted instantiation: _RNvYtNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
Unexecuted instantiation: _RNvYuNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
Unexecuted instantiation: _RNvYxNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
Unexecuted instantiation: _RNvYyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable20from_bytes_uncheckedB7_
69
0
    fn hash(&self) -> [u8; 32] {
70
0
        let mut ctx = Sha256::new();
71
0
        self.update_digest(&mut ctx);
72
0
        ctx.finalize().into()
73
0
    }
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls10public_key9PublicKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls10secret_key9SecretKeyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB6_
Unexecuted instantiation: _RNvYNtNtCs568wuOlRYFZ_8chia_bls9signature9SignatureNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB6_
Unexecuted instantiation: _RNvYNtNtCsiBl6Lc3cFal_5alloc6string6StringNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashBI_
Unexecuted instantiation: _RNvYaNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
Unexecuted instantiation: _RNvYbNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
Unexecuted instantiation: _RNvYhNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
Unexecuted instantiation: _RNvYlNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
Unexecuted instantiation: _RNvYmNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
Unexecuted instantiation: _RNvYnNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
Unexecuted instantiation: _RNvYoNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
Unexecuted instantiation: _RNvYsNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
Unexecuted instantiation: _RNvYtNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
Unexecuted instantiation: _RNvYuNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
Unexecuted instantiation: _RNvYxNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
Unexecuted instantiation: _RNvYyNtNtCs2IvCg5PL8uK_11chia_traits10streamable10Streamable4hashB7_
74
}
75
76
macro_rules! streamable_primitive {
77
    ($t:ty) => {
78
        impl Streamable for $t {
79
0
            fn update_digest(&self, digest: &mut Sha256) {
80
0
                digest.update(&self.to_be_bytes());
81
0
            }
Unexecuted instantiation: _RNvXs6_NtCs2IvCg5PL8uK_11chia_traits10streamablehNtB5_10Streamable13update_digest
Unexecuted instantiation: _RNvXs7_NtCs2IvCg5PL8uK_11chia_traits10streamableaNtB5_10Streamable13update_digest
Unexecuted instantiation: _RNvXs8_NtCs2IvCg5PL8uK_11chia_traits10streamabletNtB5_10Streamable13update_digest
Unexecuted instantiation: _RNvXs9_NtCs2IvCg5PL8uK_11chia_traits10streamablesNtB5_10Streamable13update_digest
Unexecuted instantiation: _RNvXsa_NtCs2IvCg5PL8uK_11chia_traits10streamablemNtB5_10Streamable13update_digest
Unexecuted instantiation: _RNvXsb_NtCs2IvCg5PL8uK_11chia_traits10streamablelNtB5_10Streamable13update_digest
Unexecuted instantiation: _RNvXsc_NtCs2IvCg5PL8uK_11chia_traits10streamableyNtB5_10Streamable13update_digest
Unexecuted instantiation: _RNvXsd_NtCs2IvCg5PL8uK_11chia_traits10streamablexNtB5_10Streamable13update_digest
Unexecuted instantiation: _RNvXse_NtCs2IvCg5PL8uK_11chia_traits10streamableoNtB5_10Streamable13update_digest
Unexecuted instantiation: _RNvXsf_NtCs2IvCg5PL8uK_11chia_traits10streamablenNtB5_10Streamable13update_digest
82
0
            fn stream(&self, out: &mut Vec<u8>) -> Result<()> {
83
0
                Ok(out.extend_from_slice(&self.to_be_bytes()))
84
0
            }
Unexecuted instantiation: _RNvXs6_NtCs2IvCg5PL8uK_11chia_traits10streamablehNtB5_10Streamable6stream
Unexecuted instantiation: _RNvXs7_NtCs2IvCg5PL8uK_11chia_traits10streamableaNtB5_10Streamable6stream
Unexecuted instantiation: _RNvXs8_NtCs2IvCg5PL8uK_11chia_traits10streamabletNtB5_10Streamable6stream
Unexecuted instantiation: _RNvXs9_NtCs2IvCg5PL8uK_11chia_traits10streamablesNtB5_10Streamable6stream
Unexecuted instantiation: _RNvXsa_NtCs2IvCg5PL8uK_11chia_traits10streamablemNtB5_10Streamable6stream
Unexecuted instantiation: _RNvXsb_NtCs2IvCg5PL8uK_11chia_traits10streamablelNtB5_10Streamable6stream
Unexecuted instantiation: _RNvXsc_NtCs2IvCg5PL8uK_11chia_traits10streamableyNtB5_10Streamable6stream
Unexecuted instantiation: _RNvXsd_NtCs2IvCg5PL8uK_11chia_traits10streamablexNtB5_10Streamable6stream
Unexecuted instantiation: _RNvXse_NtCs2IvCg5PL8uK_11chia_traits10streamableoNtB5_10Streamable6stream
Unexecuted instantiation: _RNvXsf_NtCs2IvCg5PL8uK_11chia_traits10streamablenNtB5_10Streamable6stream
85
0
            fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> Result<Self> {
86
0
                let sz = mem::size_of::<$t>();
87
0
                Ok(<$t>::from_be_bytes(
88
0
                    read_bytes(input, sz)?.try_into().unwrap(),
89
                ))
90
0
            }
Unexecuted instantiation: _RINvXs6_NtCs2IvCg5PL8uK_11chia_traits10streamablehNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXs6_NtCs2IvCg5PL8uK_11chia_traits10streamablehNtB6_10Streamable5parseKb1_EB8_
Unexecuted instantiation: _RINvXs7_NtCs2IvCg5PL8uK_11chia_traits10streamableaNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXs7_NtCs2IvCg5PL8uK_11chia_traits10streamableaNtB6_10Streamable5parseKb1_EB8_
Unexecuted instantiation: _RINvXs8_NtCs2IvCg5PL8uK_11chia_traits10streamabletNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXs8_NtCs2IvCg5PL8uK_11chia_traits10streamabletNtB6_10Streamable5parseKb1_EB8_
Unexecuted instantiation: _RINvXs9_NtCs2IvCg5PL8uK_11chia_traits10streamablesNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXs9_NtCs2IvCg5PL8uK_11chia_traits10streamablesNtB6_10Streamable5parseKb1_EB8_
Unexecuted instantiation: _RINvXsa_NtCs2IvCg5PL8uK_11chia_traits10streamablemNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXsa_NtCs2IvCg5PL8uK_11chia_traits10streamablemNtB6_10Streamable5parseKb1_EB8_
Unexecuted instantiation: _RINvXsb_NtCs2IvCg5PL8uK_11chia_traits10streamablelNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXsb_NtCs2IvCg5PL8uK_11chia_traits10streamablelNtB6_10Streamable5parseKb1_EB8_
Unexecuted instantiation: _RINvXsc_NtCs2IvCg5PL8uK_11chia_traits10streamableyNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXsc_NtCs2IvCg5PL8uK_11chia_traits10streamableyNtB6_10Streamable5parseKb1_EB8_
Unexecuted instantiation: _RINvXsd_NtCs2IvCg5PL8uK_11chia_traits10streamablexNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXsd_NtCs2IvCg5PL8uK_11chia_traits10streamablexNtB6_10Streamable5parseKb1_EB8_
Unexecuted instantiation: _RINvXse_NtCs2IvCg5PL8uK_11chia_traits10streamableoNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXse_NtCs2IvCg5PL8uK_11chia_traits10streamableoNtB6_10Streamable5parseKb1_EB8_
Unexecuted instantiation: _RINvXsf_NtCs2IvCg5PL8uK_11chia_traits10streamablenNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXsf_NtCs2IvCg5PL8uK_11chia_traits10streamablenNtB6_10Streamable5parseKb1_EB8_
91
        }
92
    };
93
}
94
95
streamable_primitive!(u8);
96
streamable_primitive!(i8);
97
streamable_primitive!(u16);
98
streamable_primitive!(i16);
99
streamable_primitive!(u32);
100
streamable_primitive!(i32);
101
streamable_primitive!(u64);
102
streamable_primitive!(i64);
103
streamable_primitive!(u128);
104
streamable_primitive!(i128);
105
106
impl<T: Streamable> Streamable for Vec<T> {
107
0
    fn update_digest(&self, digest: &mut Sha256) {
108
0
        (self.len() as u32).update_digest(digest);
109
0
        for e in self {
110
0
            e.update_digest(digest);
111
0
        }
112
0
    }
113
114
0
    fn stream(&self, out: &mut Vec<u8>) -> Result<()> {
115
0
        if self.len() > u32::MAX as usize {
116
0
            Err(Error::InputTooLarge)
117
        } else {
118
0
            (self.len() as u32).stream(out)?;
119
0
            for e in self {
120
0
                e.stream(out)?;
121
            }
122
0
            Ok(())
123
        }
124
0
    }
125
126
0
    fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> Result<Self> {
127
0
        let len = u32::parse::<TRUSTED>(input)?;
128
129
0
        let mut ret = if mem::size_of::<T>() == 0 {
130
0
            Vec::<T>::new()
131
        } else {
132
0
            let limit = 2 * 1024 * 1024 / mem::size_of::<T>();
133
0
            Vec::<T>::with_capacity(std::cmp::min(limit, len as usize))
134
        };
135
0
        for _ in 0..len {
136
0
            ret.push(T::parse::<TRUSTED>(input)?);
137
        }
138
0
        Ok(ret)
139
0
    }
140
}
141
142
impl Streamable for String {
143
0
    fn update_digest(&self, digest: &mut Sha256) {
144
0
        let bytes = self.as_bytes();
145
0
        (bytes.len() as u32).update_digest(digest);
146
0
        digest.update(bytes);
147
0
    }
148
149
0
    fn stream(&self, out: &mut Vec<u8>) -> Result<()> {
150
0
        // bytes is the UTF-8 sequence
151
0
        let bytes = self.bytes();
152
0
        if bytes.len() > u32::MAX as usize {
153
0
            Err(Error::InputTooLarge)
154
        } else {
155
0
            (bytes.len() as u32).stream(out)?;
156
0
            out.extend(bytes);
157
0
            Ok(())
158
        }
159
0
    }
160
161
0
    fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> Result<Self> {
162
0
        let len = u32::parse::<TRUSTED>(input)?;
163
        Ok(String::from(
164
0
            std::str::from_utf8(read_bytes(input, len as usize)?)
165
0
                .map_err(|_| Error::InvalidString)?,
Unexecuted instantiation: _RNCINvXs_NtCs2IvCg5PL8uK_11chia_traits10streamableNtNtCsiBl6Lc3cFal_5alloc6string6StringNtB7_10Streamable5parseKb0_E0B9_
Unexecuted instantiation: _RNCINvXs_NtCs2IvCg5PL8uK_11chia_traits10streamableNtNtCsiBl6Lc3cFal_5alloc6string6StringNtB7_10Streamable5parseKb1_E0B9_
166
        ))
167
0
    }
Unexecuted instantiation: _RINvXs_NtCs2IvCg5PL8uK_11chia_traits10streamableNtNtCsiBl6Lc3cFal_5alloc6string6StringNtB5_10Streamable5parseKb0_EB7_
Unexecuted instantiation: _RINvXs_NtCs2IvCg5PL8uK_11chia_traits10streamableNtNtCsiBl6Lc3cFal_5alloc6string6StringNtB5_10Streamable5parseKb1_EB7_
168
}
169
170
impl Streamable for bool {
171
0
    fn update_digest(&self, digest: &mut Sha256) {
172
0
        digest.update(if *self { [1] } else { [0] });
173
0
    }
174
175
0
    fn stream(&self, out: &mut Vec<u8>) -> Result<()> {
176
0
        out.extend_from_slice(if *self { &[1] } else { &[0] });
177
0
        Ok(())
178
0
    }
179
0
    fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> Result<Self> {
180
0
        let val = read_bytes(input, 1)?[0];
181
0
        match val {
182
0
            0 => Ok(false),
183
0
            1 => Ok(true),
184
0
            _ => Err(Error::InvalidBool),
185
        }
186
0
    }
Unexecuted instantiation: _RINvXs0_NtCs2IvCg5PL8uK_11chia_traits10streamablebNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXs0_NtCs2IvCg5PL8uK_11chia_traits10streamablebNtB6_10Streamable5parseKb1_EB8_
187
}
188
189
impl Streamable for () {
190
0
    fn update_digest(&self, _digest: &mut Sha256) {}
191
0
    fn stream(&self, _out: &mut Vec<u8>) -> Result<()> {
192
0
        Ok(())
193
0
    }
194
0
    fn parse<const TRUSTED: bool>(_input: &mut Cursor<&[u8]>) -> Result<Self> {
195
0
        Ok(())
196
0
    }
Unexecuted instantiation: _RINvXs1_NtCs2IvCg5PL8uK_11chia_traits10streamableuNtB6_10Streamable5parseKb0_EB8_
Unexecuted instantiation: _RINvXs1_NtCs2IvCg5PL8uK_11chia_traits10streamableuNtB6_10Streamable5parseKb1_EB8_
197
}
198
199
impl<T: Streamable> Streamable for Option<T> {
200
0
    fn update_digest(&self, digest: &mut Sha256) {
201
0
        match self {
202
0
            None => {
203
0
                digest.update([0]);
204
0
            }
205
0
            Some(v) => {
206
0
                digest.update([1]);
207
0
                v.update_digest(digest);
208
0
            }
209
        }
210
0
    }
211
212
0
    fn stream(&self, out: &mut Vec<u8>) -> Result<()> {
213
0
        match self {
214
0
            None => {
215
0
                out.push(0);
216
0
            }
217
0
            Some(v) => {
218
0
                out.push(1);
219
0
                v.stream(out)?;
220
            }
221
        }
222
0
        Ok(())
223
0
    }
224
0
    fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> Result<Self> {
225
0
        let val = read_bytes(input, 1)?[0];
226
0
        match val {
227
0
            0 => Ok(None),
228
0
            1 => Ok(Some(T::parse::<TRUSTED>(input)?)),
229
0
            _ => Err(Error::InvalidOptional),
230
        }
231
0
    }
232
}
233
234
impl<T: Streamable, U: Streamable> Streamable for (T, U) {
235
0
    fn update_digest(&self, digest: &mut Sha256) {
236
0
        self.0.update_digest(digest);
237
0
        self.1.update_digest(digest);
238
0
    }
239
0
    fn stream(&self, out: &mut Vec<u8>) -> Result<()> {
240
0
        self.0.stream(out)?;
241
0
        self.1.stream(out)?;
242
0
        Ok(())
243
0
    }
244
0
    fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> Result<Self> {
245
0
        Ok((T::parse::<TRUSTED>(input)?, U::parse::<TRUSTED>(input)?))
246
0
    }
247
}
248
249
impl<T: Streamable, U: Streamable, V: Streamable> Streamable for (T, U, V) {
250
0
    fn update_digest(&self, digest: &mut Sha256) {
251
0
        self.0.update_digest(digest);
252
0
        self.1.update_digest(digest);
253
0
        self.2.update_digest(digest);
254
0
    }
255
0
    fn stream(&self, out: &mut Vec<u8>) -> Result<()> {
256
0
        self.0.stream(out)?;
257
0
        self.1.stream(out)?;
258
0
        self.2.stream(out)?;
259
0
        Ok(())
260
0
    }
261
0
    fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> Result<Self> {
262
0
        Ok((
263
0
            T::parse::<TRUSTED>(input)?,
264
0
            U::parse::<TRUSTED>(input)?,
265
0
            V::parse::<TRUSTED>(input)?,
266
        ))
267
0
    }
268
}
269
270
impl<T: Streamable, U: Streamable, V: Streamable, W: Streamable> Streamable for (T, U, V, W) {
271
0
    fn update_digest(&self, digest: &mut Sha256) {
272
0
        self.0.update_digest(digest);
273
0
        self.1.update_digest(digest);
274
0
        self.2.update_digest(digest);
275
0
        self.3.update_digest(digest);
276
0
    }
277
0
    fn stream(&self, out: &mut Vec<u8>) -> Result<()> {
278
0
        self.0.stream(out)?;
279
0
        self.1.stream(out)?;
280
0
        self.2.stream(out)?;
281
0
        self.3.stream(out)?;
282
0
        Ok(())
283
0
    }
284
0
    fn parse<const TRUSTED: bool>(input: &mut Cursor<&[u8]>) -> Result<Self> {
285
0
        Ok((
286
0
            T::parse::<TRUSTED>(input)?,
287
0
            U::parse::<TRUSTED>(input)?,
288
0
            V::parse::<TRUSTED>(input)?,
289
0
            W::parse::<TRUSTED>(input)?,
290
        ))
291
0
    }
292
}
293
294
// ===== TESTS ====
295
296
#[cfg(test)]
297
#[allow(clippy::needless_pass_by_value)]
298
fn from_bytes<T: Streamable + std::fmt::Debug + PartialEq>(buf: &[u8], expected: T) {
299
    let mut input = Cursor::<&[u8]>::new(buf);
300
    assert_eq!(T::parse::<false>(&mut input).unwrap(), expected);
301
}
302
303
#[cfg(test)]
304
#[allow(clippy::needless_pass_by_value)]
305
fn from_bytes_fail<T: Streamable + std::fmt::Debug + PartialEq>(buf: &[u8], expected: Error) {
306
    let mut input = Cursor::<&[u8]>::new(buf);
307
    assert_eq!(T::parse::<false>(&mut input).unwrap_err(), expected);
308
}
309
310
#[test]
311
fn test_parse_u64() {
312
    from_bytes::<u64>(&[0, 0, 0, 0, 0, 0, 0, 0], 0);
313
    from_bytes::<u64>(&[0, 0, 0, 0, 0, 0, 0, 1], 1);
314
    from_bytes::<u64>(&[0x80, 0, 0, 0, 0, 0, 0, 0], 0x8000_0000_0000_0000);
315
    from_bytes::<u64>(
316
        &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
317
        0xffff_ffff_ffff_ffff,
318
    );
319
320
    // truncated
321
    from_bytes_fail::<u64>(&[0, 0, 0, 0, 0, 0, 0], Error::EndOfBuffer);
322
    from_bytes_fail::<u64>(&[0, 0, 0, 0, 0, 0], Error::EndOfBuffer);
323
    from_bytes_fail::<u64>(&[0, 0, 0, 0, 0], Error::EndOfBuffer);
324
    from_bytes_fail::<u64>(&[0, 0, 0, 0], Error::EndOfBuffer);
325
    from_bytes_fail::<u64>(&[0, 0, 0], Error::EndOfBuffer);
326
    from_bytes_fail::<u64>(&[0, 0], Error::EndOfBuffer);
327
}
328
329
#[test]
330
fn test_parse_u128() {
331
    from_bytes::<u128>(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0);
332
    from_bytes::<u128>(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 1);
333
    from_bytes::<u128>(
334
        &[0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
335
        0x8000_0000_0000_0000_0000_0000_0000_0000,
336
    );
337
    from_bytes::<u128>(
338
        &[
339
            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
340
            0xff, 0xff,
341
        ],
342
        0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff,
343
    );
344
345
    // truncated
346
    from_bytes_fail::<u128>(
347
        &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
348
        Error::EndOfBuffer,
349
    );
350
    from_bytes_fail::<u128>(
351
        &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
352
        Error::EndOfBuffer,
353
    );
354
    from_bytes_fail::<u128>(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], Error::EndOfBuffer);
355
    from_bytes_fail::<u128>(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], Error::EndOfBuffer);
356
    from_bytes_fail::<u128>(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], Error::EndOfBuffer);
357
    from_bytes_fail::<u128>(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], Error::EndOfBuffer);
358
}
359
360
#[test]
361
fn test_parse_empty_list() {
362
    let buf: &[u8] = &[0, 0, 0, 0];
363
    from_bytes::<Vec<u32>>(buf, vec![]);
364
}
365
366
#[test]
367
fn test_parse_list_1() {
368
    let buf: &[u8] = &[0, 0, 0, 1, 1, 2, 3, 4];
369
    from_bytes::<Vec<u32>>(buf, vec![0x0102_0304]);
370
}
371
372
#[test]
373
fn test_parse_list_3() {
374
    let buf: &[u8] = &[0, 0, 0, 3, 1, 2, 3, 4, 1, 3, 3, 7, 0, 0, 4, 2];
375
    from_bytes::<Vec<u32>>(buf, vec![0x0102_0304, 0x0103_0307, 0x402]);
376
}
377
378
#[test]
379
fn test_parse_list_list_3() {
380
    let buf: &[u8] = &[
381
        0, 0, 0, 3, 0, 0, 0, 1, 1, 2, 3, 4, 0, 0, 0, 1, 1, 3, 3, 7, 0, 0, 0, 1, 0, 0, 4, 2,
382
    ];
383
    from_bytes::<Vec<Vec<u32>>>(buf, vec![vec![0x0102_0304], vec![0x0103_0307], vec![0x402]]);
384
}
385
386
#[test]
387
fn test_parse_list_empty() {
388
    let buf: &[u8] = &[0, 0, 0, 3];
389
    from_bytes::<Vec<()>>(buf, vec![(), (), ()]);
390
}
391
392
#[test]
393
fn test_parse_long_list() {
394
    let buf: &[u8] = &[0xff, 0xff, 0xff, 0xff, 0, 0, 0];
395
    from_bytes_fail::<Vec<u32>>(buf, Error::EndOfBuffer);
396
}
397
398
#[test]
399
fn test_parse_tuple() {
400
    let buf: &[u8] = &[0, 0, 0, 3, 42, 0xff];
401
    from_bytes::<(u32, u8, i8)>(buf, (3, 42, -1));
402
}
403
404
#[test]
405
fn test_parse_nested_tuple() {
406
    let buf: &[u8] = &[0, 0, 0, 3, 42, 43, 44, 0xff, 0xff, 0xff, 0xff];
407
    from_bytes::<(u32, (u8, u8, u8), i32)>(buf, (3, (42, 43, 44), -1));
408
}
409
410
#[test]
411
fn test_parse_optional_clear() {
412
    let buf: &[u8] = &[0];
413
    from_bytes::<Option<u32>>(buf, None);
414
}
415
416
#[test]
417
fn test_parse_optional_zero() {
418
    let buf: &[u8] = &[1, 0];
419
    from_bytes::<Option<u8>>(buf, Some(0));
420
}
421
422
#[test]
423
fn test_parse_optional_u32() {
424
    let buf: &[u8] = &[1, 0, 0, 0x13, 0x37];
425
    from_bytes::<Option<u32>>(buf, Some(0x1337));
426
}
427
428
#[test]
429
fn test_parse_optional_str() {
430
    let buf: &[u8] = &[1, 0, 0, 0, 3, b'f', b'o', b'o'];
431
    from_bytes::<Option<String>>(buf, Some("foo".to_string()));
432
}
433
434
#[test]
435
fn test_parse_invalid_optional() {
436
    // the prefix has to be 0 or 1
437
    // 2 is invalid
438
    let buf: &[u8] = &[2, 0, 0, 0, 0];
439
    from_bytes_fail::<Option<u32>>(buf, Error::InvalidOptional);
440
}
441
442
#[test]
443
fn test_parse_true() {
444
    let buf: &[u8] = &[1];
445
    from_bytes::<bool>(buf, true);
446
}
447
448
#[test]
449
fn test_parse_false() {
450
    let buf: &[u8] = &[0];
451
    from_bytes::<bool>(buf, false);
452
}
453
454
#[test]
455
fn test_parse_invalid_bool() {
456
    // the bool has to be 0 or 1
457
    // 2 is invalid
458
    let buf: &[u8] = &[2];
459
    from_bytes_fail::<bool>(buf, Error::InvalidBool);
460
}
461
462
#[test]
463
fn test_parse_str() {
464
    let buf: &[u8] = &[0, 0, 0, 3, b'f', b'o', b'o'];
465
    from_bytes::<String>(buf, "foo".to_string());
466
}
467
468
#[test]
469
fn test_parse_invalid_utf8_str() {
470
    let buf: &[u8] = &[
471
        0, 0, 0, 11, 195, 165, 195, 0, 164, 195, 182, 195, 188, 195, 174,
472
    ];
473
    from_bytes_fail::<String>(buf, Error::InvalidString);
474
}
475
476
#[test]
477
fn test_parse_empty_str() {
478
    let buf: &[u8] = &[0, 0, 0, 0];
479
    from_bytes::<String>(buf, String::new());
480
}
481
482
#[test]
483
fn test_parse_truncated_str() {
484
    let buf: &[u8] = &[0, 0, 0, 10, b'f', b'o', b'o'];
485
    from_bytes_fail::<String>(buf, Error::EndOfBuffer);
486
}
487
488
#[cfg(test)]
489
use chia_streamable_macro::Streamable;
490
491
#[cfg(test)]
492
#[derive(Streamable, PartialEq, Debug)]
493
struct TestStruct {
494
    a: Vec<i8>,
495
    b: String,
496
    c: (u32, u32),
497
}
498
499
#[test]
500
fn test_parse_struct() {
501
    let buf: &[u8] = &[
502
        0, 0, 0, 2, 42, 0xff, 0, 0, 0, 3, b'b', b'a', b'z', 0xff, 0xff, 0xff, 0xff, 0, 0, 0x13,
503
        0x37,
504
    ];
505
    from_bytes::<TestStruct>(
506
        buf,
507
        TestStruct {
508
            a: vec![42_i8, -1],
509
            b: "baz".to_string(),
510
            c: (0xffff_ffff, 0x1337),
511
        },
512
    );
513
}
514
515
#[cfg(test)]
516
#[derive(Streamable, PartialEq, Debug)]
517
struct TestTuple(String, u32);
518
519
#[test]
520
fn test_parse_custom_tuple() {
521
    let buf: &[u8] = &[0, 0, 0, 3, b'b', b'a', b'z', 0, 0, 0, 42];
522
    from_bytes::<TestTuple>(buf, TestTuple("baz".to_string(), 42));
523
}
524
525
#[cfg(test)]
526
fn stream<T: Streamable>(v: &T) -> Vec<u8> {
527
    let mut buf = Vec::<u8>::new();
528
    v.stream(&mut buf).unwrap();
529
    let mut ctx1 = Sha256::new();
530
    let mut ctx2 = Sha256::new();
531
    v.update_digest(&mut ctx1);
532
    ctx2.update(&buf);
533
    assert_eq!(&ctx1.finalize(), &ctx2.finalize());
534
    buf
535
}
536
537
#[test]
538
fn test_stream_i32() {
539
    let b: i32 = 0x0102_0304;
540
    let buf = stream(&b);
541
    assert_eq!(&buf[..], [1, 2, 3, 4]);
542
}
543
544
#[test]
545
fn test_stream_sequence() {
546
    let b: Vec<u8> = vec![1, 2, 3, 4, 5, 42, 127];
547
    let buf = stream(&b);
548
    // 4 byte length prefix
549
    assert_eq!(&buf[..], [0, 0, 0, 7, 1, 2, 3, 4, 5, 42, 127]);
550
}
551
552
#[test]
553
fn test_stream_empty_sequence() {
554
    let b: Vec<u8> = vec![];
555
    let buf = stream(&b);
556
    // 4 byte length prefix
557
    assert_eq!(&buf[..], [0, 0, 0, 0]);
558
}
559
560
#[test]
561
fn test_stream_none() {
562
    let b: Option<u8> = None;
563
    let buf = stream(&b);
564
    assert_eq!(&buf[..], [0]);
565
}
566
567
#[test]
568
fn test_stream_optional() {
569
    let b: Option<u32> = Some(0x1337);
570
    let buf = stream(&b);
571
    assert_eq!(&buf[..], [1, 0, 0, 0x13, 0x37]);
572
}
573
574
#[test]
575
fn test_stream_optional_zero() {
576
    let b: Option<u32> = Some(0);
577
    let buf = stream(&b);
578
    assert_eq!(&buf[..], [1, 0, 0, 0, 0]);
579
}
580
581
#[test]
582
fn test_stream_optional_set1() {
583
    let out = stream(&Some(42_u32));
584
    assert_eq!(&out, &[1, 0, 0, 0, 42]);
585
}
586
587
#[test]
588
fn test_stream_optional_set2() {
589
    let out = stream(&Some("foobar".to_string()));
590
    assert_eq!(&out, &[1, 0, 0, 0, 6, b'f', b'o', b'o', b'b', b'a', b'r']);
591
}
592
593
#[test]
594
fn test_stream_tuple() {
595
    let b: (u8, u32, u64, bool) = (42, 0x1337, 0x0102_0304_0506_0708, true);
596
    let buf = stream(&b);
597
    assert_eq!(&buf[..], [42, 0, 0, 0x13, 0x37, 1, 2, 3, 4, 5, 6, 7, 8, 1]);
598
}
599
600
#[test]
601
fn test_stream_tuple_of_lists() {
602
    let b: (Vec<u8>, Vec<u8>) = (vec![0, 1, 2, 3], vec![4, 5, 6, 7, 8, 9]);
603
    let buf = stream(&b);
604
    assert_eq!(
605
        &buf[..],
606
        [0, 0, 0, 4, 0, 1, 2, 3, 0, 0, 0, 6, 4, 5, 6, 7, 8, 9]
607
    );
608
}
609
610
#[test]
611
fn test_stream_tuple1() {
612
    let out = stream(&(42_u32));
613
    assert_eq!(&out, &[0, 0, 0, 42]);
614
}
615
#[test]
616
fn test_stream_tuple2() {
617
    let out = stream(&("test".to_string(), 42_u32));
618
    assert_eq!(&out, &[0, 0, 0, 4, b't', b'e', b's', b't', 0, 0, 0, 42]);
619
}
620
621
#[test]
622
fn test_stream_tuple_of_tuples() {
623
    let out = stream(&((0x1337_u32, 42_u32), ("foo".to_string(), "bar".to_string())));
624
    assert_eq!(
625
        &out,
626
        &[
627
            0, 0, 0x13, 0x37, 0, 0, 0, 42, 0, 0, 0, 3, b'f', b'o', b'o', 0, 0, 0, 3, b'b', b'a',
628
            b'r'
629
        ]
630
    );
631
}
632
633
#[test]
634
fn test_stream_false() {
635
    let b = false;
636
    let buf = stream(&b);
637
    assert_eq!(&buf[..], [0]);
638
}
639
640
#[test]
641
fn test_stream_true() {
642
    let b = true;
643
    let buf = stream(&b);
644
    assert_eq!(&buf[..], [1]);
645
}
646
647
#[test]
648
fn test_stream_string() {
649
    let b = "abc".to_string();
650
    let buf = stream(&b);
651
    assert_eq!(&buf[..], [0, 0, 0, 3, b'a', b'b', b'c']);
652
}
653
654
#[test]
655
fn test_stream_empty_string() {
656
    let b = String::new();
657
    let buf = stream(&b);
658
    assert_eq!(&buf[..], [0, 0, 0, 0]);
659
}
660
661
#[test]
662
fn test_stream_utf8_string() {
663
    let b = "åäöüî".to_string();
664
    let buf = stream(&b);
665
    assert_eq!(
666
        &buf[..],
667
        [0, 0, 0, 10, 195, 165, 195, 164, 195, 182, 195, 188, 195, 174]
668
    );
669
}
670
671
#[test]
672
fn test_stream_struct() {
673
    let b = TestStruct {
674
        a: [1, 2, 3].to_vec(),
675
        b: "abc".to_string(),
676
        c: (0x1337, 42),
677
    };
678
    let buf = stream(&b);
679
    assert_eq!(
680
        &buf[..],
681
        [0, 0, 0, 3, 1, 2, 3, 0, 0, 0, 3, b'a', b'b', b'c', 0, 0, 0x13, 0x37, 0, 0, 0, 42]
682
    );
683
}
684
685
#[test]
686
fn test_stream_custom_tuple() {
687
    let b = TestTuple("abc".to_string(), 1337);
688
    let buf = stream(&b);
689
    assert_eq!(&buf[..], [0, 0, 0, 3, b'a', b'b', b'c', 0, 0, 0x05, 0x39]);
690
}
691
692
#[test]
693
fn test_stream_list() {
694
    let out = stream(&vec![0x0103_0307_u32, 42, 0xffff_ffff]);
695
    assert_eq!(
696
        &out,
697
        &[0, 0, 0, 3, 1, 3, 3, 7, 0, 0, 0, 42, 0xff, 0xff, 0xff, 0xff]
698
    );
699
}
700
701
#[test]
702
fn test_stream_list_of_empty() {
703
    let out = stream(&vec![(), (), ()]);
704
    assert_eq!(&out, &[0, 0, 0, 3]);
705
}
706
707
#[test]
708
fn test_stream_list_list() {
709
    let out = stream(&vec![
710
        vec![0x0103_0307_u32],
711
        vec![42_u32],
712
        vec![0xffff_ffff_u32],
713
    ]);
714
    assert_eq!(
715
        &out,
716
        &[
717
            0, 0, 0, 3, 0, 0, 0, 1, 1, 3, 3, 7, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 1, 0xff, 0xff,
718
            0xff, 0xff
719
        ]
720
    );
721
}
722
723
#[test]
724
fn test_stream_u128() {
725
    let out = stream(&(1337_u128, -1337_i128));
726
    assert_eq!(
727
        &out,
728
        &[
729
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x05, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff,
730
            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xc7
731
        ]
732
    );
733
}
734
735
#[cfg(test)]
736
#[derive(Streamable, Hash, Copy, Debug, Clone, Eq, PartialEq)]
737
enum TestEnum {
738
    A = 0,
739
    B = 1,
740
    C = 255,
741
}
742
743
#[test]
744
fn test_parse_enum() {
745
    from_bytes::<TestEnum>(&[0], TestEnum::A);
746
    from_bytes::<TestEnum>(&[1], TestEnum::B);
747
    from_bytes::<TestEnum>(&[255], TestEnum::C);
748
    from_bytes_fail::<TestEnum>(&[3], Error::InvalidEnum);
749
    from_bytes_fail::<TestEnum>(&[254], Error::InvalidEnum);
750
    from_bytes_fail::<TestEnum>(&[128], Error::InvalidEnum);
751
}
752
753
#[test]
754
fn test_stream_enum() {
755
    assert_eq!(stream::<TestEnum>(&TestEnum::A), &[0_u8]);
756
    assert_eq!(stream::<TestEnum>(&TestEnum::B), &[1_u8]);
757
    assert_eq!(stream::<TestEnum>(&TestEnum::C), &[255_u8]);
758
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/const-oid-0.9.6/src/arcs.rs
Line
Count
Source
1
//! Arcs are integer values which exist within an OID's hierarchy.
2
3
use crate::{Error, ObjectIdentifier, Result};
4
use core::mem;
5
6
/// Type alias used to represent an "arc" (i.e. integer identifier value).
7
///
8
/// X.660 does not define a maximum size of an arc.
9
///
10
/// The current representation is `u32`, which has been selected as being
11
/// sufficient to cover the current PKCS/PKIX use cases this library has been
12
/// used in conjunction with.
13
///
14
/// Future versions may potentially make it larger if a sufficiently important
15
/// use case is discovered.
16
pub type Arc = u32;
17
18
/// Maximum value of the first arc in an OID.
19
pub(crate) const ARC_MAX_FIRST: Arc = 2;
20
21
/// Maximum value of the second arc in an OID.
22
pub(crate) const ARC_MAX_SECOND: Arc = 39;
23
24
/// Maximum number of bytes supported in an arc.
25
const ARC_MAX_BYTES: usize = mem::size_of::<Arc>();
26
27
/// Maximum value of the last byte in an arc.
28
const ARC_MAX_LAST_OCTET: u8 = 0b11110000; // Max bytes of leading 1-bits
29
30
/// [`Iterator`] over [`Arc`] values (a.k.a. nodes) in an [`ObjectIdentifier`].
31
///
32
/// This iterates over all arcs in an OID, including the root.
33
pub struct Arcs<'a> {
34
    /// OID we're iterating over
35
    oid: &'a ObjectIdentifier,
36
37
    /// Current position within the serialized DER bytes of this OID
38
    cursor: Option<usize>,
39
}
40
41
impl<'a> Arcs<'a> {
42
    /// Create a new iterator over the arcs of this OID
43
0
    pub(crate) fn new(oid: &'a ObjectIdentifier) -> Self {
44
0
        Self { oid, cursor: None }
45
0
    }
46
47
    /// Try to parse the next arc in this OID.
48
    ///
49
    /// This method is fallible so it can be used as a first pass to determine
50
    /// that the arcs in the OID are well-formed.
51
0
    pub(crate) fn try_next(&mut self) -> Result<Option<Arc>> {
52
0
        match self.cursor {
53
            // Indicates we're on the root OID
54
            None => {
55
0
                let root = RootArcs::try_from(self.oid.as_bytes()[0])?;
56
0
                self.cursor = Some(0);
57
0
                Ok(Some(root.first_arc()))
58
            }
59
            Some(0) => {
60
0
                let root = RootArcs::try_from(self.oid.as_bytes()[0])?;
61
0
                self.cursor = Some(1);
62
0
                Ok(Some(root.second_arc()))
63
            }
64
0
            Some(offset) => {
65
0
                let mut result = 0;
66
0
                let mut arc_bytes = 0;
67
68
                loop {
69
0
                    let len = checked_add!(offset, arc_bytes);
70
71
0
                    match self.oid.as_bytes().get(len).cloned() {
72
                        // The arithmetic below includes advance checks
73
                        // against `ARC_MAX_BYTES` and `ARC_MAX_LAST_OCTET`
74
                        // which ensure the operations will not overflow.
75
                        #[allow(clippy::integer_arithmetic)]
76
0
                        Some(byte) => {
77
0
                            arc_bytes = checked_add!(arc_bytes, 1);
78
79
0
                            if (arc_bytes > ARC_MAX_BYTES) && (byte & ARC_MAX_LAST_OCTET != 0) {
80
0
                                return Err(Error::ArcTooBig);
81
0
                            }
82
0
83
0
                            result = result << 7 | (byte & 0b1111111) as Arc;
84
0
85
0
                            if byte & 0b10000000 == 0 {
86
0
                                self.cursor = Some(checked_add!(offset, arc_bytes));
87
0
                                return Ok(Some(result));
88
0
                            }
89
                        }
90
                        None => {
91
0
                            if arc_bytes == 0 {
92
0
                                return Ok(None);
93
                            } else {
94
0
                                return Err(Error::Base128);
95
                            }
96
                        }
97
                    }
98
                }
99
            }
100
        }
101
0
    }
102
}
103
104
impl<'a> Iterator for Arcs<'a> {
105
    type Item = Arc;
106
107
0
    fn next(&mut self) -> Option<Arc> {
108
0
        // ObjectIdentifier constructors should ensure the OID is well-formed
109
0
        self.try_next().expect("OID malformed")
110
0
    }
111
}
112
113
/// Byte containing the first and second arcs of an OID.
114
///
115
/// This is represented this way in order to reduce the overall size of the
116
/// [`ObjectIdentifier`] struct.
117
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
118
struct RootArcs(u8);
119
120
impl RootArcs {
121
    /// Create [`RootArcs`] from the first and second arc values represented
122
    /// as `Arc` integers.
123
0
    pub(crate) const fn new(first_arc: Arc, second_arc: Arc) -> Result<Self> {
124
0
        if first_arc > ARC_MAX_FIRST {
125
0
            return Err(Error::ArcInvalid { arc: first_arc });
126
0
        }
127
0
128
0
        if second_arc > ARC_MAX_SECOND {
129
0
            return Err(Error::ArcInvalid { arc: second_arc });
130
0
        }
131
0
132
0
        // The checks above ensure this operation will not overflow
133
0
        #[allow(clippy::integer_arithmetic)]
134
0
        let byte = (first_arc * (ARC_MAX_SECOND + 1)) as u8 + second_arc as u8;
135
0
136
0
        Ok(Self(byte))
137
0
    }
138
139
    /// Get the value of the first arc
140
    #[allow(clippy::integer_arithmetic)]
141
0
    pub(crate) const fn first_arc(self) -> Arc {
142
0
        self.0 as Arc / (ARC_MAX_SECOND + 1)
143
0
    }
144
145
    /// Get the value of the second arc
146
    #[allow(clippy::integer_arithmetic)]
147
0
    pub(crate) const fn second_arc(self) -> Arc {
148
0
        self.0 as Arc % (ARC_MAX_SECOND + 1)
149
0
    }
150
}
151
152
impl TryFrom<u8> for RootArcs {
153
    type Error = Error;
154
155
    // Ensured not to overflow by constructor invariants
156
    #[allow(clippy::integer_arithmetic)]
157
0
    fn try_from(octet: u8) -> Result<Self> {
158
0
        let first = octet as Arc / (ARC_MAX_SECOND + 1);
159
0
        let second = octet as Arc % (ARC_MAX_SECOND + 1);
160
0
        let result = Self::new(first, second)?;
161
0
        debug_assert_eq!(octet, result.0);
162
0
        Ok(result)
163
0
    }
164
}
165
166
impl From<RootArcs> for u8 {
167
0
    fn from(root_arcs: RootArcs) -> u8 {
168
0
        root_arcs.0
169
0
    }
170
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/const-oid-0.9.6/src/encoder.rs
Line
Count
Source
1
//! OID encoder with `const` support.
2
3
use crate::{
4
    arcs::{ARC_MAX_FIRST, ARC_MAX_SECOND},
5
    Arc, Error, ObjectIdentifier, Result,
6
};
7
8
/// BER/DER encoder
9
#[derive(Debug)]
10
pub(crate) struct Encoder {
11
    /// Current state
12
    state: State,
13
14
    /// Bytes of the OID being encoded in-progress
15
    bytes: [u8; ObjectIdentifier::MAX_SIZE],
16
17
    /// Current position within the byte buffer
18
    cursor: usize,
19
}
20
21
/// Current state of the encoder
22
#[derive(Debug)]
23
enum State {
24
    /// Initial state - no arcs yet encoded
25
    Initial,
26
27
    /// First arc parsed
28
    FirstArc(Arc),
29
30
    /// Encoding base 128 body of the OID
31
    Body,
32
}
33
34
impl Encoder {
35
    /// Create a new encoder initialized to an empty default state.
36
0
    pub(crate) const fn new() -> Self {
37
0
        Self {
38
0
            state: State::Initial,
39
0
            bytes: [0u8; ObjectIdentifier::MAX_SIZE],
40
0
            cursor: 0,
41
0
        }
42
0
    }
43
44
    /// Extend an existing OID.
45
0
    pub(crate) const fn extend(oid: ObjectIdentifier) -> Self {
46
0
        Self {
47
0
            state: State::Body,
48
0
            bytes: oid.bytes,
49
0
            cursor: oid.length as usize,
50
0
        }
51
0
    }
52
53
    /// Encode an [`Arc`] as base 128 into the internal buffer.
54
0
    pub(crate) const fn arc(mut self, arc: Arc) -> Result<Self> {
55
0
        match self.state {
56
            State::Initial => {
57
0
                if arc > ARC_MAX_FIRST {
58
0
                    return Err(Error::ArcInvalid { arc });
59
0
                }
60
0
61
0
                self.state = State::FirstArc(arc);
62
0
                Ok(self)
63
            }
64
            // Ensured not to overflow by `ARC_MAX_SECOND` check
65
            #[allow(clippy::integer_arithmetic)]
66
0
            State::FirstArc(first_arc) => {
67
0
                if arc > ARC_MAX_SECOND {
68
0
                    return Err(Error::ArcInvalid { arc });
69
0
                }
70
0
71
0
                self.state = State::Body;
72
0
                self.bytes[0] = (first_arc * (ARC_MAX_SECOND + 1)) as u8 + arc as u8;
73
0
                self.cursor = 1;
74
0
                Ok(self)
75
            }
76
            // TODO(tarcieri): finer-grained overflow safety / checked arithmetic
77
            #[allow(clippy::integer_arithmetic)]
78
            State::Body => {
79
                // Total number of bytes in encoded arc - 1
80
0
                let nbytes = base128_len(arc);
81
0
82
0
                // Shouldn't overflow on any 16-bit+ architectures
83
0
                if self.cursor + nbytes + 1 >= ObjectIdentifier::MAX_SIZE {
84
0
                    return Err(Error::Length);
85
0
                }
86
0
87
0
                let new_cursor = self.cursor + nbytes + 1;
88
0
89
0
                // TODO(tarcieri): use `?` when stable in `const fn`
90
0
                match self.encode_base128_byte(arc, nbytes, false) {
91
0
                    Ok(mut encoder) => {
92
0
                        encoder.cursor = new_cursor;
93
0
                        Ok(encoder)
94
                    }
95
0
                    Err(err) => Err(err),
96
                }
97
            }
98
        }
99
0
    }
100
101
    /// Finish encoding an OID.
102
0
    pub(crate) const fn finish(self) -> Result<ObjectIdentifier> {
103
0
        if self.cursor >= 2 {
104
0
            Ok(ObjectIdentifier {
105
0
                bytes: self.bytes,
106
0
                length: self.cursor as u8,
107
0
            })
108
        } else {
109
0
            Err(Error::NotEnoughArcs)
110
        }
111
0
    }
112
113
    /// Encode a single byte of a Base 128 value.
114
0
    const fn encode_base128_byte(mut self, mut n: u32, i: usize, continued: bool) -> Result<Self> {
115
0
        let mask = if continued { 0b10000000 } else { 0 };
116
117
        // Underflow checked by branch
118
        #[allow(clippy::integer_arithmetic)]
119
0
        if n > 0x80 {
120
0
            self.bytes[checked_add!(self.cursor, i)] = (n & 0b1111111) as u8 | mask;
121
0
            n >>= 7;
122
0
123
0
            if i > 0 {
124
0
                self.encode_base128_byte(n, i.saturating_sub(1), true)
125
            } else {
126
0
                Err(Error::Base128)
127
            }
128
        } else {
129
0
            self.bytes[self.cursor] = n as u8 | mask;
130
0
            Ok(self)
131
        }
132
0
    }
133
}
134
135
/// Compute the length - 1 of an arc when encoded in base 128.
136
0
const fn base128_len(arc: Arc) -> usize {
137
0
    match arc {
138
0
        0..=0x7f => 0,
139
0
        0x80..=0x3fff => 1,
140
0
        0x4000..=0x1fffff => 2,
141
0
        0x200000..=0x1fffffff => 3,
142
0
        _ => 4,
143
    }
144
0
}
145
146
#[cfg(test)]
147
mod tests {
148
    use super::Encoder;
149
    use hex_literal::hex;
150
151
    /// OID `1.2.840.10045.2.1` encoded as ASN.1 BER/DER
152
    const EXAMPLE_OID_BER: &[u8] = &hex!("2A8648CE3D0201");
153
154
    #[test]
155
    fn encode() {
156
        let encoder = Encoder::new();
157
        let encoder = encoder.arc(1).unwrap();
158
        let encoder = encoder.arc(2).unwrap();
159
        let encoder = encoder.arc(840).unwrap();
160
        let encoder = encoder.arc(10045).unwrap();
161
        let encoder = encoder.arc(2).unwrap();
162
        let encoder = encoder.arc(1).unwrap();
163
        assert_eq!(&encoder.bytes[..encoder.cursor], EXAMPLE_OID_BER);
164
    }
165
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/const-oid-0.9.6/src/error.rs
Line
Count
Source
1
//! Error types
2
3
use crate::Arc;
4
use core::fmt;
5
6
/// Result type
7
pub type Result<T> = core::result::Result<T, Error>;
8
9
/// OID errors.
10
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
11
pub enum Error {
12
    /// Arc exceeds allowed range (i.e. for first or second OID)
13
    ArcInvalid {
14
        /// Arc value that is erroneous.
15
        arc: Arc,
16
    },
17
18
    /// Arc is too big (exceeds 32-bit limits of this library).
19
    ///
20
    /// Technically the size of an arc is not constrained by X.660, however
21
    /// this library has elected to use `u32` as the arc representation as
22
    /// sufficient for PKIX/PKCS usages.
23
    ArcTooBig,
24
25
    /// Base 128 encoding error (used in BER/DER serialization of arcs).
26
    Base128,
27
28
    /// Expected a digit, but was provided something else.
29
    DigitExpected {
30
        /// What was found instead of a digit
31
        actual: u8,
32
    },
33
34
    /// Input data is empty.
35
    Empty,
36
37
    /// OID length is invalid (too short or too long).
38
    Length,
39
40
    /// Minimum 3 arcs required.
41
    NotEnoughArcs,
42
43
    /// Trailing `.` character at end of input.
44
    TrailingDot,
45
}
46
47
impl Error {
48
    /// Escalate this error into a panic.
49
    ///
50
    /// This is a workaround until `Result::unwrap` is allowed in `const fn`.
51
    #[allow(clippy::panic)]
52
0
    pub(crate) const fn panic(self) -> ! {
53
0
        match self {
54
0
            Error::ArcInvalid { .. } | Error::ArcTooBig => panic!("OID contains invalid arc"),
55
0
            Error::Base128 => panic!("OID contains arc with invalid base 128 encoding"),
56
0
            Error::DigitExpected { .. } => panic!("OID expected to start with digit"),
57
0
            Error::Empty => panic!("OID value is empty"),
58
0
            Error::Length => panic!("OID length invalid"),
59
0
            Error::NotEnoughArcs => panic!("OID requires minimum of 3 arcs"),
60
0
            Error::TrailingDot => panic!("OID ends with invalid trailing '.'"),
61
        }
62
    }
63
}
64
65
impl fmt::Display for Error {
66
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67
0
        match *self {
68
0
            Error::ArcInvalid { arc } => write!(f, "OID contains out-of-range arc: {}", arc),
69
0
            Error::ArcTooBig => f.write_str("OID contains arc which is larger than 32-bits"),
70
0
            Error::Base128 => f.write_str("OID contains arc with invalid base 128 encoding"),
71
0
            Error::DigitExpected { actual } => {
72
0
                write!(f, "expected digit, got '{}'", char::from(actual))
73
            }
74
0
            Error::Empty => f.write_str("OID value is empty"),
75
0
            Error::Length => f.write_str("OID length invalid"),
76
0
            Error::NotEnoughArcs => f.write_str("OID requires minimum of 3 arcs"),
77
0
            Error::TrailingDot => f.write_str("OID ends with invalid trailing '.'"),
78
        }
79
0
    }
80
}
81
82
#[cfg(feature = "std")]
83
impl std::error::Error for Error {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/const-oid-0.9.6/src/lib.rs
Line
Count
Source
1
#![no_std]
2
#![cfg_attr(docsrs, feature(doc_cfg))]
3
#![doc = include_str!("../README.md")]
4
#![doc(
5
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
6
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
7
)]
8
#![forbid(unsafe_code)]
9
#![warn(
10
    clippy::integer_arithmetic,
11
    clippy::panic,
12
    clippy::panic_in_result_fn,
13
    clippy::unwrap_used,
14
    missing_docs,
15
    rust_2018_idioms,
16
    unused_lifetimes,
17
    unused_qualifications
18
)]
19
20
#[cfg(feature = "std")]
21
extern crate std;
22
23
#[macro_use]
24
mod checked;
25
26
mod arcs;
27
mod encoder;
28
mod error;
29
mod parser;
30
31
#[cfg(feature = "db")]
32
#[cfg_attr(docsrs, doc(cfg(feature = "db")))]
33
pub mod db;
34
35
pub use crate::{
36
    arcs::{Arc, Arcs},
37
    error::{Error, Result},
38
};
39
40
use crate::encoder::Encoder;
41
use core::{fmt, str::FromStr};
42
43
/// A trait which associates an OID with a type.
44
pub trait AssociatedOid {
45
    /// The OID associated with this type.
46
    const OID: ObjectIdentifier;
47
}
48
49
/// A trait which associates a dynamic, `&self`-dependent OID with a type,
50
/// which may change depending on the type's value.
51
///
52
/// This trait is object safe and auto-impl'd for any types which impl
53
/// [`AssociatedOid`].
54
pub trait DynAssociatedOid {
55
    /// Get the OID associated with this value.
56
    fn oid(&self) -> ObjectIdentifier;
57
}
58
59
impl<T: AssociatedOid> DynAssociatedOid for T {
60
0
    fn oid(&self) -> ObjectIdentifier {
61
0
        T::OID
62
0
    }
63
}
64
65
/// Object identifier (OID).
66
///
67
/// OIDs are hierarchical structures consisting of "arcs", i.e. integer
68
/// identifiers.
69
///
70
/// # Validity
71
///
72
/// In order for an OID to be considered valid by this library, it must meet
73
/// the following criteria:
74
///
75
/// - The OID MUST have at least 3 arcs
76
/// - The first arc MUST be within the range 0-2
77
/// - The second arc MUST be within the range 0-39
78
/// - The BER/DER encoding of the OID MUST be shorter than
79
///   [`ObjectIdentifier::MAX_SIZE`]
80
#[derive(Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
81
pub struct ObjectIdentifier {
82
    /// Length in bytes
83
    length: u8,
84
85
    /// Array containing BER/DER-serialized bytes (no header)
86
    bytes: [u8; Self::MAX_SIZE],
87
}
88
89
#[allow(clippy::len_without_is_empty)]
90
impl ObjectIdentifier {
91
    /// Maximum size of a BER/DER-encoded OID in bytes.
92
    pub const MAX_SIZE: usize = 39; // makes `ObjectIdentifier` 40-bytes total w\ 1-byte length
93
94
    /// Parse an [`ObjectIdentifier`] from the dot-delimited string form,
95
    /// panicking on parse errors.
96
    ///
97
    /// This function exists as a workaround for `unwrap` not yet being
98
    /// stable in `const fn` contexts, and is intended to allow the result to
99
    /// be bound to a constant value:
100
    ///
101
    /// ```
102
    /// use const_oid::ObjectIdentifier;
103
    ///
104
    /// pub const MY_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1");
105
    /// ```
106
    ///
107
    /// In future versions of Rust it should be possible to replace this with
108
    /// `ObjectIdentifier::new(...).unwrap()`.
109
    ///
110
    /// Use [`ObjectIdentifier::new`] for fallible parsing.
111
    // TODO(tarcieri): remove this when `Result::unwrap` is `const fn`
112
0
    pub const fn new_unwrap(s: &str) -> Self {
113
0
        match Self::new(s) {
114
0
            Ok(oid) => oid,
115
0
            Err(err) => err.panic(),
116
        }
117
0
    }
118
119
    /// Parse an [`ObjectIdentifier`] from the dot-delimited string form.
120
0
    pub const fn new(s: &str) -> Result<Self> {
121
0
        // TODO(tarcieri): use `?` when stable in `const fn`
122
0
        match parser::Parser::parse(s) {
123
0
            Ok(parser) => parser.finish(),
124
0
            Err(err) => Err(err),
125
        }
126
0
    }
127
128
    /// Parse an OID from a slice of [`Arc`] values (i.e. integers).
129
0
    pub fn from_arcs(arcs: impl IntoIterator<Item = Arc>) -> Result<Self> {
130
0
        let mut encoder = Encoder::new();
131
132
0
        for arc in arcs {
133
0
            encoder = encoder.arc(arc)?;
134
        }
135
136
0
        encoder.finish()
137
0
    }
138
139
    /// Parse an OID from from its BER/DER encoding.
140
0
    pub fn from_bytes(ber_bytes: &[u8]) -> Result<Self> {
141
0
        let len = ber_bytes.len();
142
0
143
0
        match len {
144
0
            0 => return Err(Error::Empty),
145
0
            3..=Self::MAX_SIZE => (),
146
0
            _ => return Err(Error::NotEnoughArcs),
147
        }
148
0
        let mut bytes = [0u8; Self::MAX_SIZE];
149
0
        bytes[..len].copy_from_slice(ber_bytes);
150
0
151
0
        let oid = Self {
152
0
            bytes,
153
0
            length: len as u8,
154
0
        };
155
0
156
0
        // Ensure arcs are well-formed
157
0
        let mut arcs = oid.arcs();
158
0
        while arcs.try_next()?.is_some() {}
159
160
0
        Ok(oid)
161
0
    }
162
163
    /// Get the BER/DER serialization of this OID as bytes.
164
    ///
165
    /// Note that this encoding omits the tag/length, and only contains the
166
    /// value portion of the encoded OID.
167
0
    pub fn as_bytes(&self) -> &[u8] {
168
0
        &self.bytes[..self.length as usize]
169
0
    }
170
171
    /// Return the arc with the given index, if it exists.
172
0
    pub fn arc(&self, index: usize) -> Option<Arc> {
173
0
        self.arcs().nth(index)
174
0
    }
175
176
    /// Iterate over the arcs (a.k.a. nodes) of an [`ObjectIdentifier`].
177
    ///
178
    /// Returns [`Arcs`], an iterator over [`Arc`] values.
179
0
    pub fn arcs(&self) -> Arcs<'_> {
180
0
        Arcs::new(self)
181
0
    }
182
183
    /// Get the length of this [`ObjectIdentifier`] in arcs.
184
0
    pub fn len(&self) -> usize {
185
0
        self.arcs().count()
186
0
    }
187
188
    /// Get the parent OID of this one (if applicable).
189
0
    pub fn parent(&self) -> Option<Self> {
190
0
        let num_arcs = self.len().checked_sub(1)?;
191
0
        Self::from_arcs(self.arcs().take(num_arcs)).ok()
192
0
    }
193
194
    /// Push an additional arc onto this OID, returning the child OID.
195
0
    pub const fn push_arc(self, arc: Arc) -> Result<Self> {
196
0
        // TODO(tarcieri): use `?` when stable in `const fn`
197
0
        match Encoder::extend(self).arc(arc) {
198
0
            Ok(encoder) => encoder.finish(),
199
0
            Err(err) => Err(err),
200
        }
201
0
    }
202
}
203
204
impl AsRef<[u8]> for ObjectIdentifier {
205
0
    fn as_ref(&self) -> &[u8] {
206
0
        self.as_bytes()
207
0
    }
208
}
209
210
impl FromStr for ObjectIdentifier {
211
    type Err = Error;
212
213
0
    fn from_str(string: &str) -> Result<Self> {
214
0
        Self::new(string)
215
0
    }
216
}
217
218
impl TryFrom<&[u8]> for ObjectIdentifier {
219
    type Error = Error;
220
221
0
    fn try_from(ber_bytes: &[u8]) -> Result<Self> {
222
0
        Self::from_bytes(ber_bytes)
223
0
    }
224
}
225
226
impl From<&ObjectIdentifier> for ObjectIdentifier {
227
0
    fn from(oid: &ObjectIdentifier) -> ObjectIdentifier {
228
0
        *oid
229
0
    }
230
}
231
232
impl fmt::Debug for ObjectIdentifier {
233
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
234
0
        write!(f, "ObjectIdentifier({})", self)
235
0
    }
236
}
237
238
impl fmt::Display for ObjectIdentifier {
239
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240
0
        let len = self.arcs().count();
241
242
0
        for (i, arc) in self.arcs().enumerate() {
243
0
            write!(f, "{}", arc)?;
244
245
0
            if let Some(j) = i.checked_add(1) {
246
0
                if j < len {
247
0
                    write!(f, ".")?;
248
0
                }
249
0
            }
250
        }
251
252
0
        Ok(())
253
0
    }
254
}
255
256
// Implement by hand because the derive would create invalid values.
257
// Use the constructor to create a valid oid with at least 3 arcs.
258
#[cfg(feature = "arbitrary")]
259
impl<'a> arbitrary::Arbitrary<'a> for ObjectIdentifier {
260
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
261
        let first = u.int_in_range(0..=arcs::ARC_MAX_FIRST)?;
262
        let second = u.int_in_range(0..=arcs::ARC_MAX_SECOND)?;
263
        let third = u.arbitrary()?;
264
265
        let mut oid = Self::from_arcs([first, second, third])
266
            .map_err(|_| arbitrary::Error::IncorrectFormat)?;
267
268
        for arc in u.arbitrary_iter()? {
269
            oid = oid
270
                .push_arc(arc?)
271
                .map_err(|_| arbitrary::Error::IncorrectFormat)?;
272
        }
273
274
        Ok(oid)
275
    }
276
277
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
278
        (Arc::size_hint(depth).0.saturating_mul(3), None)
279
    }
280
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/const-oid-0.9.6/src/parser.rs
Line
Count
Source
1
//! OID string parser with `const` support.
2
3
use crate::{encoder::Encoder, Arc, Error, ObjectIdentifier, Result};
4
5
/// Const-friendly OID string parser.
6
///
7
/// Parses an OID from the dotted string representation.
8
#[derive(Debug)]
9
pub(crate) struct Parser {
10
    /// Current arc in progress
11
    current_arc: Arc,
12
13
    /// BER/DER encoder
14
    encoder: Encoder,
15
}
16
17
impl Parser {
18
    /// Parse an OID from a dot-delimited string e.g. `1.2.840.113549.1.1.1`
19
0
    pub(crate) const fn parse(s: &str) -> Result<Self> {
20
0
        let bytes = s.as_bytes();
21
0
22
0
        if bytes.is_empty() {
23
0
            return Err(Error::Empty);
24
0
        }
25
0
26
0
        match bytes[0] {
27
0
            b'0'..=b'9' => Self {
28
0
                current_arc: 0,
29
0
                encoder: Encoder::new(),
30
0
            }
31
0
            .parse_bytes(bytes),
32
0
            actual => Err(Error::DigitExpected { actual }),
33
        }
34
0
    }
35
36
    /// Finish parsing, returning the result
37
0
    pub(crate) const fn finish(self) -> Result<ObjectIdentifier> {
38
0
        self.encoder.finish()
39
0
    }
40
41
    /// Parse the remaining bytes
42
0
    const fn parse_bytes(mut self, bytes: &[u8]) -> Result<Self> {
43
0
        match bytes {
44
0
            // TODO(tarcieri): use `?` when stable in `const fn`
45
0
            [] => match self.encoder.arc(self.current_arc) {
46
0
                Ok(encoder) => {
47
0
                    self.encoder = encoder;
48
0
                    Ok(self)
49
                }
50
0
                Err(err) => Err(err),
51
            },
52
            // TODO(tarcieri): checked arithmetic
53
            #[allow(clippy::integer_arithmetic)]
54
0
            [byte @ b'0'..=b'9', remaining @ ..] => {
55
0
                let digit = byte.saturating_sub(b'0');
56
0
                self.current_arc = self.current_arc * 10 + digit as Arc;
57
0
                self.parse_bytes(remaining)
58
            }
59
0
            [b'.', remaining @ ..] => {
60
0
                if remaining.is_empty() {
61
0
                    return Err(Error::TrailingDot);
62
0
                }
63
0
64
0
                // TODO(tarcieri): use `?` when stable in `const fn`
65
0
                match self.encoder.arc(self.current_arc) {
66
0
                    Ok(encoder) => {
67
0
                        self.encoder = encoder;
68
0
                        self.current_arc = 0;
69
0
                        self.parse_bytes(remaining)
70
                    }
71
0
                    Err(err) => Err(err),
72
                }
73
            }
74
0
            [byte, ..] => Err(Error::DigitExpected { actual: *byte }),
75
        }
76
0
    }
77
}
78
79
#[cfg(test)]
80
mod tests {
81
    use super::Parser;
82
    use crate::Error;
83
84
    #[test]
85
    fn parse() {
86
        let oid = Parser::parse("1.23.456").unwrap().finish().unwrap();
87
        assert_eq!(oid, "1.23.456".parse().unwrap());
88
    }
89
90
    #[test]
91
    fn reject_empty_string() {
92
        assert_eq!(Parser::parse("").err().unwrap(), Error::Empty);
93
    }
94
95
    #[test]
96
    fn reject_non_digits() {
97
        assert_eq!(
98
            Parser::parse("X").err().unwrap(),
99
            Error::DigitExpected { actual: b'X' }
100
        );
101
102
        assert_eq!(
103
            Parser::parse("1.2.X").err().unwrap(),
104
            Error::DigitExpected { actual: b'X' }
105
        );
106
    }
107
108
    #[test]
109
    fn reject_trailing_dot() {
110
        assert_eq!(Parser::parse("1.23.").err().unwrap(), Error::TrailingDot);
111
    }
112
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cpufeatures-0.2.12/src/lib.rs
Line
Count
Source
1
//! This crate provides macros for runtime CPU feature detection. It's intended
2
//! as a stopgap until Rust [RFC 2725] adding first-class target feature detection
3
//! macros to `libcore` is implemented.
4
//!
5
//! # Supported target architectures
6
//!
7
//! *NOTE: target features with an asterisk are unstable (nightly-only) and
8
//! subject to change to match upstream name changes in the Rust standard
9
//! library.
10
//!
11
//! ## `aarch64`
12
//!
13
//! Linux, iOS, and macOS/ARM only (ARM64 does not support OS-independent feature detection)
14
//!
15
//! Target features:
16
//!
17
//! - `aes`*
18
//! - `sha2`*
19
//! - `sha3`*
20
//!
21
//! Linux only
22
//!
23
//! - `sm4`*
24
//!
25
//! ## `loongarch64`
26
//!
27
//! Linux only (LoongArch64 does not support OS-independent feature detection)
28
//!
29
//! Target features:
30
//!
31
//! - `lam`*
32
//! - `ual`*
33
//! - `fpu`*
34
//! - `lsx`*
35
//! - `lasx`*
36
//! - `crc32`*
37
//! - `complex`*
38
//! - `crypto`*
39
//! - `lvz`*
40
//! - `lbt.x86`*
41
//! - `lbt.arm`*
42
//! - `lbt.mips`*
43
//! - `ptw`*
44
//!
45
//! ## `x86`/`x86_64`
46
//!
47
//! OS independent and `no_std`-friendly
48
//!
49
//! Target features:
50
//!
51
//! - `adx`
52
//! - `aes`
53
//! - `avx`
54
//! - `avx2`
55
//! - `avx512bw`*
56
//! - `avx512cd`*
57
//! - `avx512dq`*
58
//! - `avx512er`*
59
//! - `avx512f`*
60
//! - `avx512ifma`*
61
//! - `avx512pf`*
62
//! - `avx512vl`*
63
//! - `bmi1`
64
//! - `bmi2`
65
//! - `fma`,
66
//! - `mmx`
67
//! - `pclmulqdq`
68
//! - `popcnt`
69
//! - `rdrand`
70
//! - `rdseed`
71
//! - `sgx`
72
//! - `sha`
73
//! - `sse`
74
//! - `sse2`
75
//! - `sse3`
76
//! - `sse4.1`
77
//! - `sse4.2`
78
//! - `ssse3`
79
//!
80
//! If you would like detection support for a target feature which is not on
81
//! this list, please [open a GitHub issue][gh].
82
//!
83
//! # Example
84
//! ```
85
//! # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
86
//! # {
87
//! // This macro creates `cpuid_aes_sha` module
88
//! cpufeatures::new!(cpuid_aes_sha, "aes", "sha");
89
//!
90
//! // `token` is a Zero Sized Type (ZST) value, which guarantees
91
//! // that underlying static storage got properly initialized,
92
//! // which allows to omit initialization branch
93
//! let token: cpuid_aes_sha::InitToken = cpuid_aes_sha::init();
94
//!
95
//! if token.get() {
96
//!     println!("CPU supports both SHA and AES extensions");
97
//! } else {
98
//!     println!("SHA and AES extensions are not supported");
99
//! }
100
//!
101
//! // If stored value needed only once you can get stored value
102
//! // omitting the token
103
//! let val = cpuid_aes_sha::get();
104
//! assert_eq!(val, token.get());
105
//!
106
//! // Additionally you can get both token and value
107
//! let (token, val) = cpuid_aes_sha::init_get();
108
//! assert_eq!(val, token.get());
109
//! # }
110
//! ```
111
//!
112
//! Note that if all tested target features are enabled via compiler options
113
//! (e.g. by using `RUSTFLAGS`), the `get` method will always return `true`
114
//! and `init` will not use CPUID instruction. Such behavior allows
115
//! compiler to completely eliminate fallback code.
116
//!
117
//! After first call macro caches result and returns it in subsequent
118
//! calls, thus runtime overhead for them is minimal.
119
//!
120
//! [RFC 2725]: https://github.com/rust-lang/rfcs/pull/2725
121
//! [gh]: https://github.com/RustCrypto/utils/issues/new?title=cpufeatures:%20requesting%20support%20for%20CHANGEME%20target%20feature
122
123
#![no_std]
124
#![doc(
125
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
126
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
127
)]
128
129
#[cfg(not(miri))]
130
#[cfg(target_arch = "aarch64")]
131
#[doc(hidden)]
132
pub mod aarch64;
133
134
#[cfg(not(miri))]
135
#[cfg(target_arch = "loongarch64")]
136
#[doc(hidden)]
137
pub mod loongarch64;
138
139
#[cfg(not(miri))]
140
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
141
mod x86;
142
143
#[cfg(miri)]
144
mod miri;
145
146
#[cfg(not(any(
147
    target_arch = "aarch64",
148
    target_arch = "loongarch64",
149
    target_arch = "x86",
150
    target_arch = "x86_64"
151
)))]
152
compile_error!("This crate works only on `aarch64`, `loongarch64`, `x86`, and `x86-64` targets.");
153
154
/// Create module with CPU feature detection code.
155
#[macro_export]
156
macro_rules! new {
157
    ($mod_name:ident, $($tf:tt),+ $(,)?) => {
158
        mod $mod_name {
159
            use core::sync::atomic::{AtomicU8, Ordering::Relaxed};
160
161
            const UNINIT: u8 = u8::max_value();
162
            static STORAGE: AtomicU8 = AtomicU8::new(UNINIT);
163
164
            /// Initialization token
165
            #[derive(Copy, Clone, Debug)]
166
            pub struct InitToken(());
167
168
            impl InitToken {
169
                /// Get initialized value
170
                #[inline(always)]
171
                pub fn get(&self) -> bool {
172
                    $crate::__unless_target_features! {
173
                        $($tf),+ => {
174
                            STORAGE.load(Relaxed) == 1
175
                        }
176
                    }
177
                }
178
            }
179
180
            /// Initialize underlying storage if needed and get
181
            /// stored value and initialization token.
182
            #[inline]
183
20.2k
            pub fn init_get() -> (InitToken, bool) {
184
20.2k
                let res = $crate::__unless_target_features! {
185
                    $($tf),+ => {
186
                        // Relaxed ordering is fine, as we only have a single atomic variable.
187
20.2k
                        let val = STORAGE.load(Relaxed);
188
20.2k
189
20.2k
                        if val == UNINIT {
190
1
                            let res = $crate::__detect_target_features!($($tf),+);
191
1
                            STORAGE.store(res as u8, Relaxed);
192
1
                            res
193
                        } else {
194
20.2k
                            val == 1
195
                        }
196
                    }
197
                };
198
199
20.2k
                (InitToken(()), res)
200
20.2k
            }
_RNvNtNtNtCs23lnNM1woOA_4sha26sha2563x8611shani_cpuid8init_getB7_
Line
Count
Source
183
20.2k
            pub fn init_get() -> (InitToken, bool) {
184
20.2k
                let res = $crate::__unless_target_features! {
185
                    $($tf),+ => {
186
                        // Relaxed ordering is fine, as we only have a single atomic variable.
187
20.2k
                        let val = STORAGE.load(Relaxed);
188
20.2k
189
20.2k
                        if val == UNINIT {
190
1
                            let res = $crate::__detect_target_features!($($tf),+);
191
1
                            STORAGE.store(res as u8, Relaxed);
192
1
                            res
193
                        } else {
194
20.2k
                            val == 1
195
                        }
196
                    }
197
                };
198
199
20.2k
                (InitToken(()), res)
200
20.2k
            }
Unexecuted instantiation: _RNvNtNtNtCs23lnNM1woOA_4sha26sha5123x8610avx2_cpuid8init_getB7_
201
202
            /// Initialize underlying storage if needed and get
203
            /// initialization token.
204
            #[inline]
205
0
            pub fn init() -> InitToken {
206
0
                init_get().0
207
0
            }
Unexecuted instantiation: _RNvNtNtNtCs23lnNM1woOA_4sha26sha2563x8611shani_cpuid4initB7_
Unexecuted instantiation: _RNvNtNtNtCs23lnNM1woOA_4sha26sha5123x8610avx2_cpuid4initB7_
208
209
            /// Initialize underlying storage if needed and get
210
            /// stored value.
211
            #[inline]
212
20.2k
            pub fn get() -> bool {
213
20.2k
                init_get().1
214
20.2k
            }
_RNvNtNtNtCs23lnNM1woOA_4sha26sha2563x8611shani_cpuid3getB7_
Line
Count
Source
212
20.2k
            pub fn get() -> bool {
213
20.2k
                init_get().1
214
20.2k
            }
Unexecuted instantiation: _RNvNtNtNtCs23lnNM1woOA_4sha26sha5123x8610avx2_cpuid3getB7_
215
        }
216
    };
217
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cpufeatures-0.2.12/src/x86.rs
Line
Count
Source
1
//! x86/x86-64 CPU feature detection support.
2
//!
3
//! Portable, `no_std`-friendly implementation that relies on the x86 `CPUID`
4
//! instruction for feature detection.
5
6
/// Evaluate the given `$body` expression any of the supplied target features
7
/// are not enabled. Otherwise returns true.
8
///
9
/// The `$body` expression is not evaluated on SGX targets, and returns false
10
/// on these targets unless *all* supplied target features are enabled.
11
#[macro_export]
12
#[doc(hidden)]
13
macro_rules! __unless_target_features {
14
    ($($tf:tt),+ => $body:expr ) => {{
15
        #[cfg(not(all($(target_feature=$tf,)*)))]
16
        {
17
            #[cfg(not(any(target_env = "sgx", target_os = "", target_os = "uefi")))]
18
            $body
19
20
            // CPUID is not available on SGX. Freestanding and UEFI targets
21
            // do not support SIMD features with default compilation flags.
22
            #[cfg(any(target_env = "sgx", target_os = "", target_os = "uefi"))]
23
            false
24
        }
25
26
        #[cfg(all($(target_feature=$tf,)*))]
27
        true
28
    }};
29
}
30
31
/// Use CPUID to detect the presence of all supplied target features.
32
#[macro_export]
33
#[doc(hidden)]
34
macro_rules! __detect_target_features {
35
    ($($tf:tt),+) => {{
36
        #[cfg(target_arch = "x86")]
37
        use core::arch::x86::{__cpuid, __cpuid_count, CpuidResult};
38
        #[cfg(target_arch = "x86_64")]
39
        use core::arch::x86_64::{__cpuid, __cpuid_count, CpuidResult};
40
41
        // These wrappers are workarounds around
42
        // https://github.com/rust-lang/rust/issues/101346
43
        //
44
        // DO NOT remove it until MSRV is bumped to a version
45
        // with the issue fix (at least 1.64).
46
        #[inline(never)]
47
1
        unsafe fn cpuid(leaf: u32) -> CpuidResult {
48
1
            __cpuid(leaf)
49
1
        }
_RNvNvNtNtNtCs23lnNM1woOA_4sha26sha2563x8611shani_cpuid8init_get5cpuid
Line
Count
Source
47
1
        unsafe fn cpuid(leaf: u32) -> CpuidResult {
48
1
            __cpuid(leaf)
49
1
        }
Unexecuted instantiation: _RNvNvNtNtNtCs23lnNM1woOA_4sha26sha5123x8610avx2_cpuid8init_get5cpuid
50
51
        #[inline(never)]
52
1
        unsafe fn cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult {
53
1
            __cpuid_count(leaf, sub_leaf)
54
1
        }
_RNvNvNtNtNtCs23lnNM1woOA_4sha26sha2563x8611shani_cpuid8init_get11cpuid_count
Line
Count
Source
52
1
        unsafe fn cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult {
53
1
            __cpuid_count(leaf, sub_leaf)
54
1
        }
Unexecuted instantiation: _RNvNvNtNtNtCs23lnNM1woOA_4sha26sha5123x8610avx2_cpuid8init_get11cpuid_count
55
56
        let cr = unsafe {
57
            [cpuid(1), cpuid_count(7, 0)]
58
        };
59
60
        $($crate::check!(cr, $tf) & )+ true
61
    }};
62
}
63
64
/// Check that OS supports required SIMD registers
65
#[macro_export]
66
#[doc(hidden)]
67
macro_rules! __xgetbv {
68
    ($cr:expr, $mask:expr) => {{
69
        #[cfg(target_arch = "x86")]
70
        use core::arch::x86 as arch;
71
        #[cfg(target_arch = "x86_64")]
72
        use core::arch::x86_64 as arch;
73
74
        // Check bits 26 and 27
75
        let xmask = 0b11 << 26;
76
        let xsave = $cr[0].ecx & xmask == xmask;
77
        if xsave {
78
            let xcr0 = unsafe { arch::_xgetbv(arch::_XCR_XFEATURE_ENABLED_MASK) };
79
            (xcr0 & $mask) == $mask
80
        } else {
81
            false
82
        }
83
    }};
84
}
85
86
macro_rules! __expand_check_macro {
87
    ($(($name:tt, $reg_cap:tt $(, $i:expr, $reg:ident, $offset:expr)*)),* $(,)?) => {
88
        #[macro_export]
89
        #[doc(hidden)]
90
        macro_rules! check {
91
            $(
92
                ($cr:expr, $name) => {{
93
                    // Register bits are listed here:
94
                    // https://wiki.osdev.org/CPU_Registers_x86#Extended_Control_Registers
95
                    let reg_cap = match $reg_cap {
96
                        // Bit 1
97
                        "xmm" => $crate::__xgetbv!($cr, 0b10),
98
                        // Bits 1 and 2
99
                        "ymm" => $crate::__xgetbv!($cr, 0b110),
100
                        // Bits 1, 2, 5, 6, and 7
101
                        "zmm" => $crate::__xgetbv!($cr, 0b1110_0110),
102
                        _ => true,
103
                    };
104
                    reg_cap
105
                    $(
106
                        & ($cr[$i].$reg & (1 << $offset) != 0)
107
                    )*
108
                }};
109
            )*
110
        }
111
    };
112
}
113
114
__expand_check_macro! {
115
    ("sse3", "xmm", 0, ecx, 0),
116
    ("pclmulqdq", "xmm", 0, ecx, 1),
117
    ("ssse3", "xmm", 0, ecx, 9),
118
    ("fma", "xmm", 0, ecx, 12, 0, ecx, 28),
119
    ("sse4.1", "xmm", 0, ecx, 19),
120
    ("sse4.2", "xmm", 0, ecx, 20),
121
    ("popcnt", "", 0, ecx, 23),
122
    ("aes", "xmm", 0, ecx, 25),
123
    ("avx", "xmm", 0, ecx, 28),
124
    ("rdrand", "", 0, ecx, 30),
125
126
    ("mmx", "", 0, edx, 23),
127
    ("sse", "xmm", 0, edx, 25),
128
    ("sse2", "xmm", 0, edx, 26),
129
130
    ("sgx", "", 1, ebx, 2),
131
    ("bmi1", "", 1, ebx, 3),
132
    ("bmi2", "", 1, ebx, 8),
133
    ("avx2", "ymm", 1, ebx, 5, 0, ecx, 28),
134
    ("avx512f", "zmm", 1, ebx, 16),
135
    ("avx512dq", "zmm", 1, ebx, 17),
136
    ("rdseed", "", 1, ebx, 18),
137
    ("adx", "", 1, ebx, 19),
138
    ("avx512ifma", "zmm", 1, ebx, 21),
139
    ("avx512pf", "zmm", 1, ebx, 26),
140
    ("avx512er", "zmm", 1, ebx, 27),
141
    ("avx512cd", "zmm", 1, ebx, 28),
142
    ("sha", "xmm", 1, ebx, 29),
143
    ("avx512bw", "zmm", 1, ebx, 30),
144
    ("avx512vl", "zmm", 1, ebx, 31),
145
    ("avx512vbmi", "zmm", 1, ecx, 1),
146
    ("avx512vbmi2", "zmm", 1, ecx, 6),
147
    ("gfni", "zmm", 1, ecx, 8),
148
    ("vaes", "zmm", 1, ecx, 9),
149
    ("vpclmulqdq", "zmm", 1, ecx, 10),
150
    ("avx512bitalg", "zmm", 1, ecx, 12),
151
    ("avx512vpopcntdq", "zmm", 1, ecx, 14),
152
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/checked.rs
Line
Count
Source
1
//! Checked arithmetic.
2
3
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
4
5
#[cfg(feature = "serde")]
6
use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8
/// Provides intentionally-checked arithmetic on `T`.
9
///
10
/// Internally this leverages the [`CtOption`] type from the [`subtle`] crate
11
/// in order to handle overflows.
12
#[derive(Copy, Clone, Debug)]
13
pub struct Checked<T>(pub CtOption<T>);
14
15
impl<T> Checked<T> {
16
    /// Create a new checked arithmetic wrapper for the given value.
17
0
    pub fn new(val: T) -> Self {
18
0
        Self(CtOption::new(val, Choice::from(1)))
19
0
    }
20
}
21
22
impl<T> Default for Checked<T>
23
where
24
    T: Default,
25
{
26
0
    fn default() -> Self {
27
0
        Self::new(T::default())
28
0
    }
29
}
30
31
impl<T: ConditionallySelectable> ConditionallySelectable for Checked<T> {
32
    #[inline]
33
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
34
0
        Self(CtOption::conditional_select(&a.0, &b.0, choice))
35
0
    }
36
}
37
38
impl<T: ConstantTimeEq> ConstantTimeEq for Checked<T> {
39
    #[inline]
40
0
    fn ct_eq(&self, rhs: &Self) -> Choice {
41
0
        self.0.ct_eq(&rhs.0)
42
0
    }
43
}
44
45
impl<T> From<Checked<T>> for CtOption<T> {
46
0
    fn from(checked: Checked<T>) -> CtOption<T> {
47
0
        checked.0
48
0
    }
49
}
50
51
impl<T> From<CtOption<T>> for Checked<T> {
52
0
    fn from(ct_option: CtOption<T>) -> Checked<T> {
53
0
        Checked(ct_option)
54
0
    }
55
}
56
57
impl<T> From<Checked<T>> for Option<T> {
58
0
    fn from(checked: Checked<T>) -> Option<T> {
59
0
        checked.0.into()
60
0
    }
61
}
62
63
#[cfg(feature = "serde")]
64
impl<'de, T: Default + Deserialize<'de>> Deserialize<'de> for Checked<T> {
65
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
66
    where
67
        D: Deserializer<'de>,
68
    {
69
        let value = Option::<T>::deserialize(deserializer)?;
70
        let choice = Choice::from(value.is_some() as u8);
71
        Ok(Self(CtOption::new(value.unwrap_or_default(), choice)))
72
    }
73
}
74
75
#[cfg(feature = "serde")]
76
impl<T: Copy + Serialize> Serialize for Checked<T> {
77
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
78
    where
79
        S: Serializer,
80
    {
81
        Option::<T>::from(self.0).serialize(serializer)
82
    }
83
}
84
85
#[cfg(all(test, feature = "serde"))]
86
#[allow(clippy::unwrap_used)]
87
mod tests {
88
89
    use crate::{Checked, U64};
90
    use subtle::{Choice, ConstantTimeEq, CtOption};
91
92
    #[test]
93
    fn serde() {
94
        let test = Checked::new(U64::from_u64(0x0011223344556677));
95
96
        let serialized = bincode::serialize(&test).unwrap();
97
        let deserialized: Checked<U64> = bincode::deserialize(&serialized).unwrap();
98
99
        assert!(bool::from(test.ct_eq(&deserialized)));
100
101
        let test = Checked::new(U64::ZERO) - Checked::new(U64::ONE);
102
        assert!(bool::from(
103
            test.ct_eq(&Checked(CtOption::new(U64::ZERO, Choice::from(0))))
104
        ));
105
106
        let serialized = bincode::serialize(&test).unwrap();
107
        let deserialized: Checked<U64> = bincode::deserialize(&serialized).unwrap();
108
109
        assert!(bool::from(test.ct_eq(&deserialized)));
110
    }
111
112
    #[test]
113
    fn serde_owned() {
114
        let test = Checked::new(U64::from_u64(0x0011223344556677));
115
116
        let serialized = bincode::serialize(&test).unwrap();
117
        let deserialized: Checked<U64> = bincode::deserialize_from(serialized.as_slice()).unwrap();
118
119
        assert!(bool::from(test.ct_eq(&deserialized)));
120
121
        let test = Checked::new(U64::ZERO) - Checked::new(U64::ONE);
122
        assert!(bool::from(
123
            test.ct_eq(&Checked(CtOption::new(U64::ZERO, Choice::from(0))))
124
        ));
125
126
        let serialized = bincode::serialize(&test).unwrap();
127
        let deserialized: Checked<U64> = bincode::deserialize_from(serialized.as_slice()).unwrap();
128
129
        assert!(bool::from(test.ct_eq(&deserialized)));
130
    }
131
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/ct_choice.rs
Line
Count
Source
1
use subtle::Choice;
2
3
use crate::Word;
4
5
/// A boolean value returned by constant-time `const fn`s.
6
// TODO: should be replaced by `subtle::Choice` or `CtOption`
7
// when `subtle` starts supporting const fns.
8
#[derive(Debug, Copy, Clone)]
9
pub struct CtChoice(Word);
10
11
impl CtChoice {
12
    /// The falsy value.
13
    pub const FALSE: Self = Self(0);
14
15
    /// The truthy value.
16
    pub const TRUE: Self = Self(Word::MAX);
17
18
    /// Returns the truthy value if `value == Word::MAX`, and the falsy value if `value == 0`.
19
    /// Panics for other values.
20
7.21k
    pub(crate) const fn from_mask(value: Word) -> Self {
21
7.21k
        debug_assert!(value == Self::FALSE.0 || value == Self::TRUE.0);
22
7.21k
        Self(value)
23
7.21k
    }
24
25
    /// Returns the truthy value if `value == 1`, and the falsy value if `value == 0`.
26
    /// Panics for other values.
27
1.06M
    pub(crate) const fn from_lsb(value: Word) -> Self {
28
1.06M
        debug_assert!(value == 0 || value == 1);
29
1.06M
        Self(value.wrapping_neg())
30
1.06M
    }
31
32
    /// Returns the truthy value if `value != 0`, and the falsy value otherwise.
33
0
    pub(crate) const fn from_usize_being_nonzero(value: usize) -> Self {
34
        const HI_BIT: u32 = usize::BITS - 1;
35
0
        Self::from_lsb(((value | value.wrapping_neg()) >> HI_BIT) as Word)
36
0
    }
37
38
    /// Returns the truthy value if `x == y`, and the falsy value otherwise.
39
0
    pub(crate) const fn from_usize_equality(x: usize, y: usize) -> Self {
40
0
        Self::from_usize_being_nonzero(x.wrapping_sub(y)).not()
41
0
    }
42
43
    /// Returns the truthy value if `x < y`, and the falsy value otherwise.
44
0
    pub(crate) const fn from_usize_lt(x: usize, y: usize) -> Self {
45
0
        let bit = (((!x) & y) | (((!x) | y) & (x.wrapping_sub(y)))) >> (usize::BITS - 1);
46
0
        Self::from_lsb(bit as Word)
47
0
    }
48
49
815k
    pub(crate) const fn not(&self) -> Self {
50
815k
        Self(!self.0)
51
815k
    }
_RNvMNtCshRehcWQJ0wE_13crypto_bigint9ct_choiceNtB2_8CtChoice3notCs4RkbDk9WRL5_5clvmr
Line
Count
Source
49
2.77k
    pub(crate) const fn not(&self) -> Self {
50
2.77k
        Self(!self.0)
51
2.77k
    }
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint9ct_choiceNtB2_8CtChoice3notB4_
_RNvMNtCshRehcWQJ0wE_13crypto_bigint9ct_choiceNtB2_8CtChoice3notCsjewTDwKBbyD_4k256
Line
Count
Source
49
98.8k
    pub(crate) const fn not(&self) -> Self {
50
98.8k
        Self(!self.0)
51
98.8k
    }
_RNvMNtCshRehcWQJ0wE_13crypto_bigint9ct_choiceNtB2_8CtChoice3notCsaHRNXv1Y9Bq_4p256
Line
Count
Source
49
714k
    pub(crate) const fn not(&self) -> Self {
50
714k
        Self(!self.0)
51
714k
    }
52
53
0
    pub(crate) const fn or(&self, other: Self) -> Self {
54
0
        Self(self.0 | other.0)
55
0
    }
56
57
0
    pub(crate) const fn and(&self, other: Self) -> Self {
58
0
        Self(self.0 & other.0)
59
0
    }
60
61
    /// Return `b` if `self` is truthy, otherwise return `a`.
62
0
    pub(crate) const fn select(&self, a: Word, b: Word) -> Word {
63
0
        a ^ (self.0 & (a ^ b))
64
0
    }
65
66
    /// Return `x` if `self` is truthy, otherwise return 0.
67
8.36k
    pub(crate) const fn if_true(&self, x: Word) -> Word {
68
8.36k
        x & self.0
69
8.36k
    }
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint9ct_choiceNtB2_8CtChoice7if_trueB4_
_RNvMNtCshRehcWQJ0wE_13crypto_bigint9ct_choiceNtB2_8CtChoice7if_trueCsjewTDwKBbyD_4k256
Line
Count
Source
67
8.36k
    pub(crate) const fn if_true(&self, x: Word) -> Word {
68
8.36k
        x & self.0
69
8.36k
    }
70
71
0
    pub(crate) const fn is_true_vartime(&self) -> bool {
72
0
        self.0 == CtChoice::TRUE.0
73
0
    }
74
75
1.07M
    pub(crate) const fn to_u8(self) -> u8 {
76
1.07M
        (self.0 as u8) & 1
77
1.07M
    }
_RNvMNtCshRehcWQJ0wE_13crypto_bigint9ct_choiceNtB2_8CtChoice5to_u8B4_
Line
Count
Source
75
823k
    pub(crate) const fn to_u8(self) -> u8 {
76
823k
        (self.0 as u8) & 1
77
823k
    }
_RNvMNtCshRehcWQJ0wE_13crypto_bigint9ct_choiceNtB2_8CtChoice5to_u8CsjewTDwKBbyD_4k256
Line
Count
Source
75
93.5k
    pub(crate) const fn to_u8(self) -> u8 {
76
93.5k
        (self.0 as u8) & 1
77
93.5k
    }
_RNvMNtCshRehcWQJ0wE_13crypto_bigint9ct_choiceNtB2_8CtChoice5to_u8CsaHRNXv1Y9Bq_4p256
Line
Count
Source
75
154k
    pub(crate) const fn to_u8(self) -> u8 {
76
154k
        (self.0 as u8) & 1
77
154k
    }
78
}
79
80
impl From<CtChoice> for Choice {
81
823k
    fn from(choice: CtChoice) -> Self {
82
823k
        Choice::from(choice.to_u8())
83
823k
    }
84
}
85
86
impl From<CtChoice> for bool {
87
0
    fn from(choice: CtChoice) -> Self {
88
0
        choice.is_true_vartime()
89
0
    }
90
}
91
92
#[cfg(test)]
93
mod tests {
94
    use super::CtChoice;
95
    use crate::Word;
96
97
    #[test]
98
    fn select() {
99
        let a: Word = 1;
100
        let b: Word = 2;
101
        assert_eq!(CtChoice::TRUE.select(a, b), b);
102
        assert_eq!(CtChoice::FALSE.select(a, b), a);
103
    }
104
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb.rs
Line
Count
Source
1
//! Big integers are represented as an array of smaller CPU word-size integers
2
//! called "limbs".
3
4
mod add;
5
mod bit_and;
6
mod bit_not;
7
mod bit_or;
8
mod bit_xor;
9
mod bits;
10
mod cmp;
11
mod encoding;
12
mod from;
13
mod mul;
14
mod neg;
15
mod shl;
16
mod shr;
17
mod sub;
18
19
#[cfg(feature = "rand_core")]
20
mod rand;
21
22
use crate::{Bounded, Zero};
23
use core::fmt;
24
use subtle::{Choice, ConditionallySelectable};
25
26
#[cfg(feature = "serde")]
27
use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer};
28
29
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
30
compile_error!("this crate builds on 32-bit and 64-bit platforms only");
31
32
//
33
// 32-bit definitions
34
//
35
36
/// Inner integer type that the [`Limb`] newtype wraps.
37
#[cfg(target_pointer_width = "32")]
38
pub type Word = u32;
39
40
/// Unsigned wide integer type: double the width of [`Word`].
41
#[cfg(target_pointer_width = "32")]
42
pub type WideWord = u64;
43
44
//
45
// 64-bit definitions
46
//
47
48
/// Unsigned integer type that the [`Limb`] newtype wraps.
49
#[cfg(target_pointer_width = "64")]
50
pub type Word = u64;
51
52
/// Wide integer type: double the width of [`Word`].
53
#[cfg(target_pointer_width = "64")]
54
pub type WideWord = u128;
55
56
/// Highest bit in a [`Limb`].
57
pub(crate) const HI_BIT: usize = Limb::BITS - 1;
58
59
/// Big integers are represented as an array of smaller CPU word-size integers
60
/// called "limbs".
61
// Our PartialEq impl only differs from the default one by being constant-time, so this is safe
62
#[allow(clippy::derived_hash_with_manual_eq)]
63
#[derive(Copy, Clone, Default, Hash)]
64
#[repr(transparent)]
65
pub struct Limb(pub Word);
66
67
impl Limb {
68
    /// The value `0`.
69
    pub const ZERO: Self = Limb(0);
70
71
    /// The value `1`.
72
    pub const ONE: Self = Limb(1);
73
74
    /// Maximum value this [`Limb`] can express.
75
    pub const MAX: Self = Limb(Word::MAX);
76
77
    // 32-bit
78
79
    /// Size of the inner integer in bits.
80
    #[cfg(target_pointer_width = "32")]
81
    pub const BITS: usize = 32;
82
    /// Size of the inner integer in bytes.
83
    #[cfg(target_pointer_width = "32")]
84
    pub const BYTES: usize = 4;
85
86
    // 64-bit
87
88
    /// Size of the inner integer in bits.
89
    #[cfg(target_pointer_width = "64")]
90
    pub const BITS: usize = 64;
91
    /// Size of the inner integer in bytes.
92
    #[cfg(target_pointer_width = "64")]
93
    pub const BYTES: usize = 8;
94
}
95
96
impl Bounded for Limb {
97
    const BITS: usize = Self::BITS;
98
    const BYTES: usize = Self::BYTES;
99
}
100
101
impl ConditionallySelectable for Limb {
102
    #[inline]
103
19.3M
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
104
19.3M
        Self(Word::conditional_select(&a.0, &b.0, choice))
105
19.3M
    }
Unexecuted instantiation: _RNvXs0_NtCshRehcWQJ0wE_13crypto_bigint4limbNtB5_4LimbNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectB7_
_RNvXs0_NtCshRehcWQJ0wE_13crypto_bigint4limbNtB5_4LimbNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectCsjewTDwKBbyD_4k256
Line
Count
Source
103
37.6k
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
104
37.6k
        Self(Word::conditional_select(&a.0, &b.0, choice))
105
37.6k
    }
_RNvXs0_NtCshRehcWQJ0wE_13crypto_bigint4limbNtB5_4LimbNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectCsaHRNXv1Y9Bq_4p256
Line
Count
Source
103
19.3M
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
104
19.3M
        Self(Word::conditional_select(&a.0, &b.0, choice))
105
19.3M
    }
106
}
107
108
impl Zero for Limb {
109
    const ZERO: Self = Self::ZERO;
110
}
111
112
impl fmt::Debug for Limb {
113
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114
0
        write!(f, "Limb(0x{self:X})")
115
0
    }
116
}
117
118
impl fmt::Display for Limb {
119
    #[inline]
120
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121
0
        fmt::UpperHex::fmt(self, f)
122
0
    }
123
}
124
125
impl fmt::LowerHex for Limb {
126
    #[inline]
127
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128
0
        write!(f, "{:0width$x}", &self.0, width = Self::BYTES * 2)
129
0
    }
130
}
131
132
impl fmt::UpperHex for Limb {
133
    #[inline]
134
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135
0
        write!(f, "{:0width$X}", &self.0, width = Self::BYTES * 2)
136
0
    }
Unexecuted instantiation: _RNvXs5_NtCshRehcWQJ0wE_13crypto_bigint4limbNtB5_4LimbNtNtCsbQ8arDwx5Xq_4core3fmt8UpperHex3fmtB7_
Unexecuted instantiation: _RNvXs5_NtCshRehcWQJ0wE_13crypto_bigint4limbNtB5_4LimbNtNtCsbQ8arDwx5Xq_4core3fmt8UpperHex3fmtCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs5_NtCshRehcWQJ0wE_13crypto_bigint4limbNtB5_4LimbNtNtCsbQ8arDwx5Xq_4core3fmt8UpperHex3fmtCsaHRNXv1Y9Bq_4p256
137
}
138
139
#[cfg(feature = "serde")]
140
impl<'de> Deserialize<'de> for Limb {
141
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
142
    where
143
        D: Deserializer<'de>,
144
    {
145
        Ok(Self(Word::deserialize(deserializer)?))
146
    }
147
}
148
149
#[cfg(feature = "serde")]
150
impl Serialize for Limb {
151
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
152
    where
153
        S: Serializer,
154
    {
155
        self.0.serialize(serializer)
156
    }
157
}
158
159
#[cfg(feature = "zeroize")]
160
impl zeroize::DefaultIsZeroes for Limb {}
161
162
#[cfg(test)]
163
mod tests {
164
    #[cfg(feature = "alloc")]
165
    use {super::Limb, alloc::format};
166
167
    #[cfg(feature = "alloc")]
168
    #[test]
169
    fn debug() {
170
        #[cfg(target_pointer_width = "32")]
171
        assert_eq!(format!("{:?}", Limb(42)), "Limb(0x0000002A)");
172
173
        #[cfg(target_pointer_width = "64")]
174
        assert_eq!(format!("{:?}", Limb(42)), "Limb(0x000000000000002A)");
175
    }
176
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/add.rs
Line
Count
Source
1
//! Limb addition
2
3
use crate::{Checked, CheckedAdd, Limb, WideWord, Word, Wrapping, Zero};
4
use core::ops::{Add, AddAssign};
5
use subtle::CtOption;
6
7
impl Limb {
8
    /// Computes `self + rhs + carry`, returning the result along with the new carry.
9
    #[inline(always)]
10
5.87M
    pub const fn adc(self, rhs: Limb, carry: Limb) -> (Limb, Limb) {
11
5.87M
        let a = self.0 as WideWord;
12
5.87M
        let b = rhs.0 as WideWord;
13
5.87M
        let carry = carry.0 as WideWord;
14
5.87M
        let ret = a + b + carry;
15
5.87M
        (Limb(ret as Word), Limb((ret >> Self::BITS) as Word))
16
5.87M
    }
17
18
    /// Perform saturating addition.
19
    #[inline]
20
0
    pub const fn saturating_add(&self, rhs: Self) -> Self {
21
0
        Limb(self.0.saturating_add(rhs.0))
22
0
    }
23
24
    /// Perform wrapping addition, discarding overflow.
25
    #[inline(always)]
26
0
    pub const fn wrapping_add(&self, rhs: Self) -> Self {
27
0
        Limb(self.0.wrapping_add(rhs.0))
28
0
    }
29
}
30
31
impl CheckedAdd for Limb {
32
    type Output = Self;
33
34
    #[inline]
35
0
    fn checked_add(&self, rhs: Self) -> CtOption<Self> {
36
0
        let (result, carry) = self.adc(rhs, Limb::ZERO);
37
0
        CtOption::new(result, carry.is_zero())
38
0
    }
39
}
40
41
impl Add for Wrapping<Limb> {
42
    type Output = Self;
43
44
0
    fn add(self, rhs: Self) -> Wrapping<Limb> {
45
0
        Wrapping(self.0.wrapping_add(rhs.0))
46
0
    }
47
}
48
49
impl Add<&Wrapping<Limb>> for Wrapping<Limb> {
50
    type Output = Wrapping<Limb>;
51
52
0
    fn add(self, rhs: &Wrapping<Limb>) -> Wrapping<Limb> {
53
0
        Wrapping(self.0.wrapping_add(rhs.0))
54
0
    }
55
}
56
57
impl Add<Wrapping<Limb>> for &Wrapping<Limb> {
58
    type Output = Wrapping<Limb>;
59
60
0
    fn add(self, rhs: Wrapping<Limb>) -> Wrapping<Limb> {
61
0
        Wrapping(self.0.wrapping_add(rhs.0))
62
0
    }
63
}
64
65
impl Add<&Wrapping<Limb>> for &Wrapping<Limb> {
66
    type Output = Wrapping<Limb>;
67
68
0
    fn add(self, rhs: &Wrapping<Limb>) -> Wrapping<Limb> {
69
0
        Wrapping(self.0.wrapping_add(rhs.0))
70
0
    }
71
}
72
73
impl AddAssign for Wrapping<Limb> {
74
0
    fn add_assign(&mut self, other: Self) {
75
0
        *self = *self + other;
76
0
    }
77
}
78
79
impl AddAssign<&Wrapping<Limb>> for Wrapping<Limb> {
80
0
    fn add_assign(&mut self, other: &Self) {
81
0
        *self = *self + other;
82
0
    }
83
}
84
85
impl Add for Checked<Limb> {
86
    type Output = Self;
87
88
0
    fn add(self, rhs: Self) -> Checked<Limb> {
89
0
        Checked(
90
0
            self.0
91
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_add(rhs))),
92
0
        )
93
0
    }
94
}
95
96
impl Add<&Checked<Limb>> for Checked<Limb> {
97
    type Output = Checked<Limb>;
98
99
0
    fn add(self, rhs: &Checked<Limb>) -> Checked<Limb> {
100
0
        Checked(
101
0
            self.0
102
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_add(rhs))),
103
0
        )
104
0
    }
105
}
106
107
impl Add<Checked<Limb>> for &Checked<Limb> {
108
    type Output = Checked<Limb>;
109
110
0
    fn add(self, rhs: Checked<Limb>) -> Checked<Limb> {
111
0
        Checked(
112
0
            self.0
113
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_add(rhs))),
114
0
        )
115
0
    }
116
}
117
118
impl Add<&Checked<Limb>> for &Checked<Limb> {
119
    type Output = Checked<Limb>;
120
121
0
    fn add(self, rhs: &Checked<Limb>) -> Checked<Limb> {
122
0
        Checked(
123
0
            self.0
124
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_add(rhs))),
125
0
        )
126
0
    }
127
}
128
129
impl AddAssign for Checked<Limb> {
130
0
    fn add_assign(&mut self, other: Self) {
131
0
        *self = *self + other;
132
0
    }
133
}
134
135
impl AddAssign<&Checked<Limb>> for Checked<Limb> {
136
0
    fn add_assign(&mut self, other: &Self) {
137
0
        *self = *self + other;
138
0
    }
139
}
140
141
#[cfg(test)]
142
mod tests {
143
    use crate::{CheckedAdd, Limb};
144
145
    #[test]
146
    fn adc_no_carry() {
147
        let (res, carry) = Limb::ZERO.adc(Limb::ONE, Limb::ZERO);
148
        assert_eq!(res, Limb::ONE);
149
        assert_eq!(carry, Limb::ZERO);
150
    }
151
152
    #[test]
153
    fn adc_with_carry() {
154
        let (res, carry) = Limb::MAX.adc(Limb::ONE, Limb::ZERO);
155
        assert_eq!(res, Limb::ZERO);
156
        assert_eq!(carry, Limb::ONE);
157
    }
158
159
    #[test]
160
    fn wrapping_add_no_carry() {
161
        assert_eq!(Limb::ZERO.wrapping_add(Limb::ONE), Limb::ONE);
162
    }
163
164
    #[test]
165
    fn wrapping_add_with_carry() {
166
        assert_eq!(Limb::MAX.wrapping_add(Limb::ONE), Limb::ZERO);
167
    }
168
169
    #[test]
170
    fn checked_add_ok() {
171
        let result = Limb::ZERO.checked_add(Limb::ONE);
172
        assert_eq!(result.unwrap(), Limb::ONE);
173
    }
174
175
    #[test]
176
    fn checked_add_overflow() {
177
        let result = Limb::MAX.checked_add(Limb::ONE);
178
        assert!(!bool::from(result.is_some()));
179
    }
180
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/bit_and.rs
Line
Count
Source
1
//! Limb bit and operations.
2
3
use super::Limb;
4
use core::ops::BitAnd;
5
6
impl Limb {
7
    /// Calculates `a & b`.
8
    #[inline(always)]
9
3.92M
    pub const fn bitand(self, rhs: Self) -> Self {
10
3.92M
        Limb(self.0 & rhs.0)
11
3.92M
    }
12
}
13
14
impl BitAnd for Limb {
15
    type Output = Limb;
16
17
    #[inline(always)]
18
    fn bitand(self, rhs: Self) -> Self::Output {
19
        self.bitand(rhs)
20
    }
21
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/bit_not.rs
Line
Count
Source
1
//! Limb bit not operations.
2
3
use super::Limb;
4
use core::ops::Not;
5
6
impl Limb {
7
    /// Calculates `!a`.
8
0
    pub const fn not(self) -> Self {
9
0
        Limb(!self.0)
10
0
    }
11
}
12
13
impl Not for Limb {
14
    type Output = Limb;
15
16
0
    fn not(self) -> <Self as Not>::Output {
17
0
        self.not()
18
0
    }
19
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/bit_or.rs
Line
Count
Source
1
//! Limb bit or operations.
2
3
use super::Limb;
4
use core::ops::BitOr;
5
6
impl Limb {
7
    /// Calculates `a | b`.
8
991k
    pub const fn bitor(self, rhs: Self) -> Self {
9
991k
        Limb(self.0 | rhs.0)
10
991k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4limb6bit_orNtB4_4Limb5bitorB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4limb6bit_orNtB4_4Limb5bitorCsjewTDwKBbyD_4k256
Line
Count
Source
8
374k
    pub const fn bitor(self, rhs: Self) -> Self {
9
374k
        Limb(self.0 | rhs.0)
10
374k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4limb6bit_orNtB4_4Limb5bitorCsaHRNXv1Y9Bq_4p256
Line
Count
Source
8
617k
    pub const fn bitor(self, rhs: Self) -> Self {
9
617k
        Limb(self.0 | rhs.0)
10
617k
    }
11
}
12
13
impl BitOr for Limb {
14
    type Output = Limb;
15
16
0
    fn bitor(self, rhs: Self) -> Self::Output {
17
0
        self.bitor(rhs)
18
0
    }
19
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/bit_xor.rs
Line
Count
Source
1
//! Limb bit xor operations.
2
3
use super::Limb;
4
use core::ops::BitXor;
5
6
impl Limb {
7
    /// Calculates `a ^ b`.
8
0
    pub const fn bitxor(self, rhs: Self) -> Self {
9
0
        Limb(self.0 ^ rhs.0)
10
0
    }
11
}
12
13
impl BitXor for Limb {
14
    type Output = Limb;
15
16
0
    fn bitxor(self, rhs: Self) -> Self::Output {
17
0
        self.bitxor(rhs)
18
0
    }
19
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/bits.rs
Line
Count
Source
1
use super::Limb;
2
3
impl Limb {
4
    /// Calculate the number of bits needed to represent this number.
5
0
    pub const fn bits(self) -> usize {
6
0
        Limb::BITS - (self.0.leading_zeros() as usize)
7
0
    }
8
9
    /// Calculate the number of leading zeros in the binary representation of this number.
10
0
    pub const fn leading_zeros(self) -> usize {
11
0
        self.0.leading_zeros() as usize
12
0
    }
13
14
    /// Calculate the number of trailing zeros in the binary representation of this number.
15
0
    pub const fn trailing_zeros(self) -> usize {
16
0
        self.0.trailing_zeros() as usize
17
0
    }
18
19
    /// Calculate the number of trailing ones the binary representation of this number.
20
0
    pub const fn trailing_ones(self) -> usize {
21
0
        self.0.trailing_ones() as usize
22
0
    }
23
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/cmp.rs
Line
Count
Source
1
//! Limb comparisons
2
3
use super::HI_BIT;
4
use crate::{CtChoice, Limb};
5
use core::cmp::Ordering;
6
use subtle::{Choice, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess};
7
8
impl Limb {
9
    /// Is this limb an odd number?
10
    #[inline]
11
1.46M
    pub fn is_odd(&self) -> Choice {
12
1.46M
        Choice::from(self.0 as u8 & 1)
13
1.46M
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4limb3cmpNtB4_4Limb6is_oddB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4limb3cmpNtB4_4Limb6is_oddCsjewTDwKBbyD_4k256
Line
Count
Source
11
560k
    pub fn is_odd(&self) -> Choice {
12
560k
        Choice::from(self.0 as u8 & 1)
13
560k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4limb3cmpNtB4_4Limb6is_oddCsaHRNXv1Y9Bq_4p256
Line
Count
Source
11
906k
    pub fn is_odd(&self) -> Choice {
12
906k
        Choice::from(self.0 as u8 & 1)
13
906k
    }
14
15
    /// Perform a comparison of the inner value in variable-time.
16
    ///
17
    /// Note that the [`PartialOrd`] and [`Ord`] impls wrap constant-time
18
    /// comparisons using the `subtle` crate.
19
0
    pub fn cmp_vartime(&self, other: &Self) -> Ordering {
20
0
        self.0.cmp(&other.0)
21
0
    }
22
23
    /// Performs an equality check in variable-time.
24
0
    pub const fn eq_vartime(&self, other: &Self) -> bool {
25
0
        self.0 == other.0
26
0
    }
27
28
    /// Return `b` if `c` is truthy, otherwise return `a`.
29
    #[inline]
30
0
    pub(crate) const fn ct_select(a: Self, b: Self, c: CtChoice) -> Self {
31
0
        Self(c.select(a.0, b.0))
32
0
    }
33
34
    /// Returns the truthy value if `self != 0` and the falsy value otherwise.
35
    #[inline]
36
1.06M
    pub(crate) const fn ct_is_nonzero(&self) -> CtChoice {
37
1.06M
        let inner = self.0;
38
1.06M
        CtChoice::from_lsb((inner | inner.wrapping_neg()) >> HI_BIT)
39
1.06M
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4limb3cmpNtB4_4Limb13ct_is_nonzeroCs4RkbDk9WRL5_5clvmr
Line
Count
Source
36
2.77k
    pub(crate) const fn ct_is_nonzero(&self) -> CtChoice {
37
2.77k
        let inner = self.0;
38
2.77k
        CtChoice::from_lsb((inner | inner.wrapping_neg()) >> HI_BIT)
39
2.77k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4limb3cmpNtB4_4Limb13ct_is_nonzeroB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4limb3cmpNtB4_4Limb13ct_is_nonzeroCsjewTDwKBbyD_4k256
Line
Count
Source
36
194k
    pub(crate) const fn ct_is_nonzero(&self) -> CtChoice {
37
194k
        let inner = self.0;
38
194k
        CtChoice::from_lsb((inner | inner.wrapping_neg()) >> HI_BIT)
39
194k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4limb3cmpNtB4_4Limb13ct_is_nonzeroCsaHRNXv1Y9Bq_4p256
Line
Count
Source
36
868k
    pub(crate) const fn ct_is_nonzero(&self) -> CtChoice {
37
868k
        let inner = self.0;
38
868k
        CtChoice::from_lsb((inner | inner.wrapping_neg()) >> HI_BIT)
39
868k
    }
40
41
    /// Returns the truthy value if `lhs == rhs` and the falsy value otherwise.
42
    #[inline]
43
0
    pub(crate) const fn ct_eq(lhs: Self, rhs: Self) -> CtChoice {
44
0
        let x = lhs.0;
45
0
        let y = rhs.0;
46
0
47
0
        // x ^ y == 0 if and only if x == y
48
0
        Self(x ^ y).ct_is_nonzero().not()
49
0
    }
50
51
    /// Returns the truthy value if `lhs < rhs` and the falsy value otherwise.
52
    #[inline]
53
0
    pub(crate) const fn ct_lt(lhs: Self, rhs: Self) -> CtChoice {
54
0
        let x = lhs.0;
55
0
        let y = rhs.0;
56
0
        let bit = (((!x) & y) | (((!x) | y) & (x.wrapping_sub(y)))) >> (Limb::BITS - 1);
57
0
        CtChoice::from_lsb(bit)
58
0
    }
59
60
    /// Returns the truthy value if `lhs <= rhs` and the falsy value otherwise.
61
    #[inline]
62
0
    pub(crate) const fn ct_le(lhs: Self, rhs: Self) -> CtChoice {
63
0
        let x = lhs.0;
64
0
        let y = rhs.0;
65
0
        let bit = (((!x) | y) & ((x ^ y) | !(y.wrapping_sub(x)))) >> (Limb::BITS - 1);
66
0
        CtChoice::from_lsb(bit)
67
0
    }
68
}
69
70
impl ConstantTimeEq for Limb {
71
    #[inline]
72
0
    fn ct_eq(&self, other: &Self) -> Choice {
73
0
        self.0.ct_eq(&other.0)
74
0
    }
75
}
76
77
impl ConstantTimeGreater for Limb {
78
    #[inline]
79
0
    fn ct_gt(&self, other: &Self) -> Choice {
80
0
        self.0.ct_gt(&other.0)
81
0
    }
82
}
83
84
impl ConstantTimeLess for Limb {
85
    #[inline]
86
0
    fn ct_lt(&self, other: &Self) -> Choice {
87
0
        self.0.ct_lt(&other.0)
88
0
    }
89
}
90
91
impl Eq for Limb {}
92
93
impl Ord for Limb {
94
0
    fn cmp(&self, other: &Self) -> Ordering {
95
0
        let mut n = 0i8;
96
0
        n -= self.ct_lt(other).unwrap_u8() as i8;
97
0
        n += self.ct_gt(other).unwrap_u8() as i8;
98
0
99
0
        match n {
100
0
            -1 => Ordering::Less,
101
0
            1 => Ordering::Greater,
102
            _ => {
103
0
                debug_assert_eq!(n, 0);
104
0
                debug_assert!(bool::from(self.ct_eq(other)));
105
0
                Ordering::Equal
106
            }
107
        }
108
0
    }
109
}
110
111
impl PartialOrd for Limb {
112
    #[inline]
113
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
114
0
        Some(self.cmp(other))
115
0
    }
116
}
117
118
impl PartialEq for Limb {
119
    #[inline]
120
0
    fn eq(&self, other: &Self) -> bool {
121
0
        self.ct_eq(other).into()
122
0
    }
123
}
124
125
#[cfg(test)]
126
mod tests {
127
    use crate::{Limb, Zero};
128
    use core::cmp::Ordering;
129
    use subtle::{ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess};
130
131
    #[test]
132
    fn is_zero() {
133
        assert!(bool::from(Limb::ZERO.is_zero()));
134
        assert!(!bool::from(Limb::ONE.is_zero()));
135
        assert!(!bool::from(Limb::MAX.is_zero()));
136
    }
137
138
    #[test]
139
    fn is_odd() {
140
        assert!(!bool::from(Limb::ZERO.is_odd()));
141
        assert!(bool::from(Limb::ONE.is_odd()));
142
        assert!(bool::from(Limb::MAX.is_odd()));
143
    }
144
145
    #[test]
146
    fn ct_eq() {
147
        let a = Limb::ZERO;
148
        let b = Limb::MAX;
149
150
        assert!(bool::from(a.ct_eq(&a)));
151
        assert!(!bool::from(a.ct_eq(&b)));
152
        assert!(!bool::from(b.ct_eq(&a)));
153
        assert!(bool::from(b.ct_eq(&b)));
154
    }
155
156
    #[test]
157
    fn ct_gt() {
158
        let a = Limb::ZERO;
159
        let b = Limb::ONE;
160
        let c = Limb::MAX;
161
162
        assert!(bool::from(b.ct_gt(&a)));
163
        assert!(bool::from(c.ct_gt(&a)));
164
        assert!(bool::from(c.ct_gt(&b)));
165
166
        assert!(!bool::from(a.ct_gt(&a)));
167
        assert!(!bool::from(b.ct_gt(&b)));
168
        assert!(!bool::from(c.ct_gt(&c)));
169
170
        assert!(!bool::from(a.ct_gt(&b)));
171
        assert!(!bool::from(a.ct_gt(&c)));
172
        assert!(!bool::from(b.ct_gt(&c)));
173
    }
174
175
    #[test]
176
    fn ct_lt() {
177
        let a = Limb::ZERO;
178
        let b = Limb::ONE;
179
        let c = Limb::MAX;
180
181
        assert!(bool::from(a.ct_lt(&b)));
182
        assert!(bool::from(a.ct_lt(&c)));
183
        assert!(bool::from(b.ct_lt(&c)));
184
185
        assert!(!bool::from(a.ct_lt(&a)));
186
        assert!(!bool::from(b.ct_lt(&b)));
187
        assert!(!bool::from(c.ct_lt(&c)));
188
189
        assert!(!bool::from(b.ct_lt(&a)));
190
        assert!(!bool::from(c.ct_lt(&a)));
191
        assert!(!bool::from(c.ct_lt(&b)));
192
    }
193
194
    #[test]
195
    fn cmp() {
196
        assert_eq!(Limb::ZERO.cmp(&Limb::ONE), Ordering::Less);
197
        assert_eq!(Limb::ONE.cmp(&Limb::ONE), Ordering::Equal);
198
        assert_eq!(Limb::MAX.cmp(&Limb::ONE), Ordering::Greater);
199
    }
200
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/encoding.rs
Line
Count
Source
1
//! Limb encoding
2
3
use super::{Limb, Word};
4
use crate::Encoding;
5
6
impl Encoding for Limb {
7
    #[cfg(target_pointer_width = "32")]
8
    type Repr = [u8; 4];
9
    #[cfg(target_pointer_width = "64")]
10
    type Repr = [u8; 8];
11
12
    #[inline]
13
0
    fn from_be_bytes(bytes: Self::Repr) -> Self {
14
0
        Limb(Word::from_be_bytes(bytes))
15
0
    }
16
17
    #[inline]
18
0
    fn from_le_bytes(bytes: Self::Repr) -> Self {
19
0
        Limb(Word::from_le_bytes(bytes))
20
0
    }
21
22
    #[inline]
23
11.8k
    fn to_be_bytes(&self) -> Self::Repr {
24
11.8k
        self.0.to_be_bytes()
25
11.8k
    }
Unexecuted instantiation: _RNvXNtNtCshRehcWQJ0wE_13crypto_bigint4limb8encodingNtB4_4LimbNtNtB6_6traits8Encoding11to_be_bytesB6_
_RNvXNtNtCshRehcWQJ0wE_13crypto_bigint4limb8encodingNtB4_4LimbNtNtB6_6traits8Encoding11to_be_bytesCsjewTDwKBbyD_4k256
Line
Count
Source
23
8.36k
    fn to_be_bytes(&self) -> Self::Repr {
24
8.36k
        self.0.to_be_bytes()
25
8.36k
    }
_RNvXNtNtCshRehcWQJ0wE_13crypto_bigint4limb8encodingNtB4_4LimbNtNtB6_6traits8Encoding11to_be_bytesCsaHRNXv1Y9Bq_4p256
Line
Count
Source
23
3.46k
    fn to_be_bytes(&self) -> Self::Repr {
24
3.46k
        self.0.to_be_bytes()
25
3.46k
    }
26
27
    #[inline]
28
6.70k
    fn to_le_bytes(&self) -> Self::Repr {
29
6.70k
        self.0.to_le_bytes()
30
6.70k
    }
_RNvXNtNtCshRehcWQJ0wE_13crypto_bigint4limb8encodingNtB4_4LimbNtNtB6_6traits8Encoding11to_le_bytesCs4RkbDk9WRL5_5clvmr
Line
Count
Source
28
6.70k
    fn to_le_bytes(&self) -> Self::Repr {
29
6.70k
        self.0.to_le_bytes()
30
6.70k
    }
Unexecuted instantiation: _RNvXNtNtCshRehcWQJ0wE_13crypto_bigint4limb8encodingNtB4_4LimbNtNtB6_6traits8Encoding11to_le_bytesB6_
Unexecuted instantiation: _RNvXNtNtCshRehcWQJ0wE_13crypto_bigint4limb8encodingNtB4_4LimbNtNtB6_6traits8Encoding11to_le_bytesCsaHRNXv1Y9Bq_4p256
31
}
32
33
#[cfg(test)]
34
mod test {
35
    use super::*;
36
    use proptest::prelude::*;
37
38
    prop_compose! {
39
        fn limb()(inner in any::<Word>()) -> Limb {
40
            Limb(inner)
41
        }
42
    }
43
44
    proptest! {
45
        #[test]
46
        fn roundtrip(a in limb()) {
47
            assert_eq!(a, Limb::from_be_bytes(a.to_be_bytes()));
48
            assert_eq!(a, Limb::from_le_bytes(a.to_le_bytes()));
49
        }
50
    }
51
52
    proptest! {
53
        #[test]
54
        fn reverse(a in limb()) {
55
            let mut bytes = a.to_be_bytes();
56
            bytes.reverse();
57
            assert_eq!(a, Limb::from_le_bytes(bytes));
58
59
            let mut bytes = a.to_le_bytes();
60
            bytes.reverse();
61
            assert_eq!(a, Limb::from_be_bytes(bytes));
62
        }
63
    }
64
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/from.rs
Line
Count
Source
1
//! `From`-like conversions for [`Limb`].
2
3
use super::{Limb, WideWord, Word};
4
5
impl Limb {
6
    /// Create a [`Limb`] from a `u8` integer (const-friendly)
7
    // TODO(tarcieri): replace with `const impl From<u8>` when stable
8
0
    pub const fn from_u8(n: u8) -> Self {
9
0
        Limb(n as Word)
10
0
    }
11
12
    /// Create a [`Limb`] from a `u16` integer (const-friendly)
13
    // TODO(tarcieri): replace with `const impl From<u16>` when stable
14
0
    pub const fn from_u16(n: u16) -> Self {
15
0
        Limb(n as Word)
16
0
    }
17
18
    /// Create a [`Limb`] from a `u32` integer (const-friendly)
19
    // TODO(tarcieri): replace with `const impl From<u32>` when stable
20
0
    pub const fn from_u32(n: u32) -> Self {
21
0
        #[allow(trivial_numeric_casts)]
22
0
        Limb(n as Word)
23
0
    }
24
25
    /// Create a [`Limb`] from a `u64` integer (const-friendly)
26
    // TODO(tarcieri): replace with `const impl From<u64>` when stable
27
    #[cfg(target_pointer_width = "64")]
28
0
    pub const fn from_u64(n: u64) -> Self {
29
0
        Limb(n)
30
0
    }
31
}
32
33
impl From<u8> for Limb {
34
    #[inline]
35
0
    fn from(n: u8) -> Limb {
36
0
        Limb(n.into())
37
0
    }
38
}
39
40
impl From<u16> for Limb {
41
    #[inline]
42
0
    fn from(n: u16) -> Limb {
43
0
        Limb(n.into())
44
0
    }
45
}
46
47
impl From<u32> for Limb {
48
    #[inline]
49
0
    fn from(n: u32) -> Limb {
50
0
        Limb(n.into())
51
0
    }
52
}
53
54
#[cfg(target_pointer_width = "64")]
55
impl From<u64> for Limb {
56
    #[inline]
57
0
    fn from(n: u64) -> Limb {
58
0
        Limb(n)
59
0
    }
60
}
61
62
impl From<Limb> for Word {
63
    #[inline]
64
0
    fn from(limb: Limb) -> Word {
65
0
        limb.0
66
0
    }
67
}
68
69
impl From<Limb> for WideWord {
70
    #[inline]
71
0
    fn from(limb: Limb) -> WideWord {
72
0
        limb.0.into()
73
0
    }
74
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/mul.rs
Line
Count
Source
1
//! Limb multiplication
2
3
use crate::{Checked, CheckedMul, Limb, WideWord, Word, Wrapping, Zero};
4
use core::ops::{Mul, MulAssign};
5
use subtle::CtOption;
6
7
impl Limb {
8
    /// Computes `self + (b * c) + carry`, returning the result along with the new carry.
9
    #[inline(always)]
10
26.8k
    pub const fn mac(self, b: Limb, c: Limb, carry: Limb) -> (Limb, Limb) {
11
26.8k
        let a = self.0 as WideWord;
12
26.8k
        let b = b.0 as WideWord;
13
26.8k
        let c = c.0 as WideWord;
14
26.8k
        let carry = carry.0 as WideWord;
15
26.8k
        let ret = a + (b * c) + carry;
16
26.8k
        (Limb(ret as Word), Limb((ret >> Self::BITS) as Word))
17
26.8k
    }
18
19
    /// Perform saturating multiplication.
20
    #[inline]
21
0
    pub const fn saturating_mul(&self, rhs: Self) -> Self {
22
0
        Limb(self.0.saturating_mul(rhs.0))
23
0
    }
24
25
    /// Perform wrapping multiplication, discarding overflow.
26
    #[inline(always)]
27
0
    pub const fn wrapping_mul(&self, rhs: Self) -> Self {
28
0
        Limb(self.0.wrapping_mul(rhs.0))
29
0
    }
30
31
    /// Compute "wide" multiplication, with a product twice the size of the input.
32
0
    pub(crate) const fn mul_wide(&self, rhs: Self) -> WideWord {
33
0
        (self.0 as WideWord) * (rhs.0 as WideWord)
34
0
    }
35
}
36
37
impl CheckedMul for Limb {
38
    type Output = Self;
39
40
    #[inline]
41
0
    fn checked_mul(&self, rhs: Self) -> CtOption<Self> {
42
0
        let result = self.mul_wide(rhs);
43
0
        let overflow = Limb((result >> Self::BITS) as Word);
44
0
        CtOption::new(Limb(result as Word), overflow.is_zero())
45
0
    }
46
}
47
48
impl Mul for Wrapping<Limb> {
49
    type Output = Self;
50
51
0
    fn mul(self, rhs: Self) -> Wrapping<Limb> {
52
0
        Wrapping(self.0.wrapping_mul(rhs.0))
53
0
    }
54
}
55
56
impl Mul<&Wrapping<Limb>> for Wrapping<Limb> {
57
    type Output = Wrapping<Limb>;
58
59
0
    fn mul(self, rhs: &Wrapping<Limb>) -> Wrapping<Limb> {
60
0
        Wrapping(self.0.wrapping_mul(rhs.0))
61
0
    }
62
}
63
64
impl Mul<Wrapping<Limb>> for &Wrapping<Limb> {
65
    type Output = Wrapping<Limb>;
66
67
0
    fn mul(self, rhs: Wrapping<Limb>) -> Wrapping<Limb> {
68
0
        Wrapping(self.0.wrapping_mul(rhs.0))
69
0
    }
70
}
71
72
impl Mul<&Wrapping<Limb>> for &Wrapping<Limb> {
73
    type Output = Wrapping<Limb>;
74
75
0
    fn mul(self, rhs: &Wrapping<Limb>) -> Wrapping<Limb> {
76
0
        Wrapping(self.0.wrapping_mul(rhs.0))
77
0
    }
78
}
79
80
impl MulAssign for Wrapping<Limb> {
81
0
    fn mul_assign(&mut self, other: Self) {
82
0
        *self = *self * other;
83
0
    }
84
}
85
86
impl MulAssign<&Wrapping<Limb>> for Wrapping<Limb> {
87
0
    fn mul_assign(&mut self, other: &Self) {
88
0
        *self = *self * other;
89
0
    }
90
}
91
92
impl Mul for Checked<Limb> {
93
    type Output = Self;
94
95
0
    fn mul(self, rhs: Self) -> Checked<Limb> {
96
0
        Checked(
97
0
            self.0
98
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_mul(rhs))),
99
0
        )
100
0
    }
101
}
102
103
impl Mul<&Checked<Limb>> for Checked<Limb> {
104
    type Output = Checked<Limb>;
105
106
0
    fn mul(self, rhs: &Checked<Limb>) -> Checked<Limb> {
107
0
        Checked(
108
0
            self.0
109
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_mul(rhs))),
110
0
        )
111
0
    }
112
}
113
114
impl Mul<Checked<Limb>> for &Checked<Limb> {
115
    type Output = Checked<Limb>;
116
117
0
    fn mul(self, rhs: Checked<Limb>) -> Checked<Limb> {
118
0
        Checked(
119
0
            self.0
120
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_mul(rhs))),
121
0
        )
122
0
    }
123
}
124
125
impl Mul<&Checked<Limb>> for &Checked<Limb> {
126
    type Output = Checked<Limb>;
127
128
0
    fn mul(self, rhs: &Checked<Limb>) -> Checked<Limb> {
129
0
        Checked(
130
0
            self.0
131
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_mul(rhs))),
132
0
        )
133
0
    }
134
}
135
136
impl MulAssign for Checked<Limb> {
137
0
    fn mul_assign(&mut self, other: Self) {
138
0
        *self = *self * other;
139
0
    }
140
}
141
142
impl MulAssign<&Checked<Limb>> for Checked<Limb> {
143
0
    fn mul_assign(&mut self, other: &Self) {
144
0
        *self = *self * other;
145
0
    }
146
}
147
148
#[cfg(test)]
149
mod tests {
150
    use super::{CheckedMul, Limb, WideWord};
151
152
    #[test]
153
    fn mul_wide_zero_and_one() {
154
        assert_eq!(Limb::ZERO.mul_wide(Limb::ZERO), 0);
155
        assert_eq!(Limb::ZERO.mul_wide(Limb::ONE), 0);
156
        assert_eq!(Limb::ONE.mul_wide(Limb::ZERO), 0);
157
        assert_eq!(Limb::ONE.mul_wide(Limb::ONE), 1);
158
    }
159
160
    #[test]
161
    fn mul_wide() {
162
        let primes: &[u32] = &[3, 5, 17, 257, 65537];
163
164
        for &a_int in primes {
165
            for &b_int in primes {
166
                let actual = Limb::from_u32(a_int).mul_wide(Limb::from_u32(b_int));
167
                let expected = a_int as WideWord * b_int as WideWord;
168
                assert_eq!(actual, expected);
169
            }
170
        }
171
    }
172
173
    #[test]
174
    #[cfg(target_pointer_width = "32")]
175
    fn checked_mul_ok() {
176
        let n = Limb::from_u16(0xffff);
177
        assert_eq!(n.checked_mul(n).unwrap(), Limb::from_u32(0xfffe_0001));
178
    }
179
180
    #[test]
181
    #[cfg(target_pointer_width = "64")]
182
    fn checked_mul_ok() {
183
        let n = Limb::from_u32(0xffff_ffff);
184
        assert_eq!(
185
            n.checked_mul(n).unwrap(),
186
            Limb::from_u64(0xffff_fffe_0000_0001)
187
        );
188
    }
189
190
    #[test]
191
    fn checked_mul_overflow() {
192
        let n = Limb::MAX;
193
        assert!(bool::from(n.checked_mul(n).is_none()));
194
    }
195
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/neg.rs
Line
Count
Source
1
//! Limb negation
2
3
use crate::{Limb, Wrapping};
4
use core::ops::Neg;
5
6
impl Neg for Wrapping<Limb> {
7
    type Output = Self;
8
9
0
    fn neg(self) -> Self::Output {
10
0
        Self(self.0.wrapping_neg())
11
0
    }
12
}
13
14
impl Limb {
15
    /// Perform wrapping negation.
16
    #[inline(always)]
17
0
    pub const fn wrapping_neg(self) -> Self {
18
0
        Limb(self.0.wrapping_neg())
19
0
    }
20
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/rand.rs
Line
Count
Source
1
//! Random number generator support
2
3
use super::Limb;
4
use crate::{Encoding, NonZero, Random, RandomMod};
5
use rand_core::CryptoRngCore;
6
use subtle::ConstantTimeLess;
7
8
impl Random for Limb {
9
    #[cfg(target_pointer_width = "32")]
10
    fn random(rng: &mut impl CryptoRngCore) -> Self {
11
        Self(rng.next_u32())
12
    }
13
14
    #[cfg(target_pointer_width = "64")]
15
0
    fn random(rng: &mut impl CryptoRngCore) -> Self {
16
0
        Self(rng.next_u64())
17
0
    }
18
}
19
20
impl RandomMod for Limb {
21
0
    fn random_mod(rng: &mut impl CryptoRngCore, modulus: &NonZero<Self>) -> Self {
22
0
        let mut bytes = <Self as Encoding>::Repr::default();
23
0
24
0
        let n_bits = modulus.bits();
25
0
        let n_bytes = (n_bits + 7) / 8;
26
0
        let mask = 0xff >> (8 * n_bytes - n_bits);
27
28
        loop {
29
0
            rng.fill_bytes(&mut bytes[..n_bytes]);
30
0
            bytes[n_bytes - 1] &= mask;
31
0
32
0
            let n = Limb::from_le_bytes(bytes);
33
0
            if n.ct_lt(modulus).into() {
34
0
                return n;
35
0
            }
36
        }
37
0
    }
38
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/shl.rs
Line
Count
Source
1
//! Limb left bitshift
2
3
use crate::{Limb, Word};
4
use core::ops::{Shl, ShlAssign};
5
6
impl Limb {
7
    /// Computes `self << rhs`.
8
    /// Panics if `rhs` overflows `Limb::BITS`.
9
    #[inline(always)]
10
0
    pub const fn shl(self, rhs: Self) -> Self {
11
0
        Limb(self.0 << rhs.0)
12
0
    }
13
}
14
15
impl Shl for Limb {
16
    type Output = Self;
17
18
    #[inline(always)]
19
    fn shl(self, rhs: Self) -> Self::Output {
20
        self.shl(rhs)
21
    }
22
}
23
24
impl Shl<usize> for Limb {
25
    type Output = Self;
26
27
    #[inline(always)]
28
    fn shl(self, rhs: usize) -> Self::Output {
29
        self.shl(Limb(rhs as Word))
30
    }
31
}
32
33
impl ShlAssign for Limb {
34
    #[inline(always)]
35
    fn shl_assign(&mut self, other: Self) {
36
        *self = self.shl(other);
37
    }
38
}
39
40
impl ShlAssign<usize> for Limb {
41
    #[inline(always)]
42
    fn shl_assign(&mut self, other: usize) {
43
        *self = self.shl(Limb(other as Word));
44
    }
45
}
46
47
#[cfg(test)]
48
mod tests {
49
    use crate::Limb;
50
51
    #[test]
52
    fn shl1() {
53
        assert_eq!(Limb(1) << 1, Limb(2));
54
    }
55
56
    #[test]
57
    fn shl2() {
58
        assert_eq!(Limb(1) << 2, Limb(4));
59
    }
60
61
    #[test]
62
    fn shl_assign1() {
63
        let mut l = Limb(1);
64
        l <<= 1;
65
        assert_eq!(l, Limb(2));
66
    }
67
68
    #[test]
69
    fn shl_assign2() {
70
        let mut l = Limb(1);
71
        l <<= 2;
72
        assert_eq!(l, Limb(4));
73
    }
74
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/limb/sub.rs
Line
Count
Source
1
//! Limb subtraction
2
3
use crate::{Checked, CheckedSub, Limb, WideWord, Word, Wrapping, Zero};
4
use core::ops::{Sub, SubAssign};
5
use subtle::CtOption;
6
7
impl Limb {
8
    /// Computes `self - (rhs + borrow)`, returning the result along with the new borrow.
9
    #[inline(always)]
10
5.46M
    pub const fn sbb(self, rhs: Limb, borrow: Limb) -> (Limb, Limb) {
11
5.46M
        let a = self.0 as WideWord;
12
5.46M
        let b = rhs.0 as WideWord;
13
5.46M
        let borrow = (borrow.0 >> (Self::BITS - 1)) as WideWord;
14
5.46M
        let ret = a.wrapping_sub(b + borrow);
15
5.46M
        (Limb(ret as Word), Limb((ret >> Self::BITS) as Word))
16
5.46M
    }
17
18
    /// Perform saturating subtraction.
19
    #[inline]
20
0
    pub const fn saturating_sub(&self, rhs: Self) -> Self {
21
0
        Limb(self.0.saturating_sub(rhs.0))
22
0
    }
23
24
    /// Perform wrapping subtraction, discarding underflow and wrapping around
25
    /// the boundary of the type.
26
    #[inline(always)]
27
0
    pub const fn wrapping_sub(&self, rhs: Self) -> Self {
28
0
        Limb(self.0.wrapping_sub(rhs.0))
29
0
    }
30
}
31
32
impl CheckedSub for Limb {
33
    type Output = Self;
34
35
    #[inline]
36
0
    fn checked_sub(&self, rhs: Self) -> CtOption<Self> {
37
0
        let (result, underflow) = self.sbb(rhs, Limb::ZERO);
38
0
        CtOption::new(result, underflow.is_zero())
39
0
    }
40
}
41
42
impl Sub for Wrapping<Limb> {
43
    type Output = Self;
44
45
0
    fn sub(self, rhs: Self) -> Wrapping<Limb> {
46
0
        Wrapping(self.0.wrapping_sub(rhs.0))
47
0
    }
48
}
49
50
impl Sub<&Wrapping<Limb>> for Wrapping<Limb> {
51
    type Output = Wrapping<Limb>;
52
53
0
    fn sub(self, rhs: &Wrapping<Limb>) -> Wrapping<Limb> {
54
0
        Wrapping(self.0.wrapping_sub(rhs.0))
55
0
    }
56
}
57
58
impl Sub<Wrapping<Limb>> for &Wrapping<Limb> {
59
    type Output = Wrapping<Limb>;
60
61
0
    fn sub(self, rhs: Wrapping<Limb>) -> Wrapping<Limb> {
62
0
        Wrapping(self.0.wrapping_sub(rhs.0))
63
0
    }
64
}
65
66
impl Sub<&Wrapping<Limb>> for &Wrapping<Limb> {
67
    type Output = Wrapping<Limb>;
68
69
0
    fn sub(self, rhs: &Wrapping<Limb>) -> Wrapping<Limb> {
70
0
        Wrapping(self.0.wrapping_sub(rhs.0))
71
0
    }
72
}
73
74
impl SubAssign for Wrapping<Limb> {
75
0
    fn sub_assign(&mut self, other: Self) {
76
0
        *self = *self - other;
77
0
    }
78
}
79
80
impl SubAssign<&Wrapping<Limb>> for Wrapping<Limb> {
81
0
    fn sub_assign(&mut self, other: &Self) {
82
0
        *self = *self - other;
83
0
    }
84
}
85
86
impl Sub for Checked<Limb> {
87
    type Output = Self;
88
89
0
    fn sub(self, rhs: Self) -> Checked<Limb> {
90
0
        Checked(
91
0
            self.0
92
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_sub(rhs))),
93
0
        )
94
0
    }
95
}
96
97
impl Sub<&Checked<Limb>> for Checked<Limb> {
98
    type Output = Checked<Limb>;
99
100
0
    fn sub(self, rhs: &Checked<Limb>) -> Checked<Limb> {
101
0
        Checked(
102
0
            self.0
103
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_sub(rhs))),
104
0
        )
105
0
    }
106
}
107
108
impl Sub<Checked<Limb>> for &Checked<Limb> {
109
    type Output = Checked<Limb>;
110
111
0
    fn sub(self, rhs: Checked<Limb>) -> Checked<Limb> {
112
0
        Checked(
113
0
            self.0
114
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_sub(rhs))),
115
0
        )
116
0
    }
117
}
118
119
impl Sub<&Checked<Limb>> for &Checked<Limb> {
120
    type Output = Checked<Limb>;
121
122
0
    fn sub(self, rhs: &Checked<Limb>) -> Checked<Limb> {
123
0
        Checked(
124
0
            self.0
125
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_sub(rhs))),
126
0
        )
127
0
    }
128
}
129
130
impl SubAssign for Checked<Limb> {
131
0
    fn sub_assign(&mut self, other: Self) {
132
0
        *self = *self - other;
133
0
    }
134
}
135
136
impl SubAssign<&Checked<Limb>> for Checked<Limb> {
137
0
    fn sub_assign(&mut self, other: &Self) {
138
0
        *self = *self - other;
139
0
    }
140
}
141
142
#[cfg(test)]
143
mod tests {
144
    use crate::{CheckedSub, Limb};
145
146
    #[test]
147
    fn sbb_no_borrow() {
148
        let (res, borrow) = Limb::ONE.sbb(Limb::ONE, Limb::ZERO);
149
        assert_eq!(res, Limb::ZERO);
150
        assert_eq!(borrow, Limb::ZERO);
151
    }
152
153
    #[test]
154
    fn sbb_with_borrow() {
155
        let (res, borrow) = Limb::ZERO.sbb(Limb::ONE, Limb::ZERO);
156
157
        assert_eq!(res, Limb::MAX);
158
        assert_eq!(borrow, Limb::MAX);
159
    }
160
161
    #[test]
162
    fn wrapping_sub_no_borrow() {
163
        assert_eq!(Limb::ONE.wrapping_sub(Limb::ONE), Limb::ZERO);
164
    }
165
166
    #[test]
167
    fn wrapping_sub_with_borrow() {
168
        assert_eq!(Limb::ZERO.wrapping_sub(Limb::ONE), Limb::MAX);
169
    }
170
171
    #[test]
172
    fn checked_sub_ok() {
173
        let result = Limb::ONE.checked_sub(Limb::ONE);
174
        assert_eq!(result.unwrap(), Limb::ZERO);
175
    }
176
177
    #[test]
178
    fn checked_sub_overflow() {
179
        let result = Limb::ZERO.checked_sub(Limb::ONE);
180
        assert!(!bool::from(result.is_some()));
181
    }
182
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/non_zero.rs
Line
Count
Source
1
//! Wrapper type for non-zero integers.
2
3
use crate::{CtChoice, Encoding, Integer, Limb, Uint, Zero};
4
use core::{
5
    fmt,
6
    num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8},
7
    ops::Deref,
8
};
9
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
10
11
#[cfg(feature = "generic-array")]
12
use crate::{ArrayEncoding, ByteArray};
13
14
#[cfg(feature = "rand_core")]
15
use {crate::Random, rand_core::CryptoRngCore};
16
17
#[cfg(feature = "serde")]
18
use serdect::serde::{
19
    de::{Error, Unexpected},
20
    Deserialize, Deserializer, Serialize, Serializer,
21
};
22
23
/// Wrapper type for non-zero integers.
24
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
25
pub struct NonZero<T: Zero>(T);
26
27
impl NonZero<Limb> {
28
    /// Creates a new non-zero limb in a const context.
29
    /// The second return value is `FALSE` if `n` is zero, `TRUE` otherwise.
30
0
    pub const fn const_new(n: Limb) -> (Self, CtChoice) {
31
0
        (Self(n), n.ct_is_nonzero())
32
0
    }
33
}
34
35
impl<const LIMBS: usize> NonZero<Uint<LIMBS>> {
36
    /// Creates a new non-zero integer in a const context.
37
    /// The second return value is `FALSE` if `n` is zero, `TRUE` otherwise.
38
0
    pub const fn const_new(n: Uint<LIMBS>) -> (Self, CtChoice) {
39
0
        (Self(n), n.ct_is_nonzero())
40
0
    }
41
}
42
43
impl<T> NonZero<T>
44
where
45
    T: Zero,
46
{
47
    /// Create a new non-zero integer.
48
0
    pub fn new(n: T) -> CtOption<Self> {
49
0
        let is_zero = n.is_zero();
50
0
        CtOption::new(Self(n), !is_zero)
51
0
    }
52
}
53
54
impl<T> NonZero<T>
55
where
56
    T: Integer,
57
{
58
    /// The value `1`.
59
    pub const ONE: Self = Self(T::ONE);
60
61
    /// Maximum value this integer can express.
62
    pub const MAX: Self = Self(T::MAX);
63
}
64
65
impl<T> NonZero<T>
66
where
67
    T: Encoding + Zero,
68
{
69
    /// Decode from big endian bytes.
70
0
    pub fn from_be_bytes(bytes: T::Repr) -> CtOption<Self> {
71
0
        Self::new(T::from_be_bytes(bytes))
72
0
    }
73
74
    /// Decode from little endian bytes.
75
0
    pub fn from_le_bytes(bytes: T::Repr) -> CtOption<Self> {
76
0
        Self::new(T::from_le_bytes(bytes))
77
0
    }
78
}
79
80
#[cfg(feature = "generic-array")]
81
impl<T> NonZero<T>
82
where
83
    T: ArrayEncoding + Zero,
84
{
85
    /// Decode a non-zero integer from big endian bytes.
86
0
    pub fn from_be_byte_array(bytes: ByteArray<T>) -> CtOption<Self> {
87
0
        Self::new(T::from_be_byte_array(bytes))
88
0
    }
89
90
    /// Decode a non-zero integer from big endian bytes.
91
0
    pub fn from_le_byte_array(bytes: ByteArray<T>) -> CtOption<Self> {
92
0
        Self::new(T::from_be_byte_array(bytes))
93
0
    }
94
}
95
96
impl<T> AsRef<T> for NonZero<T>
97
where
98
    T: Zero,
99
{
100
0
    fn as_ref(&self) -> &T {
101
0
        &self.0
102
0
    }
103
}
104
105
impl<T> ConditionallySelectable for NonZero<T>
106
where
107
    T: ConditionallySelectable + Zero,
108
{
109
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
110
0
        Self(T::conditional_select(&a.0, &b.0, choice))
111
0
    }
112
}
113
114
impl<T> ConstantTimeEq for NonZero<T>
115
where
116
    T: Zero,
117
{
118
0
    fn ct_eq(&self, other: &Self) -> Choice {
119
0
        self.0.ct_eq(&other.0)
120
0
    }
121
}
122
123
impl<T> Deref for NonZero<T>
124
where
125
    T: Zero,
126
{
127
    type Target = T;
128
129
0
    fn deref(&self) -> &T {
130
0
        &self.0
131
0
    }
132
}
133
134
#[cfg(feature = "rand_core")]
135
impl<T> Random for NonZero<T>
136
where
137
    T: Random + Zero,
138
{
139
    /// Generate a random `NonZero<T>`.
140
0
    fn random(mut rng: &mut impl CryptoRngCore) -> Self {
141
        // Use rejection sampling to eliminate zero values.
142
        // While this method isn't constant-time, the attacker shouldn't learn
143
        // anything about unrelated outputs so long as `rng` is a CSRNG.
144
        loop {
145
0
            if let Some(result) = Self::new(T::random(&mut rng)).into() {
146
0
                break result;
147
0
            }
148
        }
149
0
    }
150
}
151
152
impl<T> fmt::Display for NonZero<T>
153
where
154
    T: fmt::Display + Zero,
155
{
156
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157
0
        fmt::Display::fmt(&self.0, f)
158
0
    }
159
}
160
161
impl<T> fmt::Binary for NonZero<T>
162
where
163
    T: fmt::Binary + Zero,
164
{
165
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166
0
        fmt::Binary::fmt(&self.0, f)
167
0
    }
168
}
169
170
impl<T> fmt::Octal for NonZero<T>
171
where
172
    T: fmt::Octal + Zero,
173
{
174
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175
0
        fmt::Octal::fmt(&self.0, f)
176
0
    }
177
}
178
179
impl<T> fmt::LowerHex for NonZero<T>
180
where
181
    T: fmt::LowerHex + Zero,
182
{
183
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184
0
        fmt::LowerHex::fmt(&self.0, f)
185
0
    }
186
}
187
188
impl<T> fmt::UpperHex for NonZero<T>
189
where
190
    T: fmt::UpperHex + Zero,
191
{
192
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
193
0
        fmt::UpperHex::fmt(&self.0, f)
194
0
    }
195
}
196
197
impl NonZero<Limb> {
198
    /// Create a [`NonZero<Limb>`] from a [`NonZeroU8`] (const-friendly)
199
    // TODO(tarcieri): replace with `const impl From<NonZeroU8>` when stable
200
0
    pub const fn from_u8(n: NonZeroU8) -> Self {
201
0
        Self(Limb::from_u8(n.get()))
202
0
    }
203
204
    /// Create a [`NonZero<Limb>`] from a [`NonZeroU16`] (const-friendly)
205
    // TODO(tarcieri): replace with `const impl From<NonZeroU16>` when stable
206
0
    pub const fn from_u16(n: NonZeroU16) -> Self {
207
0
        Self(Limb::from_u16(n.get()))
208
0
    }
209
210
    /// Create a [`NonZero<Limb>`] from a [`NonZeroU32`] (const-friendly)
211
    // TODO(tarcieri): replace with `const impl From<NonZeroU32>` when stable
212
0
    pub const fn from_u32(n: NonZeroU32) -> Self {
213
0
        Self(Limb::from_u32(n.get()))
214
0
    }
215
216
    /// Create a [`NonZero<Limb>`] from a [`NonZeroU64`] (const-friendly)
217
    // TODO(tarcieri): replace with `const impl From<NonZeroU64>` when stable
218
    #[cfg(target_pointer_width = "64")]
219
0
    pub const fn from_u64(n: NonZeroU64) -> Self {
220
0
        Self(Limb::from_u64(n.get()))
221
0
    }
222
}
223
224
impl From<NonZeroU8> for NonZero<Limb> {
225
0
    fn from(integer: NonZeroU8) -> Self {
226
0
        Self::from_u8(integer)
227
0
    }
228
}
229
230
impl From<NonZeroU16> for NonZero<Limb> {
231
0
    fn from(integer: NonZeroU16) -> Self {
232
0
        Self::from_u16(integer)
233
0
    }
234
}
235
236
impl From<NonZeroU32> for NonZero<Limb> {
237
0
    fn from(integer: NonZeroU32) -> Self {
238
0
        Self::from_u32(integer)
239
0
    }
240
}
241
242
#[cfg(target_pointer_width = "64")]
243
impl From<NonZeroU64> for NonZero<Limb> {
244
0
    fn from(integer: NonZeroU64) -> Self {
245
0
        Self::from_u64(integer)
246
0
    }
247
}
248
249
impl<const LIMBS: usize> NonZero<Uint<LIMBS>> {
250
    /// Create a [`NonZero<Uint>`] from a [`Uint`] (const-friendly)
251
0
    pub const fn from_uint(n: Uint<LIMBS>) -> Self {
252
0
        let mut i = 0;
253
0
        let mut found_non_zero = false;
254
0
        while i < LIMBS {
255
0
            if n.as_limbs()[i].0 != 0 {
256
0
                found_non_zero = true;
257
0
            }
258
0
            i += 1;
259
        }
260
0
        assert!(found_non_zero, "found zero");
261
0
        Self(n)
262
0
    }
263
264
    /// Create a [`NonZero<Uint>`] from a [`NonZeroU8`] (const-friendly)
265
    // TODO(tarcieri): replace with `const impl From<NonZeroU8>` when stable
266
0
    pub const fn from_u8(n: NonZeroU8) -> Self {
267
0
        Self(Uint::from_u8(n.get()))
268
0
    }
269
270
    /// Create a [`NonZero<Uint>`] from a [`NonZeroU16`] (const-friendly)
271
    // TODO(tarcieri): replace with `const impl From<NonZeroU16>` when stable
272
0
    pub const fn from_u16(n: NonZeroU16) -> Self {
273
0
        Self(Uint::from_u16(n.get()))
274
0
    }
275
276
    /// Create a [`NonZero<Uint>`] from a [`NonZeroU32`] (const-friendly)
277
    // TODO(tarcieri): replace with `const impl From<NonZeroU32>` when stable
278
0
    pub const fn from_u32(n: NonZeroU32) -> Self {
279
0
        Self(Uint::from_u32(n.get()))
280
0
    }
281
282
    /// Create a [`NonZero<Uint>`] from a [`NonZeroU64`] (const-friendly)
283
    // TODO(tarcieri): replace with `const impl From<NonZeroU64>` when stable
284
0
    pub const fn from_u64(n: NonZeroU64) -> Self {
285
0
        Self(Uint::from_u64(n.get()))
286
0
    }
287
288
    /// Create a [`NonZero<Uint>`] from a [`NonZeroU128`] (const-friendly)
289
    // TODO(tarcieri): replace with `const impl From<NonZeroU128>` when stable
290
0
    pub const fn from_u128(n: NonZeroU128) -> Self {
291
0
        Self(Uint::from_u128(n.get()))
292
0
    }
293
}
294
295
impl<const LIMBS: usize> From<NonZeroU8> for NonZero<Uint<LIMBS>> {
296
0
    fn from(integer: NonZeroU8) -> Self {
297
0
        Self::from_u8(integer)
298
0
    }
299
}
300
301
impl<const LIMBS: usize> From<NonZeroU16> for NonZero<Uint<LIMBS>> {
302
0
    fn from(integer: NonZeroU16) -> Self {
303
0
        Self::from_u16(integer)
304
0
    }
305
}
306
307
impl<const LIMBS: usize> From<NonZeroU32> for NonZero<Uint<LIMBS>> {
308
0
    fn from(integer: NonZeroU32) -> Self {
309
0
        Self::from_u32(integer)
310
0
    }
311
}
312
313
impl<const LIMBS: usize> From<NonZeroU64> for NonZero<Uint<LIMBS>> {
314
0
    fn from(integer: NonZeroU64) -> Self {
315
0
        Self::from_u64(integer)
316
0
    }
317
}
318
319
impl<const LIMBS: usize> From<NonZeroU128> for NonZero<Uint<LIMBS>> {
320
0
    fn from(integer: NonZeroU128) -> Self {
321
0
        Self::from_u128(integer)
322
0
    }
323
}
324
325
#[cfg(feature = "serde")]
326
impl<'de, T: Deserialize<'de> + Zero> Deserialize<'de> for NonZero<T> {
327
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
328
    where
329
        D: Deserializer<'de>,
330
    {
331
        let value: T = T::deserialize(deserializer)?;
332
333
        if bool::from(value.is_zero()) {
334
            Err(D::Error::invalid_value(
335
                Unexpected::Other("zero"),
336
                &"a non-zero value",
337
            ))
338
        } else {
339
            Ok(Self(value))
340
        }
341
    }
342
}
343
344
#[cfg(feature = "serde")]
345
impl<T: Serialize + Zero> Serialize for NonZero<T> {
346
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
347
    where
348
        S: Serializer,
349
    {
350
        self.0.serialize(serializer)
351
    }
352
}
353
354
#[cfg(all(test, feature = "serde"))]
355
#[allow(clippy::unwrap_used)]
356
mod tests {
357
    use crate::{NonZero, U64};
358
    use bincode::ErrorKind;
359
360
    #[test]
361
    fn serde() {
362
        let test =
363
            Option::<NonZero<U64>>::from(NonZero::new(U64::from_u64(0x0011223344556677))).unwrap();
364
365
        let serialized = bincode::serialize(&test).unwrap();
366
        let deserialized: NonZero<U64> = bincode::deserialize(&serialized).unwrap();
367
368
        assert_eq!(test, deserialized);
369
370
        let serialized = bincode::serialize(&U64::ZERO).unwrap();
371
        assert!(matches!(
372
            *bincode::deserialize::<NonZero<U64>>(&serialized).unwrap_err(),
373
            ErrorKind::Custom(message) if message == "invalid value: zero, expected a non-zero value"
374
        ));
375
    }
376
377
    #[test]
378
    fn serde_owned() {
379
        let test =
380
            Option::<NonZero<U64>>::from(NonZero::new(U64::from_u64(0x0011223344556677))).unwrap();
381
382
        let serialized = bincode::serialize(&test).unwrap();
383
        let deserialized: NonZero<U64> = bincode::deserialize_from(serialized.as_slice()).unwrap();
384
385
        assert_eq!(test, deserialized);
386
387
        let serialized = bincode::serialize(&U64::ZERO).unwrap();
388
        assert!(matches!(
389
            *bincode::deserialize_from::<_, NonZero<U64>>(serialized.as_slice()).unwrap_err(),
390
            ErrorKind::Custom(message) if message == "invalid value: zero, expected a non-zero value"
391
        ));
392
    }
393
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/traits.rs
Line
Count
Source
1
//! Traits provided by this crate
2
3
use crate::{Limb, NonZero};
4
use core::fmt::Debug;
5
use core::ops::{BitAnd, BitOr, BitXor, Div, Not, Rem, Shl, Shr};
6
use subtle::{
7
    Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
8
    CtOption,
9
};
10
11
#[cfg(feature = "rand_core")]
12
use rand_core::CryptoRngCore;
13
14
/// Integer type.
15
pub trait Integer:
16
    'static
17
    + AsRef<[Limb]>
18
    + BitAnd<Output = Self>
19
    + BitOr<Output = Self>
20
    + BitXor<Output = Self>
21
    + for<'a> CheckedAdd<&'a Self, Output = Self>
22
    + for<'a> CheckedSub<&'a Self, Output = Self>
23
    + for<'a> CheckedMul<&'a Self, Output = Self>
24
    + Copy
25
    + ConditionallySelectable
26
    + ConstantTimeEq
27
    + ConstantTimeGreater
28
    + ConstantTimeLess
29
    + Debug
30
    + Default
31
    + Div<NonZero<Self>, Output = Self>
32
    + Eq
33
    + From<u64>
34
    + Not
35
    + Ord
36
    + Rem<NonZero<Self>, Output = Self>
37
    + Send
38
    + Sized
39
    + Shl<usize, Output = Self>
40
    + Shr<usize, Output = Self>
41
    + Sync
42
    + Zero
43
{
44
    /// The value `1`.
45
    const ONE: Self;
46
47
    /// Maximum value this integer can express.
48
    const MAX: Self;
49
50
    /// Total size of the represented integer in bits.
51
    const BITS: usize;
52
53
    /// Total size of the represented integer in bytes.
54
    const BYTES: usize;
55
56
    /// The number of limbs used on this platform.
57
    const LIMBS: usize;
58
59
    /// Is this integer value an odd number?
60
    ///
61
    /// # Returns
62
    ///
63
    /// If odd, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
64
    fn is_odd(&self) -> Choice;
65
66
    /// Is this integer value an even number?
67
    ///
68
    /// # Returns
69
    ///
70
    /// If even, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
71
0
    fn is_even(&self) -> Choice {
72
0
        !self.is_odd()
73
0
    }
74
}
75
76
/// Zero values.
77
pub trait Zero: ConstantTimeEq + Sized {
78
    /// The value `0`.
79
    const ZERO: Self;
80
81
    /// Determine if this value is equal to zero.
82
    ///
83
    /// # Returns
84
    ///
85
    /// If zero, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
86
99.4k
    fn is_zero(&self) -> Choice {
87
99.4k
        self.ct_eq(&Self::ZERO)
88
99.4k
    }
_RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj4_ENtNtB7_6traits4Zero7is_zeroCs4RkbDk9WRL5_5clvmr
Line
Count
Source
86
2.77k
    fn is_zero(&self) -> Choice {
87
2.77k
        self.ct_eq(&Self::ZERO)
88
2.77k
    }
Unexecuted instantiation: _RNvYNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbNtNtB6_6traits4Zero7is_zeroB6_
_RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj4_ENtNtB7_6traits4Zero7is_zeroCsjewTDwKBbyD_4k256
Line
Count
Source
86
96.7k
    fn is_zero(&self) -> Choice {
87
96.7k
        self.ct_eq(&Self::ZERO)
88
96.7k
    }
89
}
90
91
/// Random number generation support.
92
#[cfg(feature = "rand_core")]
93
pub trait Random: Sized {
94
    /// Generate a cryptographically secure random value.
95
    fn random(rng: &mut impl CryptoRngCore) -> Self;
96
}
97
98
/// Modular random number generation support.
99
#[cfg(feature = "rand_core")]
100
pub trait RandomMod: Sized + Zero {
101
    /// Generate a cryptographically secure random number which is less than
102
    /// a given `modulus`.
103
    ///
104
    /// This function uses rejection sampling, a method which produces an
105
    /// unbiased distribution of in-range values provided the underlying
106
    /// CSRNG is unbiased, but runs in variable-time.
107
    ///
108
    /// The variable-time nature of the algorithm should not pose a security
109
    /// issue so long as the underlying random number generator is truly a
110
    /// CSRNG, where previous outputs are unrelated to subsequent
111
    /// outputs and do not reveal information about the RNG's internal state.
112
    fn random_mod(rng: &mut impl CryptoRngCore, modulus: &NonZero<Self>) -> Self;
113
}
114
115
/// Compute `self + rhs mod p`.
116
pub trait AddMod<Rhs = Self> {
117
    /// Output type.
118
    type Output;
119
120
    /// Compute `self + rhs mod p`.
121
    ///
122
    /// Assumes `self` and `rhs` are `< p`.
123
    fn add_mod(&self, rhs: &Rhs, p: &Self) -> Self::Output;
124
}
125
126
/// Compute `self - rhs mod p`.
127
pub trait SubMod<Rhs = Self> {
128
    /// Output type.
129
    type Output;
130
131
    /// Compute `self - rhs mod p`.
132
    ///
133
    /// Assumes `self` and `rhs` are `< p`.
134
    fn sub_mod(&self, rhs: &Rhs, p: &Self) -> Self::Output;
135
}
136
137
/// Compute `-self mod p`.
138
pub trait NegMod {
139
    /// Output type.
140
    type Output;
141
142
    /// Compute `-self mod p`.
143
    #[must_use]
144
    fn neg_mod(&self, p: &Self) -> Self::Output;
145
}
146
147
/// Compute `self * rhs mod p`.
148
///
149
/// Requires `p_inv = -(p^{-1} mod 2^{BITS}) mod 2^{BITS}` to be provided for efficiency.
150
pub trait MulMod<Rhs = Self> {
151
    /// Output type.
152
    type Output;
153
154
    /// Compute `self * rhs mod p`.
155
    ///
156
    /// Requires `p_inv = -(p^{-1} mod 2^{BITS}) mod 2^{BITS}` to be provided for efficiency.
157
    fn mul_mod(&self, rhs: &Rhs, p: &Self, p_inv: Limb) -> Self::Output;
158
}
159
160
/// Checked addition.
161
pub trait CheckedAdd<Rhs = Self>: Sized {
162
    /// Output type.
163
    type Output;
164
165
    /// Perform checked subtraction, returning a [`CtOption`] which `is_some`
166
    /// only if the operation did not overflow.
167
    fn checked_add(&self, rhs: Rhs) -> CtOption<Self>;
168
}
169
170
/// Checked multiplication.
171
pub trait CheckedMul<Rhs = Self>: Sized {
172
    /// Output type.
173
    type Output;
174
175
    /// Perform checked multiplication, returning a [`CtOption`] which `is_some`
176
    /// only if the operation did not overflow.
177
    fn checked_mul(&self, rhs: Rhs) -> CtOption<Self>;
178
}
179
180
/// Checked subtraction.
181
pub trait CheckedSub<Rhs = Self>: Sized {
182
    /// Output type.
183
    type Output;
184
185
    /// Perform checked subtraction, returning a [`CtOption`] which `is_some`
186
    /// only if the operation did not underflow.
187
    fn checked_sub(&self, rhs: Rhs) -> CtOption<Self>;
188
}
189
190
/// Concatenate two numbers into a "wide" double-width value, using the `lo`
191
/// value as the least significant value.
192
pub trait Concat: ConcatMixed<Self, MixedOutput = Self::Output> {
193
    /// Concatenated output: twice the width of `Self`.
194
    type Output;
195
196
    /// Concatenate the two halves, with `self` as most significant and `lo`
197
    /// as the least significant.
198
0
    fn concat(&self, lo: &Self) -> Self::Output {
199
0
        self.concat_mixed(lo)
200
0
    }
201
}
202
203
/// Concatenate two numbers into a "wide" combined-width value, using the `lo`
204
/// value as the least significant value.
205
pub trait ConcatMixed<Lo: ?Sized = Self> {
206
    /// Concatenated output: combination of `Lo` and `Self`.
207
    type MixedOutput;
208
209
    /// Concatenate the two values, with `self` as most significant and `lo`
210
    /// as the least significant.
211
    fn concat_mixed(&self, lo: &Lo) -> Self::MixedOutput;
212
}
213
214
/// Split a number in half, returning the most significant half followed by
215
/// the least significant.
216
pub trait Split: SplitMixed<Self::Output, Self::Output> {
217
    /// Split output: high/low components of the value.
218
    type Output;
219
220
    /// Split this number in half, returning its high and low components
221
    /// respectively.
222
0
    fn split(&self) -> (Self::Output, Self::Output) {
223
0
        self.split_mixed()
224
0
    }
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj100_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj10_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj14_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj18_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj1c_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj20_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj2_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj30_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj38_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj40_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj42_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj44_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj4_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj60_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj6_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj80_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj8_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKja_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKjc_ENtNtB7_6traits5Split5splitB7_
Unexecuted instantiation: _RNvYINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKje_ENtNtB7_6traits5Split5splitB7_
225
}
226
227
/// Split a number into parts, returning the most significant part followed by
228
/// the least significant.
229
pub trait SplitMixed<Hi, Lo> {
230
    /// Split this number into parts, returning its high and low components
231
    /// respectively.
232
    fn split_mixed(&self) -> (Hi, Lo);
233
}
234
235
/// Integers whose representation takes a bounded amount of space.
236
pub trait Bounded {
237
    /// Size of this integer in bits.
238
    const BITS: usize;
239
240
    /// Size of this integer in bytes.
241
    const BYTES: usize;
242
}
243
244
/// Encoding support.
245
pub trait Encoding: Sized {
246
    /// Byte array representation.
247
    type Repr: AsRef<[u8]> + AsMut<[u8]> + Copy + Clone + Sized;
248
249
    /// Decode from big endian bytes.
250
    fn from_be_bytes(bytes: Self::Repr) -> Self;
251
252
    /// Decode from little endian bytes.
253
    fn from_le_bytes(bytes: Self::Repr) -> Self;
254
255
    /// Encode to big endian bytes.
256
    fn to_be_bytes(&self) -> Self::Repr;
257
258
    /// Encode to little endian bytes.
259
    fn to_le_bytes(&self) -> Self::Repr;
260
}
261
262
/// Support for optimized squaring
263
pub trait Square: Sized
264
where
265
    for<'a> &'a Self: core::ops::Mul<&'a Self, Output = Self>,
266
{
267
    /// Computes the same as `self.mul(self)`, but may be more efficient.
268
0
    fn square(&self) -> Self {
269
0
        self * self
270
0
    }
271
}
272
273
/// Constant-time exponentiation.
274
pub trait Pow<Exponent> {
275
    /// Raises to the `exponent` power.
276
    fn pow(&self, exponent: &Exponent) -> Self;
277
}
278
279
impl<T: PowBoundedExp<Exponent>, Exponent: Bounded> Pow<Exponent> for T {
280
0
    fn pow(&self, exponent: &Exponent) -> Self {
281
0
        self.pow_bounded_exp(exponent, Exponent::BITS)
282
0
    }
283
}
284
285
/// Constant-time exponentiation with exponent of a bounded bit size.
286
pub trait PowBoundedExp<Exponent> {
287
    /// Raises to the `exponent` power,
288
    /// with `exponent_bits` representing the number of (least significant) bits
289
    /// to take into account for the exponent.
290
    ///
291
    /// NOTE: `exponent_bits` may be leaked in the time pattern.
292
    fn pow_bounded_exp(&self, exponent: &Exponent, exponent_bits: usize) -> Self;
293
}
294
295
/// Performs modular multi-exponentiation using Montgomery's ladder.
296
///
297
/// See: Straus, E. G. Problems and solutions: Addition chains of vectors. American Mathematical Monthly 71 (1964), 806–808.
298
pub trait MultiExponentiate<Exponent, BasesAndExponents>: Pow<Exponent> + Sized
299
where
300
    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
301
{
302
    /// Calculates `x1 ^ k1 * ... * xn ^ kn`.
303
    fn multi_exponentiate(bases_and_exponents: &BasesAndExponents) -> Self;
304
}
305
306
impl<T, Exponent, BasesAndExponents> MultiExponentiate<Exponent, BasesAndExponents> for T
307
where
308
    T: MultiExponentiateBoundedExp<Exponent, BasesAndExponents>,
309
    Exponent: Bounded,
310
    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
311
{
312
0
    fn multi_exponentiate(bases_and_exponents: &BasesAndExponents) -> Self {
313
0
        Self::multi_exponentiate_bounded_exp(bases_and_exponents, Exponent::BITS)
314
0
    }
315
}
316
317
/// Performs modular multi-exponentiation using Montgomery's ladder.
318
/// `exponent_bits` represents the number of bits to take into account for the exponent.
319
///
320
/// See: Straus, E. G. Problems and solutions: Addition chains of vectors. American Mathematical Monthly 71 (1964), 806–808.
321
///
322
/// NOTE: this value is leaked in the time pattern.
323
pub trait MultiExponentiateBoundedExp<Exponent, BasesAndExponents>: Pow<Exponent> + Sized
324
where
325
    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
326
{
327
    /// Calculates `x1 ^ k1 * ... * xn ^ kn`.
328
    fn multi_exponentiate_bounded_exp(
329
        bases_and_exponents: &BasesAndExponents,
330
        exponent_bits: usize,
331
    ) -> Self;
332
}
333
334
/// Constant-time inversion.
335
pub trait Invert: Sized {
336
    /// Output of the inversion.
337
    type Output;
338
339
    /// Computes the inverse.
340
    fn invert(&self) -> Self::Output;
341
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint.rs
Line
Count
Source
1
//! Stack-allocated big unsigned integers.
2
3
#![allow(clippy::needless_range_loop, clippy::many_single_char_names)]
4
5
#[macro_use]
6
mod macros;
7
8
mod add;
9
mod add_mod;
10
mod bit_and;
11
mod bit_not;
12
mod bit_or;
13
mod bit_xor;
14
mod bits;
15
mod cmp;
16
mod concat;
17
mod div;
18
pub(crate) mod div_limb;
19
mod encoding;
20
mod from;
21
mod inv_mod;
22
mod mul;
23
mod mul_mod;
24
mod neg;
25
mod neg_mod;
26
mod resize;
27
mod shl;
28
mod shr;
29
mod split;
30
mod sqrt;
31
mod sub;
32
mod sub_mod;
33
34
/// Implements modular arithmetic for constant moduli.
35
pub mod modular;
36
37
#[cfg(feature = "generic-array")]
38
mod array;
39
40
#[cfg(feature = "rand_core")]
41
mod rand;
42
43
use crate::{Bounded, Encoding, Integer, Limb, Word, Zero};
44
use core::fmt;
45
use subtle::{Choice, ConditionallySelectable};
46
47
#[cfg(feature = "serde")]
48
use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer};
49
50
#[cfg(feature = "zeroize")]
51
use zeroize::DefaultIsZeroes;
52
53
/// Stack-allocated big unsigned integer.
54
///
55
/// Generic over the given number of `LIMBS`
56
///
57
/// # Encoding support
58
/// This type supports many different types of encodings, either via the
59
/// [`Encoding`][`crate::Encoding`] trait or various `const fn` decoding and
60
/// encoding functions that can be used with [`Uint`] constants.
61
///
62
/// Optional crate features for encoding (off-by-default):
63
/// - `generic-array`: enables [`ArrayEncoding`][`crate::ArrayEncoding`] trait which can be used to
64
///   [`Uint`] as `GenericArray<u8, N>` and a [`ArrayDecoding`][`crate::ArrayDecoding`] trait which
65
///   can be used to `GenericArray<u8, N>` as [`Uint`].
66
/// - `rlp`: support for [Recursive Length Prefix (RLP)][RLP] encoding.
67
///
68
/// [RLP]: https://eth.wiki/fundamentals/rlp
69
// TODO(tarcieri): make generic around a specified number of bits.
70
// Our PartialEq impl only differs from the default one by being constant-time, so this is safe
71
#[allow(clippy::derived_hash_with_manual_eq)]
72
#[derive(Copy, Clone, Hash)]
73
pub struct Uint<const LIMBS: usize> {
74
    /// Inner limb array. Stored from least significant to most significant.
75
    limbs: [Limb; LIMBS],
76
}
77
78
impl<const LIMBS: usize> Uint<LIMBS> {
79
    /// The value `0`.
80
    pub const ZERO: Self = Self::from_u8(0);
81
82
    /// The value `1`.
83
    pub const ONE: Self = Self::from_u8(1);
84
85
    /// Maximum value this [`Uint`] can express.
86
    pub const MAX: Self = Self {
87
        limbs: [Limb::MAX; LIMBS],
88
    };
89
90
    /// Total size of the represented integer in bits.
91
    pub const BITS: usize = LIMBS * Limb::BITS;
92
93
    /// Bit size of `BITS`.
94
    // Note: assumes the type of `BITS` is `usize`. Any way to assert that?
95
    pub(crate) const LOG2_BITS: usize = (usize::BITS - Self::BITS.leading_zeros()) as usize;
96
97
    /// Total size of the represented integer in bytes.
98
    pub const BYTES: usize = LIMBS * Limb::BYTES;
99
100
    /// The number of limbs used on this platform.
101
    pub const LIMBS: usize = LIMBS;
102
103
    /// Const-friendly [`Uint`] constructor.
104
7.32k
    pub const fn new(limbs: [Limb; LIMBS]) -> Self {
105
7.32k
        Self { limbs }
106
7.32k
    }
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj100_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj10_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj14_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj18_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj1_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj1c_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj200_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj20_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj2_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj30_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj38_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj3_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj40_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj42_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj44_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj4_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj5_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj60_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj6_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj7_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj80_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj8_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj9_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKja_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKjb_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKjc_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKjd_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKje_E3newB4_
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKjf_E3newB4_
_RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj4_E3newCsjewTDwKBbyD_4k256
Line
Count
Source
104
2.16k
    pub const fn new(limbs: [Limb; LIMBS]) -> Self {
105
2.16k
        Self { limbs }
106
2.16k
    }
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj8_E3newCsjewTDwKBbyD_4k256
_RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj4_E3newCsaHRNXv1Y9Bq_4p256
Line
Count
Source
104
5.16k
    pub const fn new(limbs: [Limb; LIMBS]) -> Self {
105
5.16k
        Self { limbs }
106
5.16k
    }
107
108
    /// Create a [`Uint`] from an array of [`Word`]s (i.e. word-sized unsigned
109
    /// integers).
110
    #[inline]
111
22.4M
    pub const fn from_words(arr: [Word; LIMBS]) -> Self {
112
22.4M
        let mut limbs = [Limb::ZERO; LIMBS];
113
22.4M
        let mut i = 0;
114
115
112M
        while i < LIMBS {
116
89.6M
            limbs[i] = Limb(arr[i]);
117
89.6M
            i += 1;
118
89.6M
        }
119
120
22.4M
        Self { limbs }
121
22.4M
    }
_RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj4_E10from_wordsCs4RkbDk9WRL5_5clvmr
Line
Count
Source
111
14.7M
    pub const fn from_words(arr: [Word; LIMBS]) -> Self {
112
14.7M
        let mut limbs = [Limb::ZERO; LIMBS];
113
14.7M
        let mut i = 0;
114
115
73.9M
        while i < LIMBS {
116
59.1M
            limbs[i] = Limb(arr[i]);
117
59.1M
            i += 1;
118
59.1M
        }
119
120
14.7M
        Self { limbs }
121
14.7M
    }
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKpE10from_wordsB4_
_RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj4_E10from_wordsCsjewTDwKBbyD_4k256
Line
Count
Source
111
393k
    pub const fn from_words(arr: [Word; LIMBS]) -> Self {
112
393k
        let mut limbs = [Limb::ZERO; LIMBS];
113
393k
        let mut i = 0;
114
115
1.96M
        while i < LIMBS {
116
1.57M
            limbs[i] = Limb(arr[i]);
117
1.57M
            i += 1;
118
1.57M
        }
119
120
393k
        Self { limbs }
121
393k
    }
_RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj8_E10from_wordsCsjewTDwKBbyD_4k256
Line
Count
Source
111
6.27k
    pub const fn from_words(arr: [Word; LIMBS]) -> Self {
112
6.27k
        let mut limbs = [Limb::ZERO; LIMBS];
113
6.27k
        let mut i = 0;
114
115
56.4k
        while i < LIMBS {
116
50.2k
            limbs[i] = Limb(arr[i]);
117
50.2k
            i += 1;
118
50.2k
        }
119
120
6.27k
        Self { limbs }
121
6.27k
    }
_RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj4_E10from_wordsCsaHRNXv1Y9Bq_4p256
Line
Count
Source
111
7.22M
    pub const fn from_words(arr: [Word; LIMBS]) -> Self {
112
7.22M
        let mut limbs = [Limb::ZERO; LIMBS];
113
7.22M
        let mut i = 0;
114
115
36.1M
        while i < LIMBS {
116
28.9M
            limbs[i] = Limb(arr[i]);
117
28.9M
            i += 1;
118
28.9M
        }
119
120
7.22M
        Self { limbs }
121
7.22M
    }
122
123
    /// Create an array of [`Word`]s (i.e. word-sized unsigned integers) from
124
    /// a [`Uint`].
125
    #[inline]
126
18.8k
    pub const fn to_words(self) -> [Word; LIMBS] {
127
18.8k
        let mut arr = [0; LIMBS];
128
18.8k
        let mut i = 0;
129
130
119k
        while i < LIMBS {
131
100k
            arr[i] = self.limbs[i].0;
132
100k
            i += 1;
133
100k
        }
134
135
18.8k
        arr
136
18.8k
    }
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKpE8to_wordsB4_
_RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj4_E8to_wordsCsjewTDwKBbyD_4k256
Line
Count
Source
126
12.5k
    pub const fn to_words(self) -> [Word; LIMBS] {
127
12.5k
        let mut arr = [0; LIMBS];
128
12.5k
        let mut i = 0;
129
130
62.7k
        while i < LIMBS {
131
50.2k
            arr[i] = self.limbs[i].0;
132
50.2k
            i += 1;
133
50.2k
        }
134
135
12.5k
        arr
136
12.5k
    }
_RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj8_E8to_wordsCsjewTDwKBbyD_4k256
Line
Count
Source
126
6.27k
    pub const fn to_words(self) -> [Word; LIMBS] {
127
6.27k
        let mut arr = [0; LIMBS];
128
6.27k
        let mut i = 0;
129
130
56.4k
        while i < LIMBS {
131
50.2k
            arr[i] = self.limbs[i].0;
132
50.2k
            i += 1;
133
50.2k
        }
134
135
6.27k
        arr
136
6.27k
    }
137
138
    /// Borrow the inner limbs as an array of [`Word`]s.
139
79.7M
    pub const fn as_words(&self) -> &[Word; LIMBS] {
140
79.7M
        // SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
141
79.7M
        #[allow(trivial_casts, unsafe_code)]
142
79.7M
        unsafe {
143
79.7M
            &*((&self.limbs as *const _) as *const [Word; LIMBS])
144
79.7M
        }
145
79.7M
    }
_RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj4_E8as_wordsCs4RkbDk9WRL5_5clvmr
Line
Count
Source
139
29.0M
    pub const fn as_words(&self) -> &[Word; LIMBS] {
140
29.0M
        // SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
141
29.0M
        #[allow(trivial_casts, unsafe_code)]
142
29.0M
        unsafe {
143
29.0M
            &*((&self.limbs as *const _) as *const [Word; LIMBS])
144
29.0M
        }
145
29.0M
    }
Unexecuted instantiation: _RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKpE8as_wordsB4_
_RNvMNtCshRehcWQJ0wE_13crypto_bigint4uintINtB2_4UintKj4_E8as_wordsCsaHRNXv1Y9Bq_4p256
Line
Count
Source
139
50.7M
    pub const fn as_words(&self) -> &[Word; LIMBS] {
140
50.7M
        // SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
141
50.7M
        #[allow(trivial_casts, unsafe_code)]
142
50.7M
        unsafe {
143
50.7M
            &*((&self.limbs as *const _) as *const [Word; LIMBS])
144
50.7M
        }
145
50.7M
    }
146
147
    /// Borrow the inner limbs as a mutable array of [`Word`]s.
148
0
    pub fn as_words_mut(&mut self) -> &mut [Word; LIMBS] {
149
0
        // SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
150
0
        #[allow(trivial_casts, unsafe_code)]
151
0
        unsafe {
152
0
            &mut *((&mut self.limbs as *mut _) as *mut [Word; LIMBS])
153
0
        }
154
0
    }
155
156
    /// Borrow the limbs of this [`Uint`].
157
0
    pub const fn as_limbs(&self) -> &[Limb; LIMBS] {
158
0
        &self.limbs
159
0
    }
160
161
    /// Borrow the limbs of this [`Uint`] mutably.
162
0
    pub fn as_limbs_mut(&mut self) -> &mut [Limb; LIMBS] {
163
0
        &mut self.limbs
164
0
    }
165
166
    /// Convert this [`Uint`] into its inner limbs.
167
0
    pub const fn to_limbs(self) -> [Limb; LIMBS] {
168
0
        self.limbs
169
0
    }
170
}
171
172
impl<const LIMBS: usize> AsRef<[Word; LIMBS]> for Uint<LIMBS> {
173
29.0M
    fn as_ref(&self) -> &[Word; LIMBS] {
174
29.0M
        self.as_words()
175
29.0M
    }
_RNvXs_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB4_4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert5AsRefAyBQ_E6as_refCs4RkbDk9WRL5_5clvmr
Line
Count
Source
173
29.0M
    fn as_ref(&self) -> &[Word; LIMBS] {
174
29.0M
        self.as_words()
175
29.0M
    }
Unexecuted instantiation: _RNvXININtCshRehcWQJ0wE_13crypto_bigint4uints_0KpEINtB5_4UintKpEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefAypE6as_refB7_
_RNvXs_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB4_4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert5AsRefAyBQ_E6as_refCsaHRNXv1Y9Bq_4p256
Line
Count
Source
173
9.77k
    fn as_ref(&self) -> &[Word; LIMBS] {
174
9.77k
        self.as_words()
175
9.77k
    }
176
}
177
178
impl<const LIMBS: usize> AsMut<[Word; LIMBS]> for Uint<LIMBS> {
179
0
    fn as_mut(&mut self) -> &mut [Word; LIMBS] {
180
0
        self.as_words_mut()
181
0
    }
182
}
183
184
impl<const LIMBS: usize> AsRef<[Limb]> for Uint<LIMBS> {
185
0
    fn as_ref(&self) -> &[Limb] {
186
0
        self.as_limbs()
187
0
    }
188
}
189
190
impl<const LIMBS: usize> AsMut<[Limb]> for Uint<LIMBS> {
191
0
    fn as_mut(&mut self) -> &mut [Limb] {
192
0
        self.as_limbs_mut()
193
0
    }
194
}
195
196
impl<const LIMBS: usize> ConditionallySelectable for Uint<LIMBS> {
197
4.84M
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
198
4.84M
        let mut limbs = [Limb::ZERO; LIMBS];
199
200
24.2M
        for i in 0..LIMBS {
201
19.3M
            limbs[i] = Limb::conditional_select(&a.limbs[i], &b.limbs[i], choice);
202
19.3M
        }
203
204
4.84M
        Self { limbs }
205
4.84M
    }
Unexecuted instantiation: _RNvXININtCshRehcWQJ0wE_13crypto_bigint4uints3_0KpEINtB5_4UintKpENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectB7_
_RNvXs3_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectCsjewTDwKBbyD_4k256
Line
Count
Source
197
9.41k
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
198
9.41k
        let mut limbs = [Limb::ZERO; LIMBS];
199
200
47.0k
        for i in 0..LIMBS {
201
37.6k
            limbs[i] = Limb::conditional_select(&a.limbs[i], &b.limbs[i], choice);
202
37.6k
        }
203
204
9.41k
        Self { limbs }
205
9.41k
    }
_RNvXs3_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectCsaHRNXv1Y9Bq_4p256
Line
Count
Source
197
4.83M
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
198
4.83M
        let mut limbs = [Limb::ZERO; LIMBS];
199
200
24.1M
        for i in 0..LIMBS {
201
19.3M
            limbs[i] = Limb::conditional_select(&a.limbs[i], &b.limbs[i], choice);
202
19.3M
        }
203
204
4.83M
        Self { limbs }
205
4.83M
    }
206
}
207
208
impl<const LIMBS: usize> Default for Uint<LIMBS> {
209
0
    fn default() -> Self {
210
0
        Self::ZERO
211
0
    }
Unexecuted instantiation: _RNvXININtCshRehcWQJ0wE_13crypto_bigint4uints4_0KpEINtB5_4UintKpENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultB7_
Unexecuted instantiation: _RNvXs4_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs4_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj8_ENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs4_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCsaHRNXv1Y9Bq_4p256
212
}
213
214
impl<const LIMBS: usize> Integer for Uint<LIMBS> {
215
    const ONE: Self = Self::ONE;
216
    const MAX: Self = Self::MAX;
217
    const BITS: usize = Self::BITS;
218
    const BYTES: usize = Self::BYTES;
219
    const LIMBS: usize = Self::LIMBS;
220
221
1.46M
    fn is_odd(&self) -> Choice {
222
1.46M
        self.limbs
223
1.46M
            .first()
224
1.46M
            .map(|limb| limb.is_odd())
Unexecuted instantiation: _RNCNvXININtCshRehcWQJ0wE_13crypto_bigint4uints5_0KpEINtB7_4UintKpENtNtB9_6traits7Integer6is_odd0B9_
_RNCNvXs5_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB7_4UintKj4_ENtNtB9_6traits7Integer6is_odd0CsjewTDwKBbyD_4k256
Line
Count
Source
224
560k
            .map(|limb| limb.is_odd())
_RNCNvXs5_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB7_4UintKj4_ENtNtB9_6traits7Integer6is_odd0CsaHRNXv1Y9Bq_4p256
Line
Count
Source
224
906k
            .map(|limb| limb.is_odd())
225
1.46M
            .unwrap_or_else(|| Choice::from(0))
Unexecuted instantiation: _RNCNvXININtCshRehcWQJ0wE_13crypto_bigint4uints5_0KpEINtB7_4UintKpENtNtB9_6traits7Integer6is_odds_0B9_
Unexecuted instantiation: _RNCNvXs5_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB7_4UintKj4_ENtNtB9_6traits7Integer6is_odds_0CsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNCNvXs5_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB7_4UintKj4_ENtNtB9_6traits7Integer6is_odds_0CsaHRNXv1Y9Bq_4p256
226
1.46M
    }
Unexecuted instantiation: _RNvXININtCshRehcWQJ0wE_13crypto_bigint4uints5_0KpEINtB5_4UintKpENtNtB7_6traits7Integer6is_oddB7_
_RNvXs5_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtB7_6traits7Integer6is_oddCsjewTDwKBbyD_4k256
Line
Count
Source
221
560k
    fn is_odd(&self) -> Choice {
222
560k
        self.limbs
223
560k
            .first()
224
560k
            .map(|limb| limb.is_odd())
225
560k
            .unwrap_or_else(|| Choice::from(0))
226
560k
    }
_RNvXs5_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtB7_6traits7Integer6is_oddCsaHRNXv1Y9Bq_4p256
Line
Count
Source
221
906k
    fn is_odd(&self) -> Choice {
222
906k
        self.limbs
223
906k
            .first()
224
906k
            .map(|limb| limb.is_odd())
225
906k
            .unwrap_or_else(|| Choice::from(0))
226
906k
    }
227
}
228
229
impl<const LIMBS: usize> Zero for Uint<LIMBS> {
230
    const ZERO: Self = Self::ZERO;
231
}
232
233
impl<const LIMBS: usize> Bounded for Uint<LIMBS> {
234
    const BITS: usize = Self::BITS;
235
    const BYTES: usize = Self::BYTES;
236
}
237
238
impl<const LIMBS: usize> fmt::Debug for Uint<LIMBS> {
239
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240
0
        write!(f, "Uint(0x{self:X})")
241
0
    }
Unexecuted instantiation: _RNvXININtCshRehcWQJ0wE_13crypto_bigint4uints8_0KpEINtB5_4UintKpENtNtCsbQ8arDwx5Xq_4core3fmt5Debug3fmtB7_
Unexecuted instantiation: _RNvXs8_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtCsbQ8arDwx5Xq_4core3fmt5Debug3fmtCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs8_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj8_ENtNtCsbQ8arDwx5Xq_4core3fmt5Debug3fmtCsjewTDwKBbyD_4k256
242
}
243
244
impl<const LIMBS: usize> fmt::Display for Uint<LIMBS> {
245
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246
0
        fmt::UpperHex::fmt(self, f)
247
0
    }
248
}
249
250
impl<const LIMBS: usize> fmt::LowerHex for Uint<LIMBS> {
251
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
252
0
        for limb in self.limbs.iter().rev() {
253
0
            fmt::LowerHex::fmt(limb, f)?;
254
        }
255
0
        Ok(())
256
0
    }
257
}
258
259
impl<const LIMBS: usize> fmt::UpperHex for Uint<LIMBS> {
260
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261
0
        for limb in self.limbs.iter().rev() {
262
0
            fmt::UpperHex::fmt(limb, f)?;
263
        }
264
0
        Ok(())
265
0
    }
Unexecuted instantiation: _RNvXININtCshRehcWQJ0wE_13crypto_bigint4uintsb_0KpEINtB5_4UintKpENtNtCsbQ8arDwx5Xq_4core3fmt8UpperHex3fmtB7_
Unexecuted instantiation: _RNvXsb_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtCsbQ8arDwx5Xq_4core3fmt8UpperHex3fmtCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXsb_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj8_ENtNtCsbQ8arDwx5Xq_4core3fmt8UpperHex3fmtCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXsb_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtCsbQ8arDwx5Xq_4core3fmt8UpperHex3fmtCsaHRNXv1Y9Bq_4p256
266
}
267
268
#[cfg(feature = "serde")]
269
impl<'de, const LIMBS: usize> Deserialize<'de> for Uint<LIMBS>
270
where
271
    Uint<LIMBS>: Encoding,
272
{
273
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
274
    where
275
        D: Deserializer<'de>,
276
    {
277
        let mut buffer = Self::ZERO.to_le_bytes();
278
        serdect::array::deserialize_hex_or_bin(buffer.as_mut(), deserializer)?;
279
280
        Ok(Self::from_le_bytes(buffer))
281
    }
282
}
283
284
#[cfg(feature = "serde")]
285
impl<const LIMBS: usize> Serialize for Uint<LIMBS>
286
where
287
    Uint<LIMBS>: Encoding,
288
{
289
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
290
    where
291
        S: Serializer,
292
    {
293
        serdect::array::serialize_hex_lower_or_bin(&Encoding::to_le_bytes(self), serializer)
294
    }
295
}
296
297
#[cfg(feature = "zeroize")]
298
impl<const LIMBS: usize> DefaultIsZeroes for Uint<LIMBS> {}
299
300
// TODO(tarcieri): use `generic_const_exprs` when stable to make generic around bits.
301
impl_uint_aliases! {
302
    (U64, 64, "64-bit"),
303
    (U128, 128, "128-bit"),
304
    (U192, 192, "192-bit"),
305
    (U256, 256, "256-bit"),
306
    (U320, 320, "320-bit"),
307
    (U384, 384, "384-bit"),
308
    (U448, 448, "448-bit"),
309
    (U512, 512, "512-bit"),
310
    (U576, 576, "576-bit"),
311
    (U640, 640, "640-bit"),
312
    (U704, 704, "704-bit"),
313
    (U768, 768, "768-bit"),
314
    (U832, 832, "832-bit"),
315
    (U896, 896, "896-bit"),
316
    (U960, 960, "960-bit"),
317
    (U1024, 1024, "1024-bit"),
318
    (U1280, 1280, "1280-bit"),
319
    (U1536, 1536, "1536-bit"),
320
    (U1792, 1792, "1792-bit"),
321
    (U2048, 2048, "2048-bit"),
322
    (U3072, 3072, "3072-bit"),
323
    (U3584, 3584, "3584-bit"),
324
    (U4096, 4096, "4096-bit"),
325
    (U4224, 4224, "4224-bit"),
326
    (U4352, 4352, "4352-bit"),
327
    (U6144, 6144, "6144-bit"),
328
    (U8192, 8192, "8192-bit"),
329
    (U16384, 16384, "16384-bit"),
330
    (U32768, 32768, "32768-bit")
331
}
332
333
#[cfg(target_pointer_width = "32")]
334
impl_uint_aliases! {
335
    (U224, 224, "224-bit"), // For NIST P-224
336
    (U544, 544, "544-bit")  // For NIST P-521
337
}
338
339
#[cfg(target_pointer_width = "32")]
340
impl_uint_concat_split_even! {
341
    U64,
342
}
343
344
// Implement concat and split for double-width Uint sizes: these should be
345
// multiples of 128 bits.
346
impl_uint_concat_split_even! {
347
    U128,
348
    U256,
349
    U384,
350
    U512,
351
    U640,
352
    U768,
353
    U896,
354
    U1024,
355
    U1280,
356
    U1536,
357
    U1792,
358
    U2048,
359
    U3072,
360
    U3584,
361
    U4096,
362
    U4224,
363
    U4352,
364
    U6144,
365
    U8192,
366
    U16384,
367
}
368
369
// Implement mixed concat and split for combinations not implemented by
370
// impl_uint_concat_split_even. The numbers represent the size of each
371
// component Uint in multiple of 64 bits. For example,
372
// (U256, [1, 3]) will allow splitting U256 into (U64, U192) as well as
373
// (U192, U64), while the (U128, U128) combination is already covered.
374
impl_uint_concat_split_mixed! {
375
    (U192, [1, 2]),
376
    (U256, [1, 3]),
377
    (U320, [1, 2, 3, 4]),
378
    (U384, [1, 2, 4, 5]),
379
    (U448, [1, 2, 3, 4, 5, 6]),
380
    (U512, [1, 2, 3, 5, 6, 7]),
381
    (U576, [1, 2, 3, 4, 5, 6, 7, 8]),
382
    (U640, [1, 2, 3, 4, 6, 7, 8, 9]),
383
    (U704, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
384
    (U768, [1, 2, 3, 4, 5, 7, 8, 9, 10, 11]),
385
    (U832, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),
386
    (U896, [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13]),
387
    (U960, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]),
388
    (U1024, [1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15]),
389
}
390
391
#[cfg(feature = "extra-sizes")]
392
mod extra_sizes;
393
#[cfg(feature = "extra-sizes")]
394
pub use extra_sizes::*;
395
396
#[cfg(test)]
397
#[allow(clippy::unwrap_used)]
398
mod tests {
399
    use crate::{Encoding, U128};
400
    use subtle::ConditionallySelectable;
401
402
    #[cfg(feature = "alloc")]
403
    use alloc::format;
404
405
    #[cfg(feature = "serde")]
406
    use crate::U64;
407
408
    #[cfg(feature = "alloc")]
409
    #[test]
410
    fn debug() {
411
        let hex = "AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD";
412
        let n = U128::from_be_hex(hex);
413
414
        assert_eq!(
415
            format!("{:?}", n),
416
            "Uint(0xAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD)"
417
        );
418
    }
419
420
    #[cfg(feature = "alloc")]
421
    #[test]
422
    fn display() {
423
        let hex = "AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD";
424
        let n = U128::from_be_hex(hex);
425
426
        use alloc::string::ToString;
427
        assert_eq!(hex, n.to_string());
428
429
        let hex = "AAAAAAAABBBBBBBB0000000000000000";
430
        let n = U128::from_be_hex(hex);
431
        assert_eq!(hex, n.to_string());
432
433
        let hex = "AAAAAAAABBBBBBBB00000000DDDDDDDD";
434
        let n = U128::from_be_hex(hex);
435
        assert_eq!(hex, n.to_string());
436
437
        let hex = "AAAAAAAABBBBBBBB0CCCCCCCDDDDDDDD";
438
        let n = U128::from_be_hex(hex);
439
        assert_eq!(hex, n.to_string());
440
    }
441
442
    #[test]
443
    fn from_bytes() {
444
        let a = U128::from_be_hex("AAAAAAAABBBBBBBB0CCCCCCCDDDDDDDD");
445
446
        let be_bytes = a.to_be_bytes();
447
        let le_bytes = a.to_le_bytes();
448
        for i in 0..16 {
449
            assert_eq!(le_bytes[i], be_bytes[15 - i]);
450
        }
451
452
        let a_from_be = U128::from_be_bytes(be_bytes);
453
        let a_from_le = U128::from_le_bytes(le_bytes);
454
        assert_eq!(a_from_be, a_from_le);
455
        assert_eq!(a_from_be, a);
456
    }
457
458
    #[test]
459
    fn conditional_select() {
460
        let a = U128::from_be_hex("00002222444466668888AAAACCCCEEEE");
461
        let b = U128::from_be_hex("11113333555577779999BBBBDDDDFFFF");
462
463
        let select_0 = U128::conditional_select(&a, &b, 0.into());
464
        assert_eq!(a, select_0);
465
466
        let select_1 = U128::conditional_select(&a, &b, 1.into());
467
        assert_eq!(b, select_1);
468
    }
469
470
    #[cfg(feature = "serde")]
471
    #[test]
472
    fn serde() {
473
        const TEST: U64 = U64::from_u64(0x0011223344556677);
474
475
        let serialized = bincode::serialize(&TEST).unwrap();
476
        let deserialized: U64 = bincode::deserialize(&serialized).unwrap();
477
478
        assert_eq!(TEST, deserialized);
479
    }
480
481
    #[cfg(feature = "serde")]
482
    #[test]
483
    fn serde_owned() {
484
        const TEST: U64 = U64::from_u64(0x0011223344556677);
485
486
        let serialized = bincode::serialize(&TEST).unwrap();
487
        let deserialized: U64 = bincode::deserialize_from(serialized.as_slice()).unwrap();
488
489
        assert_eq!(TEST, deserialized);
490
    }
491
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/add.rs
Line
Count
Source
1
//! [`Uint`] addition operations.
2
3
use crate::{Checked, CheckedAdd, CtChoice, Limb, Uint, Wrapping, Zero};
4
use core::ops::{Add, AddAssign};
5
use subtle::CtOption;
6
7
impl<const LIMBS: usize> Uint<LIMBS> {
8
    /// Computes `a + b + carry`, returning the result along with the new carry.
9
    #[inline(always)]
10
1.46M
    pub const fn adc(&self, rhs: &Self, mut carry: Limb) -> (Self, Limb) {
11
1.46M
        let mut limbs = [Limb::ZERO; LIMBS];
12
1.46M
        let mut i = 0;
13
14
7.33M
        while i < LIMBS {
15
5.87M
            let (w, c) = self.limbs[i].adc(rhs.limbs[i], carry);
16
5.87M
            limbs[i] = w;
17
5.87M
            carry = c;
18
5.87M
            i += 1;
19
5.87M
        }
20
21
1.46M
        (Self { limbs }, carry)
22
1.46M
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3addINtB4_4UintKpE3adcB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3addINtB4_4UintKj4_E3adcCsjewTDwKBbyD_4k256
Line
Count
Source
10
586k
    pub const fn adc(&self, rhs: &Self, mut carry: Limb) -> (Self, Limb) {
11
586k
        let mut limbs = [Limb::ZERO; LIMBS];
12
586k
        let mut i = 0;
13
14
2.93M
        while i < LIMBS {
15
2.34M
            let (w, c) = self.limbs[i].adc(rhs.limbs[i], carry);
16
2.34M
            limbs[i] = w;
17
2.34M
            carry = c;
18
2.34M
            i += 1;
19
2.34M
        }
20
21
586k
        (Self { limbs }, carry)
22
586k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3addINtB4_4UintKj4_E3adcCsaHRNXv1Y9Bq_4p256
Line
Count
Source
10
881k
    pub const fn adc(&self, rhs: &Self, mut carry: Limb) -> (Self, Limb) {
11
881k
        let mut limbs = [Limb::ZERO; LIMBS];
12
881k
        let mut i = 0;
13
14
4.40M
        while i < LIMBS {
15
3.52M
            let (w, c) = self.limbs[i].adc(rhs.limbs[i], carry);
16
3.52M
            limbs[i] = w;
17
3.52M
            carry = c;
18
3.52M
            i += 1;
19
3.52M
        }
20
21
881k
        (Self { limbs }, carry)
22
881k
    }
23
24
    /// Perform saturating addition, returning `MAX` on overflow.
25
0
    pub const fn saturating_add(&self, rhs: &Self) -> Self {
26
0
        let (res, overflow) = self.adc(rhs, Limb::ZERO);
27
0
        Self::ct_select(&res, &Self::MAX, CtChoice::from_lsb(overflow.0))
28
0
    }
29
30
    /// Perform wrapping addition, discarding overflow.
31
981k
    pub const fn wrapping_add(&self, rhs: &Self) -> Self {
32
981k
        self.adc(rhs, Limb::ZERO).0
33
981k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3addINtB4_4UintKpE12wrapping_addB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3addINtB4_4UintKj4_E12wrapping_addCsjewTDwKBbyD_4k256
Line
Count
Source
31
386k
    pub const fn wrapping_add(&self, rhs: &Self) -> Self {
32
386k
        self.adc(rhs, Limb::ZERO).0
33
386k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3addINtB4_4UintKj4_E12wrapping_addCsaHRNXv1Y9Bq_4p256
Line
Count
Source
31
594k
    pub const fn wrapping_add(&self, rhs: &Self) -> Self {
32
594k
        self.adc(rhs, Limb::ZERO).0
33
594k
    }
34
35
    /// Perform wrapping addition, returning the truthy value as the second element of the tuple
36
    /// if an overflow has occurred.
37
0
    pub(crate) const fn conditional_wrapping_add(
38
0
        &self,
39
0
        rhs: &Self,
40
0
        choice: CtChoice,
41
0
    ) -> (Self, CtChoice) {
42
0
        let actual_rhs = Uint::ct_select(&Uint::ZERO, rhs, choice);
43
0
        let (sum, carry) = self.adc(&actual_rhs, Limb::ZERO);
44
0
        (sum, CtChoice::from_lsb(carry.0))
45
0
    }
46
}
47
48
impl<const LIMBS: usize> CheckedAdd<&Uint<LIMBS>> for Uint<LIMBS> {
49
    type Output = Self;
50
51
0
    fn checked_add(&self, rhs: &Self) -> CtOption<Self> {
52
0
        let (result, carry) = self.adc(rhs, Limb::ZERO);
53
0
        CtOption::new(result, carry.is_zero())
54
0
    }
55
}
56
57
impl<const LIMBS: usize> Add for Wrapping<Uint<LIMBS>> {
58
    type Output = Self;
59
60
0
    fn add(self, rhs: Self) -> Wrapping<Uint<LIMBS>> {
61
0
        Wrapping(self.0.wrapping_add(&rhs.0))
62
0
    }
63
}
64
65
impl<const LIMBS: usize> Add<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
66
    type Output = Wrapping<Uint<LIMBS>>;
67
68
0
    fn add(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
69
0
        Wrapping(self.0.wrapping_add(&rhs.0))
70
0
    }
71
}
72
73
impl<const LIMBS: usize> Add<Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
74
    type Output = Wrapping<Uint<LIMBS>>;
75
76
0
    fn add(self, rhs: Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
77
0
        Wrapping(self.0.wrapping_add(&rhs.0))
78
0
    }
79
}
80
81
impl<const LIMBS: usize> Add<&Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
82
    type Output = Wrapping<Uint<LIMBS>>;
83
84
0
    fn add(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
85
0
        Wrapping(self.0.wrapping_add(&rhs.0))
86
0
    }
87
}
88
89
impl<const LIMBS: usize> AddAssign for Wrapping<Uint<LIMBS>> {
90
0
    fn add_assign(&mut self, other: Self) {
91
0
        *self = *self + other;
92
0
    }
93
}
94
95
impl<const LIMBS: usize> AddAssign<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
96
0
    fn add_assign(&mut self, other: &Self) {
97
0
        *self = *self + other;
98
0
    }
99
}
100
101
impl<const LIMBS: usize> Add for Checked<Uint<LIMBS>> {
102
    type Output = Self;
103
104
0
    fn add(self, rhs: Self) -> Checked<Uint<LIMBS>> {
105
0
        Checked(
106
0
            self.0
107
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_add(&rhs))),
108
0
        )
109
0
    }
110
}
111
112
impl<const LIMBS: usize> Add<&Checked<Uint<LIMBS>>> for Checked<Uint<LIMBS>> {
113
    type Output = Checked<Uint<LIMBS>>;
114
115
0
    fn add(self, rhs: &Checked<Uint<LIMBS>>) -> Checked<Uint<LIMBS>> {
116
0
        Checked(
117
0
            self.0
118
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_add(&rhs))),
119
0
        )
120
0
    }
121
}
122
123
impl<const LIMBS: usize> Add<Checked<Uint<LIMBS>>> for &Checked<Uint<LIMBS>> {
124
    type Output = Checked<Uint<LIMBS>>;
125
126
0
    fn add(self, rhs: Checked<Uint<LIMBS>>) -> Checked<Uint<LIMBS>> {
127
0
        Checked(
128
0
            self.0
129
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_add(&rhs))),
130
0
        )
131
0
    }
132
}
133
134
impl<const LIMBS: usize> Add<&Checked<Uint<LIMBS>>> for &Checked<Uint<LIMBS>> {
135
    type Output = Checked<Uint<LIMBS>>;
136
137
0
    fn add(self, rhs: &Checked<Uint<LIMBS>>) -> Checked<Uint<LIMBS>> {
138
0
        Checked(
139
0
            self.0
140
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_add(&rhs))),
141
0
        )
142
0
    }
143
}
144
145
impl<const LIMBS: usize> AddAssign for Checked<Uint<LIMBS>> {
146
0
    fn add_assign(&mut self, other: Self) {
147
0
        *self = *self + other;
148
0
    }
149
}
150
151
impl<const LIMBS: usize> AddAssign<&Checked<Uint<LIMBS>>> for Checked<Uint<LIMBS>> {
152
0
    fn add_assign(&mut self, other: &Self) {
153
0
        *self = *self + other;
154
0
    }
155
}
156
157
#[cfg(test)]
158
mod tests {
159
    use crate::{CheckedAdd, Limb, U128};
160
161
    #[test]
162
    fn adc_no_carry() {
163
        let (res, carry) = U128::ZERO.adc(&U128::ONE, Limb::ZERO);
164
        assert_eq!(res, U128::ONE);
165
        assert_eq!(carry, Limb::ZERO);
166
    }
167
168
    #[test]
169
    fn adc_with_carry() {
170
        let (res, carry) = U128::MAX.adc(&U128::ONE, Limb::ZERO);
171
        assert_eq!(res, U128::ZERO);
172
        assert_eq!(carry, Limb::ONE);
173
    }
174
175
    #[test]
176
    fn saturating_add_no_carry() {
177
        assert_eq!(U128::ZERO.saturating_add(&U128::ONE), U128::ONE);
178
    }
179
180
    #[test]
181
    fn saturating_add_with_carry() {
182
        assert_eq!(U128::MAX.saturating_add(&U128::ONE), U128::MAX);
183
    }
184
185
    #[test]
186
    fn wrapping_add_no_carry() {
187
        assert_eq!(U128::ZERO.wrapping_add(&U128::ONE), U128::ONE);
188
    }
189
190
    #[test]
191
    fn wrapping_add_with_carry() {
192
        assert_eq!(U128::MAX.wrapping_add(&U128::ONE), U128::ZERO);
193
    }
194
195
    #[test]
196
    fn checked_add_ok() {
197
        let result = U128::ZERO.checked_add(&U128::ONE);
198
        assert_eq!(result.unwrap(), U128::ONE);
199
    }
200
201
    #[test]
202
    fn checked_add_overflow() {
203
        let result = U128::MAX.checked_add(&U128::ONE);
204
        assert!(!bool::from(result.is_some()));
205
    }
206
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/add_mod.rs
Line
Count
Source
1
//! [`Uint`] addition modulus operations.
2
3
use crate::{AddMod, Limb, Uint};
4
5
impl<const LIMBS: usize> Uint<LIMBS> {
6
    /// Computes `self + rhs mod p`.
7
    ///
8
    /// Assumes `self + rhs` as unbounded integer is `< 2p`.
9
486k
    pub const fn add_mod(&self, rhs: &Uint<LIMBS>, p: &Uint<LIMBS>) -> Uint<LIMBS> {
10
486k
        let (w, carry) = self.adc(rhs, Limb::ZERO);
11
486k
12
486k
        // Attempt to subtract the modulus, to ensure the result is in the field.
13
486k
        let (w, borrow) = w.sbb(p, Limb::ZERO);
14
486k
        let (_, borrow) = carry.sbb(Limb::ZERO, borrow);
15
486k
16
486k
        // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise
17
486k
        // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the
18
486k
        // modulus.
19
486k
        let mask = Uint::from_words([borrow.0; LIMBS]);
20
486k
21
486k
        w.wrapping_add(&p.bitand(&mask))
22
486k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint7add_modINtB4_4UintKpE7add_modB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint7add_modINtB4_4UintKj4_E7add_modCsjewTDwKBbyD_4k256
Line
Count
Source
9
199k
    pub const fn add_mod(&self, rhs: &Uint<LIMBS>, p: &Uint<LIMBS>) -> Uint<LIMBS> {
10
199k
        let (w, carry) = self.adc(rhs, Limb::ZERO);
11
199k
12
199k
        // Attempt to subtract the modulus, to ensure the result is in the field.
13
199k
        let (w, borrow) = w.sbb(p, Limb::ZERO);
14
199k
        let (_, borrow) = carry.sbb(Limb::ZERO, borrow);
15
199k
16
199k
        // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise
17
199k
        // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the
18
199k
        // modulus.
19
199k
        let mask = Uint::from_words([borrow.0; LIMBS]);
20
199k
21
199k
        w.wrapping_add(&p.bitand(&mask))
22
199k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint7add_modINtB4_4UintKj4_E7add_modCsaHRNXv1Y9Bq_4p256
Line
Count
Source
9
286k
    pub const fn add_mod(&self, rhs: &Uint<LIMBS>, p: &Uint<LIMBS>) -> Uint<LIMBS> {
10
286k
        let (w, carry) = self.adc(rhs, Limb::ZERO);
11
286k
12
286k
        // Attempt to subtract the modulus, to ensure the result is in the field.
13
286k
        let (w, borrow) = w.sbb(p, Limb::ZERO);
14
286k
        let (_, borrow) = carry.sbb(Limb::ZERO, borrow);
15
286k
16
286k
        // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise
17
286k
        // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the
18
286k
        // modulus.
19
286k
        let mask = Uint::from_words([borrow.0; LIMBS]);
20
286k
21
286k
        w.wrapping_add(&p.bitand(&mask))
22
286k
    }
23
24
    /// Computes `self + rhs mod p` for the special modulus
25
    /// `p = MAX+1-c` where `c` is small enough to fit in a single [`Limb`].
26
    ///
27
    /// Assumes `self + rhs` as unbounded integer is `< 2p`.
28
0
    pub const fn add_mod_special(&self, rhs: &Self, c: Limb) -> Self {
29
0
        // `Uint::adc` also works with a carry greater than 1.
30
0
        let (out, carry) = self.adc(rhs, c);
31
0
32
0
        // If overflow occurred, then above addition of `c` already accounts
33
0
        // for the overflow. Otherwise, we need to subtract `c` again, which
34
0
        // in that case cannot underflow.
35
0
        let l = carry.0.wrapping_sub(1) & c.0;
36
0
        out.wrapping_sub(&Uint::from_word(l))
37
0
    }
38
}
39
40
impl<const LIMBS: usize> AddMod for Uint<LIMBS> {
41
    type Output = Self;
42
43
0
    fn add_mod(&self, rhs: &Self, p: &Self) -> Self {
44
0
        debug_assert!(self < p);
45
0
        debug_assert!(rhs < p);
46
0
        self.add_mod(rhs, p)
47
0
    }
48
}
49
50
#[cfg(all(test, feature = "rand"))]
51
mod tests {
52
    use crate::{Limb, NonZero, Random, RandomMod, Uint, U256};
53
    use rand_core::SeedableRng;
54
55
    // TODO(tarcieri): additional tests + proptests
56
57
    #[test]
58
    fn add_mod_nist_p256() {
59
        let a =
60
            U256::from_be_hex("44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56");
61
        let b =
62
            U256::from_be_hex("d5777c45019673125ad240f83094d4252d829516fac8601ed01979ec1ec1a251");
63
        let n =
64
            U256::from_be_hex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
65
66
        let actual = a.add_mod(&b, &n);
67
        let expected =
68
            U256::from_be_hex("1a2472fde50286541d97ca6a3592dd75beb9c9646e40c511b82496cfc3926956");
69
70
        assert_eq!(expected, actual);
71
    }
72
73
    macro_rules! test_add_mod_special {
74
        ($size:expr, $test_name:ident) => {
75
            #[test]
76
            fn $test_name() {
77
                let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(1);
78
                let moduli = [
79
                    NonZero::<Limb>::random(&mut rng),
80
                    NonZero::<Limb>::random(&mut rng),
81
                ];
82
83
                for special in &moduli {
84
                    let p = &NonZero::new(Uint::ZERO.wrapping_sub(&Uint::from_word(special.0)))
85
                        .unwrap();
86
87
                    let minus_one = p.wrapping_sub(&Uint::ONE);
88
89
                    let base_cases = [
90
                        (Uint::ZERO, Uint::ZERO, Uint::ZERO),
91
                        (Uint::ONE, Uint::ZERO, Uint::ONE),
92
                        (Uint::ZERO, Uint::ONE, Uint::ONE),
93
                        (minus_one, Uint::ONE, Uint::ZERO),
94
                        (Uint::ONE, minus_one, Uint::ZERO),
95
                    ];
96
                    for (a, b, c) in &base_cases {
97
                        let x = a.add_mod_special(b, *special.as_ref());
98
                        assert_eq!(*c, x, "{} + {} mod {} = {} != {}", a, b, p, x, c);
99
                    }
100
101
                    for _i in 0..100 {
102
                        let a = Uint::<$size>::random_mod(&mut rng, p);
103
                        let b = Uint::<$size>::random_mod(&mut rng, p);
104
105
                        let c = a.add_mod_special(&b, *special.as_ref());
106
                        assert!(c < **p, "not reduced: {} >= {} ", c, p);
107
108
                        let expected = a.add_mod(&b, p);
109
                        assert_eq!(c, expected, "incorrect result");
110
                    }
111
                }
112
            }
113
        };
114
    }
115
116
    test_add_mod_special!(1, add_mod_special_1);
117
    test_add_mod_special!(2, add_mod_special_2);
118
    test_add_mod_special!(3, add_mod_special_3);
119
    test_add_mod_special!(4, add_mod_special_4);
120
    test_add_mod_special!(5, add_mod_special_5);
121
    test_add_mod_special!(6, add_mod_special_6);
122
    test_add_mod_special!(7, add_mod_special_7);
123
    test_add_mod_special!(8, add_mod_special_8);
124
    test_add_mod_special!(9, add_mod_special_9);
125
    test_add_mod_special!(10, add_mod_special_10);
126
    test_add_mod_special!(11, add_mod_special_11);
127
    test_add_mod_special!(12, add_mod_special_12);
128
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/array.rs
Line
Count
Source
1
//! `generic-array` integration with `Uint`.
2
// TODO(tarcieri): completely phase out `generic-array` when const generics are powerful enough
3
4
use crate::{ArrayDecoding, ArrayEncoding, ByteArray};
5
use generic_array::{typenum, GenericArray};
6
7
macro_rules! impl_uint_array_encoding {
8
    ($(($uint:ident, $bytes:path)),+) => {
9
        $(
10
            impl ArrayEncoding for super::$uint {
11
                type ByteSize = $bytes;
12
13
                #[inline]
14
7.32k
                fn from_be_byte_array(bytes: ByteArray<Self>) -> Self {
15
7.32k
                    Self::from_be_slice(&bytes)
16
7.32k
                }
Unexecuted instantiation: _RNvXNtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB4_4UintKj1_ENtNtB6_5array13ArrayEncoding18from_be_byte_arrayB6_
Unexecuted instantiation: _RNvXs0_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj2_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXs2_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj3_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXs4_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj4_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXs6_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj6_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXs8_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj7_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsa_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj8_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsc_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj9_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXse_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKjc_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsg_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKjd_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsi_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKje_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsk_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj10_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsm_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj18_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXso_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj1c_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsq_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj20_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXss_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj30_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsu_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj38_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsw_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj40_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsy_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj60_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsA_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj80_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayB9_
_RNvXs4_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj4_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayCsjewTDwKBbyD_4k256
Line
Count
Source
14
2.16k
                fn from_be_byte_array(bytes: ByteArray<Self>) -> Self {
15
2.16k
                    Self::from_be_slice(&bytes)
16
2.16k
                }
Unexecuted instantiation: _RNvXsa_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj8_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayCsjewTDwKBbyD_4k256
_RNvXs4_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj4_ENtNtB9_5array13ArrayEncoding18from_be_byte_arrayCsaHRNXv1Y9Bq_4p256
Line
Count
Source
14
5.16k
                fn from_be_byte_array(bytes: ByteArray<Self>) -> Self {
15
5.16k
                    Self::from_be_slice(&bytes)
16
5.16k
                }
17
18
                #[inline]
19
0
                fn from_le_byte_array(bytes: ByteArray<Self>) -> Self {
20
0
                    Self::from_le_slice(&bytes)
21
0
                }
Unexecuted instantiation: _RNvXNtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB4_4UintKj1_ENtNtB6_5array13ArrayEncoding18from_le_byte_arrayB6_
Unexecuted instantiation: _RNvXs0_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj2_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXs2_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj3_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXs4_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj4_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXs6_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj6_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXs8_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj7_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsa_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj8_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsc_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj9_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXse_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKjc_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsg_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKjd_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsi_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKje_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsk_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj10_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsm_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj18_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXso_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj1c_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsq_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj20_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXss_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj30_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsu_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj38_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsw_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj40_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsy_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj60_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsA_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj80_ENtNtB9_5array13ArrayEncoding18from_le_byte_arrayB9_
22
23
                #[inline]
24
2.95k
                fn to_be_byte_array(&self) -> ByteArray<Self> {
25
2.95k
                    let mut result = GenericArray::default();
26
2.95k
                    self.write_be_bytes(&mut result);
27
2.95k
                    result
28
2.95k
                }
Unexecuted instantiation: _RNvXNtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB4_4UintKj1_ENtNtB6_5array13ArrayEncoding16to_be_byte_arrayB6_
Unexecuted instantiation: _RNvXs0_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj2_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXs2_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj3_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXs4_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj4_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXs6_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj6_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXs8_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj7_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsa_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj8_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsc_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj9_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXse_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKjc_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsg_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKjd_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsi_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKje_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsk_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj10_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsm_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj18_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXso_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj1c_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsq_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj20_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXss_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj30_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsu_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj38_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsw_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj40_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsy_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj60_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
Unexecuted instantiation: _RNvXsA_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj80_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayB9_
_RNvXs4_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj4_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayCsjewTDwKBbyD_4k256
Line
Count
Source
24
2.09k
                fn to_be_byte_array(&self) -> ByteArray<Self> {
25
2.09k
                    let mut result = GenericArray::default();
26
2.09k
                    self.write_be_bytes(&mut result);
27
2.09k
                    result
28
2.09k
                }
_RNvXs4_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj4_ENtNtB9_5array13ArrayEncoding16to_be_byte_arrayCsaHRNXv1Y9Bq_4p256
Line
Count
Source
24
866
                fn to_be_byte_array(&self) -> ByteArray<Self> {
25
866
                    let mut result = GenericArray::default();
26
866
                    self.write_be_bytes(&mut result);
27
866
                    result
28
866
                }
29
30
                #[inline]
31
1.67k
                fn to_le_byte_array(&self) -> ByteArray<Self> {
32
1.67k
                    let mut result = GenericArray::default();
33
1.67k
                    self.write_le_bytes(&mut result);
34
1.67k
                    result
35
1.67k
                }
_RNvXs4_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj4_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayCs4RkbDk9WRL5_5clvmr
Line
Count
Source
31
1.67k
                fn to_le_byte_array(&self) -> ByteArray<Self> {
32
1.67k
                    let mut result = GenericArray::default();
33
1.67k
                    self.write_le_bytes(&mut result);
34
1.67k
                    result
35
1.67k
                }
Unexecuted instantiation: _RNvXNtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB4_4UintKj1_ENtNtB6_5array13ArrayEncoding16to_le_byte_arrayB6_
Unexecuted instantiation: _RNvXs0_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj2_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXs2_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj3_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXs4_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj4_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXs6_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj6_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXs8_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj7_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsa_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj8_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsc_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj9_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXse_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKjc_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsg_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKjd_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsi_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKje_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsk_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj10_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsm_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj18_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXso_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj1c_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsq_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj20_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXss_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj30_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsu_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj38_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsw_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj40_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsy_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj60_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXsA_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj80_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayB9_
Unexecuted instantiation: _RNvXs4_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtB7_4UintKj4_ENtNtB9_5array13ArrayEncoding16to_le_byte_arrayCsaHRNXv1Y9Bq_4p256
36
            }
37
38
            impl ArrayDecoding for GenericArray<u8, $bytes> {
39
                type Output = super::$uint;
40
41
0
                fn into_uint_be(self) -> Self::Output {
42
0
                    Self::Output::from_be_byte_array(self)
43
0
                }
Unexecuted instantiation: _RNvXs_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1y_IB1y_IB1y_NtB1A_5UTermNtNtB1C_3bit2B1ENtB2B_2B0EB2P_EB2P_EENtNtB8_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXs1_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB2H_2B0EB2V_EB2V_EB2V_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXs3_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2F_ENtB2H_2B0EB30_EB30_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXs5_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB2M_2B0EB30_EB30_EB30_EB30_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXs7_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2K_ENtB2M_2B0EB35_EB35_EB35_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXs9_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2K_EB2K_ENtB2M_2B0EB3a_EB3a_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsb_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB2R_2B0EB35_EB35_EB35_EB35_EB35_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsd_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB2R_2B0EB35_EB2P_EB35_EB35_EB35_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsf_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2P_ENtB2R_2B0EB3a_EB3a_EB3a_EB3a_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsh_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2P_ENtB2R_2B0EB2P_EB3a_EB3a_EB3a_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsj_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2P_EB2P_ENtB2R_2B0EB3f_EB3f_EB3f_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsl_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB2W_2B0EB3a_EB3a_EB3a_EB3a_EB3a_EB3a_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsn_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2U_ENtB2W_2B0EB3f_EB3f_EB3f_EB3f_EB3f_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsp_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2U_EB2U_ENtB2W_2B0EB3k_EB3k_EB3k_EB3k_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsr_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB31_2B0EB3f_EB3f_EB3f_EB3f_EB3f_EB3f_EB3f_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXst_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2Z_ENtB31_2B0EB3k_EB3k_EB3k_EB3k_EB3k_EB3k_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsv_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2Z_EB2Z_ENtB31_2B0EB3p_EB3p_EB3p_EB3p_EB3p_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsx_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB36_2B0EB3k_EB3k_EB3k_EB3k_EB3k_EB3k_EB3k_EB3k_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsz_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB34_ENtB36_2B0EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EENtNtB9_5array13ArrayDecoding12into_uint_be
Unexecuted instantiation: _RNvXsB_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB3b_2B0EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EENtNtB9_5array13ArrayDecoding12into_uint_be
44
45
0
                fn into_uint_le(self) -> Self::Output {
46
0
                    Self::Output::from_le_byte_array(self)
47
0
                }
Unexecuted instantiation: _RNvXs_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1y_IB1y_IB1y_NtB1A_5UTermNtNtB1C_3bit2B1ENtB2B_2B0EB2P_EB2P_EENtNtB8_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXs1_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB2H_2B0EB2V_EB2V_EB2V_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXs3_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2F_ENtB2H_2B0EB30_EB30_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXs5_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB2M_2B0EB30_EB30_EB30_EB30_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXs7_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2K_ENtB2M_2B0EB35_EB35_EB35_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXs9_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2K_EB2K_ENtB2M_2B0EB3a_EB3a_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsb_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB2R_2B0EB35_EB35_EB35_EB35_EB35_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsd_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB2R_2B0EB35_EB2P_EB35_EB35_EB35_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsf_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2P_ENtB2R_2B0EB3a_EB3a_EB3a_EB3a_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsh_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2P_ENtB2R_2B0EB2P_EB3a_EB3a_EB3a_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsj_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2P_EB2P_ENtB2R_2B0EB3f_EB3f_EB3f_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsl_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB2W_2B0EB3a_EB3a_EB3a_EB3a_EB3a_EB3a_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsn_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2U_ENtB2W_2B0EB3f_EB3f_EB3f_EB3f_EB3f_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsp_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2U_EB2U_ENtB2W_2B0EB3k_EB3k_EB3k_EB3k_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsr_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB31_2B0EB3f_EB3f_EB3f_EB3f_EB3f_EB3f_EB3f_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXst_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2Z_ENtB31_2B0EB3k_EB3k_EB3k_EB3k_EB3k_EB3k_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsv_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB2Z_EB2Z_ENtB31_2B0EB3p_EB3p_EB3p_EB3p_EB3p_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsx_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB36_2B0EB3k_EB3k_EB3k_EB3k_EB3k_EB3k_EB3k_EB3k_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsz_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1EB34_ENtB36_2B0EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EENtNtB9_5array13ArrayDecoding12into_uint_le
Unexecuted instantiation: _RNvXsB_NtNtCshRehcWQJ0wE_13crypto_bigint4uint5arrayINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_IB1z_NtB1B_5UTermNtNtB1D_3bit2B1ENtB3b_2B0EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EB3p_EENtNtB9_5array13ArrayDecoding12into_uint_le
48
            }
49
        )+
50
     };
51
}
52
53
// TODO(tarcieri): use `generic_const_exprs` when stable to make generic around bits.
54
impl_uint_array_encoding! {
55
    (U64, typenum::U8),
56
    (U128, typenum::U16),
57
    (U192, typenum::U24),
58
    (U256, typenum::U32),
59
    (U384, typenum::U48),
60
    (U448, typenum::U56),
61
    (U512, typenum::U64),
62
    (U576, typenum::U72),
63
    (U768, typenum::U96),
64
    (U832, typenum::U104),
65
    (U896, typenum::U112),
66
    (U1024, typenum::U128),
67
    (U1536, typenum::U192),
68
    (U1792, typenum::U224),
69
    (U2048, typenum::U256),
70
    (U3072, typenum::U384),
71
    (U3584, typenum::U448),
72
    (U4096, typenum::U512),
73
    (U6144, typenum::U768),
74
    (U8192, typenum::U1024)
75
}
76
77
#[cfg(target_pointer_width = "32")]
78
impl_uint_array_encoding! {
79
    (U224, typenum::U28), // For NIST P-224
80
    (U544, typenum::U68)  // For NIST P-521
81
}
82
83
#[cfg(test)]
84
mod tests {
85
    use crate::{ArrayDecoding, ArrayEncoding, Limb};
86
    use hex_literal::hex;
87
88
    #[cfg(target_pointer_width = "32")]
89
    use crate::U64 as UintEx;
90
91
    #[cfg(target_pointer_width = "64")]
92
    use crate::U128 as UintEx;
93
94
    /// Byte array that corresponds to `UintEx`
95
    type ByteArray = crate::ByteArray<UintEx>;
96
97
    #[test]
98
    #[cfg(target_pointer_width = "32")]
99
    fn from_be_byte_array() {
100
        let n = UintEx::from_be_byte_array(hex!("0011223344556677").into());
101
        assert_eq!(n.as_limbs(), &[Limb(0x44556677), Limb(0x00112233)]);
102
    }
103
104
    #[test]
105
    #[cfg(target_pointer_width = "64")]
106
    fn from_be_byte_array() {
107
        let n = UintEx::from_be_byte_array(hex!("00112233445566778899aabbccddeeff").into());
108
        assert_eq!(
109
            n.as_limbs(),
110
            &[Limb(0x8899aabbccddeeff), Limb(0x0011223344556677)]
111
        );
112
    }
113
114
    #[test]
115
    #[cfg(target_pointer_width = "32")]
116
    fn from_le_byte_array() {
117
        let n = UintEx::from_le_byte_array(hex!("7766554433221100").into());
118
        assert_eq!(n.as_limbs(), &[Limb(0x44556677), Limb(0x00112233)]);
119
    }
120
121
    #[test]
122
    #[cfg(target_pointer_width = "64")]
123
    fn from_le_byte_array() {
124
        let n = UintEx::from_le_byte_array(hex!("ffeeddccbbaa99887766554433221100").into());
125
        assert_eq!(
126
            n.as_limbs(),
127
            &[Limb(0x8899aabbccddeeff), Limb(0x0011223344556677)]
128
        );
129
    }
130
131
    #[test]
132
    #[cfg(target_pointer_width = "32")]
133
    fn to_be_byte_array() {
134
        let expected_bytes = ByteArray::from(hex!("0011223344556677"));
135
        let actual_bytes = UintEx::from_be_byte_array(expected_bytes).to_be_byte_array();
136
        assert_eq!(expected_bytes, actual_bytes);
137
    }
138
139
    #[test]
140
    #[cfg(target_pointer_width = "64")]
141
    fn to_be_byte_array() {
142
        let expected_bytes = ByteArray::from(hex!("00112233445566778899aabbccddeeff"));
143
        let actual_bytes = UintEx::from_be_byte_array(expected_bytes).to_be_byte_array();
144
        assert_eq!(expected_bytes, actual_bytes);
145
    }
146
147
    #[test]
148
    #[cfg(target_pointer_width = "32")]
149
    fn to_le_byte_array() {
150
        let expected_bytes = ByteArray::from(hex!("7766554433221100"));
151
        let actual_bytes = UintEx::from_le_byte_array(expected_bytes).to_le_byte_array();
152
        assert_eq!(expected_bytes, actual_bytes);
153
    }
154
155
    #[test]
156
    #[cfg(target_pointer_width = "64")]
157
    fn to_le_byte_array() {
158
        let expected_bytes = ByteArray::from(hex!("ffeeddccbbaa99887766554433221100"));
159
        let actual_bytes = UintEx::from_le_byte_array(expected_bytes).to_le_byte_array();
160
        assert_eq!(expected_bytes, actual_bytes);
161
    }
162
163
    #[test]
164
    #[cfg(target_pointer_width = "32")]
165
    fn into_uint_be() {
166
        let expected_bytes = ByteArray::from(hex!("0011223344556677"));
167
        let actual_bytes = expected_bytes.into_uint_be().to_be_byte_array();
168
        assert_eq!(expected_bytes, actual_bytes);
169
    }
170
171
    #[test]
172
    #[cfg(target_pointer_width = "64")]
173
    fn into_uint_be() {
174
        let expected_bytes = ByteArray::from(hex!("00112233445566778899aabbccddeeff"));
175
        let actual_bytes = expected_bytes.into_uint_be().to_be_byte_array();
176
        assert_eq!(expected_bytes, actual_bytes);
177
    }
178
179
    #[test]
180
    #[cfg(target_pointer_width = "32")]
181
    fn into_uint_le() {
182
        let expected_bytes = ByteArray::from(hex!("7766554433221100"));
183
        let actual_bytes = expected_bytes.into_uint_le().to_le_byte_array();
184
        assert_eq!(expected_bytes, actual_bytes);
185
    }
186
187
    #[test]
188
    #[cfg(target_pointer_width = "64")]
189
    fn into_uint_le() {
190
        let expected_bytes = ByteArray::from(hex!("ffeeddccbbaa99887766554433221100"));
191
        let actual_bytes = expected_bytes.into_uint_le().to_le_byte_array();
192
        assert_eq!(expected_bytes, actual_bytes);
193
    }
194
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/bit_and.rs
Line
Count
Source
1
//! [`Uint`] bitwise and operations.
2
3
use super::Uint;
4
use crate::{Limb, Wrapping};
5
use core::ops::{BitAnd, BitAndAssign};
6
use subtle::{Choice, CtOption};
7
8
impl<const LIMBS: usize> Uint<LIMBS> {
9
    /// Computes bitwise `a & b`.
10
    #[inline(always)]
11
981k
    pub const fn bitand(&self, rhs: &Self) -> Self {
12
981k
        let mut limbs = [Limb::ZERO; LIMBS];
13
981k
        let mut i = 0;
14
15
4.90M
        while i < LIMBS {
16
3.92M
            limbs[i] = self.limbs[i].bitand(rhs.limbs[i]);
17
3.92M
            i += 1;
18
3.92M
        }
19
20
981k
        Self { limbs }
21
981k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint7bit_andINtB4_4UintKpE6bitandB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint7bit_andINtB4_4UintKj4_E6bitandCsjewTDwKBbyD_4k256
Line
Count
Source
11
386k
    pub const fn bitand(&self, rhs: &Self) -> Self {
12
386k
        let mut limbs = [Limb::ZERO; LIMBS];
13
386k
        let mut i = 0;
14
15
1.93M
        while i < LIMBS {
16
1.54M
            limbs[i] = self.limbs[i].bitand(rhs.limbs[i]);
17
1.54M
            i += 1;
18
1.54M
        }
19
20
386k
        Self { limbs }
21
386k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint7bit_andINtB4_4UintKj4_E6bitandCsaHRNXv1Y9Bq_4p256
Line
Count
Source
11
594k
    pub const fn bitand(&self, rhs: &Self) -> Self {
12
594k
        let mut limbs = [Limb::ZERO; LIMBS];
13
594k
        let mut i = 0;
14
15
2.97M
        while i < LIMBS {
16
2.37M
            limbs[i] = self.limbs[i].bitand(rhs.limbs[i]);
17
2.37M
            i += 1;
18
2.37M
        }
19
20
594k
        Self { limbs }
21
594k
    }
22
23
    /// Perform wrapping bitwise `AND`.
24
    ///
25
    /// There's no way wrapping could ever happen.
26
    /// This function exists so that all operations are accounted for in the wrapping operations
27
0
    pub const fn wrapping_and(&self, rhs: &Self) -> Self {
28
0
        self.bitand(rhs)
29
0
    }
30
31
    /// Perform checked bitwise `AND`, returning a [`CtOption`] which `is_some` always
32
0
    pub fn checked_and(&self, rhs: &Self) -> CtOption<Self> {
33
0
        let result = self.bitand(rhs);
34
0
        CtOption::new(result, Choice::from(1))
35
0
    }
36
}
37
38
impl<const LIMBS: usize> BitAnd for Uint<LIMBS> {
39
    type Output = Self;
40
41
0
    fn bitand(self, rhs: Self) -> Uint<LIMBS> {
42
0
        self.bitand(&rhs)
43
0
    }
44
}
45
46
impl<const LIMBS: usize> BitAnd<&Uint<LIMBS>> for Uint<LIMBS> {
47
    type Output = Uint<LIMBS>;
48
49
    #[allow(clippy::needless_borrow)]
50
0
    fn bitand(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
51
0
        (&self).bitand(rhs)
52
0
    }
53
}
54
55
impl<const LIMBS: usize> BitAnd<Uint<LIMBS>> for &Uint<LIMBS> {
56
    type Output = Uint<LIMBS>;
57
58
0
    fn bitand(self, rhs: Uint<LIMBS>) -> Uint<LIMBS> {
59
0
        self.bitand(&rhs)
60
0
    }
61
}
62
63
impl<const LIMBS: usize> BitAnd<&Uint<LIMBS>> for &Uint<LIMBS> {
64
    type Output = Uint<LIMBS>;
65
66
0
    fn bitand(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
67
0
        self.bitand(rhs)
68
0
    }
69
}
70
71
impl<const LIMBS: usize> BitAndAssign for Uint<LIMBS> {
72
    #[allow(clippy::assign_op_pattern)]
73
0
    fn bitand_assign(&mut self, other: Self) {
74
0
        *self = *self & other;
75
0
    }
76
}
77
78
impl<const LIMBS: usize> BitAndAssign<&Uint<LIMBS>> for Uint<LIMBS> {
79
    #[allow(clippy::assign_op_pattern)]
80
0
    fn bitand_assign(&mut self, other: &Self) {
81
0
        *self = *self & other;
82
0
    }
83
}
84
85
impl<const LIMBS: usize> BitAnd for Wrapping<Uint<LIMBS>> {
86
    type Output = Self;
87
88
0
    fn bitand(self, rhs: Self) -> Wrapping<Uint<LIMBS>> {
89
0
        Wrapping(self.0.bitand(&rhs.0))
90
0
    }
91
}
92
93
impl<const LIMBS: usize> BitAnd<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
94
    type Output = Wrapping<Uint<LIMBS>>;
95
96
0
    fn bitand(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
97
0
        Wrapping(self.0.bitand(&rhs.0))
98
0
    }
99
}
100
101
impl<const LIMBS: usize> BitAnd<Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
102
    type Output = Wrapping<Uint<LIMBS>>;
103
104
0
    fn bitand(self, rhs: Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
105
0
        Wrapping(self.0.bitand(&rhs.0))
106
0
    }
107
}
108
109
impl<const LIMBS: usize> BitAnd<&Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
110
    type Output = Wrapping<Uint<LIMBS>>;
111
112
0
    fn bitand(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
113
0
        Wrapping(self.0.bitand(&rhs.0))
114
0
    }
115
}
116
117
impl<const LIMBS: usize> BitAndAssign for Wrapping<Uint<LIMBS>> {
118
    #[allow(clippy::assign_op_pattern)]
119
0
    fn bitand_assign(&mut self, other: Self) {
120
0
        *self = *self & other;
121
0
    }
122
}
123
124
impl<const LIMBS: usize> BitAndAssign<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
125
    #[allow(clippy::assign_op_pattern)]
126
0
    fn bitand_assign(&mut self, other: &Self) {
127
0
        *self = *self & other;
128
0
    }
129
}
130
131
#[cfg(test)]
132
mod tests {
133
    use crate::U128;
134
135
    #[test]
136
    fn checked_and_ok() {
137
        let result = U128::ZERO.checked_and(&U128::ONE);
138
        assert_eq!(result.unwrap(), U128::ZERO);
139
    }
140
141
    #[test]
142
    fn overlapping_and_ok() {
143
        let result = U128::MAX.wrapping_and(&U128::ONE);
144
        assert_eq!(result, U128::ONE);
145
    }
146
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/bit_not.rs
Line
Count
Source
1
//! [`Uint`] bitwise not operations.
2
3
use super::Uint;
4
use crate::{Limb, Wrapping};
5
use core::ops::Not;
6
7
impl<const LIMBS: usize> Uint<LIMBS> {
8
    /// Computes bitwise `!a`.
9
    #[inline(always)]
10
0
    pub const fn not(&self) -> Self {
11
0
        let mut limbs = [Limb::ZERO; LIMBS];
12
0
        let mut i = 0;
13
14
0
        while i < LIMBS {
15
0
            limbs[i] = self.limbs[i].not();
16
0
            i += 1;
17
0
        }
18
19
0
        Self { limbs }
20
0
    }
21
}
22
23
impl<const LIMBS: usize> Not for Uint<LIMBS> {
24
    type Output = Self;
25
26
    #[allow(clippy::needless_borrow)]
27
0
    fn not(self) -> <Self as Not>::Output {
28
0
        (&self).not()
29
0
    }
30
}
31
32
impl<const LIMBS: usize> Not for Wrapping<Uint<LIMBS>> {
33
    type Output = Self;
34
35
0
    fn not(self) -> <Self as Not>::Output {
36
0
        Wrapping(self.0.not())
37
0
    }
38
}
39
40
#[cfg(test)]
41
mod tests {
42
    use crate::U128;
43
44
    #[test]
45
    fn bitnot_ok() {
46
        assert_eq!(U128::ZERO.not(), U128::MAX);
47
        assert_eq!(U128::MAX.not(), U128::ZERO);
48
    }
49
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/bit_or.rs
Line
Count
Source
1
//! [`Uint`] bitwise or operations.
2
3
use super::Uint;
4
use crate::{Limb, Wrapping};
5
use core::ops::{BitOr, BitOrAssign};
6
use subtle::{Choice, CtOption};
7
8
impl<const LIMBS: usize> Uint<LIMBS> {
9
    /// Computes bitwise `a & b`.
10
    #[inline(always)]
11
0
    pub const fn bitor(&self, rhs: &Self) -> Self {
12
0
        let mut limbs = [Limb::ZERO; LIMBS];
13
0
        let mut i = 0;
14
15
0
        while i < LIMBS {
16
0
            limbs[i] = self.limbs[i].bitor(rhs.limbs[i]);
17
0
            i += 1;
18
0
        }
19
20
0
        Self { limbs }
21
0
    }
22
23
    /// Perform wrapping bitwise `OR`.
24
    ///
25
    /// There's no way wrapping could ever happen.
26
    /// This function exists so that all operations are accounted for in the wrapping operations
27
0
    pub const fn wrapping_or(&self, rhs: &Self) -> Self {
28
0
        self.bitor(rhs)
29
0
    }
30
31
    /// Perform checked bitwise `OR`, returning a [`CtOption`] which `is_some` always
32
0
    pub fn checked_or(&self, rhs: &Self) -> CtOption<Self> {
33
0
        let result = self.bitor(rhs);
34
0
        CtOption::new(result, Choice::from(1))
35
0
    }
36
}
37
38
impl<const LIMBS: usize> BitOr for Uint<LIMBS> {
39
    type Output = Self;
40
41
0
    fn bitor(self, rhs: Self) -> Uint<LIMBS> {
42
0
        self.bitor(&rhs)
43
0
    }
44
}
45
46
impl<const LIMBS: usize> BitOr<&Uint<LIMBS>> for Uint<LIMBS> {
47
    type Output = Uint<LIMBS>;
48
49
    #[allow(clippy::needless_borrow)]
50
0
    fn bitor(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
51
0
        (&self).bitor(rhs)
52
0
    }
53
}
54
55
impl<const LIMBS: usize> BitOr<Uint<LIMBS>> for &Uint<LIMBS> {
56
    type Output = Uint<LIMBS>;
57
58
0
    fn bitor(self, rhs: Uint<LIMBS>) -> Uint<LIMBS> {
59
0
        self.bitor(&rhs)
60
0
    }
61
}
62
63
impl<const LIMBS: usize> BitOr<&Uint<LIMBS>> for &Uint<LIMBS> {
64
    type Output = Uint<LIMBS>;
65
66
0
    fn bitor(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
67
0
        self.bitor(rhs)
68
0
    }
69
}
70
71
impl<const LIMBS: usize> BitOrAssign for Uint<LIMBS> {
72
0
    fn bitor_assign(&mut self, other: Self) {
73
0
        *self = *self | other;
74
0
    }
75
}
76
77
impl<const LIMBS: usize> BitOrAssign<&Uint<LIMBS>> for Uint<LIMBS> {
78
0
    fn bitor_assign(&mut self, other: &Self) {
79
0
        *self = *self | other;
80
0
    }
81
}
82
83
impl<const LIMBS: usize> BitOr for Wrapping<Uint<LIMBS>> {
84
    type Output = Self;
85
86
0
    fn bitor(self, rhs: Self) -> Wrapping<Uint<LIMBS>> {
87
0
        Wrapping(self.0.bitor(&rhs.0))
88
0
    }
89
}
90
91
impl<const LIMBS: usize> BitOr<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
92
    type Output = Wrapping<Uint<LIMBS>>;
93
94
0
    fn bitor(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
95
0
        Wrapping(self.0.bitor(&rhs.0))
96
0
    }
97
}
98
99
impl<const LIMBS: usize> BitOr<Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
100
    type Output = Wrapping<Uint<LIMBS>>;
101
102
0
    fn bitor(self, rhs: Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
103
0
        Wrapping(self.0.bitor(&rhs.0))
104
0
    }
105
}
106
107
impl<const LIMBS: usize> BitOr<&Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
108
    type Output = Wrapping<Uint<LIMBS>>;
109
110
0
    fn bitor(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
111
0
        Wrapping(self.0.bitor(&rhs.0))
112
0
    }
113
}
114
115
impl<const LIMBS: usize> BitOrAssign for Wrapping<Uint<LIMBS>> {
116
0
    fn bitor_assign(&mut self, other: Self) {
117
0
        *self = *self | other;
118
0
    }
119
}
120
121
impl<const LIMBS: usize> BitOrAssign<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
122
0
    fn bitor_assign(&mut self, other: &Self) {
123
0
        *self = *self | other;
124
0
    }
125
}
126
127
#[cfg(test)]
128
mod tests {
129
    use crate::U128;
130
131
    #[test]
132
    fn checked_or_ok() {
133
        let result = U128::ZERO.checked_or(&U128::ONE);
134
        assert_eq!(result.unwrap(), U128::ONE);
135
    }
136
137
    #[test]
138
    fn overlapping_or_ok() {
139
        let result = U128::MAX.wrapping_or(&U128::ONE);
140
        assert_eq!(result, U128::MAX);
141
    }
142
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/bit_xor.rs
Line
Count
Source
1
//! [`Uint`] bitwise xor operations.
2
3
use super::Uint;
4
use crate::{Limb, Wrapping};
5
use core::ops::{BitXor, BitXorAssign};
6
use subtle::{Choice, CtOption};
7
8
impl<const LIMBS: usize> Uint<LIMBS> {
9
    /// Computes bitwise `a ^ b`.
10
    #[inline(always)]
11
0
    pub const fn bitxor(&self, rhs: &Self) -> Self {
12
0
        let mut limbs = [Limb::ZERO; LIMBS];
13
0
        let mut i = 0;
14
15
0
        while i < LIMBS {
16
0
            limbs[i] = self.limbs[i].bitxor(rhs.limbs[i]);
17
0
            i += 1;
18
0
        }
19
20
0
        Self { limbs }
21
0
    }
22
23
    /// Perform wrapping bitwise `XOR``.
24
    ///
25
    /// There's no way wrapping could ever happen.
26
    /// This function exists so that all operations are accounted for in the wrapping operations
27
0
    pub const fn wrapping_xor(&self, rhs: &Self) -> Self {
28
0
        self.bitxor(rhs)
29
0
    }
30
31
    /// Perform checked bitwise `XOR`, returning a [`CtOption`] which `is_some` always
32
0
    pub fn checked_xor(&self, rhs: &Self) -> CtOption<Self> {
33
0
        let result = self.bitxor(rhs);
34
0
        CtOption::new(result, Choice::from(1))
35
0
    }
36
}
37
38
impl<const LIMBS: usize> BitXor for Uint<LIMBS> {
39
    type Output = Self;
40
41
0
    fn bitxor(self, rhs: Self) -> Uint<LIMBS> {
42
0
        self.bitxor(&rhs)
43
0
    }
44
}
45
46
impl<const LIMBS: usize> BitXor<&Uint<LIMBS>> for Uint<LIMBS> {
47
    type Output = Uint<LIMBS>;
48
49
    #[allow(clippy::needless_borrow)]
50
0
    fn bitxor(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
51
0
        (&self).bitxor(rhs)
52
0
    }
53
}
54
55
impl<const LIMBS: usize> BitXor<Uint<LIMBS>> for &Uint<LIMBS> {
56
    type Output = Uint<LIMBS>;
57
58
0
    fn bitxor(self, rhs: Uint<LIMBS>) -> Uint<LIMBS> {
59
0
        self.bitxor(&rhs)
60
0
    }
61
}
62
63
impl<const LIMBS: usize> BitXor<&Uint<LIMBS>> for &Uint<LIMBS> {
64
    type Output = Uint<LIMBS>;
65
66
0
    fn bitxor(self, rhs: &Uint<LIMBS>) -> Uint<LIMBS> {
67
0
        self.bitxor(rhs)
68
0
    }
69
}
70
71
impl<const LIMBS: usize> BitXorAssign for Uint<LIMBS> {
72
0
    fn bitxor_assign(&mut self, other: Self) {
73
0
        *self = *self ^ other;
74
0
    }
75
}
76
77
impl<const LIMBS: usize> BitXorAssign<&Uint<LIMBS>> for Uint<LIMBS> {
78
0
    fn bitxor_assign(&mut self, other: &Self) {
79
0
        *self = *self ^ other;
80
0
    }
81
}
82
83
impl<const LIMBS: usize> BitXor for Wrapping<Uint<LIMBS>> {
84
    type Output = Self;
85
86
0
    fn bitxor(self, rhs: Self) -> Wrapping<Uint<LIMBS>> {
87
0
        Wrapping(self.0.bitxor(&rhs.0))
88
0
    }
89
}
90
91
impl<const LIMBS: usize> BitXor<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
92
    type Output = Wrapping<Uint<LIMBS>>;
93
94
0
    fn bitxor(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
95
0
        Wrapping(self.0.bitxor(&rhs.0))
96
0
    }
97
}
98
99
impl<const LIMBS: usize> BitXor<Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
100
    type Output = Wrapping<Uint<LIMBS>>;
101
102
0
    fn bitxor(self, rhs: Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
103
0
        Wrapping(self.0.bitxor(&rhs.0))
104
0
    }
105
}
106
107
impl<const LIMBS: usize> BitXor<&Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
108
    type Output = Wrapping<Uint<LIMBS>>;
109
110
0
    fn bitxor(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
111
0
        Wrapping(self.0.bitxor(&rhs.0))
112
0
    }
113
}
114
115
impl<const LIMBS: usize> BitXorAssign for Wrapping<Uint<LIMBS>> {
116
0
    fn bitxor_assign(&mut self, other: Self) {
117
0
        *self = *self ^ other;
118
0
    }
119
}
120
121
impl<const LIMBS: usize> BitXorAssign<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
122
0
    fn bitxor_assign(&mut self, other: &Self) {
123
0
        *self = *self ^ other;
124
0
    }
125
}
126
127
#[cfg(test)]
128
mod tests {
129
    use crate::U128;
130
131
    #[test]
132
    fn checked_xor_ok() {
133
        let result = U128::ZERO.checked_xor(&U128::ONE);
134
        assert_eq!(result.unwrap(), U128::ONE);
135
    }
136
137
    #[test]
138
    fn overlapping_xor_ok() {
139
        let result = U128::ZERO.wrapping_xor(&U128::ONE);
140
        assert_eq!(result, U128::ONE);
141
    }
142
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/bits.rs
Line
Count
Source
1
use crate::{CtChoice, Limb, Uint, Word};
2
3
impl<const LIMBS: usize> Uint<LIMBS> {
4
    /// Returns `true` if the bit at position `index` is set, `false` otherwise.
5
    ///
6
    /// # Remarks
7
    /// This operation is variable time with respect to `index` only.
8
    #[inline(always)]
9
0
    pub const fn bit_vartime(&self, index: usize) -> bool {
10
0
        if index >= Self::BITS {
11
0
            false
12
        } else {
13
0
            (self.limbs[index / Limb::BITS].0 >> (index % Limb::BITS)) & 1 == 1
14
        }
15
0
    }
16
17
    /// Calculate the number of bits needed to represent this number.
18
0
    pub const fn bits_vartime(&self) -> usize {
19
0
        let mut i = LIMBS - 1;
20
0
        while i > 0 && self.limbs[i].0 == 0 {
21
0
            i -= 1;
22
0
        }
23
24
0
        let limb = self.limbs[i];
25
0
        Limb::BITS * (i + 1) - limb.leading_zeros()
26
0
    }
27
28
    /// Calculate the number of leading zeros in the binary representation of this number.
29
0
    pub const fn leading_zeros(&self) -> usize {
30
0
        let limbs = self.as_limbs();
31
0
32
0
        let mut count: Word = 0;
33
0
        let mut i = LIMBS;
34
0
        let mut nonzero_limb_not_encountered = CtChoice::TRUE;
35
0
        while i > 0 {
36
0
            i -= 1;
37
0
            let l = limbs[i];
38
0
            let z = l.leading_zeros() as Word;
39
0
            count += nonzero_limb_not_encountered.if_true(z);
40
0
            nonzero_limb_not_encountered =
41
0
                nonzero_limb_not_encountered.and(l.ct_is_nonzero().not());
42
0
        }
43
44
0
        count as usize
45
0
    }
46
47
    /// Calculate the number of leading zeros in the binary representation of this number,
48
    /// variable time in `self`.
49
0
    pub const fn leading_zeros_vartime(&self) -> usize {
50
0
        let limbs = self.as_limbs();
51
0
52
0
        let mut count = 0;
53
0
        let mut i = LIMBS;
54
0
        while i > 0 {
55
0
            i -= 1;
56
0
            let l = limbs[i];
57
0
            let z = l.leading_zeros();
58
0
            count += z;
59
0
            if z != Limb::BITS {
60
0
                break;
61
0
            }
62
        }
63
64
0
        count
65
0
    }
66
67
    /// Calculate the number of trailing zeros in the binary representation of this number.
68
0
    pub const fn trailing_zeros(&self) -> usize {
69
0
        let limbs = self.as_limbs();
70
0
71
0
        let mut count: Word = 0;
72
0
        let mut i = 0;
73
0
        let mut nonzero_limb_not_encountered = CtChoice::TRUE;
74
0
        while i < LIMBS {
75
0
            let l = limbs[i];
76
0
            let z = l.trailing_zeros() as Word;
77
0
            count += nonzero_limb_not_encountered.if_true(z);
78
0
            nonzero_limb_not_encountered =
79
0
                nonzero_limb_not_encountered.and(l.ct_is_nonzero().not());
80
0
            i += 1;
81
0
        }
82
83
0
        count as usize
84
0
    }
85
86
    /// Calculate the number of trailing zeros in the binary representation of this number,
87
    /// variable time in `self`.
88
0
    pub const fn trailing_zeros_vartime(&self) -> usize {
89
0
        let limbs = self.as_limbs();
90
0
91
0
        let mut count = 0;
92
0
        let mut i = 0;
93
0
        while i < LIMBS {
94
0
            let l = limbs[i];
95
0
            let z = l.trailing_zeros();
96
0
            count += z;
97
0
            if z != Limb::BITS {
98
0
                break;
99
0
            }
100
0
            i += 1;
101
        }
102
103
0
        count
104
0
    }
105
106
    /// Calculate the number of trailing ones in the binary representation of this number.
107
0
    pub const fn trailing_ones(&self) -> usize {
108
0
        let limbs = self.as_limbs();
109
0
110
0
        let mut count: Word = 0;
111
0
        let mut i = 0;
112
0
        let mut nonmax_limb_not_encountered = CtChoice::TRUE;
113
0
        while i < LIMBS {
114
0
            let l = limbs[i];
115
0
            let z = l.trailing_ones() as Word;
116
0
            count += nonmax_limb_not_encountered.if_true(z);
117
0
            nonmax_limb_not_encountered =
118
0
                nonmax_limb_not_encountered.and(Limb::ct_eq(l, Limb::MAX));
119
0
            i += 1;
120
0
        }
121
122
0
        count as usize
123
0
    }
124
125
    /// Calculate the number of trailing ones in the binary representation of this number,
126
    /// variable time in `self`.
127
0
    pub const fn trailing_ones_vartime(&self) -> usize {
128
0
        let limbs = self.as_limbs();
129
0
130
0
        let mut count = 0;
131
0
        let mut i = 0;
132
0
        while i < LIMBS {
133
0
            let l = limbs[i];
134
0
            let z = l.trailing_ones();
135
0
            count += z;
136
0
            if z != Limb::BITS {
137
0
                break;
138
0
            }
139
0
            i += 1;
140
        }
141
142
0
        count
143
0
    }
144
145
    /// Calculate the number of bits needed to represent this number.
146
0
    pub const fn bits(&self) -> usize {
147
0
        Self::BITS - self.leading_zeros()
148
0
    }
149
150
    /// Get the value of the bit at position `index`, as a truthy or falsy `CtChoice`.
151
    /// Returns the falsy value for indices out of range.
152
0
    pub const fn bit(&self, index: usize) -> CtChoice {
153
0
        let limb_num = index / Limb::BITS;
154
0
        let index_in_limb = index % Limb::BITS;
155
0
        let index_mask = 1 << index_in_limb;
156
0
157
0
        let limbs = self.as_words();
158
0
159
0
        let mut result: Word = 0;
160
0
        let mut i = 0;
161
0
        while i < LIMBS {
162
0
            let bit = limbs[i] & index_mask;
163
0
            let is_right_limb = CtChoice::from_usize_equality(i, limb_num);
164
0
            result |= is_right_limb.if_true(bit);
165
0
            i += 1;
166
0
        }
167
168
0
        CtChoice::from_lsb(result >> index_in_limb)
169
0
    }
170
171
    /// Sets the bit at `index` to 0 or 1 depending on the value of `bit_value`.
172
0
    pub(crate) const fn set_bit(self, index: usize, bit_value: CtChoice) -> Self {
173
0
        let mut result = self;
174
0
        let limb_num = index / Limb::BITS;
175
0
        let index_in_limb = index % Limb::BITS;
176
0
        let index_mask = 1 << index_in_limb;
177
0
178
0
        let mut i = 0;
179
0
        while i < LIMBS {
180
0
            let is_right_limb = CtChoice::from_usize_equality(i, limb_num);
181
0
            let old_limb = result.limbs[i].0;
182
0
            let new_limb = bit_value.select(old_limb & !index_mask, old_limb | index_mask);
183
0
            result.limbs[i] = Limb(is_right_limb.select(old_limb, new_limb));
184
0
            i += 1;
185
0
        }
186
0
        result
187
0
    }
188
}
189
190
#[cfg(test)]
191
mod tests {
192
    use crate::{CtChoice, U256};
193
194
    fn uint_with_bits_at(positions: &[usize]) -> U256 {
195
        let mut result = U256::ZERO;
196
        for pos in positions {
197
            result |= U256::ONE << *pos;
198
        }
199
        result
200
    }
201
202
    #[test]
203
    fn bit_vartime() {
204
        let u = uint_with_bits_at(&[16, 48, 112, 127, 255]);
205
        assert!(!u.bit_vartime(0));
206
        assert!(!u.bit_vartime(1));
207
        assert!(u.bit_vartime(16));
208
        assert!(u.bit_vartime(127));
209
        assert!(u.bit_vartime(255));
210
        assert!(!u.bit_vartime(256));
211
        assert!(!u.bit_vartime(260));
212
    }
213
214
    #[test]
215
    fn bit() {
216
        let u = uint_with_bits_at(&[16, 48, 112, 127, 255]);
217
        assert!(!u.bit(0).is_true_vartime());
218
        assert!(!u.bit(1).is_true_vartime());
219
        assert!(u.bit(16).is_true_vartime());
220
        assert!(u.bit(127).is_true_vartime());
221
        assert!(u.bit(255).is_true_vartime());
222
        assert!(!u.bit(256).is_true_vartime());
223
        assert!(!u.bit(260).is_true_vartime());
224
    }
225
226
    #[test]
227
    fn leading_zeros() {
228
        let u = uint_with_bits_at(&[256 - 16, 256 - 79, 256 - 207]);
229
        assert_eq!(u.leading_zeros(), 15);
230
231
        let u = uint_with_bits_at(&[256 - 79, 256 - 207]);
232
        assert_eq!(u.leading_zeros(), 78);
233
234
        let u = uint_with_bits_at(&[256 - 207]);
235
        assert_eq!(u.leading_zeros(), 206);
236
237
        let u = uint_with_bits_at(&[256 - 1, 256 - 75, 256 - 150]);
238
        assert_eq!(u.leading_zeros(), 0);
239
240
        let u = U256::ZERO;
241
        assert_eq!(u.leading_zeros(), 256);
242
    }
243
244
    #[test]
245
    fn leading_zeros_vartime() {
246
        let u = uint_with_bits_at(&[256 - 16, 256 - 79, 256 - 207]);
247
        assert_eq!(u.leading_zeros_vartime(), 15);
248
249
        let u = uint_with_bits_at(&[256 - 79, 256 - 207]);
250
        assert_eq!(u.leading_zeros_vartime(), 78);
251
252
        let u = uint_with_bits_at(&[256 - 207]);
253
        assert_eq!(u.leading_zeros_vartime(), 206);
254
255
        let u = uint_with_bits_at(&[256 - 1, 256 - 75, 256 - 150]);
256
        assert_eq!(u.leading_zeros_vartime(), 0);
257
258
        let u = U256::ZERO;
259
        assert_eq!(u.leading_zeros_vartime(), 256);
260
    }
261
262
    #[test]
263
    fn trailing_zeros() {
264
        let u = uint_with_bits_at(&[16, 79, 150]);
265
        assert_eq!(u.trailing_zeros(), 16);
266
267
        let u = uint_with_bits_at(&[79, 150]);
268
        assert_eq!(u.trailing_zeros(), 79);
269
270
        let u = uint_with_bits_at(&[150, 207]);
271
        assert_eq!(u.trailing_zeros(), 150);
272
273
        let u = uint_with_bits_at(&[0, 150, 207]);
274
        assert_eq!(u.trailing_zeros(), 0);
275
276
        let u = U256::ZERO;
277
        assert_eq!(u.trailing_zeros(), 256);
278
    }
279
280
    #[test]
281
    fn trailing_zeros_vartime() {
282
        let u = uint_with_bits_at(&[16, 79, 150]);
283
        assert_eq!(u.trailing_zeros_vartime(), 16);
284
285
        let u = uint_with_bits_at(&[79, 150]);
286
        assert_eq!(u.trailing_zeros_vartime(), 79);
287
288
        let u = uint_with_bits_at(&[150, 207]);
289
        assert_eq!(u.trailing_zeros_vartime(), 150);
290
291
        let u = uint_with_bits_at(&[0, 150, 207]);
292
        assert_eq!(u.trailing_zeros_vartime(), 0);
293
294
        let u = U256::ZERO;
295
        assert_eq!(u.trailing_zeros_vartime(), 256);
296
    }
297
298
    #[test]
299
    fn trailing_ones() {
300
        let u = !uint_with_bits_at(&[16, 79, 150]);
301
        assert_eq!(u.trailing_ones(), 16);
302
303
        let u = !uint_with_bits_at(&[79, 150]);
304
        assert_eq!(u.trailing_ones(), 79);
305
306
        let u = !uint_with_bits_at(&[150, 207]);
307
        assert_eq!(u.trailing_ones(), 150);
308
309
        let u = !uint_with_bits_at(&[0, 150, 207]);
310
        assert_eq!(u.trailing_ones(), 0);
311
312
        let u = U256::MAX;
313
        assert_eq!(u.trailing_ones(), 256);
314
    }
315
316
    #[test]
317
    fn trailing_ones_vartime() {
318
        let u = !uint_with_bits_at(&[16, 79, 150]);
319
        assert_eq!(u.trailing_ones_vartime(), 16);
320
321
        let u = !uint_with_bits_at(&[79, 150]);
322
        assert_eq!(u.trailing_ones_vartime(), 79);
323
324
        let u = !uint_with_bits_at(&[150, 207]);
325
        assert_eq!(u.trailing_ones_vartime(), 150);
326
327
        let u = !uint_with_bits_at(&[0, 150, 207]);
328
        assert_eq!(u.trailing_ones_vartime(), 0);
329
330
        let u = U256::MAX;
331
        assert_eq!(u.trailing_ones_vartime(), 256);
332
    }
333
334
    #[test]
335
    fn set_bit() {
336
        let u = uint_with_bits_at(&[16, 79, 150]);
337
        assert_eq!(
338
            u.set_bit(127, CtChoice::TRUE),
339
            uint_with_bits_at(&[16, 79, 127, 150])
340
        );
341
342
        let u = uint_with_bits_at(&[16, 79, 150]);
343
        assert_eq!(
344
            u.set_bit(150, CtChoice::TRUE),
345
            uint_with_bits_at(&[16, 79, 150])
346
        );
347
348
        let u = uint_with_bits_at(&[16, 79, 150]);
349
        assert_eq!(
350
            u.set_bit(127, CtChoice::FALSE),
351
            uint_with_bits_at(&[16, 79, 150])
352
        );
353
354
        let u = uint_with_bits_at(&[16, 79, 150]);
355
        assert_eq!(
356
            u.set_bit(150, CtChoice::FALSE),
357
            uint_with_bits_at(&[16, 79])
358
        );
359
    }
360
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/cmp.rs
Line
Count
Source
1
//! [`Uint`] comparisons.
2
//!
3
//! By default these are all constant-time and use the `subtle` crate.
4
5
use super::Uint;
6
use crate::{CtChoice, Limb};
7
use core::cmp::Ordering;
8
use subtle::{Choice, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess};
9
10
impl<const LIMBS: usize> Uint<LIMBS> {
11
    /// Return `b` if `c` is truthy, otherwise return `a`.
12
    #[inline]
13
0
    pub(crate) const fn ct_select(a: &Self, b: &Self, c: CtChoice) -> Self {
14
0
        let mut limbs = [Limb::ZERO; LIMBS];
15
0
16
0
        let mut i = 0;
17
0
        while i < LIMBS {
18
0
            limbs[i] = Limb::ct_select(a.limbs[i], b.limbs[i], c);
19
0
            i += 1;
20
0
        }
21
22
0
        Uint { limbs }
23
0
    }
24
25
    #[inline]
26
0
    pub(crate) const fn ct_swap(a: &Self, b: &Self, c: CtChoice) -> (Self, Self) {
27
0
        let new_a = Self::ct_select(a, b, c);
28
0
        let new_b = Self::ct_select(b, a, c);
29
0
30
0
        (new_a, new_b)
31
0
    }
32
33
    /// Returns the truthy value if `self`!=0 or the falsy value otherwise.
34
    #[inline]
35
2.09k
    pub(crate) const fn ct_is_nonzero(&self) -> CtChoice {
36
2.09k
        let mut b = 0;
37
2.09k
        let mut i = 0;
38
10.4k
        while i < LIMBS {
39
8.36k
            b |= self.limbs[i].0;
40
8.36k
            i += 1;
41
8.36k
        }
42
2.09k
        Limb(b).ct_is_nonzero()
43
2.09k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKpE13ct_is_nonzeroB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E13ct_is_nonzeroCsjewTDwKBbyD_4k256
Line
Count
Source
35
2.09k
    pub(crate) const fn ct_is_nonzero(&self) -> CtChoice {
36
2.09k
        let mut b = 0;
37
2.09k
        let mut i = 0;
38
10.4k
        while i < LIMBS {
39
8.36k
            b |= self.limbs[i].0;
40
8.36k
            i += 1;
41
8.36k
        }
42
2.09k
        Limb(b).ct_is_nonzero()
43
2.09k
    }
44
45
    /// Returns the truthy value if `self` is odd or the falsy value otherwise.
46
0
    pub(crate) const fn ct_is_odd(&self) -> CtChoice {
47
0
        CtChoice::from_lsb(self.limbs[0].0 & 1)
48
0
    }
49
50
    /// Returns the truthy value if `self == rhs` or the falsy value otherwise.
51
    #[inline]
52
815k
    pub(crate) const fn ct_eq(lhs: &Self, rhs: &Self) -> CtChoice {
53
815k
        let mut acc = 0;
54
815k
        let mut i = 0;
55
56
4.07M
        while i < LIMBS {
57
3.26M
            acc |= lhs.limbs[i].0 ^ rhs.limbs[i].0;
58
3.26M
            i += 1;
59
3.26M
        }
60
61
        // acc == 0 if and only if self == rhs
62
815k
        Limb(acc).ct_is_nonzero().not()
63
815k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E5ct_eqCs4RkbDk9WRL5_5clvmr
Line
Count
Source
52
2.77k
    pub(crate) const fn ct_eq(lhs: &Self, rhs: &Self) -> CtChoice {
53
2.77k
        let mut acc = 0;
54
2.77k
        let mut i = 0;
55
56
13.8k
        while i < LIMBS {
57
11.1k
            acc |= lhs.limbs[i].0 ^ rhs.limbs[i].0;
58
11.1k
            i += 1;
59
11.1k
        }
60
61
        // acc == 0 if and only if self == rhs
62
2.77k
        Limb(acc).ct_is_nonzero().not()
63
2.77k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKpE5ct_eqB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E5ct_eqCsjewTDwKBbyD_4k256
Line
Count
Source
52
98.8k
    pub(crate) const fn ct_eq(lhs: &Self, rhs: &Self) -> CtChoice {
53
98.8k
        let mut acc = 0;
54
98.8k
        let mut i = 0;
55
56
494k
        while i < LIMBS {
57
395k
            acc |= lhs.limbs[i].0 ^ rhs.limbs[i].0;
58
395k
            i += 1;
59
395k
        }
60
61
        // acc == 0 if and only if self == rhs
62
98.8k
        Limb(acc).ct_is_nonzero().not()
63
98.8k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E5ct_eqCsaHRNXv1Y9Bq_4p256
Line
Count
Source
52
714k
    pub(crate) const fn ct_eq(lhs: &Self, rhs: &Self) -> CtChoice {
53
714k
        let mut acc = 0;
54
714k
        let mut i = 0;
55
56
3.57M
        while i < LIMBS {
57
2.85M
            acc |= lhs.limbs[i].0 ^ rhs.limbs[i].0;
58
2.85M
            i += 1;
59
2.85M
        }
60
61
        // acc == 0 if and only if self == rhs
62
714k
        Limb(acc).ct_is_nonzero().not()
63
714k
    }
64
65
    /// Returns the truthy value if `self <= rhs` and the falsy value otherwise.
66
    #[inline]
67
4.57k
    pub(crate) const fn ct_lt(lhs: &Self, rhs: &Self) -> CtChoice {
68
4.57k
        // We could use the same approach as in Limb::ct_lt(),
69
4.57k
        // but since we have to use Uint::wrapping_sub(), which calls `sbb()`,
70
4.57k
        // there are no savings compared to just calling `sbb()` directly.
71
4.57k
        let (_res, borrow) = lhs.sbb(rhs, Limb::ZERO);
72
4.57k
        CtChoice::from_mask(borrow.0)
73
4.57k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E5ct_ltCs4RkbDk9WRL5_5clvmr
Line
Count
Source
67
2.84k
    pub(crate) const fn ct_lt(lhs: &Self, rhs: &Self) -> CtChoice {
68
2.84k
        // We could use the same approach as in Limb::ct_lt(),
69
2.84k
        // but since we have to use Uint::wrapping_sub(), which calls `sbb()`,
70
2.84k
        // there are no savings compared to just calling `sbb()` directly.
71
2.84k
        let (_res, borrow) = lhs.sbb(rhs, Limb::ZERO);
72
2.84k
        CtChoice::from_mask(borrow.0)
73
2.84k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKpE5ct_ltB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E5ct_ltCsjewTDwKBbyD_4k256
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E5ct_ltCsaHRNXv1Y9Bq_4p256
Line
Count
Source
67
1.72k
    pub(crate) const fn ct_lt(lhs: &Self, rhs: &Self) -> CtChoice {
68
1.72k
        // We could use the same approach as in Limb::ct_lt(),
69
1.72k
        // but since we have to use Uint::wrapping_sub(), which calls `sbb()`,
70
1.72k
        // there are no savings compared to just calling `sbb()` directly.
71
1.72k
        let (_res, borrow) = lhs.sbb(rhs, Limb::ZERO);
72
1.72k
        CtChoice::from_mask(borrow.0)
73
1.72k
    }
74
75
    /// Returns the truthy value if `self >= rhs` and the falsy value otherwise.
76
    #[inline]
77
2.64k
    pub(crate) const fn ct_gt(lhs: &Self, rhs: &Self) -> CtChoice {
78
2.64k
        let (_res, borrow) = rhs.sbb(lhs, Limb::ZERO);
79
2.64k
        CtChoice::from_mask(borrow.0)
80
2.64k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E5ct_gtCs4RkbDk9WRL5_5clvmr
Line
Count
Source
77
14
    pub(crate) const fn ct_gt(lhs: &Self, rhs: &Self) -> CtChoice {
78
14
        let (_res, borrow) = rhs.sbb(lhs, Limb::ZERO);
79
14
        CtChoice::from_mask(borrow.0)
80
14
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKpE5ct_gtB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E5ct_gtCsjewTDwKBbyD_4k256
Line
Count
Source
77
2.62k
    pub(crate) const fn ct_gt(lhs: &Self, rhs: &Self) -> CtChoice {
78
2.62k
        let (_res, borrow) = rhs.sbb(lhs, Limb::ZERO);
79
2.62k
        CtChoice::from_mask(borrow.0)
80
2.62k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E5ct_gtCsaHRNXv1Y9Bq_4p256
81
82
    /// Returns the ordering between `self` and `rhs` as an i8.
83
    /// Values correspond to the Ordering enum:
84
    ///   -1 is Less
85
    ///   0 is Equal
86
    ///   1 is Greater
87
    #[inline]
88
247k
    pub(crate) const fn ct_cmp(lhs: &Self, rhs: &Self) -> i8 {
89
247k
        let mut i = 0;
90
247k
        let mut borrow = Limb::ZERO;
91
247k
        let mut diff = Limb::ZERO;
92
93
1.23M
        while i < LIMBS {
94
991k
            let (w, b) = rhs.limbs[i].sbb(lhs.limbs[i], borrow);
95
991k
            diff = diff.bitor(w);
96
991k
            borrow = b;
97
991k
            i += 1;
98
991k
        }
99
247k
        let sgn = ((borrow.0 & 2) as i8) - 1;
100
247k
        (diff.ct_is_nonzero().to_u8() as i8) * sgn
101
247k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKpE6ct_cmpB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E6ct_cmpCsjewTDwKBbyD_4k256
Line
Count
Source
88
93.5k
    pub(crate) const fn ct_cmp(lhs: &Self, rhs: &Self) -> i8 {
89
93.5k
        let mut i = 0;
90
93.5k
        let mut borrow = Limb::ZERO;
91
93.5k
        let mut diff = Limb::ZERO;
92
93
467k
        while i < LIMBS {
94
374k
            let (w, b) = rhs.limbs[i].sbb(lhs.limbs[i], borrow);
95
374k
            diff = diff.bitor(w);
96
374k
            borrow = b;
97
374k
            i += 1;
98
374k
        }
99
93.5k
        let sgn = ((borrow.0 & 2) as i8) - 1;
100
93.5k
        (diff.ct_is_nonzero().to_u8() as i8) * sgn
101
93.5k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB4_4UintKj4_E6ct_cmpCsaHRNXv1Y9Bq_4p256
Line
Count
Source
88
154k
    pub(crate) const fn ct_cmp(lhs: &Self, rhs: &Self) -> i8 {
89
154k
        let mut i = 0;
90
154k
        let mut borrow = Limb::ZERO;
91
154k
        let mut diff = Limb::ZERO;
92
93
771k
        while i < LIMBS {
94
617k
            let (w, b) = rhs.limbs[i].sbb(lhs.limbs[i], borrow);
95
617k
            diff = diff.bitor(w);
96
617k
            borrow = b;
97
617k
            i += 1;
98
617k
        }
99
154k
        let sgn = ((borrow.0 & 2) as i8) - 1;
100
154k
        (diff.ct_is_nonzero().to_u8() as i8) * sgn
101
154k
    }
102
103
    /// Returns the Ordering between `self` and `rhs` in variable time.
104
0
    pub const fn cmp_vartime(&self, rhs: &Self) -> Ordering {
105
0
        let mut i = LIMBS - 1;
106
        loop {
107
0
            let (val, borrow) = self.limbs[i].sbb(rhs.limbs[i], Limb::ZERO);
108
0
            if val.0 != 0 {
109
0
                return if borrow.0 != 0 {
110
0
                    Ordering::Less
111
                } else {
112
0
                    Ordering::Greater
113
                };
114
0
            }
115
0
            if i == 0 {
116
0
                return Ordering::Equal;
117
0
            }
118
0
            i -= 1;
119
        }
120
0
    }
121
}
122
123
impl<const LIMBS: usize> ConstantTimeEq for Uint<LIMBS> {
124
    #[inline]
125
815k
    fn ct_eq(&self, other: &Self) -> Choice {
126
815k
        Uint::ct_eq(self, other).into()
127
815k
    }
_RNvXs_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB6_4UintKj4_ENtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_eqCs4RkbDk9WRL5_5clvmr
Line
Count
Source
125
2.77k
    fn ct_eq(&self, other: &Self) -> Choice {
126
2.77k
        Uint::ct_eq(self, other).into()
127
2.77k
    }
Unexecuted instantiation: _RNvXININtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmps_0KpEINtB7_4UintKpENtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_eqB9_
_RNvXs_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB6_4UintKj4_ENtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_eqCsjewTDwKBbyD_4k256
Line
Count
Source
125
98.8k
    fn ct_eq(&self, other: &Self) -> Choice {
126
98.8k
        Uint::ct_eq(self, other).into()
127
98.8k
    }
_RNvXs_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB6_4UintKj4_ENtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_eqCsaHRNXv1Y9Bq_4p256
Line
Count
Source
125
714k
    fn ct_eq(&self, other: &Self) -> Choice {
126
714k
        Uint::ct_eq(self, other).into()
127
714k
    }
128
}
129
130
impl<const LIMBS: usize> ConstantTimeGreater for Uint<LIMBS> {
131
    #[inline]
132
2.64k
    fn ct_gt(&self, other: &Self) -> Choice {
133
2.64k
        Uint::ct_gt(self, other).into()
134
2.64k
    }
_RNvXs0_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB7_4UintKj4_ENtCs3v1T4Vw6hEJ_6subtle19ConstantTimeGreater5ct_gtCs4RkbDk9WRL5_5clvmr
Line
Count
Source
132
14
    fn ct_gt(&self, other: &Self) -> Choice {
133
14
        Uint::ct_gt(self, other).into()
134
14
    }
Unexecuted instantiation: _RNvXININtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmps0_0KpEINtB7_4UintKpENtCs3v1T4Vw6hEJ_6subtle19ConstantTimeGreater5ct_gtB9_
_RNvXs0_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB7_4UintKj4_ENtCs3v1T4Vw6hEJ_6subtle19ConstantTimeGreater5ct_gtCsjewTDwKBbyD_4k256
Line
Count
Source
132
2.62k
    fn ct_gt(&self, other: &Self) -> Choice {
133
2.62k
        Uint::ct_gt(self, other).into()
134
2.62k
    }
Unexecuted instantiation: _RNvXs0_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB7_4UintKj4_ENtCs3v1T4Vw6hEJ_6subtle19ConstantTimeGreater5ct_gtCsaHRNXv1Y9Bq_4p256
135
}
136
137
impl<const LIMBS: usize> ConstantTimeLess for Uint<LIMBS> {
138
    #[inline]
139
4.57k
    fn ct_lt(&self, other: &Self) -> Choice {
140
4.57k
        Uint::ct_lt(self, other).into()
141
4.57k
    }
_RNvXs1_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB7_4UintKj4_ENtCs3v1T4Vw6hEJ_6subtle16ConstantTimeLess5ct_ltCs4RkbDk9WRL5_5clvmr
Line
Count
Source
139
2.84k
    fn ct_lt(&self, other: &Self) -> Choice {
140
2.84k
        Uint::ct_lt(self, other).into()
141
2.84k
    }
Unexecuted instantiation: _RNvXININtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmps1_0KpEINtB7_4UintKpENtCs3v1T4Vw6hEJ_6subtle16ConstantTimeLess5ct_ltB9_
Unexecuted instantiation: _RNvXs1_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB7_4UintKj4_ENtCs3v1T4Vw6hEJ_6subtle16ConstantTimeLess5ct_ltCsjewTDwKBbyD_4k256
_RNvXs1_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB7_4UintKj4_ENtCs3v1T4Vw6hEJ_6subtle16ConstantTimeLess5ct_ltCsaHRNXv1Y9Bq_4p256
Line
Count
Source
139
1.72k
    fn ct_lt(&self, other: &Self) -> Choice {
140
1.72k
        Uint::ct_lt(self, other).into()
141
1.72k
    }
142
}
143
144
impl<const LIMBS: usize> Eq for Uint<LIMBS> {}
145
146
impl<const LIMBS: usize> Ord for Uint<LIMBS> {
147
247k
    fn cmp(&self, other: &Self) -> Ordering {
148
247k
        let c = Self::ct_cmp(self, other);
149
247k
        match c {
150
124k
            -1 => Ordering::Less,
151
1.36k
            0 => Ordering::Equal,
152
122k
            _ => Ordering::Greater,
153
        }
154
247k
    }
Unexecuted instantiation: _RNvXININtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmps3_0KpEINtB7_4UintKpENtNtCsbQ8arDwx5Xq_4core3cmp3Ord3cmpB9_
_RNvXs3_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB7_4UintKj4_ENtNtCsbQ8arDwx5Xq_4core3cmp3Ord3cmpCsjewTDwKBbyD_4k256
Line
Count
Source
147
93.5k
    fn cmp(&self, other: &Self) -> Ordering {
148
93.5k
        let c = Self::ct_cmp(self, other);
149
93.5k
        match c {
150
44.0k
            -1 => Ordering::Less,
151
523
            0 => Ordering::Equal,
152
49.0k
            _ => Ordering::Greater,
153
        }
154
93.5k
    }
_RNvXs3_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB7_4UintKj4_ENtNtCsbQ8arDwx5Xq_4core3cmp3Ord3cmpCsaHRNXv1Y9Bq_4p256
Line
Count
Source
147
154k
    fn cmp(&self, other: &Self) -> Ordering {
148
154k
        let c = Self::ct_cmp(self, other);
149
154k
        match c {
150
80.1k
            -1 => Ordering::Less,
151
838
            0 => Ordering::Equal,
152
73.2k
            _ => Ordering::Greater,
153
        }
154
154k
    }
155
}
156
157
impl<const LIMBS: usize> PartialOrd for Uint<LIMBS> {
158
93.5k
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
159
93.5k
        Some(self.cmp(other))
160
93.5k
    }
Unexecuted instantiation: _RNvXININtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmps4_0KpEINtB7_4UintKpENtNtCsbQ8arDwx5Xq_4core3cmp10PartialOrd11partial_cmpB9_
_RNvXs4_NtNtCshRehcWQJ0wE_13crypto_bigint4uint3cmpINtB7_4UintKj4_ENtNtCsbQ8arDwx5Xq_4core3cmp10PartialOrd11partial_cmpCsjewTDwKBbyD_4k256
Line
Count
Source
158
93.5k
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
159
93.5k
        Some(self.cmp(other))
160
93.5k
    }
161
}
162
163
impl<const LIMBS: usize> PartialEq for Uint<LIMBS> {
164
0
    fn eq(&self, other: &Self) -> bool {
165
0
        self.ct_eq(other).into()
166
0
    }
167
}
168
169
#[cfg(test)]
170
mod tests {
171
    use crate::{Integer, Zero, U128};
172
    use core::cmp::Ordering;
173
    use subtle::{ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess};
174
175
    #[test]
176
    fn is_zero() {
177
        assert!(bool::from(U128::ZERO.is_zero()));
178
        assert!(!bool::from(U128::ONE.is_zero()));
179
        assert!(!bool::from(U128::MAX.is_zero()));
180
    }
181
182
    #[test]
183
    fn is_odd() {
184
        assert!(!bool::from(U128::ZERO.is_odd()));
185
        assert!(bool::from(U128::ONE.is_odd()));
186
        assert!(bool::from(U128::MAX.is_odd()));
187
    }
188
189
    #[test]
190
    fn ct_eq() {
191
        let a = U128::ZERO;
192
        let b = U128::MAX;
193
194
        assert!(bool::from(a.ct_eq(&a)));
195
        assert!(!bool::from(a.ct_eq(&b)));
196
        assert!(!bool::from(b.ct_eq(&a)));
197
        assert!(bool::from(b.ct_eq(&b)));
198
    }
199
200
    #[test]
201
    fn ct_gt() {
202
        let a = U128::ZERO;
203
        let b = U128::ONE;
204
        let c = U128::MAX;
205
206
        assert!(bool::from(b.ct_gt(&a)));
207
        assert!(bool::from(c.ct_gt(&a)));
208
        assert!(bool::from(c.ct_gt(&b)));
209
210
        assert!(!bool::from(a.ct_gt(&a)));
211
        assert!(!bool::from(b.ct_gt(&b)));
212
        assert!(!bool::from(c.ct_gt(&c)));
213
214
        assert!(!bool::from(a.ct_gt(&b)));
215
        assert!(!bool::from(a.ct_gt(&c)));
216
        assert!(!bool::from(b.ct_gt(&c)));
217
    }
218
219
    #[test]
220
    fn ct_lt() {
221
        let a = U128::ZERO;
222
        let b = U128::ONE;
223
        let c = U128::MAX;
224
225
        assert!(bool::from(a.ct_lt(&b)));
226
        assert!(bool::from(a.ct_lt(&c)));
227
        assert!(bool::from(b.ct_lt(&c)));
228
229
        assert!(!bool::from(a.ct_lt(&a)));
230
        assert!(!bool::from(b.ct_lt(&b)));
231
        assert!(!bool::from(c.ct_lt(&c)));
232
233
        assert!(!bool::from(b.ct_lt(&a)));
234
        assert!(!bool::from(c.ct_lt(&a)));
235
        assert!(!bool::from(c.ct_lt(&b)));
236
    }
237
238
    #[test]
239
    fn cmp() {
240
        let a = U128::ZERO;
241
        let b = U128::ONE;
242
        let c = U128::MAX;
243
244
        assert_eq!(a.cmp(&b), Ordering::Less);
245
        assert_eq!(a.cmp(&c), Ordering::Less);
246
        assert_eq!(b.cmp(&c), Ordering::Less);
247
248
        assert_eq!(a.cmp(&a), Ordering::Equal);
249
        assert_eq!(b.cmp(&b), Ordering::Equal);
250
        assert_eq!(c.cmp(&c), Ordering::Equal);
251
252
        assert_eq!(b.cmp(&a), Ordering::Greater);
253
        assert_eq!(c.cmp(&a), Ordering::Greater);
254
        assert_eq!(c.cmp(&b), Ordering::Greater);
255
    }
256
257
    #[test]
258
    fn cmp_vartime() {
259
        let a = U128::ZERO;
260
        let b = U128::ONE;
261
        let c = U128::MAX;
262
263
        assert_eq!(a.cmp_vartime(&b), Ordering::Less);
264
        assert_eq!(a.cmp_vartime(&c), Ordering::Less);
265
        assert_eq!(b.cmp_vartime(&c), Ordering::Less);
266
267
        assert_eq!(a.cmp_vartime(&a), Ordering::Equal);
268
        assert_eq!(b.cmp_vartime(&b), Ordering::Equal);
269
        assert_eq!(c.cmp_vartime(&c), Ordering::Equal);
270
271
        assert_eq!(b.cmp_vartime(&a), Ordering::Greater);
272
        assert_eq!(c.cmp_vartime(&a), Ordering::Greater);
273
        assert_eq!(c.cmp_vartime(&b), Ordering::Greater);
274
    }
275
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/concat.rs
Line
Count
Source
1
use crate::{Concat, ConcatMixed, Limb, Uint};
2
3
impl<T> Concat for T
4
where
5
    T: ConcatMixed<T>,
6
{
7
    type Output = Self::MixedOutput;
8
}
9
10
/// Concatenate the two values, with `lo` as least significant and `hi`
11
/// as the most significant.
12
#[inline]
13
0
pub(crate) const fn concat_mixed<const L: usize, const H: usize, const O: usize>(
14
0
    lo: &Uint<L>,
15
0
    hi: &Uint<H>,
16
0
) -> Uint<O> {
17
0
    let top = L + H;
18
0
    let top = if top < O { top } else { O };
19
0
    let mut limbs = [Limb::ZERO; O];
20
0
    let mut i = 0;
21
22
0
    while i < top {
23
0
        if i < L {
24
0
            limbs[i] = lo.limbs[i];
25
0
        } else {
26
0
            limbs[i] = hi.limbs[i - L];
27
0
        }
28
0
        i += 1;
29
    }
30
31
0
    Uint { limbs }
32
0
}
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj10_KB10_Kj20_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj18_KB10_Kj30_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_KB10_Kj2_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kj2_Kj3_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kj3_Kj4_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kj4_Kj5_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kj5_Kj6_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kj6_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kj7_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kj8_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kj9_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kja_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kjb_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kjc_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kjd_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kje_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1_Kjf_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj1c_KB10_Kj38_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj20_KB10_Kj40_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj21_KB10_Kj42_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj22_KB10_Kj44_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_KB10_Kj4_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kj1_Kj3_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kj3_Kj5_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kj4_Kj6_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kj5_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kj6_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kj7_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kj8_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kj9_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kja_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kjb_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kjc_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kjd_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj2_Kje_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj30_KB10_Kj60_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_KB10_Kj6_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kj1_Kj4_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kj2_Kj5_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kj4_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kj5_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kj6_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kj7_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kj8_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kj9_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kja_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kjb_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kjc_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj3_Kjd_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj40_KB10_Kj80_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_KB10_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_Kj1_Kj5_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_Kj2_Kj6_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_Kj3_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_Kj5_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_Kj6_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_Kj7_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_Kj8_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_Kj9_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_Kja_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_Kjb_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj4_Kjc_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj5_KB10_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj5_Kj1_Kj6_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj5_Kj2_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj5_Kj3_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj5_Kj4_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj5_Kj6_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj5_Kj7_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj5_Kj8_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj5_Kj9_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj5_Kja_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj5_Kjb_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj6_KB10_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj6_Kj1_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj6_Kj2_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj6_Kj3_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj6_Kj4_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj6_Kj5_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj6_Kj7_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj6_Kj8_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj6_Kj9_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj6_Kja_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj7_KB10_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj7_Kj1_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj7_Kj2_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj7_Kj3_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj7_Kj4_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj7_Kj5_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj7_Kj6_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj7_Kj8_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj7_Kj9_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj80_KB10_Kj100_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj8_KB10_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj8_Kj1_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj8_Kj2_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj8_Kj3_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj8_Kj4_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj8_Kj5_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj8_Kj6_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj8_Kj7_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj9_Kj1_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj9_Kj2_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj9_Kj3_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj9_Kj4_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj9_Kj5_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj9_Kj6_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKj9_Kj7_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKja_KB10_Kj14_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKja_Kj1_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKja_Kj2_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKja_Kj3_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKja_Kj4_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKja_Kj5_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKja_Kj6_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjb_Kj1_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjb_Kj2_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjb_Kj3_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjb_Kj4_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjb_Kj5_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjc_KB10_Kj18_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjc_Kj1_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjc_Kj2_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjc_Kj3_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjc_Kj4_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjd_Kj1_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjd_Kj2_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjd_Kj3_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKje_KB10_Kj1c_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKje_Kj1_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKje_Kj2_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint6concat12concat_mixedKjf_Kj1_Kj10_EB6_
33
34
#[cfg(test)]
35
mod tests {
36
    use crate::{ConcatMixed, U128, U192, U64};
37
38
    #[test]
39
    fn concat() {
40
        let hi = U64::from_u64(0x0011223344556677);
41
        let lo = U64::from_u64(0x8899aabbccddeeff);
42
        assert_eq!(
43
            hi.concat(&lo),
44
            U128::from_be_hex("00112233445566778899aabbccddeeff")
45
        );
46
    }
47
48
    #[test]
49
    fn concat_mixed() {
50
        let a = U64::from_u64(0x0011223344556677);
51
        let b = U128::from_u128(0x8899aabbccddeeff_8899aabbccddeeff);
52
        assert_eq!(
53
            a.concat_mixed(&b),
54
            U192::from_be_hex("00112233445566778899aabbccddeeff8899aabbccddeeff")
55
        );
56
        assert_eq!(
57
            b.concat_mixed(&a),
58
            U192::from_be_hex("8899aabbccddeeff8899aabbccddeeff0011223344556677")
59
        );
60
    }
61
62
    #[test]
63
    fn convert() {
64
        let res: U128 = U64::ONE.mul_wide(&U64::ONE).into();
65
        assert_eq!(res, U128::ONE);
66
67
        let res: U128 = U64::ONE.square_wide().into();
68
        assert_eq!(res, U128::ONE);
69
    }
70
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/div.rs
Line
Count
Source
1
//! [`Uint`] division operations.
2
3
use super::div_limb::{div_rem_limb_with_reciprocal, Reciprocal};
4
use crate::{CtChoice, Limb, NonZero, Uint, Word, Wrapping};
5
use core::ops::{Div, DivAssign, Rem, RemAssign};
6
use subtle::CtOption;
7
8
impl<const LIMBS: usize> Uint<LIMBS> {
9
    /// Computes `self` / `rhs` using a pre-made reciprocal,
10
    /// returns the quotient (q) and remainder (r).
11
    #[inline(always)]
12
0
    pub const fn ct_div_rem_limb_with_reciprocal(&self, reciprocal: &Reciprocal) -> (Self, Limb) {
13
0
        div_rem_limb_with_reciprocal(self, reciprocal)
14
0
    }
15
16
    /// Computes `self` / `rhs` using a pre-made reciprocal,
17
    /// returns the quotient (q) and remainder (r).
18
    #[inline(always)]
19
0
    pub fn div_rem_limb_with_reciprocal(
20
0
        &self,
21
0
        reciprocal: &CtOption<Reciprocal>,
22
0
    ) -> CtOption<(Self, Limb)> {
23
0
        reciprocal.map(|r| div_rem_limb_with_reciprocal(self, &r))
24
0
    }
25
26
    /// Computes `self` / `rhs`, returns the quotient (q) and remainder (r).
27
    /// Returns the truthy value as the third element of the tuple if `rhs != 0`,
28
    /// and the falsy value otherwise.
29
    #[inline(always)]
30
0
    pub(crate) const fn ct_div_rem_limb(&self, rhs: Limb) -> (Self, Limb, CtChoice) {
31
0
        let (reciprocal, is_some) = Reciprocal::ct_new(rhs);
32
0
        let (quo, rem) = div_rem_limb_with_reciprocal(self, &reciprocal);
33
0
        (quo, rem, is_some)
34
0
    }
35
36
    /// Computes `self` / `rhs`, returns the quotient (q) and remainder (r).
37
    #[inline(always)]
38
0
    pub fn div_rem_limb(&self, rhs: NonZero<Limb>) -> (Self, Limb) {
39
0
        // Guaranteed to succeed since `rhs` is nonzero.
40
0
        let (quo, rem, _is_some) = self.ct_div_rem_limb(*rhs);
41
0
        (quo, rem)
42
0
    }
43
44
    /// Computes `self` / `rhs`, returns the quotient (q), remainder (r)
45
    /// and the truthy value for is_some or the falsy value for is_none.
46
    ///
47
    /// NOTE: Use only if you need to access const fn. Otherwise use [`Self::div_rem`] because
48
    /// the value for is_some needs to be checked before using `q` and `r`.
49
    ///
50
    /// This is variable only with respect to `rhs`.
51
    ///
52
    /// When used with a fixed `rhs`, this function is constant-time with respect
53
    /// to `self`.
54
0
    pub(crate) const fn ct_div_rem(&self, rhs: &Self) -> (Self, Self, CtChoice) {
55
0
        let mb = rhs.bits_vartime();
56
0
        let mut bd = Self::BITS - mb;
57
0
        let mut rem = *self;
58
0
        let mut quo = Self::ZERO;
59
0
        let mut c = rhs.shl_vartime(bd);
60
61
        loop {
62
0
            let (mut r, borrow) = rem.sbb(&c, Limb::ZERO);
63
0
            rem = Self::ct_select(&r, &rem, CtChoice::from_mask(borrow.0));
64
0
            r = quo.bitor(&Self::ONE);
65
0
            quo = Self::ct_select(&r, &quo, CtChoice::from_mask(borrow.0));
66
0
            if bd == 0 {
67
0
                break;
68
0
            }
69
0
            bd -= 1;
70
0
            c = c.shr_vartime(1);
71
0
            quo = quo.shl_vartime(1);
72
        }
73
74
0
        let is_some = Limb(mb as Word).ct_is_nonzero();
75
0
        quo = Self::ct_select(&Self::ZERO, &quo, is_some);
76
0
        (quo, rem, is_some)
77
0
    }
78
79
    /// Computes `self` % `rhs`, returns the remainder and
80
    /// and the truthy value for is_some or the falsy value for is_none.
81
    ///
82
    /// NOTE: Use only if you need to access const fn. Otherwise use [`Self::rem`].
83
    /// This is variable only with respect to `rhs`.
84
    ///
85
    /// When used with a fixed `rhs`, this function is constant-time with respect
86
    /// to `self`.
87
0
    pub const fn const_rem(&self, rhs: &Self) -> (Self, CtChoice) {
88
0
        let mb = rhs.bits_vartime();
89
0
        let mut bd = Self::BITS - mb;
90
0
        let mut rem = *self;
91
0
        let mut c = rhs.shl_vartime(bd);
92
93
        loop {
94
0
            let (r, borrow) = rem.sbb(&c, Limb::ZERO);
95
0
            rem = Self::ct_select(&r, &rem, CtChoice::from_mask(borrow.0));
96
0
            if bd == 0 {
97
0
                break;
98
0
            }
99
0
            bd -= 1;
100
0
            c = c.shr_vartime(1);
101
        }
102
103
0
        let is_some = Limb(mb as Word).ct_is_nonzero();
104
0
        (rem, is_some)
105
0
    }
106
107
    /// Computes `self` % `rhs`, returns the remainder and
108
    /// and the truthy value for is_some or the falsy value for is_none.
109
    ///
110
    /// This is variable only with respect to `rhs`.
111
    ///
112
    /// When used with a fixed `rhs`, this function is constant-time with respect
113
    /// to `self`.
114
0
    pub const fn const_rem_wide(lower_upper: (Self, Self), rhs: &Self) -> (Self, CtChoice) {
115
0
        let mb = rhs.bits_vartime();
116
0
117
0
        // The number of bits to consider is two sets of limbs * BITS - mb (modulus bitcount)
118
0
        let mut bd = (2 * Self::BITS) - mb;
119
0
120
0
        // The wide integer to reduce, split into two halves
121
0
        let (mut lower, mut upper) = lower_upper;
122
0
123
0
        // Factor of the modulus, split into two halves
124
0
        let mut c = Self::shl_vartime_wide((*rhs, Uint::ZERO), bd);
125
126
        loop {
127
0
            let (lower_sub, borrow) = lower.sbb(&c.0, Limb::ZERO);
128
0
            let (upper_sub, borrow) = upper.sbb(&c.1, borrow);
129
0
130
0
            lower = Self::ct_select(&lower_sub, &lower, CtChoice::from_mask(borrow.0));
131
0
            upper = Self::ct_select(&upper_sub, &upper, CtChoice::from_mask(borrow.0));
132
0
            if bd == 0 {
133
0
                break;
134
0
            }
135
0
            bd -= 1;
136
0
            c = Self::shr_vartime_wide(c, 1);
137
        }
138
139
0
        let is_some = Limb(mb as Word).ct_is_nonzero();
140
0
        (lower, is_some)
141
0
    }
142
143
    /// Computes `self` % 2^k. Faster than reduce since its a power of 2.
144
    /// Limited to 2^16-1 since Uint doesn't support higher.
145
0
    pub const fn rem2k(&self, k: usize) -> Self {
146
0
        let highest = (LIMBS - 1) as u32;
147
0
        let index = k as u32 / (Limb::BITS as u32);
148
0
        let le = Limb::ct_le(Limb::from_u32(index), Limb::from_u32(highest));
149
0
        let word = Limb::ct_select(Limb::from_u32(highest), Limb::from_u32(index), le).0 as usize;
150
0
151
0
        let base = k % Limb::BITS;
152
0
        let mask = (1 << base) - 1;
153
0
        let mut out = *self;
154
0
155
0
        let outmask = Limb(out.limbs[word].0 & mask);
156
0
157
0
        out.limbs[word] = Limb::ct_select(out.limbs[word], outmask, le);
158
0
159
0
        let mut i = word + 1;
160
0
        while i < LIMBS {
161
0
            out.limbs[i] = Limb::ZERO;
162
0
            i += 1;
163
0
        }
164
165
0
        out
166
0
    }
167
168
    /// Computes self / rhs, returns the quotient, remainder.
169
0
    pub fn div_rem(&self, rhs: &NonZero<Self>) -> (Self, Self) {
170
0
        // Since `rhs` is nonzero, this should always hold.
171
0
        let (q, r, _c) = self.ct_div_rem(rhs);
172
0
        (q, r)
173
0
    }
174
175
    /// Computes self % rhs, returns the remainder.
176
0
    pub fn rem(&self, rhs: &NonZero<Self>) -> Self {
177
0
        // Since `rhs` is nonzero, this should always hold.
178
0
        let (r, _c) = self.const_rem(rhs);
179
0
        r
180
0
    }
181
182
    /// Wrapped division is just normal division i.e. `self` / `rhs`
183
    /// There’s no way wrapping could ever happen.
184
    /// This function exists, so that all operations are accounted for in the wrapping operations.
185
    ///
186
    /// Panics if `rhs == 0`.
187
0
    pub const fn wrapping_div(&self, rhs: &Self) -> Self {
188
0
        let (q, _, c) = self.ct_div_rem(rhs);
189
0
        assert!(c.is_true_vartime(), "divide by zero");
190
0
        q
191
0
    }
192
193
    /// Perform checked division, returning a [`CtOption`] which `is_some`
194
    /// only if the rhs != 0
195
0
    pub fn checked_div(&self, rhs: &Self) -> CtOption<Self> {
196
0
        NonZero::new(*rhs).map(|rhs| {
197
0
            let (q, _r) = self.div_rem(&rhs);
198
0
            q
199
0
        })
200
0
    }
201
202
    /// Wrapped (modular) remainder calculation is just `self` % `rhs`.
203
    /// There’s no way wrapping could ever happen.
204
    /// This function exists, so that all operations are accounted for in the wrapping operations.
205
    ///
206
    /// Panics if `rhs == 0`.
207
0
    pub const fn wrapping_rem(&self, rhs: &Self) -> Self {
208
0
        let (r, c) = self.const_rem(rhs);
209
0
        assert!(c.is_true_vartime(), "modulo zero");
210
0
        r
211
0
    }
212
213
    /// Perform checked reduction, returning a [`CtOption`] which `is_some`
214
    /// only if the rhs != 0
215
0
    pub fn checked_rem(&self, rhs: &Self) -> CtOption<Self> {
216
0
        NonZero::new(*rhs).map(|rhs| self.rem(&rhs))
217
0
    }
218
}
219
220
//
221
// Division by a single limb
222
//
223
224
impl<const LIMBS: usize> Div<&NonZero<Limb>> for &Uint<LIMBS> {
225
    type Output = Uint<LIMBS>;
226
227
0
    fn div(self, rhs: &NonZero<Limb>) -> Self::Output {
228
0
        *self / *rhs
229
0
    }
230
}
231
232
impl<const LIMBS: usize> Div<&NonZero<Limb>> for Uint<LIMBS> {
233
    type Output = Uint<LIMBS>;
234
235
0
    fn div(self, rhs: &NonZero<Limb>) -> Self::Output {
236
0
        self / *rhs
237
0
    }
238
}
239
240
impl<const LIMBS: usize> Div<NonZero<Limb>> for &Uint<LIMBS> {
241
    type Output = Uint<LIMBS>;
242
243
0
    fn div(self, rhs: NonZero<Limb>) -> Self::Output {
244
0
        *self / rhs
245
0
    }
246
}
247
248
impl<const LIMBS: usize> Div<NonZero<Limb>> for Uint<LIMBS> {
249
    type Output = Uint<LIMBS>;
250
251
0
    fn div(self, rhs: NonZero<Limb>) -> Self::Output {
252
0
        let (q, _, _) = self.ct_div_rem_limb(*rhs);
253
0
        q
254
0
    }
255
}
256
257
impl<const LIMBS: usize> DivAssign<&NonZero<Limb>> for Uint<LIMBS> {
258
0
    fn div_assign(&mut self, rhs: &NonZero<Limb>) {
259
0
        *self /= *rhs;
260
0
    }
261
}
262
263
impl<const LIMBS: usize> DivAssign<NonZero<Limb>> for Uint<LIMBS> {
264
0
    fn div_assign(&mut self, rhs: NonZero<Limb>) {
265
0
        *self = *self / rhs;
266
0
    }
267
}
268
269
impl<const LIMBS: usize> Div<NonZero<Limb>> for Wrapping<Uint<LIMBS>> {
270
    type Output = Wrapping<Uint<LIMBS>>;
271
272
0
    fn div(self, rhs: NonZero<Limb>) -> Self::Output {
273
0
        Wrapping(self.0 / rhs)
274
0
    }
275
}
276
277
impl<const LIMBS: usize> Div<NonZero<Limb>> for &Wrapping<Uint<LIMBS>> {
278
    type Output = Wrapping<Uint<LIMBS>>;
279
280
0
    fn div(self, rhs: NonZero<Limb>) -> Self::Output {
281
0
        *self / rhs
282
0
    }
283
}
284
285
impl<const LIMBS: usize> Div<&NonZero<Limb>> for &Wrapping<Uint<LIMBS>> {
286
    type Output = Wrapping<Uint<LIMBS>>;
287
288
0
    fn div(self, rhs: &NonZero<Limb>) -> Self::Output {
289
0
        *self / *rhs
290
0
    }
291
}
292
293
impl<const LIMBS: usize> Div<&NonZero<Limb>> for Wrapping<Uint<LIMBS>> {
294
    type Output = Wrapping<Uint<LIMBS>>;
295
296
0
    fn div(self, rhs: &NonZero<Limb>) -> Self::Output {
297
0
        self / *rhs
298
0
    }
299
}
300
301
impl<const LIMBS: usize> DivAssign<&NonZero<Limb>> for Wrapping<Uint<LIMBS>> {
302
0
    fn div_assign(&mut self, rhs: &NonZero<Limb>) {
303
0
        *self = Wrapping(self.0 / rhs)
304
0
    }
305
}
306
307
impl<const LIMBS: usize> DivAssign<NonZero<Limb>> for Wrapping<Uint<LIMBS>> {
308
0
    fn div_assign(&mut self, rhs: NonZero<Limb>) {
309
0
        *self /= &rhs;
310
0
    }
311
}
312
313
impl<const LIMBS: usize> Rem<&NonZero<Limb>> for &Uint<LIMBS> {
314
    type Output = Limb;
315
316
0
    fn rem(self, rhs: &NonZero<Limb>) -> Self::Output {
317
0
        *self % *rhs
318
0
    }
319
}
320
321
impl<const LIMBS: usize> Rem<&NonZero<Limb>> for Uint<LIMBS> {
322
    type Output = Limb;
323
324
0
    fn rem(self, rhs: &NonZero<Limb>) -> Self::Output {
325
0
        self % *rhs
326
0
    }
327
}
328
329
impl<const LIMBS: usize> Rem<NonZero<Limb>> for &Uint<LIMBS> {
330
    type Output = Limb;
331
332
0
    fn rem(self, rhs: NonZero<Limb>) -> Self::Output {
333
0
        *self % rhs
334
0
    }
335
}
336
337
impl<const LIMBS: usize> Rem<NonZero<Limb>> for Uint<LIMBS> {
338
    type Output = Limb;
339
340
0
    fn rem(self, rhs: NonZero<Limb>) -> Self::Output {
341
0
        let (_, r, _) = self.ct_div_rem_limb(*rhs);
342
0
        r
343
0
    }
344
}
345
346
impl<const LIMBS: usize> RemAssign<&NonZero<Limb>> for Uint<LIMBS> {
347
0
    fn rem_assign(&mut self, rhs: &NonZero<Limb>) {
348
0
        *self = (*self % rhs).into();
349
0
    }
350
}
351
352
impl<const LIMBS: usize> RemAssign<NonZero<Limb>> for Uint<LIMBS> {
353
0
    fn rem_assign(&mut self, rhs: NonZero<Limb>) {
354
0
        *self %= &rhs;
355
0
    }
356
}
357
358
impl<const LIMBS: usize> Rem<NonZero<Limb>> for Wrapping<Uint<LIMBS>> {
359
    type Output = Wrapping<Limb>;
360
361
0
    fn rem(self, rhs: NonZero<Limb>) -> Self::Output {
362
0
        Wrapping(self.0 % rhs)
363
0
    }
364
}
365
366
impl<const LIMBS: usize> Rem<NonZero<Limb>> for &Wrapping<Uint<LIMBS>> {
367
    type Output = Wrapping<Limb>;
368
369
0
    fn rem(self, rhs: NonZero<Limb>) -> Self::Output {
370
0
        *self % rhs
371
0
    }
372
}
373
374
impl<const LIMBS: usize> Rem<&NonZero<Limb>> for &Wrapping<Uint<LIMBS>> {
375
    type Output = Wrapping<Limb>;
376
377
0
    fn rem(self, rhs: &NonZero<Limb>) -> Self::Output {
378
0
        *self % *rhs
379
0
    }
380
}
381
382
impl<const LIMBS: usize> Rem<&NonZero<Limb>> for Wrapping<Uint<LIMBS>> {
383
    type Output = Wrapping<Limb>;
384
385
0
    fn rem(self, rhs: &NonZero<Limb>) -> Self::Output {
386
0
        self % *rhs
387
0
    }
388
}
389
390
impl<const LIMBS: usize> RemAssign<NonZero<Limb>> for Wrapping<Uint<LIMBS>> {
391
0
    fn rem_assign(&mut self, rhs: NonZero<Limb>) {
392
0
        *self %= &rhs;
393
0
    }
394
}
395
396
impl<const LIMBS: usize> RemAssign<&NonZero<Limb>> for Wrapping<Uint<LIMBS>> {
397
0
    fn rem_assign(&mut self, rhs: &NonZero<Limb>) {
398
0
        *self = Wrapping((self.0 % rhs).into())
399
0
    }
400
}
401
402
//
403
// Division by an Uint
404
//
405
406
impl<const LIMBS: usize> Div<&NonZero<Uint<LIMBS>>> for &Uint<LIMBS> {
407
    type Output = Uint<LIMBS>;
408
409
0
    fn div(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
410
0
        *self / *rhs
411
0
    }
412
}
413
414
impl<const LIMBS: usize> Div<&NonZero<Uint<LIMBS>>> for Uint<LIMBS> {
415
    type Output = Uint<LIMBS>;
416
417
0
    fn div(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
418
0
        self / *rhs
419
0
    }
420
}
421
422
impl<const LIMBS: usize> Div<NonZero<Uint<LIMBS>>> for &Uint<LIMBS> {
423
    type Output = Uint<LIMBS>;
424
425
0
    fn div(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
426
0
        *self / rhs
427
0
    }
428
}
429
430
impl<const LIMBS: usize> Div<NonZero<Uint<LIMBS>>> for Uint<LIMBS> {
431
    type Output = Uint<LIMBS>;
432
433
0
    fn div(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
434
0
        let (q, _) = self.div_rem(&rhs);
435
0
        q
436
0
    }
437
}
438
439
impl<const LIMBS: usize> DivAssign<&NonZero<Uint<LIMBS>>> for Uint<LIMBS> {
440
0
    fn div_assign(&mut self, rhs: &NonZero<Uint<LIMBS>>) {
441
0
        *self /= *rhs
442
0
    }
443
}
444
445
impl<const LIMBS: usize> DivAssign<NonZero<Uint<LIMBS>>> for Uint<LIMBS> {
446
0
    fn div_assign(&mut self, rhs: NonZero<Uint<LIMBS>>) {
447
0
        *self = *self / rhs;
448
0
    }
449
}
450
451
impl<const LIMBS: usize> Div<NonZero<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
452
    type Output = Wrapping<Uint<LIMBS>>;
453
454
0
    fn div(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
455
0
        Wrapping(self.0 / rhs)
456
0
    }
457
}
458
459
impl<const LIMBS: usize> Div<NonZero<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
460
    type Output = Wrapping<Uint<LIMBS>>;
461
462
0
    fn div(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
463
0
        *self / rhs
464
0
    }
465
}
466
467
impl<const LIMBS: usize> Div<&NonZero<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
468
    type Output = Wrapping<Uint<LIMBS>>;
469
470
0
    fn div(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
471
0
        *self / *rhs
472
0
    }
473
}
474
475
impl<const LIMBS: usize> Div<&NonZero<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
476
    type Output = Wrapping<Uint<LIMBS>>;
477
478
0
    fn div(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
479
0
        self / *rhs
480
0
    }
481
}
482
483
impl<const LIMBS: usize> DivAssign<&NonZero<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
484
0
    fn div_assign(&mut self, rhs: &NonZero<Uint<LIMBS>>) {
485
0
        *self = Wrapping(self.0 / rhs);
486
0
    }
487
}
488
489
impl<const LIMBS: usize> DivAssign<NonZero<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
490
0
    fn div_assign(&mut self, rhs: NonZero<Uint<LIMBS>>) {
491
0
        *self /= &rhs;
492
0
    }
493
}
494
495
impl<const LIMBS: usize> Rem<&NonZero<Uint<LIMBS>>> for &Uint<LIMBS> {
496
    type Output = Uint<LIMBS>;
497
498
0
    fn rem(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
499
0
        *self % *rhs
500
0
    }
501
}
502
503
impl<const LIMBS: usize> Rem<&NonZero<Uint<LIMBS>>> for Uint<LIMBS> {
504
    type Output = Uint<LIMBS>;
505
506
0
    fn rem(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
507
0
        self % *rhs
508
0
    }
509
}
510
511
impl<const LIMBS: usize> Rem<NonZero<Uint<LIMBS>>> for &Uint<LIMBS> {
512
    type Output = Uint<LIMBS>;
513
514
0
    fn rem(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
515
0
        *self % rhs
516
0
    }
517
}
518
519
impl<const LIMBS: usize> Rem<NonZero<Uint<LIMBS>>> for Uint<LIMBS> {
520
    type Output = Uint<LIMBS>;
521
522
0
    fn rem(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
523
0
        Self::rem(&self, &rhs)
524
0
    }
525
}
526
527
impl<const LIMBS: usize> RemAssign<&NonZero<Uint<LIMBS>>> for Uint<LIMBS> {
528
0
    fn rem_assign(&mut self, rhs: &NonZero<Uint<LIMBS>>) {
529
0
        *self %= *rhs
530
0
    }
531
}
532
533
impl<const LIMBS: usize> RemAssign<NonZero<Uint<LIMBS>>> for Uint<LIMBS> {
534
0
    fn rem_assign(&mut self, rhs: NonZero<Uint<LIMBS>>) {
535
0
        *self = *self % rhs;
536
0
    }
537
}
538
539
impl<const LIMBS: usize> Rem<NonZero<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
540
    type Output = Wrapping<Uint<LIMBS>>;
541
542
0
    fn rem(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
543
0
        Wrapping(self.0 % rhs)
544
0
    }
545
}
546
547
impl<const LIMBS: usize> Rem<NonZero<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
548
    type Output = Wrapping<Uint<LIMBS>>;
549
550
0
    fn rem(self, rhs: NonZero<Uint<LIMBS>>) -> Self::Output {
551
0
        *self % rhs
552
0
    }
553
}
554
555
impl<const LIMBS: usize> Rem<&NonZero<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
556
    type Output = Wrapping<Uint<LIMBS>>;
557
558
0
    fn rem(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
559
0
        *self % *rhs
560
0
    }
561
}
562
563
impl<const LIMBS: usize> Rem<&NonZero<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
564
    type Output = Wrapping<Uint<LIMBS>>;
565
566
0
    fn rem(self, rhs: &NonZero<Uint<LIMBS>>) -> Self::Output {
567
0
        self % *rhs
568
0
    }
569
}
570
571
impl<const LIMBS: usize> RemAssign<NonZero<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
572
0
    fn rem_assign(&mut self, rhs: NonZero<Uint<LIMBS>>) {
573
0
        *self %= &rhs;
574
0
    }
575
}
576
577
impl<const LIMBS: usize> RemAssign<&NonZero<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
578
0
    fn rem_assign(&mut self, rhs: &NonZero<Uint<LIMBS>>) {
579
0
        *self = Wrapping(self.0 % rhs)
580
0
    }
581
}
582
583
#[cfg(test)]
584
mod tests {
585
    use super::*;
586
    use crate::{limb::HI_BIT, Limb, U256};
587
588
    #[cfg(feature = "rand")]
589
    use {
590
        crate::{CheckedMul, Random},
591
        rand_chacha::ChaChaRng,
592
        rand_core::RngCore,
593
        rand_core::SeedableRng,
594
    };
595
596
    #[test]
597
    fn div_word() {
598
        for (n, d, e, ee) in &[
599
            (200u64, 2u64, 100u64, 0),
600
            (100u64, 25u64, 4u64, 0),
601
            (100u64, 10u64, 10u64, 0),
602
            (1024u64, 8u64, 128u64, 0),
603
            (27u64, 13u64, 2u64, 1u64),
604
            (26u64, 13u64, 2u64, 0u64),
605
            (14u64, 13u64, 1u64, 1u64),
606
            (13u64, 13u64, 1u64, 0u64),
607
            (12u64, 13u64, 0u64, 12u64),
608
            (1u64, 13u64, 0u64, 1u64),
609
        ] {
610
            let lhs = U256::from(*n);
611
            let rhs = U256::from(*d);
612
            let (q, r, is_some) = lhs.ct_div_rem(&rhs);
613
            assert!(is_some.is_true_vartime());
614
            assert_eq!(U256::from(*e), q);
615
            assert_eq!(U256::from(*ee), r);
616
        }
617
    }
618
619
    #[cfg(feature = "rand")]
620
    #[test]
621
    fn div() {
622
        let mut rng = ChaChaRng::from_seed([7u8; 32]);
623
        for _ in 0..25 {
624
            let num = U256::random(&mut rng).shr_vartime(128);
625
            let den = U256::random(&mut rng).shr_vartime(128);
626
            let n = num.checked_mul(&den);
627
            if n.is_some().into() {
628
                let (q, _, is_some) = n.unwrap().ct_div_rem(&den);
629
                assert!(is_some.is_true_vartime());
630
                assert_eq!(q, num);
631
            }
632
        }
633
    }
634
635
    #[test]
636
    fn div_max() {
637
        let mut a = U256::ZERO;
638
        let mut b = U256::ZERO;
639
        b.limbs[b.limbs.len() - 1] = Limb(Word::MAX);
640
        let q = a.wrapping_div(&b);
641
        assert_eq!(q, Uint::ZERO);
642
        a.limbs[a.limbs.len() - 1] = Limb(1 << (HI_BIT - 7));
643
        b.limbs[b.limbs.len() - 1] = Limb(0x82 << (HI_BIT - 7));
644
        let q = a.wrapping_div(&b);
645
        assert_eq!(q, Uint::ZERO);
646
    }
647
648
    #[test]
649
    fn div_zero() {
650
        let (q, r, is_some) = U256::ONE.ct_div_rem(&U256::ZERO);
651
        assert!(!is_some.is_true_vartime());
652
        assert_eq!(q, U256::ZERO);
653
        assert_eq!(r, U256::ONE);
654
    }
655
656
    #[test]
657
    fn div_one() {
658
        let (q, r, is_some) = U256::from(10u8).ct_div_rem(&U256::ONE);
659
        assert!(is_some.is_true_vartime());
660
        assert_eq!(q, U256::from(10u8));
661
        assert_eq!(r, U256::ZERO);
662
    }
663
664
    #[test]
665
    fn reduce_one() {
666
        let (r, is_some) = U256::from(10u8).const_rem(&U256::ONE);
667
        assert!(is_some.is_true_vartime());
668
        assert_eq!(r, U256::ZERO);
669
    }
670
671
    #[test]
672
    fn reduce_zero() {
673
        let u = U256::from(10u8);
674
        let (r, is_some) = u.const_rem(&U256::ZERO);
675
        assert!(!is_some.is_true_vartime());
676
        assert_eq!(r, u);
677
    }
678
679
    #[test]
680
    fn reduce_tests() {
681
        let (r, is_some) = U256::from(10u8).const_rem(&U256::from(2u8));
682
        assert!(is_some.is_true_vartime());
683
        assert_eq!(r, U256::ZERO);
684
        let (r, is_some) = U256::from(10u8).const_rem(&U256::from(3u8));
685
        assert!(is_some.is_true_vartime());
686
        assert_eq!(r, U256::ONE);
687
        let (r, is_some) = U256::from(10u8).const_rem(&U256::from(7u8));
688
        assert!(is_some.is_true_vartime());
689
        assert_eq!(r, U256::from(3u8));
690
    }
691
692
    #[test]
693
    fn reduce_tests_wide_zero_padded() {
694
        let (r, is_some) = U256::const_rem_wide((U256::from(10u8), U256::ZERO), &U256::from(2u8));
695
        assert!(is_some.is_true_vartime());
696
        assert_eq!(r, U256::ZERO);
697
        let (r, is_some) = U256::const_rem_wide((U256::from(10u8), U256::ZERO), &U256::from(3u8));
698
        assert!(is_some.is_true_vartime());
699
        assert_eq!(r, U256::ONE);
700
        let (r, is_some) = U256::const_rem_wide((U256::from(10u8), U256::ZERO), &U256::from(7u8));
701
        assert!(is_some.is_true_vartime());
702
        assert_eq!(r, U256::from(3u8));
703
    }
704
705
    #[test]
706
    fn reduce_max() {
707
        let mut a = U256::ZERO;
708
        let mut b = U256::ZERO;
709
        b.limbs[b.limbs.len() - 1] = Limb(Word::MAX);
710
        let r = a.wrapping_rem(&b);
711
        assert_eq!(r, Uint::ZERO);
712
        a.limbs[a.limbs.len() - 1] = Limb(1 << (HI_BIT - 7));
713
        b.limbs[b.limbs.len() - 1] = Limb(0x82 << (HI_BIT - 7));
714
        let r = a.wrapping_rem(&b);
715
        assert_eq!(r, a);
716
    }
717
718
    #[cfg(feature = "rand")]
719
    #[test]
720
    fn rem2krand() {
721
        let mut rng = ChaChaRng::from_seed([7u8; 32]);
722
        for _ in 0..25 {
723
            let num = U256::random(&mut rng);
724
            let k = (rng.next_u32() % 256) as usize;
725
            let den = U256::ONE.shl_vartime(k);
726
727
            let a = num.rem2k(k);
728
            let e = num.wrapping_rem(&den);
729
            assert_eq!(a, e);
730
        }
731
    }
732
733
    #[allow(clippy::op_ref)]
734
    #[test]
735
    fn rem_trait() {
736
        let a = U256::from(10u64);
737
        let b = NonZero::new(U256::from(3u64)).unwrap();
738
        let c = U256::from(1u64);
739
740
        assert_eq!(a % b, c);
741
        assert_eq!(a % &b, c);
742
        assert_eq!(&a % b, c);
743
        assert_eq!(&a % &b, c);
744
    }
745
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/div_limb.rs
Line
Count
Source
1
//! Implementation of constant-time division via reciprocal precomputation, as described in
2
//! "Improved Division by Invariant Integers" by Niels Möller and Torbjorn Granlund
3
//! (DOI: 10.1109/TC.2010.143, <https://gmplib.org/~tege/division-paper.pdf>).
4
use subtle::{Choice, ConditionallySelectable, CtOption};
5
6
use crate::{CtChoice, Limb, Uint, WideWord, Word};
7
8
/// Calculates the reciprocal of the given 32-bit divisor with the highmost bit set.
9
#[cfg(target_pointer_width = "32")]
10
pub const fn reciprocal(d: Word) -> Word {
11
    debug_assert!(d >= (1 << (Word::BITS - 1)));
12
13
    let d0 = d & 1;
14
    let d10 = d >> 22;
15
    let d21 = (d >> 11) + 1;
16
    let d31 = (d >> 1) + d0;
17
    let v0 = short_div((1 << 24) - (1 << 14) + (1 << 9), 24, d10, 10);
18
    let (hi, _lo) = mulhilo(v0 * v0, d21);
19
    let v1 = (v0 << 4) - hi - 1;
20
21
    // Checks that the expression for `e` can be simplified in the way we did below.
22
    debug_assert!(mulhilo(v1, d31).0 == (1 << 16) - 1);
23
    let e = Word::MAX - v1.wrapping_mul(d31) + 1 + (v1 >> 1) * d0;
24
25
    let (hi, _lo) = mulhilo(v1, e);
26
    // Note: the paper does not mention a wrapping add here,
27
    // but the 64-bit version has it at this stage, and the function panics without it
28
    // when calculating a reciprocal for `Word::MAX`.
29
    let v2 = (v1 << 15).wrapping_add(hi >> 1);
30
31
    // The paper has `(v2 + 1) * d / 2^32` (there's another 2^32, but it's accounted for later).
32
    // If `v2 == 2^32-1` this should give `d`, but we can't achieve this in our wrapping arithmetic.
33
    // Hence the `ct_select()`.
34
    let x = v2.wrapping_add(1);
35
    let (hi, _lo) = mulhilo(x, d);
36
    let hi = Limb::ct_select(Limb(d), Limb(hi), Limb(x).ct_is_nonzero()).0;
37
38
    v2.wrapping_sub(hi).wrapping_sub(d)
39
}
40
41
/// Calculates the reciprocal of the given 64-bit divisor with the highmost bit set.
42
#[cfg(target_pointer_width = "64")]
43
0
pub const fn reciprocal(d: Word) -> Word {
44
0
    debug_assert!(d >= (1 << (Word::BITS - 1)));
45
46
0
    let d0 = d & 1;
47
0
    let d9 = d >> 55;
48
0
    let d40 = (d >> 24) + 1;
49
0
    let d63 = (d >> 1) + d0;
50
0
    let v0 = short_div((1 << 19) - 3 * (1 << 8), 19, d9 as u32, 9) as u64;
51
0
    let v1 = (v0 << 11) - ((v0 * v0 * d40) >> 40) - 1;
52
0
    let v2 = (v1 << 13) + ((v1 * ((1 << 60) - v1 * d40)) >> 47);
53
0
54
0
    // Checks that the expression for `e` can be simplified in the way we did below.
55
0
    debug_assert!(mulhilo(v2, d63).0 == (1 << 32) - 1);
56
0
    let e = Word::MAX - v2.wrapping_mul(d63) + 1 + (v2 >> 1) * d0;
57
0
58
0
    let (hi, _lo) = mulhilo(v2, e);
59
0
    let v3 = (v2 << 31).wrapping_add(hi >> 1);
60
0
61
0
    // The paper has `(v3 + 1) * d / 2^64` (there's another 2^64, but it's accounted for later).
62
0
    // If `v3 == 2^64-1` this should give `d`, but we can't achieve this in our wrapping arithmetic.
63
0
    // Hence the `ct_select()`.
64
0
    let x = v3.wrapping_add(1);
65
0
    let (hi, _lo) = mulhilo(x, d);
66
0
    let hi = Limb::ct_select(Limb(d), Limb(hi), Limb(x).ct_is_nonzero()).0;
67
0
68
0
    v3.wrapping_sub(hi).wrapping_sub(d)
69
0
}
70
71
/// Returns `u32::MAX` if `a < b` and `0` otherwise.
72
#[inline]
73
0
const fn ct_lt(a: u32, b: u32) -> u32 {
74
0
    let bit = (((!a) & b) | (((!a) | b) & (a.wrapping_sub(b)))) >> (u32::BITS - 1);
75
0
    bit.wrapping_neg()
76
0
}
77
78
/// Returns `a` if `c == 0` and `b` if `c == u32::MAX`.
79
#[inline(always)]
80
0
const fn ct_select(a: u32, b: u32, c: u32) -> u32 {
81
0
    a ^ (c & (a ^ b))
82
0
}
83
84
/// Calculates `dividend / divisor`, given `dividend` and `divisor`
85
/// along with their maximum bitsizes.
86
#[inline(always)]
87
0
const fn short_div(dividend: u32, dividend_bits: u32, divisor: u32, divisor_bits: u32) -> u32 {
88
0
    // TODO: this may be sped up even more using the fact that `dividend` is a known constant.
89
0
90
0
    // In the paper this is a table lookup, but since we want it to be constant-time,
91
0
    // we have to access all the elements of the table, which is quite large.
92
0
    // So this shift-and-subtract approach is actually faster.
93
0
94
0
    // Passing `dividend_bits` and `divisor_bits` because calling `.leading_zeros()`
95
0
    // causes a significant slowdown, and we know those values anyway.
96
0
97
0
    let mut dividend = dividend;
98
0
    let mut divisor = divisor << (dividend_bits - divisor_bits);
99
0
    let mut quotient: u32 = 0;
100
0
    let mut i = dividend_bits - divisor_bits + 1;
101
102
0
    while i > 0 {
103
0
        i -= 1;
104
0
        let bit = ct_lt(dividend, divisor);
105
0
        dividend = ct_select(dividend.wrapping_sub(divisor), dividend, bit);
106
0
        divisor >>= 1;
107
0
        let inv_bit = !bit;
108
0
        quotient |= (inv_bit >> (u32::BITS - 1)) << i;
109
0
    }
110
111
0
    quotient
112
0
}
113
114
/// Multiplies `x` and `y`, returning the most significant
115
/// and the least significant words as `(hi, lo)`.
116
#[inline(always)]
117
0
const fn mulhilo(x: Word, y: Word) -> (Word, Word) {
118
0
    let res = (x as WideWord) * (y as WideWord);
119
0
    ((res >> Word::BITS) as Word, res as Word)
120
0
}
121
122
/// Adds wide numbers represented by pairs of (most significant word, least significant word)
123
/// and returns the result in the same format `(hi, lo)`.
124
#[inline(always)]
125
const fn addhilo(x_hi: Word, x_lo: Word, y_hi: Word, y_lo: Word) -> (Word, Word) {
126
    let res = (((x_hi as WideWord) << Word::BITS) | (x_lo as WideWord))
127
        + (((y_hi as WideWord) << Word::BITS) | (y_lo as WideWord));
128
    ((res >> Word::BITS) as Word, res as Word)
129
}
130
131
/// Calculate the quotient and the remainder of the division of a wide word
132
/// (supplied as high and low words) by `d`, with a precalculated reciprocal `v`.
133
#[inline(always)]
134
const fn div2by1(u1: Word, u0: Word, reciprocal: &Reciprocal) -> (Word, Word) {
135
    let d = reciprocal.divisor_normalized;
136
137
    debug_assert!(d >= (1 << (Word::BITS - 1)));
138
    debug_assert!(u1 < d);
139
140
    let (q1, q0) = mulhilo(reciprocal.reciprocal, u1);
141
    let (q1, q0) = addhilo(q1, q0, u1, u0);
142
    let q1 = q1.wrapping_add(1);
143
    let r = u0.wrapping_sub(q1.wrapping_mul(d));
144
145
    let r_gt_q0 = Limb::ct_lt(Limb(q0), Limb(r));
146
    let q1 = Limb::ct_select(Limb(q1), Limb(q1.wrapping_sub(1)), r_gt_q0).0;
147
    let r = Limb::ct_select(Limb(r), Limb(r.wrapping_add(d)), r_gt_q0).0;
148
149
    // If this was a normal `if`, we wouldn't need wrapping ops, because there would be no overflow.
150
    // But since we calculate both results either way, we have to wrap.
151
    // Added an assert to still check the lack of overflow in debug mode.
152
    debug_assert!(r < d || q1 < Word::MAX);
153
    let r_ge_d = Limb::ct_le(Limb(d), Limb(r));
154
    let q1 = Limb::ct_select(Limb(q1), Limb(q1.wrapping_add(1)), r_ge_d).0;
155
    let r = Limb::ct_select(Limb(r), Limb(r.wrapping_sub(d)), r_ge_d).0;
156
157
    (q1, r)
158
}
159
160
/// A pre-calculated reciprocal for division by a single limb.
161
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
162
pub struct Reciprocal {
163
    divisor_normalized: Word,
164
    shift: u32,
165
    reciprocal: Word,
166
}
167
168
impl Reciprocal {
169
    /// Pre-calculates a reciprocal for a known divisor,
170
    /// to be used in the single-limb division later.
171
    /// Returns the reciprocal, and the truthy value if `divisor != 0`
172
    /// and the falsy value otherwise.
173
    ///
174
    /// Note: if the returned flag is falsy, the returned reciprocal object is still self-consistent
175
    /// and can be passed to functions here without causing them to panic,
176
    /// but the results are naturally not to be used.
177
0
    pub const fn ct_new(divisor: Limb) -> (Self, CtChoice) {
178
0
        // Assuming this is constant-time for primitive types.
179
0
        let shift = divisor.0.leading_zeros();
180
0
181
0
        #[allow(trivial_numeric_casts)]
182
0
        let is_some = Limb((Word::BITS - shift) as Word).ct_is_nonzero();
183
0
184
0
        // If `divisor = 0`, shifting `divisor` by `leading_zeros == Word::BITS` will cause a panic.
185
0
        // Have to substitute a "bogus" shift in that case.
186
0
        #[allow(trivial_numeric_casts)]
187
0
        let shift_limb = Limb::ct_select(Limb::ZERO, Limb(shift as Word), is_some);
188
0
189
0
        // Need to provide bogus normalized divisor and reciprocal too,
190
0
        // so that we don't get a panic in low-level functions.
191
0
        let divisor_normalized = divisor.shl(shift_limb);
192
0
        let divisor_normalized = Limb::ct_select(Limb::MAX, divisor_normalized, is_some).0;
193
0
194
0
        #[allow(trivial_numeric_casts)]
195
0
        let shift = shift_limb.0 as u32;
196
0
197
0
        (
198
0
            Self {
199
0
                divisor_normalized,
200
0
                shift,
201
0
                reciprocal: reciprocal(divisor_normalized),
202
0
            },
203
0
            is_some,
204
0
        )
205
0
    }
206
207
    /// Returns a default instance of this object.
208
    /// It is a self-consistent `Reciprocal` that will not cause panics in functions that take it.
209
    ///
210
    /// NOTE: intended for using it as a placeholder during compile-time array generation,
211
    /// don't rely on the contents.
212
0
    pub const fn default() -> Self {
213
0
        Self {
214
0
            divisor_normalized: Word::MAX,
215
0
            shift: 0,
216
0
            // The result of calling `reciprocal(Word::MAX)`
217
0
            // This holds both for 32- and 64-bit versions.
218
0
            reciprocal: 1,
219
0
        }
220
0
    }
221
222
    /// A non-const-fn version of `new_const()`, wrapping the result in a `CtOption`.
223
0
    pub fn new(divisor: Limb) -> CtOption<Self> {
224
0
        let (rec, is_some) = Self::ct_new(divisor);
225
0
        CtOption::new(rec, is_some.into())
226
0
    }
227
}
228
229
impl ConditionallySelectable for Reciprocal {
230
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
231
0
        Self {
232
0
            divisor_normalized: Word::conditional_select(
233
0
                &a.divisor_normalized,
234
0
                &b.divisor_normalized,
235
0
                choice,
236
0
            ),
237
0
            shift: u32::conditional_select(&a.shift, &b.shift, choice),
238
0
            reciprocal: Word::conditional_select(&a.reciprocal, &b.reciprocal, choice),
239
0
        }
240
0
    }
241
}
242
243
// `CtOption.map()` needs this; for some reason it doesn't use the value it already has
244
// for the `None` branch.
245
impl Default for Reciprocal {
246
0
    fn default() -> Self {
247
0
        Self::default()
248
0
    }
249
}
250
251
/// Divides `u` by the divisor encoded in the `reciprocal`, and returns
252
/// the quotient and the remainder.
253
#[inline(always)]
254
0
pub(crate) const fn div_rem_limb_with_reciprocal<const L: usize>(
255
0
    u: &Uint<L>,
256
0
    reciprocal: &Reciprocal,
257
0
) -> (Uint<L>, Limb) {
258
0
    let (u_shifted, u_hi) = u.shl_limb(reciprocal.shift as usize);
259
0
    let mut r = u_hi.0;
260
0
    let mut q = [Limb::ZERO; L];
261
0
262
0
    let mut j = L;
263
0
    while j > 0 {
264
0
        j -= 1;
265
0
        let (qj, rj) = div2by1(r, u_shifted.as_limbs()[j].0, reciprocal);
266
0
        q[j] = Limb(qj);
267
0
        r = rj;
268
0
    }
269
0
    (Uint::<L>::new(q), Limb(r >> reciprocal.shift))
270
0
}
271
272
#[cfg(test)]
273
mod tests {
274
    use super::{div2by1, Reciprocal};
275
    use crate::{Limb, Word};
276
    #[test]
277
    fn div2by1_overflow() {
278
        // A regression test for a situation when in div2by1() an operation (`q1 + 1`)
279
        // that is protected from overflowing by a condition in the original paper (`r >= d`)
280
        // still overflows because we're calculating the results for both branches.
281
        let r = Reciprocal::new(Limb(Word::MAX - 1)).unwrap();
282
        assert_eq!(
283
            div2by1(Word::MAX - 2, Word::MAX - 63, &r),
284
            (Word::MAX, Word::MAX - 65)
285
        );
286
    }
287
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/encoding.rs
Line
Count
Source
1
//! Const-friendly decoding operations for [`Uint`]
2
3
#[cfg(all(feature = "der", feature = "generic-array"))]
4
mod der;
5
6
#[cfg(feature = "rlp")]
7
mod rlp;
8
9
use super::Uint;
10
use crate::{Encoding, Limb, Word};
11
12
impl<const LIMBS: usize> Uint<LIMBS> {
13
    /// Create a new [`Uint`] from the provided big endian bytes.
14
7.32k
    pub const fn from_be_slice(bytes: &[u8]) -> Self {
15
7.32k
        assert!(
16
7.32k
            bytes.len() == Limb::BYTES * LIMBS,
17
0
            "bytes are not the expected size"
18
        );
19
20
7.32k
        let mut res = [Limb::ZERO; LIMBS];
21
7.32k
        let mut buf = [0u8; Limb::BYTES];
22
7.32k
        let mut i = 0;
23
24
36.6k
        while i < LIMBS {
25
29.3k
            let mut j = 0;
26
263k
            while j < Limb::BYTES {
27
234k
                buf[j] = bytes[i * Limb::BYTES + j];
28
234k
                j += 1;
29
234k
            }
30
29.3k
            res[LIMBS - i - 1] = Limb(Word::from_be_bytes(buf));
31
29.3k
            i += 1;
32
        }
33
34
7.32k
        Uint::new(res)
35
7.32k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj100_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj10_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj14_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj18_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj1_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj1c_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj200_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj20_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj2_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj30_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj38_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj3_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj40_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj42_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj44_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj4_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj5_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj60_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj6_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj7_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj80_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj8_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj9_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKja_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjb_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjc_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjd_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKje_E13from_be_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjf_E13from_be_sliceB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj4_E13from_be_sliceCsjewTDwKBbyD_4k256
Line
Count
Source
14
2.16k
    pub const fn from_be_slice(bytes: &[u8]) -> Self {
15
2.16k
        assert!(
16
2.16k
            bytes.len() == Limb::BYTES * LIMBS,
17
0
            "bytes are not the expected size"
18
        );
19
20
2.16k
        let mut res = [Limb::ZERO; LIMBS];
21
2.16k
        let mut buf = [0u8; Limb::BYTES];
22
2.16k
        let mut i = 0;
23
24
10.8k
        while i < LIMBS {
25
8.64k
            let mut j = 0;
26
77.8k
            while j < Limb::BYTES {
27
69.1k
                buf[j] = bytes[i * Limb::BYTES + j];
28
69.1k
                j += 1;
29
69.1k
            }
30
8.64k
            res[LIMBS - i - 1] = Limb(Word::from_be_bytes(buf));
31
8.64k
            i += 1;
32
        }
33
34
2.16k
        Uint::new(res)
35
2.16k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj8_E13from_be_sliceCsjewTDwKBbyD_4k256
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj4_E13from_be_sliceCsaHRNXv1Y9Bq_4p256
Line
Count
Source
14
5.16k
    pub const fn from_be_slice(bytes: &[u8]) -> Self {
15
5.16k
        assert!(
16
5.16k
            bytes.len() == Limb::BYTES * LIMBS,
17
0
            "bytes are not the expected size"
18
        );
19
20
5.16k
        let mut res = [Limb::ZERO; LIMBS];
21
5.16k
        let mut buf = [0u8; Limb::BYTES];
22
5.16k
        let mut i = 0;
23
24
25.8k
        while i < LIMBS {
25
20.6k
            let mut j = 0;
26
185k
            while j < Limb::BYTES {
27
165k
                buf[j] = bytes[i * Limb::BYTES + j];
28
165k
                j += 1;
29
165k
            }
30
20.6k
            res[LIMBS - i - 1] = Limb(Word::from_be_bytes(buf));
31
20.6k
            i += 1;
32
        }
33
34
5.16k
        Uint::new(res)
35
5.16k
    }
36
37
    /// Create a new [`Uint`] from the provided big endian hex string.
38
0
    pub const fn from_be_hex(hex: &str) -> Self {
39
0
        let bytes = hex.as_bytes();
40
0
41
0
        assert!(
42
0
            bytes.len() == Limb::BYTES * LIMBS * 2,
43
0
            "hex string is not the expected size"
44
        );
45
46
0
        let mut res = [Limb::ZERO; LIMBS];
47
0
        let mut buf = [0u8; Limb::BYTES];
48
0
        let mut i = 0;
49
0
        let mut err = 0;
50
51
0
        while i < LIMBS {
52
0
            let mut j = 0;
53
0
            while j < Limb::BYTES {
54
0
                let offset = (i * Limb::BYTES + j) * 2;
55
0
                let (result, byte_err) = decode_hex_byte([bytes[offset], bytes[offset + 1]]);
56
0
                err |= byte_err;
57
0
                buf[j] = result;
58
0
                j += 1;
59
0
            }
60
0
            res[LIMBS - i - 1] = Limb(Word::from_be_bytes(buf));
61
0
            i += 1;
62
        }
63
64
0
        assert!(err == 0, "invalid hex byte");
65
66
0
        Uint::new(res)
67
0
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKpE11from_be_hexB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj4_E11from_be_hexCsaHRNXv1Y9Bq_4p256
68
69
    /// Create a new [`Uint`] from the provided little endian bytes.
70
0
    pub const fn from_le_slice(bytes: &[u8]) -> Self {
71
0
        assert!(
72
0
            bytes.len() == Limb::BYTES * LIMBS,
73
0
            "bytes are not the expected size"
74
        );
75
76
0
        let mut res = [Limb::ZERO; LIMBS];
77
0
        let mut buf = [0u8; Limb::BYTES];
78
0
        let mut i = 0;
79
80
0
        while i < LIMBS {
81
0
            let mut j = 0;
82
0
            while j < Limb::BYTES {
83
0
                buf[j] = bytes[i * Limb::BYTES + j];
84
0
                j += 1;
85
0
            }
86
0
            res[i] = Limb(Word::from_le_bytes(buf));
87
0
            i += 1;
88
        }
89
90
0
        Uint::new(res)
91
0
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj100_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj10_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj14_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj18_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj1_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj1c_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj200_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj20_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj2_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj30_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj38_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj3_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj40_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj42_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj44_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj4_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj5_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj60_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj6_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj7_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj80_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj8_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj9_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKja_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjb_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjc_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjd_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKje_E13from_le_sliceB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjf_E13from_le_sliceB6_
92
93
    /// Create a new [`Uint`] from the provided little endian hex string.
94
0
    pub const fn from_le_hex(hex: &str) -> Self {
95
0
        let bytes = hex.as_bytes();
96
0
97
0
        assert!(
98
0
            bytes.len() == Limb::BYTES * LIMBS * 2,
99
0
            "bytes are not the expected size"
100
        );
101
102
0
        let mut res = [Limb::ZERO; LIMBS];
103
0
        let mut buf = [0u8; Limb::BYTES];
104
0
        let mut i = 0;
105
0
        let mut err = 0;
106
107
0
        while i < LIMBS {
108
0
            let mut j = 0;
109
0
            while j < Limb::BYTES {
110
0
                let offset = (i * Limb::BYTES + j) * 2;
111
0
                let (result, byte_err) = decode_hex_byte([bytes[offset], bytes[offset + 1]]);
112
0
                err |= byte_err;
113
0
                buf[j] = result;
114
0
                j += 1;
115
0
            }
116
0
            res[i] = Limb(Word::from_le_bytes(buf));
117
0
            i += 1;
118
        }
119
120
0
        assert!(err == 0, "invalid hex byte");
121
122
0
        Uint::new(res)
123
0
    }
124
125
    /// Serialize this [`Uint`] as big-endian, writing it into the provided
126
    /// byte slice.
127
    #[inline]
128
2.95k
    pub(crate) fn write_be_bytes(&self, out: &mut [u8]) {
129
2.95k
        debug_assert_eq!(out.len(), Limb::BYTES * LIMBS);
130
131
11.8k
        for (src, dst) in self
132
2.95k
            .limbs
133
2.95k
            .iter()
134
2.95k
            .rev()
135
2.95k
            .cloned()
136
2.95k
            .zip(out.chunks_exact_mut(Limb::BYTES))
137
11.8k
        {
138
11.8k
            dst.copy_from_slice(&src.to_be_bytes());
139
11.8k
        }
140
2.95k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj100_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj10_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj14_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj18_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj1_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj1c_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj200_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj20_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj2_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj30_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj38_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj3_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj40_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj42_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj44_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj4_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj5_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj60_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj6_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj7_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj80_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj8_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj9_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKja_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjb_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjc_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjd_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKje_E14write_be_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjf_E14write_be_bytesB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj4_E14write_be_bytesCsjewTDwKBbyD_4k256
Line
Count
Source
128
2.09k
    pub(crate) fn write_be_bytes(&self, out: &mut [u8]) {
129
2.09k
        debug_assert_eq!(out.len(), Limb::BYTES * LIMBS);
130
131
8.36k
        for (src, dst) in self
132
2.09k
            .limbs
133
2.09k
            .iter()
134
2.09k
            .rev()
135
2.09k
            .cloned()
136
2.09k
            .zip(out.chunks_exact_mut(Limb::BYTES))
137
8.36k
        {
138
8.36k
            dst.copy_from_slice(&src.to_be_bytes());
139
8.36k
        }
140
2.09k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj4_E14write_be_bytesCsaHRNXv1Y9Bq_4p256
Line
Count
Source
128
866
    pub(crate) fn write_be_bytes(&self, out: &mut [u8]) {
129
866
        debug_assert_eq!(out.len(), Limb::BYTES * LIMBS);
130
131
3.46k
        for (src, dst) in self
132
866
            .limbs
133
866
            .iter()
134
866
            .rev()
135
866
            .cloned()
136
866
            .zip(out.chunks_exact_mut(Limb::BYTES))
137
3.46k
        {
138
3.46k
            dst.copy_from_slice(&src.to_be_bytes());
139
3.46k
        }
140
866
    }
141
142
    /// Serialize this [`Uint`] as little-endian, writing it into the provided
143
    /// byte slice.
144
    #[inline]
145
1.67k
    pub(crate) fn write_le_bytes(&self, out: &mut [u8]) {
146
1.67k
        debug_assert_eq!(out.len(), Limb::BYTES * LIMBS);
147
148
6.70k
        for (src, dst) in self
149
1.67k
            .limbs
150
1.67k
            .iter()
151
1.67k
            .cloned()
152
1.67k
            .zip(out.chunks_exact_mut(Limb::BYTES))
153
6.70k
        {
154
6.70k
            dst.copy_from_slice(&src.to_le_bytes());
155
6.70k
        }
156
1.67k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj4_E14write_le_bytesCs4RkbDk9WRL5_5clvmr
Line
Count
Source
145
1.67k
    pub(crate) fn write_le_bytes(&self, out: &mut [u8]) {
146
1.67k
        debug_assert_eq!(out.len(), Limb::BYTES * LIMBS);
147
148
6.70k
        for (src, dst) in self
149
1.67k
            .limbs
150
1.67k
            .iter()
151
1.67k
            .cloned()
152
1.67k
            .zip(out.chunks_exact_mut(Limb::BYTES))
153
6.70k
        {
154
6.70k
            dst.copy_from_slice(&src.to_le_bytes());
155
6.70k
        }
156
1.67k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj100_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj10_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj14_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj18_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj1_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj1c_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj200_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj20_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj2_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj30_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj38_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj3_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj40_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj42_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj44_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj4_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj5_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj60_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj6_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj7_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj80_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj8_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj9_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKja_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjb_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjc_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjd_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKje_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKjf_E14write_le_bytesB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint8encodingINtB4_4UintKj4_E14write_le_bytesCsaHRNXv1Y9Bq_4p256
157
}
158
159
/// Decode a single nibble of upper or lower hex
160
#[inline(always)]
161
0
const fn decode_nibble(src: u8) -> u16 {
162
0
    let byte = src as i16;
163
0
    let mut ret: i16 = -1;
164
0
165
0
    // 0-9  0x30-0x39
166
0
    // if (byte > 0x2f && byte < 0x3a) ret += byte - 0x30 + 1; // -47
167
0
    ret += (((0x2fi16 - byte) & (byte - 0x3a)) >> 8) & (byte - 47);
168
0
    // A-F  0x41-0x46
169
0
    // if (byte > 0x40 && byte < 0x47) ret += byte - 0x41 + 10 + 1; // -54
170
0
    ret += (((0x40i16 - byte) & (byte - 0x47)) >> 8) & (byte - 54);
171
0
    // a-f  0x61-0x66
172
0
    // if (byte > 0x60 && byte < 0x67) ret += byte - 0x61 + 10 + 1; // -86
173
0
    ret += (((0x60i16 - byte) & (byte - 0x67)) >> 8) & (byte - 86);
174
0
175
0
    ret as u16
176
0
}
177
178
/// Decode a single byte encoded as two hexadecimal characters.
179
/// Second element of the tuple is non-zero if the `bytes` values are not in the valid range
180
/// (0-9, a-z, A-Z).
181
#[inline(always)]
182
0
const fn decode_hex_byte(bytes: [u8; 2]) -> (u8, u16) {
183
0
    let hi = decode_nibble(bytes[0]);
184
0
    let lo = decode_nibble(bytes[1]);
185
0
    let byte = (hi << 4) | lo;
186
0
    let err = byte >> 8;
187
0
    let result = byte as u8;
188
0
    (result, err)
189
0
}
190
191
#[cfg(test)]
192
mod tests {
193
    use crate::Limb;
194
    use hex_literal::hex;
195
196
    #[cfg(feature = "alloc")]
197
    use {crate::U128, alloc::format};
198
199
    #[cfg(target_pointer_width = "32")]
200
    use crate::U64 as UintEx;
201
202
    #[cfg(target_pointer_width = "64")]
203
    use crate::U128 as UintEx;
204
205
    #[test]
206
    #[cfg(target_pointer_width = "32")]
207
    fn from_be_slice() {
208
        let bytes = hex!("0011223344556677");
209
        let n = UintEx::from_be_slice(&bytes);
210
        assert_eq!(n.as_limbs(), &[Limb(0x44556677), Limb(0x00112233)]);
211
    }
212
213
    #[test]
214
    #[cfg(target_pointer_width = "64")]
215
    fn from_be_slice() {
216
        let bytes = hex!("00112233445566778899aabbccddeeff");
217
        let n = UintEx::from_be_slice(&bytes);
218
        assert_eq!(
219
            n.as_limbs(),
220
            &[Limb(0x8899aabbccddeeff), Limb(0x0011223344556677)]
221
        );
222
    }
223
224
    #[test]
225
    #[cfg(target_pointer_width = "32")]
226
    fn from_le_slice() {
227
        let bytes = hex!("7766554433221100");
228
        let n = UintEx::from_le_slice(&bytes);
229
        assert_eq!(n.as_limbs(), &[Limb(0x44556677), Limb(0x00112233)]);
230
    }
231
232
    #[test]
233
    #[cfg(target_pointer_width = "64")]
234
    fn from_le_slice() {
235
        let bytes = hex!("ffeeddccbbaa99887766554433221100");
236
        let n = UintEx::from_le_slice(&bytes);
237
        assert_eq!(
238
            n.as_limbs(),
239
            &[Limb(0x8899aabbccddeeff), Limb(0x0011223344556677)]
240
        );
241
    }
242
243
    #[test]
244
    #[cfg(target_pointer_width = "32")]
245
    fn from_be_hex() {
246
        let n = UintEx::from_be_hex("0011223344556677");
247
        assert_eq!(n.as_limbs(), &[Limb(0x44556677), Limb(0x00112233)]);
248
    }
249
250
    #[test]
251
    #[cfg(target_pointer_width = "64")]
252
    fn from_be_hex() {
253
        let n = UintEx::from_be_hex("00112233445566778899aabbccddeeff");
254
        assert_eq!(
255
            n.as_limbs(),
256
            &[Limb(0x8899aabbccddeeff), Limb(0x0011223344556677)]
257
        );
258
    }
259
260
    #[test]
261
    #[cfg(target_pointer_width = "32")]
262
    fn from_le_hex() {
263
        let n = UintEx::from_le_hex("7766554433221100");
264
        assert_eq!(n.as_limbs(), &[Limb(0x44556677), Limb(0x00112233)]);
265
    }
266
267
    #[test]
268
    #[cfg(target_pointer_width = "64")]
269
    fn from_le_hex() {
270
        let n = UintEx::from_le_hex("ffeeddccbbaa99887766554433221100");
271
        assert_eq!(
272
            n.as_limbs(),
273
            &[Limb(0x8899aabbccddeeff), Limb(0x0011223344556677)]
274
        );
275
    }
276
277
    #[cfg(feature = "alloc")]
278
    #[test]
279
    fn hex_upper() {
280
        let hex = "AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD";
281
        let n = U128::from_be_hex(hex);
282
        assert_eq!(hex, format!("{:X}", n));
283
    }
284
285
    #[cfg(feature = "alloc")]
286
    #[test]
287
    fn hex_lower() {
288
        let hex = "aaaaaaaabbbbbbbbccccccccdddddddd";
289
        let n = U128::from_be_hex(hex);
290
        assert_eq!(hex, format!("{:x}", n));
291
    }
292
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/from.rs
Line
Count
Source
1
//! `From`-like conversions for [`Uint`].
2
3
use crate::{ConcatMixed, Limb, Uint, WideWord, Word, U128, U64};
4
5
impl<const LIMBS: usize> Uint<LIMBS> {
6
    /// Create a [`Uint`] from a `u8` (const-friendly)
7
    // TODO(tarcieri): replace with `const impl From<u8>` when stable
8
0
    pub const fn from_u8(n: u8) -> Self {
9
0
        assert!(LIMBS >= 1, "number of limbs must be greater than zero");
10
0
        let mut limbs = [Limb::ZERO; LIMBS];
11
0
        limbs[0].0 = n as Word;
12
0
        Self { limbs }
13
0
    }
14
15
    /// Create a [`Uint`] from a `u16` (const-friendly)
16
    // TODO(tarcieri): replace with `const impl From<u16>` when stable
17
0
    pub const fn from_u16(n: u16) -> Self {
18
0
        assert!(LIMBS >= 1, "number of limbs must be greater than zero");
19
0
        let mut limbs = [Limb::ZERO; LIMBS];
20
0
        limbs[0].0 = n as Word;
21
0
        Self { limbs }
22
0
    }
23
24
    /// Create a [`Uint`] from a `u32` (const-friendly)
25
    // TODO(tarcieri): replace with `const impl From<u32>` when stable
26
    #[allow(trivial_numeric_casts)]
27
0
    pub const fn from_u32(n: u32) -> Self {
28
0
        assert!(LIMBS >= 1, "number of limbs must be greater than zero");
29
0
        let mut limbs = [Limb::ZERO; LIMBS];
30
0
        limbs[0].0 = n as Word;
31
0
        Self { limbs }
32
0
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB4_4UintKpE8from_u32B6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB4_4UintKj4_E8from_u32CsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB4_4UintKj4_E8from_u32CsaHRNXv1Y9Bq_4p256
33
34
    /// Create a [`Uint`] from a `u64` (const-friendly)
35
    // TODO(tarcieri): replace with `const impl From<u64>` when stable
36
    #[cfg(target_pointer_width = "32")]
37
    pub const fn from_u64(n: u64) -> Self {
38
        assert!(LIMBS >= 2, "number of limbs must be two or greater");
39
        let mut limbs = [Limb::ZERO; LIMBS];
40
        limbs[0].0 = (n & 0xFFFFFFFF) as u32;
41
        limbs[1].0 = (n >> 32) as u32;
42
        Self { limbs }
43
    }
44
45
    /// Create a [`Uint`] from a `u64` (const-friendly)
46
    // TODO(tarcieri): replace with `const impl From<u64>` when stable
47
    #[cfg(target_pointer_width = "64")]
48
553k
    pub const fn from_u64(n: u64) -> Self {
49
553k
        assert!(LIMBS >= 1, "number of limbs must be greater than zero");
50
553k
        let mut limbs = [Limb::ZERO; LIMBS];
51
553k
        limbs[0].0 = n;
52
553k
        Self { limbs }
53
553k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB4_4UintKpE8from_u64B6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB4_4UintKj1_E8from_u64CsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB4_4UintKj4_E8from_u64CsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB4_4UintKj1_E8from_u64CsaHRNXv1Y9Bq_4p256
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB4_4UintKj4_E8from_u64CsaHRNXv1Y9Bq_4p256
Line
Count
Source
48
553k
    pub const fn from_u64(n: u64) -> Self {
49
553k
        assert!(LIMBS >= 1, "number of limbs must be greater than zero");
50
553k
        let mut limbs = [Limb::ZERO; LIMBS];
51
553k
        limbs[0].0 = n;
52
553k
        Self { limbs }
53
553k
    }
54
55
    /// Create a [`Uint`] from a `u128` (const-friendly)
56
    // TODO(tarcieri): replace with `const impl From<u128>` when stable
57
0
    pub const fn from_u128(n: u128) -> Self {
58
0
        assert!(
59
0
            LIMBS >= (128 / Limb::BITS),
60
0
            "number of limbs must be greater than zero"
61
        );
62
63
0
        let lo = U64::from_u64((n & 0xffff_ffff_ffff_ffff) as u64);
64
0
        let hi = U64::from_u64((n >> 64) as u64);
65
0
66
0
        let mut limbs = [Limb::ZERO; LIMBS];
67
0
68
0
        let mut i = 0;
69
0
        while i < lo.limbs.len() {
70
0
            limbs[i] = lo.limbs[i];
71
0
            i += 1;
72
0
        }
73
74
0
        let mut j = 0;
75
0
        while j < hi.limbs.len() {
76
0
            limbs[i + j] = hi.limbs[j];
77
0
            j += 1;
78
0
        }
79
80
0
        Self { limbs }
81
0
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB4_4UintKpE9from_u128B6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB4_4UintKj4_E9from_u128CsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB4_4UintKj4_E9from_u128CsaHRNXv1Y9Bq_4p256
82
83
    /// Create a [`Uint`] from a `Word` (const-friendly)
84
    // TODO(tarcieri): replace with `const impl From<Word>` when stable
85
0
    pub const fn from_word(n: Word) -> Self {
86
0
        assert!(LIMBS >= 1, "number of limbs must be greater than zero");
87
0
        let mut limbs = [Limb::ZERO; LIMBS];
88
0
        limbs[0].0 = n;
89
0
        Self { limbs }
90
0
    }
91
92
    /// Create a [`Uint`] from a `WideWord` (const-friendly)
93
    // TODO(tarcieri): replace with `const impl From<WideWord>` when stable
94
0
    pub const fn from_wide_word(n: WideWord) -> Self {
95
0
        assert!(LIMBS >= 2, "number of limbs must be two or greater");
96
0
        let mut limbs = [Limb::ZERO; LIMBS];
97
0
        limbs[0].0 = n as Word;
98
0
        limbs[1].0 = (n >> Limb::BITS) as Word;
99
0
        Self { limbs }
100
0
    }
101
}
102
103
impl<const LIMBS: usize> From<u8> for Uint<LIMBS> {
104
0
    fn from(n: u8) -> Self {
105
0
        // TODO(tarcieri): const where clause when possible
106
0
        debug_assert!(LIMBS > 0, "limbs must be non-zero");
107
0
        Self::from_u8(n)
108
0
    }
109
}
110
111
impl<const LIMBS: usize> From<u16> for Uint<LIMBS> {
112
0
    fn from(n: u16) -> Self {
113
0
        // TODO(tarcieri): const where clause when possible
114
0
        debug_assert!(LIMBS > 0, "limbs must be non-zero");
115
0
        Self::from_u16(n)
116
0
    }
117
}
118
119
impl<const LIMBS: usize> From<u32> for Uint<LIMBS> {
120
0
    fn from(n: u32) -> Self {
121
0
        // TODO(tarcieri): const where clause when possible
122
0
        debug_assert!(LIMBS > 0, "limbs must be non-zero");
123
0
        Self::from_u32(n)
124
0
    }
Unexecuted instantiation: _RNvXININtNtCshRehcWQJ0wE_13crypto_bigint4uint4froms1_0KpEINtB7_4UintKpEINtNtCsbQ8arDwx5Xq_4core7convert4FrommE4fromB9_
Unexecuted instantiation: _RNvXs1_NtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB7_4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert4FrommE4fromCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs1_NtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB7_4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert4FrommE4fromCsaHRNXv1Y9Bq_4p256
125
}
126
127
impl<const LIMBS: usize> From<u64> for Uint<LIMBS> {
128
553k
    fn from(n: u64) -> Self {
129
553k
        // TODO(tarcieri): const where clause when possible
130
553k
        debug_assert!(LIMBS >= (64 / Limb::BITS), "not enough limbs");
131
553k
        Self::from_u64(n)
132
553k
    }
Unexecuted instantiation: _RNvXININtNtCshRehcWQJ0wE_13crypto_bigint4uint4froms2_0KpEINtB7_4UintKpEINtNtCsbQ8arDwx5Xq_4core7convert4FromyE4fromB9_
Unexecuted instantiation: _RNvXs2_NtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB7_4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert4FromyE4fromCsjewTDwKBbyD_4k256
_RNvXs2_NtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB7_4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert4FromyE4fromCsaHRNXv1Y9Bq_4p256
Line
Count
Source
128
553k
    fn from(n: u64) -> Self {
129
553k
        // TODO(tarcieri): const where clause when possible
130
553k
        debug_assert!(LIMBS >= (64 / Limb::BITS), "not enough limbs");
131
553k
        Self::from_u64(n)
132
553k
    }
133
}
134
135
impl<const LIMBS: usize> From<u128> for Uint<LIMBS> {
136
0
    fn from(n: u128) -> Self {
137
0
        // TODO(tarcieri): const where clause when possible
138
0
        debug_assert!(LIMBS >= (128 / Limb::BITS), "not enough limbs");
139
0
        Self::from_u128(n)
140
0
    }
Unexecuted instantiation: _RNvXININtNtCshRehcWQJ0wE_13crypto_bigint4uint4froms3_0KpEINtB7_4UintKpEINtNtCsbQ8arDwx5Xq_4core7convert4FromoE4fromB9_
Unexecuted instantiation: _RNvXs3_NtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB7_4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert4FromoE4fromCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs3_NtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB7_4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert4FromoE4fromCsaHRNXv1Y9Bq_4p256
141
}
142
143
#[cfg(target_pointer_width = "32")]
144
impl From<U64> for u64 {
145
    fn from(n: U64) -> u64 {
146
        (n.limbs[0].0 as u64) | ((n.limbs[1].0 as u64) << 32)
147
    }
148
}
149
150
#[cfg(target_pointer_width = "64")]
151
impl From<U64> for u64 {
152
0
    fn from(n: U64) -> u64 {
153
0
        n.limbs[0].into()
154
0
    }
155
}
156
157
impl From<U128> for u128 {
158
0
    fn from(n: U128) -> u128 {
159
0
        let mut i = U128::LIMBS - 1;
160
0
        let mut res = n.limbs[i].0 as u128;
161
0
        while i > 0 {
162
0
            i -= 1;
163
0
            res = (res << Limb::BITS) | (n.limbs[i].0 as u128);
164
0
        }
165
0
        res
166
0
    }
167
}
168
169
impl<const LIMBS: usize> From<[Word; LIMBS]> for Uint<LIMBS> {
170
14.7M
    fn from(arr: [Word; LIMBS]) -> Self {
171
14.7M
        Self::from_words(arr)
172
14.7M
    }
_RNvXs6_NtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB7_4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert4FromAyBY_E4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
170
14.7M
    fn from(arr: [Word; LIMBS]) -> Self {
171
14.7M
        Self::from_words(arr)
172
14.7M
    }
Unexecuted instantiation: _RNvXININtNtCshRehcWQJ0wE_13crypto_bigint4uint4froms6_0KpEINtB7_4UintKpEINtNtCsbQ8arDwx5Xq_4core7convert4FromAypE4fromB9_
_RNvXs6_NtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB7_4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert4FromAyBY_E4fromCsjewTDwKBbyD_4k256
Line
Count
Source
170
4.18k
    fn from(arr: [Word; LIMBS]) -> Self {
171
4.18k
        Self::from_words(arr)
172
4.18k
    }
_RNvXs6_NtNtCshRehcWQJ0wE_13crypto_bigint4uint4fromINtB7_4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert4FromAyBY_E4fromCsaHRNXv1Y9Bq_4p256
Line
Count
Source
170
4.88k
    fn from(arr: [Word; LIMBS]) -> Self {
171
4.88k
        Self::from_words(arr)
172
4.88k
    }
173
}
174
175
impl<const LIMBS: usize> From<Uint<LIMBS>> for [Word; LIMBS] {
176
0
    fn from(n: Uint<LIMBS>) -> [Word; LIMBS] {
177
0
        *n.as_ref()
178
0
    }
179
}
180
181
impl<const LIMBS: usize> From<[Limb; LIMBS]> for Uint<LIMBS> {
182
0
    fn from(limbs: [Limb; LIMBS]) -> Self {
183
0
        Self { limbs }
184
0
    }
185
}
186
187
impl<const LIMBS: usize> From<Uint<LIMBS>> for [Limb; LIMBS] {
188
0
    fn from(n: Uint<LIMBS>) -> [Limb; LIMBS] {
189
0
        n.limbs
190
0
    }
191
}
192
193
impl<const LIMBS: usize> From<Limb> for Uint<LIMBS> {
194
0
    fn from(limb: Limb) -> Self {
195
0
        limb.0.into()
196
0
    }
197
}
198
199
impl<const L: usize, const H: usize, const LIMBS: usize> From<(Uint<L>, Uint<H>)> for Uint<LIMBS>
200
where
201
    Uint<H>: ConcatMixed<Uint<L>, MixedOutput = Uint<LIMBS>>,
202
{
203
0
    fn from(nums: (Uint<L>, Uint<H>)) -> Uint<LIMBS> {
204
0
        nums.1.concat_mixed(&nums.0)
205
0
    }
206
}
207
208
impl<const L: usize, const H: usize, const LIMBS: usize> From<&(Uint<L>, Uint<H>)> for Uint<LIMBS>
209
where
210
    Uint<H>: ConcatMixed<Uint<L>, MixedOutput = Uint<LIMBS>>,
211
{
212
0
    fn from(nums: &(Uint<L>, Uint<H>)) -> Uint<LIMBS> {
213
0
        nums.1.concat_mixed(&nums.0)
214
0
    }
215
}
216
217
impl<const L: usize, const H: usize, const LIMBS: usize> From<Uint<LIMBS>> for (Uint<L>, Uint<H>) {
218
0
    fn from(num: Uint<LIMBS>) -> (Uint<L>, Uint<H>) {
219
0
        crate::uint::split::split_mixed(&num)
220
0
    }
221
}
222
223
impl<const LIMBS: usize, const LIMBS2: usize> From<&Uint<LIMBS>> for Uint<LIMBS2> {
224
0
    fn from(num: &Uint<LIMBS>) -> Uint<LIMBS2> {
225
0
        num.resize()
226
0
    }
227
}
228
229
#[cfg(test)]
230
mod tests {
231
    use crate::{Limb, Word, U128};
232
233
    #[cfg(target_pointer_width = "32")]
234
    use crate::U64 as UintEx;
235
236
    #[cfg(target_pointer_width = "64")]
237
    use crate::U128 as UintEx;
238
239
    #[test]
240
    fn from_u8() {
241
        let n = UintEx::from(42u8);
242
        assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
243
    }
244
245
    #[test]
246
    fn from_u16() {
247
        let n = UintEx::from(42u16);
248
        assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
249
    }
250
251
    #[test]
252
    fn from_u64() {
253
        let n = UintEx::from(42u64);
254
        assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
255
    }
256
257
    #[test]
258
    fn from_u128() {
259
        let n = U128::from(42u128);
260
        assert_eq!(&n.as_limbs()[..2], &[Limb(42), Limb(0)]);
261
        assert_eq!(u128::from(n), 42u128);
262
    }
263
264
    #[test]
265
    fn array_round_trip() {
266
        let arr1 = [1, 2];
267
        let n = UintEx::from(arr1);
268
        let arr2: [Word; 2] = n.into();
269
        assert_eq!(arr1, arr2);
270
    }
271
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/inv_mod.rs
Line
Count
Source
1
use super::Uint;
2
use crate::CtChoice;
3
4
impl<const LIMBS: usize> Uint<LIMBS> {
5
    /// Computes 1/`self` mod `2^k`.
6
    /// This method is constant-time w.r.t. `self` but not `k`.
7
    ///
8
    /// Conditions: `self` < 2^k and `self` must be odd
9
0
    pub const fn inv_mod2k_vartime(&self, k: usize) -> Self {
10
0
        // Using the Algorithm 3 from "A Secure Algorithm for Inversion Modulo 2k"
11
0
        // by Sadiel de la Fe and Carles Ferrer.
12
0
        // See <https://www.mdpi.com/2410-387X/2/3/23>.
13
0
14
0
        // Note that we are not using Alrgorithm 4, since we have a different approach
15
0
        // of enforcing constant-timeness w.r.t. `self`.
16
0
17
0
        let mut x = Self::ZERO; // keeps `x` during iterations
18
0
        let mut b = Self::ONE; // keeps `b_i` during iterations
19
0
        let mut i = 0;
20
21
0
        while i < k {
22
0
            // X_i = b_i mod 2
23
0
            let x_i = b.limbs[0].0 & 1;
24
0
            let x_i_choice = CtChoice::from_lsb(x_i);
25
0
            // b_{i+1} = (b_i - a * X_i) / 2
26
0
            b = Self::ct_select(&b, &b.wrapping_sub(self), x_i_choice).shr_vartime(1);
27
0
            // Store the X_i bit in the result (x = x | (1 << X_i))
28
0
            x = x.bitor(&Uint::from_word(x_i).shl_vartime(i));
29
0
30
0
            i += 1;
31
0
        }
32
33
0
        x
34
0
    }
35
36
    /// Computes 1/`self` mod `2^k`.
37
    ///
38
    /// Conditions: `self` < 2^k and `self` must be odd
39
0
    pub const fn inv_mod2k(&self, k: usize) -> Self {
40
0
        // This is the same algorithm as in `inv_mod2k_vartime()`,
41
0
        // but made constant-time w.r.t `k` as well.
42
0
43
0
        let mut x = Self::ZERO; // keeps `x` during iterations
44
0
        let mut b = Self::ONE; // keeps `b_i` during iterations
45
0
        let mut i = 0;
46
47
0
        while i < Self::BITS {
48
0
            // Only iterations for i = 0..k need to change `x`,
49
0
            // the rest are dummy ones performed for the sake of constant-timeness.
50
0
            let within_range = CtChoice::from_usize_lt(i, k);
51
0
52
0
            // X_i = b_i mod 2
53
0
            let x_i = b.limbs[0].0 & 1;
54
0
            let x_i_choice = CtChoice::from_lsb(x_i);
55
0
            // b_{i+1} = (b_i - a * X_i) / 2
56
0
            b = Self::ct_select(&b, &b.wrapping_sub(self), x_i_choice).shr_vartime(1);
57
0
58
0
            // Store the X_i bit in the result (x = x | (1 << X_i))
59
0
            // Don't change the result in dummy iterations.
60
0
            let x_i_choice = x_i_choice.and(within_range);
61
0
            x = x.set_bit(i, x_i_choice);
62
0
63
0
            i += 1;
64
0
        }
65
66
0
        x
67
0
    }
68
69
    /// Computes the multiplicative inverse of `self` mod `modulus`, where `modulus` is odd.
70
    /// In other words `self^-1 mod modulus`.
71
    /// `bits` and `modulus_bits` are the bounds on the bit size
72
    /// of `self` and `modulus`, respectively
73
    /// (the inversion speed will be proportional to `bits + modulus_bits`).
74
    /// The second element of the tuple is the truthy value if an inverse exists,
75
    /// otherwise it is a falsy value.
76
    ///
77
    /// **Note:** variable time in `bits` and `modulus_bits`.
78
    ///
79
    /// The algorithm is the same as in GMP 6.2.1's `mpn_sec_invert`.
80
0
    pub const fn inv_odd_mod_bounded(
81
0
        &self,
82
0
        modulus: &Self,
83
0
        bits: usize,
84
0
        modulus_bits: usize,
85
0
    ) -> (Self, CtChoice) {
86
0
        debug_assert!(modulus.ct_is_odd().is_true_vartime());
87
88
0
        let mut a = *self;
89
0
90
0
        let mut u = Uint::ONE;
91
0
        let mut v = Uint::ZERO;
92
0
93
0
        let mut b = *modulus;
94
0
95
0
        // `bit_size` can be anything >= `self.bits()` + `modulus.bits()`, setting to the minimum.
96
0
        let bit_size = bits + modulus_bits;
97
0
98
0
        let mut m1hp = *modulus;
99
0
        let (m1hp_new, carry) = m1hp.shr_1();
100
0
        debug_assert!(carry.is_true_vartime());
101
0
        m1hp = m1hp_new.wrapping_add(&Uint::ONE);
102
0
103
0
        let mut i = 0;
104
0
        while i < bit_size {
105
0
            debug_assert!(b.ct_is_odd().is_true_vartime());
106
107
0
            let self_odd = a.ct_is_odd();
108
0
109
0
            // Set `self -= b` if `self` is odd.
110
0
            let (new_a, swap) = a.conditional_wrapping_sub(&b, self_odd);
111
0
            // Set `b += self` if `swap` is true.
112
0
            b = Uint::ct_select(&b, &b.wrapping_add(&new_a), swap);
113
0
            // Negate `self` if `swap` is true.
114
0
            a = new_a.conditional_wrapping_neg(swap);
115
0
116
0
            let (new_u, new_v) = Uint::ct_swap(&u, &v, swap);
117
0
            let (new_u, cy) = new_u.conditional_wrapping_sub(&new_v, self_odd);
118
0
            let (new_u, cyy) = new_u.conditional_wrapping_add(modulus, cy);
119
0
            debug_assert!(cy.is_true_vartime() == cyy.is_true_vartime());
120
121
0
            let (new_a, overflow) = a.shr_1();
122
0
            debug_assert!(!overflow.is_true_vartime());
123
0
            let (new_u, cy) = new_u.shr_1();
124
0
            let (new_u, cy) = new_u.conditional_wrapping_add(&m1hp, cy);
125
0
            debug_assert!(!cy.is_true_vartime());
126
127
0
            a = new_a;
128
0
            u = new_u;
129
0
            v = new_v;
130
0
131
0
            i += 1;
132
        }
133
134
0
        debug_assert!(!a.ct_is_nonzero().is_true_vartime());
135
136
0
        (v, Uint::ct_eq(&b, &Uint::ONE))
137
0
    }
138
139
    /// Computes the multiplicative inverse of `self` mod `modulus`, where `modulus` is odd.
140
    /// Returns `(inverse, CtChoice::TRUE)` if an inverse exists,
141
    /// otherwise `(undefined, CtChoice::FALSE)`.
142
0
    pub const fn inv_odd_mod(&self, modulus: &Self) -> (Self, CtChoice) {
143
0
        self.inv_odd_mod_bounded(modulus, Uint::<LIMBS>::BITS, Uint::<LIMBS>::BITS)
144
0
    }
145
146
    /// Computes the multiplicative inverse of `self` mod `modulus`.
147
    /// Returns `(inverse, CtChoice::TRUE)` if an inverse exists,
148
    /// otherwise `(undefined, CtChoice::FALSE)`.
149
0
    pub const fn inv_mod(&self, modulus: &Self) -> (Self, CtChoice) {
150
0
        // Decompose `modulus = s * 2^k` where `s` is odd
151
0
        let k = modulus.trailing_zeros();
152
0
        let s = modulus.shr(k);
153
0
154
0
        // Decompose `self` into RNS with moduli `2^k` and `s` and calculate the inverses.
155
0
        // Using the fact that `(z^{-1} mod (m1 * m2)) mod m1 == z^{-1} mod m1`
156
0
        let (a, a_is_some) = self.inv_odd_mod(&s);
157
0
        let b = self.inv_mod2k(k);
158
0
        // inverse modulo 2^k exists either if `k` is 0 or if `self` is odd.
159
0
        let b_is_some = CtChoice::from_usize_being_nonzero(k)
160
0
            .not()
161
0
            .or(self.ct_is_odd());
162
0
163
0
        // Restore from RNS:
164
0
        // self^{-1} = a mod s = b mod 2^k
165
0
        // => self^{-1} = a + s * ((b - a) * s^(-1) mod 2^k)
166
0
        // (essentially one step of the Garner's algorithm for recovery from RNS).
167
0
168
0
        let m_odd_inv = s.inv_mod2k(k); // `s` is odd, so this always exists
169
0
170
0
        // This part is mod 2^k
171
0
        let mask = Uint::ONE.shl(k).wrapping_sub(&Uint::ONE);
172
0
        let t = (b.wrapping_sub(&a).wrapping_mul(&m_odd_inv)).bitand(&mask);
173
0
174
0
        // Will not overflow since `a <= s - 1`, `t <= 2^k - 1`,
175
0
        // so `a + s * t <= s * 2^k - 1 == modulus - 1`.
176
0
        let result = a.wrapping_add(&s.wrapping_mul(&t));
177
0
        (result, a_is_some.and(b_is_some))
178
0
    }
179
}
180
181
#[cfg(test)]
182
mod tests {
183
    use crate::{U1024, U256, U64};
184
185
    #[test]
186
    fn inv_mod2k() {
187
        let v =
188
            U256::from_be_hex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f");
189
        let e =
190
            U256::from_be_hex("3642e6faeaac7c6663b93d3d6a0d489e434ddc0123db5fa627c7f6e22ddacacf");
191
        let a = v.inv_mod2k(256);
192
        assert_eq!(e, a);
193
194
        let v =
195
            U256::from_be_hex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");
196
        let e =
197
            U256::from_be_hex("261776f29b6b106c7680cf3ed83054a1af5ae537cb4613dbb4f20099aa774ec1");
198
        let a = v.inv_mod2k(256);
199
        assert_eq!(e, a);
200
    }
201
202
    #[test]
203
    fn test_invert_odd() {
204
        let a = U1024::from_be_hex(concat![
205
            "000225E99153B467A5B451979A3F451DAEF3BF8D6C6521D2FA24BBB17F29544E",
206
            "347A412B065B75A351EA9719E2430D2477B11CC9CF9C1AD6EDEE26CB15F463F8",
207
            "BCC72EF87EA30288E95A48AA792226CEC959DCB0672D8F9D80A54CBBEA85CAD8",
208
            "382EC224DEB2F5784E62D0CC2F81C2E6AD14EBABE646D6764B30C32B87688985"
209
        ]);
210
        let m = U1024::from_be_hex(concat![
211
            "D509E7854ABDC81921F669F1DC6F61359523F3949803E58ED4EA8BC16483DC6F",
212
            "37BFE27A9AC9EEA2969B357ABC5C0EE214BE16A7D4C58FC620D5B5A20AFF001A",
213
            "D198D3155E5799DC4EA76652D64983A7E130B5EACEBAC768D28D589C36EC749C",
214
            "558D0B64E37CD0775C0D0104AE7D98BA23C815185DD43CD8B16292FD94156767"
215
        ]);
216
        let expected = U1024::from_be_hex(concat![
217
            "B03623284B0EBABCABD5C5881893320281460C0A8E7BF4BFDCFFCBCCBF436A55",
218
            "D364235C8171E46C7D21AAD0680676E57274A8FDA6D12768EF961CACDD2DAE57",
219
            "88D93DA5EB8EDC391EE3726CDCF4613C539F7D23E8702200CB31B5ED5B06E5CA",
220
            "3E520968399B4017BF98A864FABA2B647EFC4998B56774D4F2CB026BC024A336"
221
        ]);
222
223
        let (res, is_some) = a.inv_odd_mod(&m);
224
        assert!(is_some.is_true_vartime());
225
        assert_eq!(res, expected);
226
227
        // Even though it is less efficient, it still works
228
        let (res, is_some) = a.inv_mod(&m);
229
        assert!(is_some.is_true_vartime());
230
        assert_eq!(res, expected);
231
    }
232
233
    #[test]
234
    fn test_invert_even() {
235
        let a = U1024::from_be_hex(concat![
236
            "000225E99153B467A5B451979A3F451DAEF3BF8D6C6521D2FA24BBB17F29544E",
237
            "347A412B065B75A351EA9719E2430D2477B11CC9CF9C1AD6EDEE26CB15F463F8",
238
            "BCC72EF87EA30288E95A48AA792226CEC959DCB0672D8F9D80A54CBBEA85CAD8",
239
            "382EC224DEB2F5784E62D0CC2F81C2E6AD14EBABE646D6764B30C32B87688985"
240
        ]);
241
        let m = U1024::from_be_hex(concat![
242
            "D509E7854ABDC81921F669F1DC6F61359523F3949803E58ED4EA8BC16483DC6F",
243
            "37BFE27A9AC9EEA2969B357ABC5C0EE214BE16A7D4C58FC620D5B5A20AFF001A",
244
            "D198D3155E5799DC4EA76652D64983A7E130B5EACEBAC768D28D589C36EC749C",
245
            "558D0B64E37CD0775C0D0104AE7D98BA23C815185DD43CD8B16292FD94156000"
246
        ]);
247
        let expected = U1024::from_be_hex(concat![
248
            "1EBF391306817E1BC610E213F4453AD70911CCBD59A901B2A468A4FC1D64F357",
249
            "DBFC6381EC5635CAA664DF280028AF4651482C77A143DF38D6BFD4D64B6C0225",
250
            "FC0E199B15A64966FB26D88A86AD144271F6BDCD3D63193AB2B3CC53B99F21A3",
251
            "5B9BFAE5D43C6BC6E7A9856C71C7318C76530E9E5AE35882D5ABB02F1696874D",
252
        ]);
253
254
        let (res, is_some) = a.inv_mod(&m);
255
        assert!(is_some.is_true_vartime());
256
        assert_eq!(res, expected);
257
    }
258
259
    #[test]
260
    fn test_invert_bounded() {
261
        let a = U1024::from_be_hex(concat![
262
            "0000000000000000000000000000000000000000000000000000000000000000",
263
            "347A412B065B75A351EA9719E2430D2477B11CC9CF9C1AD6EDEE26CB15F463F8",
264
            "BCC72EF87EA30288E95A48AA792226CEC959DCB0672D8F9D80A54CBBEA85CAD8",
265
            "382EC224DEB2F5784E62D0CC2F81C2E6AD14EBABE646D6764B30C32B87688985"
266
        ]);
267
        let m = U1024::from_be_hex(concat![
268
            "0000000000000000000000000000000000000000000000000000000000000000",
269
            "0000000000000000000000000000000000000000000000000000000000000000",
270
            "D198D3155E5799DC4EA76652D64983A7E130B5EACEBAC768D28D589C36EC749C",
271
            "558D0B64E37CD0775C0D0104AE7D98BA23C815185DD43CD8B16292FD94156767"
272
        ]);
273
274
        let (res, is_some) = a.inv_odd_mod_bounded(&m, 768, 512);
275
276
        let expected = U1024::from_be_hex(concat![
277
            "0000000000000000000000000000000000000000000000000000000000000000",
278
            "0000000000000000000000000000000000000000000000000000000000000000",
279
            "0DCC94E2FE509E6EBBA0825645A38E73EF85D5927C79C1AD8FFE7C8DF9A822FA",
280
            "09EB396A21B1EF05CBE51E1A8EF284EF01EBDD36A9A4EA17039D8EEFDD934768"
281
        ]);
282
        assert!(is_some.is_true_vartime());
283
        assert_eq!(res, expected);
284
    }
285
286
    #[test]
287
    fn test_invert_small() {
288
        let a = U64::from(3u64);
289
        let m = U64::from(13u64);
290
291
        let (res, is_some) = a.inv_odd_mod(&m);
292
293
        assert!(is_some.is_true_vartime());
294
        assert_eq!(U64::from(9u64), res);
295
    }
296
297
    #[test]
298
    fn test_no_inverse_small() {
299
        let a = U64::from(14u64);
300
        let m = U64::from(49u64);
301
302
        let (_res, is_some) = a.inv_odd_mod(&m);
303
304
        assert!(!is_some.is_true_vartime());
305
    }
306
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/macros.rs
Line
Count
Source
1
// TODO(tarcieri): use `generic_const_exprs` when stable to make generic around bits.
2
macro_rules! impl_uint_aliases {
3
    ($(($name:ident, $bits:expr, $doc:expr)),+) => {
4
        $(
5
            #[doc = $doc]
6
            #[doc="unsigned big integer."]
7
            pub type $name = Uint<{nlimbs!($bits)}>;
8
9
            impl Encoding for $name {
10
11
                type Repr = [u8; $bits / 8];
12
13
                #[inline]
14
0
                fn from_be_bytes(bytes: Self::Repr) -> Self {
15
0
                    Self::from_be_slice(&bytes)
16
0
                }
Unexecuted instantiation: _RNvXsg_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj1_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsh_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj2_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsi_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj3_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsj_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsk_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj5_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsl_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj6_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsm_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj7_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsn_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj8_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXso_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj9_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsp_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKja_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsq_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjb_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsr_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjc_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXss_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjd_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXst_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKje_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsu_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjf_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsv_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj10_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsw_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj14_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsx_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj18_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsy_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj1c_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsz_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj20_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsA_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj30_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsB_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj38_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsC_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj40_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsD_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj42_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsE_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj44_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsF_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj60_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsG_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj80_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsH_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj100_ENtNtB7_6traits8Encoding13from_be_bytesB7_
Unexecuted instantiation: _RNvXsI_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj200_ENtNtB7_6traits8Encoding13from_be_bytesB7_
17
18
                #[inline]
19
0
                fn from_le_bytes(bytes: Self::Repr) -> Self {
20
0
                    Self::from_le_slice(&bytes)
21
0
                }
Unexecuted instantiation: _RNvXsg_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj1_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsh_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj2_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsi_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj3_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsj_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsk_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj5_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsl_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj6_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsm_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj7_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsn_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj8_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXso_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj9_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsp_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKja_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsq_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjb_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsr_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjc_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXss_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjd_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXst_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKje_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsu_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjf_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsv_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj10_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsw_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj14_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsx_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj18_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsy_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj1c_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsz_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj20_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsA_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj30_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsB_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj38_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsC_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj40_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsD_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj42_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsE_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj44_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsF_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj60_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsG_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj80_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsH_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj100_ENtNtB7_6traits8Encoding13from_le_bytesB7_
Unexecuted instantiation: _RNvXsI_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj200_ENtNtB7_6traits8Encoding13from_le_bytesB7_
22
23
                #[inline]
24
0
                fn to_be_bytes(&self) -> Self::Repr {
25
0
                    let mut result = [0u8; $bits / 8];
26
0
                    self.write_be_bytes(&mut result);
27
0
                    result
28
0
                }
Unexecuted instantiation: _RNvXsg_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj1_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsh_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj2_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsi_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj3_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsj_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsk_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj5_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsl_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj6_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsm_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj7_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsn_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj8_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXso_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj9_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsp_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKja_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsq_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjb_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsr_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjc_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXss_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjd_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXst_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKje_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsu_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjf_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsv_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj10_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsw_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj14_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsx_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj18_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsy_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj1c_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsz_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj20_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsA_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj30_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsB_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj38_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsC_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj40_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsD_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj42_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsE_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj44_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsF_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj60_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsG_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj80_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsH_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj100_ENtNtB7_6traits8Encoding11to_be_bytesB7_
Unexecuted instantiation: _RNvXsI_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj200_ENtNtB7_6traits8Encoding11to_be_bytesB7_
29
30
                #[inline]
31
0
                fn to_le_bytes(&self) -> Self::Repr {
32
0
                    let mut result = [0u8; $bits / 8];
33
0
                    self.write_le_bytes(&mut result);
34
0
                    result
35
0
                }
Unexecuted instantiation: _RNvXsg_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj1_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsh_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj2_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsi_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj3_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsj_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsk_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj5_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsl_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj6_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsm_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj7_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsn_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj8_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXso_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj9_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsp_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKja_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsq_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjb_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsr_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjc_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXss_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjd_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXst_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKje_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsu_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKjf_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsv_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj10_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsw_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj14_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsx_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj18_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsy_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj1c_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsz_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj20_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsA_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj30_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsB_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj38_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsC_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj40_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsD_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj42_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsE_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj44_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsF_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj60_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsG_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj80_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsH_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj100_ENtNtB7_6traits8Encoding11to_le_bytesB7_
Unexecuted instantiation: _RNvXsI_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj200_ENtNtB7_6traits8Encoding11to_le_bytesB7_
36
            }
37
        )+
38
     };
39
}
40
41
macro_rules! impl_uint_concat_split_mixed {
42
    ($name:ident, $size:literal) => {
43
        impl $crate::traits::ConcatMixed<Uint<{ U64::LIMBS * $size }>> for Uint<{ <$name>::LIMBS - U64::LIMBS * $size }>
44
        {
45
            type MixedOutput = $name;
46
47
0
            fn concat_mixed(&self, lo: &Uint<{ U64::LIMBS * $size }>) -> Self::MixedOutput {
48
0
                $crate::uint::concat::concat_mixed(lo, self)
49
0
            }
Unexecuted instantiation: _RNvXs2l_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs2n_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs2p_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs2r_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs2t_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs2v_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs2x_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs2z_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kj4_EE12concat_mixed
Unexecuted instantiation: _RNvXs2B_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs2D_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs2F_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kj4_EE12concat_mixed
Unexecuted instantiation: _RNvXs2H_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kj5_EE12concat_mixed
Unexecuted instantiation: _RNvXs2J_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs2L_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs2N_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs2P_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kj4_EE12concat_mixed
Unexecuted instantiation: _RNvXs2R_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kj5_EE12concat_mixed
Unexecuted instantiation: _RNvXs2T_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kj6_EE12concat_mixed
Unexecuted instantiation: _RNvXs2V_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs2X_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs2Z_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs31_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kj5_EE12concat_mixed
Unexecuted instantiation: _RNvXs33_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kj6_EE12concat_mixed
Unexecuted instantiation: _RNvXs35_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kj7_EE12concat_mixed
Unexecuted instantiation: _RNvXs37_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs39_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs3b_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs3d_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits11ConcatMixedIBH_Kj4_EE12concat_mixed
Unexecuted instantiation: _RNvXs3f_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits11ConcatMixedIBH_Kj5_EE12concat_mixed
Unexecuted instantiation: _RNvXs3h_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kj6_EE12concat_mixed
Unexecuted instantiation: _RNvXs3j_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kj7_EE12concat_mixed
Unexecuted instantiation: _RNvXs3l_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kj8_EE12concat_mixed
Unexecuted instantiation: _RNvXs3n_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs3p_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs3r_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs3t_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits11ConcatMixedIBH_Kj4_EE12concat_mixed
Unexecuted instantiation: _RNvXs3v_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits11ConcatMixedIBH_Kj6_EE12concat_mixed
Unexecuted instantiation: _RNvXs3x_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kj7_EE12concat_mixed
Unexecuted instantiation: _RNvXs3z_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kj8_EE12concat_mixed
Unexecuted instantiation: _RNvXs3B_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kj9_EE12concat_mixed
Unexecuted instantiation: _RNvXs3D_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs3F_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs3H_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs3J_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits11ConcatMixedIBH_Kj4_EE12concat_mixed
Unexecuted instantiation: _RNvXs3L_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits11ConcatMixedIBH_Kj5_EE12concat_mixed
Unexecuted instantiation: _RNvXs3N_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits11ConcatMixedIBH_Kj6_EE12concat_mixed
Unexecuted instantiation: _RNvXs3P_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits11ConcatMixedIBH_Kj7_EE12concat_mixed
Unexecuted instantiation: _RNvXs3R_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kj8_EE12concat_mixed
Unexecuted instantiation: _RNvXs3T_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kj9_EE12concat_mixed
Unexecuted instantiation: _RNvXs3V_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kja_EE12concat_mixed
Unexecuted instantiation: _RNvXs3X_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs3Z_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs41_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs43_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits11ConcatMixedIBH_Kj4_EE12concat_mixed
Unexecuted instantiation: _RNvXs45_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits11ConcatMixedIBH_Kj5_EE12concat_mixed
Unexecuted instantiation: _RNvXs47_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits11ConcatMixedIBH_Kj7_EE12concat_mixed
Unexecuted instantiation: _RNvXs49_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits11ConcatMixedIBH_Kj8_EE12concat_mixed
Unexecuted instantiation: _RNvXs4b_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kj9_EE12concat_mixed
Unexecuted instantiation: _RNvXs4d_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kja_EE12concat_mixed
Unexecuted instantiation: _RNvXs4f_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kjb_EE12concat_mixed
Unexecuted instantiation: _RNvXs4h_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs4j_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs4l_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs4n_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits11ConcatMixedIBH_Kj4_EE12concat_mixed
Unexecuted instantiation: _RNvXs4p_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits11ConcatMixedIBH_Kj5_EE12concat_mixed
Unexecuted instantiation: _RNvXs4r_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits11ConcatMixedIBH_Kj6_EE12concat_mixed
Unexecuted instantiation: _RNvXs4t_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits11ConcatMixedIBH_Kj7_EE12concat_mixed
Unexecuted instantiation: _RNvXs4v_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits11ConcatMixedIBH_Kj8_EE12concat_mixed
Unexecuted instantiation: _RNvXs4x_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits11ConcatMixedIBH_Kj9_EE12concat_mixed
Unexecuted instantiation: _RNvXs4z_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kja_EE12concat_mixed
Unexecuted instantiation: _RNvXs4B_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kjb_EE12concat_mixed
Unexecuted instantiation: _RNvXs4D_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kjc_EE12concat_mixed
Unexecuted instantiation: _RNvXs4F_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs4H_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs4J_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs4L_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits11ConcatMixedIBH_Kj4_EE12concat_mixed
Unexecuted instantiation: _RNvXs4N_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits11ConcatMixedIBH_Kj5_EE12concat_mixed
Unexecuted instantiation: _RNvXs4P_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits11ConcatMixedIBH_Kj6_EE12concat_mixed
Unexecuted instantiation: _RNvXs4R_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits11ConcatMixedIBH_Kj8_EE12concat_mixed
Unexecuted instantiation: _RNvXs4T_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits11ConcatMixedIBH_Kj9_EE12concat_mixed
Unexecuted instantiation: _RNvXs4V_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits11ConcatMixedIBH_Kja_EE12concat_mixed
Unexecuted instantiation: _RNvXs4X_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kjb_EE12concat_mixed
Unexecuted instantiation: _RNvXs4Z_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kjc_EE12concat_mixed
Unexecuted instantiation: _RNvXs51_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kjd_EE12concat_mixed
Unexecuted instantiation: _RNvXs53_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs55_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs57_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs59_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits11ConcatMixedIBH_Kj4_EE12concat_mixed
Unexecuted instantiation: _RNvXs5b_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits11ConcatMixedIBH_Kj5_EE12concat_mixed
Unexecuted instantiation: _RNvXs5d_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits11ConcatMixedIBH_Kj6_EE12concat_mixed
Unexecuted instantiation: _RNvXs5f_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits11ConcatMixedIBH_Kj7_EE12concat_mixed
Unexecuted instantiation: _RNvXs5h_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits11ConcatMixedIBH_Kj8_EE12concat_mixed
Unexecuted instantiation: _RNvXs5j_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits11ConcatMixedIBH_Kj9_EE12concat_mixed
Unexecuted instantiation: _RNvXs5l_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits11ConcatMixedIBH_Kja_EE12concat_mixed
Unexecuted instantiation: _RNvXs5n_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits11ConcatMixedIBH_Kjb_EE12concat_mixed
Unexecuted instantiation: _RNvXs5p_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kjc_EE12concat_mixed
Unexecuted instantiation: _RNvXs5r_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kjd_EE12concat_mixed
Unexecuted instantiation: _RNvXs5t_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kje_EE12concat_mixed
Unexecuted instantiation: _RNvXs5v_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits11ConcatMixedIBH_Kj1_EE12concat_mixed
Unexecuted instantiation: _RNvXs5x_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits11ConcatMixedIBH_Kj2_EE12concat_mixed
Unexecuted instantiation: _RNvXs5z_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits11ConcatMixedIBH_Kj3_EE12concat_mixed
Unexecuted instantiation: _RNvXs5B_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits11ConcatMixedIBH_Kj4_EE12concat_mixed
Unexecuted instantiation: _RNvXs5D_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits11ConcatMixedIBH_Kj5_EE12concat_mixed
Unexecuted instantiation: _RNvXs5F_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits11ConcatMixedIBH_Kj6_EE12concat_mixed
Unexecuted instantiation: _RNvXs5H_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits11ConcatMixedIBH_Kj7_EE12concat_mixed
Unexecuted instantiation: _RNvXs5J_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits11ConcatMixedIBH_Kj9_EE12concat_mixed
Unexecuted instantiation: _RNvXs5L_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits11ConcatMixedIBH_Kja_EE12concat_mixed
Unexecuted instantiation: _RNvXs5N_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits11ConcatMixedIBH_Kjb_EE12concat_mixed
Unexecuted instantiation: _RNvXs5P_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits11ConcatMixedIBH_Kjc_EE12concat_mixed
Unexecuted instantiation: _RNvXs5R_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits11ConcatMixedIBH_Kjd_EE12concat_mixed
Unexecuted instantiation: _RNvXs5T_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj2_EINtNtB8_6traits11ConcatMixedIBH_Kje_EE12concat_mixed
Unexecuted instantiation: _RNvXs5V_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1_EINtNtB8_6traits11ConcatMixedIBH_Kjf_EE12concat_mixed
50
        }
51
52
        impl $crate::traits::SplitMixed<Uint<{ U64::LIMBS * $size }>, Uint<{ <$name>::LIMBS - U64::LIMBS * $size }>> for $name
53
        {
54
0
            fn split_mixed(&self) -> (Uint<{ U64::LIMBS * $size }>, Uint<{ <$name>::LIMBS - U64::LIMBS * $size }>) {
55
0
                $crate::uint::split::split_mixed(self)
56
0
            }
Unexecuted instantiation: _RNvXs2m_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs2o_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj3_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs2q_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs2s_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj4_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs2u_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kj4_EE11split_mixed
Unexecuted instantiation: _RNvXs2w_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs2y_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs2A_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_EINtNtB8_6traits10SplitMixedIBH_Kj4_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs2C_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kj5_EE11split_mixed
Unexecuted instantiation: _RNvXs2E_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kj4_EE11split_mixed
Unexecuted instantiation: _RNvXs2G_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits10SplitMixedIBH_Kj4_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs2I_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_EINtNtB8_6traits10SplitMixedIBH_Kj5_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs2K_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kj6_EE11split_mixed
Unexecuted instantiation: _RNvXs2M_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kj5_EE11split_mixed
Unexecuted instantiation: _RNvXs2O_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kj4_EE11split_mixed
Unexecuted instantiation: _RNvXs2Q_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits10SplitMixedIBH_Kj4_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs2S_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits10SplitMixedIBH_Kj5_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs2U_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_EINtNtB8_6traits10SplitMixedIBH_Kj6_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs2W_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kj7_EE11split_mixed
Unexecuted instantiation: _RNvXs2Y_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kj6_EE11split_mixed
Unexecuted instantiation: _RNvXs30_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kj5_EE11split_mixed
Unexecuted instantiation: _RNvXs32_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits10SplitMixedIBH_Kj5_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs34_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits10SplitMixedIBH_Kj6_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs36_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits10SplitMixedIBH_Kj7_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs38_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kj8_EE11split_mixed
Unexecuted instantiation: _RNvXs3a_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kj7_EE11split_mixed
Unexecuted instantiation: _RNvXs3c_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kj6_EE11split_mixed
Unexecuted instantiation: _RNvXs3e_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits10SplitMixedIBH_Kj4_EIBH_Kj5_EE11split_mixed
Unexecuted instantiation: _RNvXs3g_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits10SplitMixedIBH_Kj5_EIBH_Kj4_EE11split_mixed
Unexecuted instantiation: _RNvXs3i_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits10SplitMixedIBH_Kj6_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs3k_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits10SplitMixedIBH_Kj7_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs3m_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj9_EINtNtB8_6traits10SplitMixedIBH_Kj8_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs3o_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kj9_EE11split_mixed
Unexecuted instantiation: _RNvXs3q_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kj8_EE11split_mixed
Unexecuted instantiation: _RNvXs3s_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kj7_EE11split_mixed
Unexecuted instantiation: _RNvXs3u_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits10SplitMixedIBH_Kj4_EIBH_Kj6_EE11split_mixed
Unexecuted instantiation: _RNvXs3w_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits10SplitMixedIBH_Kj6_EIBH_Kj4_EE11split_mixed
Unexecuted instantiation: _RNvXs3y_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits10SplitMixedIBH_Kj7_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs3A_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits10SplitMixedIBH_Kj8_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs3C_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits10SplitMixedIBH_Kj9_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs3E_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kja_EE11split_mixed
Unexecuted instantiation: _RNvXs3G_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kj9_EE11split_mixed
Unexecuted instantiation: _RNvXs3I_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kj8_EE11split_mixed
Unexecuted instantiation: _RNvXs3K_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits10SplitMixedIBH_Kj4_EIBH_Kj7_EE11split_mixed
Unexecuted instantiation: _RNvXs3M_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits10SplitMixedIBH_Kj5_EIBH_Kj6_EE11split_mixed
Unexecuted instantiation: _RNvXs3O_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits10SplitMixedIBH_Kj6_EIBH_Kj5_EE11split_mixed
Unexecuted instantiation: _RNvXs3Q_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits10SplitMixedIBH_Kj7_EIBH_Kj4_EE11split_mixed
Unexecuted instantiation: _RNvXs3S_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits10SplitMixedIBH_Kj8_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs3U_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits10SplitMixedIBH_Kj9_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs3W_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjb_EINtNtB8_6traits10SplitMixedIBH_Kja_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs3Y_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kjb_EE11split_mixed
Unexecuted instantiation: _RNvXs40_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kja_EE11split_mixed
Unexecuted instantiation: _RNvXs42_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kj9_EE11split_mixed
Unexecuted instantiation: _RNvXs44_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits10SplitMixedIBH_Kj4_EIBH_Kj8_EE11split_mixed
Unexecuted instantiation: _RNvXs46_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits10SplitMixedIBH_Kj5_EIBH_Kj7_EE11split_mixed
Unexecuted instantiation: _RNvXs48_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits10SplitMixedIBH_Kj7_EIBH_Kj5_EE11split_mixed
Unexecuted instantiation: _RNvXs4a_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits10SplitMixedIBH_Kj8_EIBH_Kj4_EE11split_mixed
Unexecuted instantiation: _RNvXs4c_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits10SplitMixedIBH_Kj9_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs4e_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits10SplitMixedIBH_Kja_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs4g_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits10SplitMixedIBH_Kjb_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs4i_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kjc_EE11split_mixed
Unexecuted instantiation: _RNvXs4k_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kjb_EE11split_mixed
Unexecuted instantiation: _RNvXs4m_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kja_EE11split_mixed
Unexecuted instantiation: _RNvXs4o_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kj4_EIBH_Kj9_EE11split_mixed
Unexecuted instantiation: _RNvXs4q_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kj5_EIBH_Kj8_EE11split_mixed
Unexecuted instantiation: _RNvXs4s_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kj6_EIBH_Kj7_EE11split_mixed
Unexecuted instantiation: _RNvXs4u_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kj7_EIBH_Kj6_EE11split_mixed
Unexecuted instantiation: _RNvXs4w_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kj8_EIBH_Kj5_EE11split_mixed
Unexecuted instantiation: _RNvXs4y_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kj9_EIBH_Kj4_EE11split_mixed
Unexecuted instantiation: _RNvXs4A_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kja_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs4C_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kjb_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs4E_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjd_EINtNtB8_6traits10SplitMixedIBH_Kjc_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs4G_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kjd_EE11split_mixed
Unexecuted instantiation: _RNvXs4I_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kjc_EE11split_mixed
Unexecuted instantiation: _RNvXs4K_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kjb_EE11split_mixed
Unexecuted instantiation: _RNvXs4M_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kj4_EIBH_Kja_EE11split_mixed
Unexecuted instantiation: _RNvXs4O_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kj5_EIBH_Kj9_EE11split_mixed
Unexecuted instantiation: _RNvXs4Q_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kj6_EIBH_Kj8_EE11split_mixed
Unexecuted instantiation: _RNvXs4S_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kj8_EIBH_Kj6_EE11split_mixed
Unexecuted instantiation: _RNvXs4U_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kj9_EIBH_Kj5_EE11split_mixed
Unexecuted instantiation: _RNvXs4W_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kja_EIBH_Kj4_EE11split_mixed
Unexecuted instantiation: _RNvXs4Y_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kjb_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs50_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kjc_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs52_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kjd_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs54_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kje_EE11split_mixed
Unexecuted instantiation: _RNvXs56_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kjd_EE11split_mixed
Unexecuted instantiation: _RNvXs58_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kjc_EE11split_mixed
Unexecuted instantiation: _RNvXs5a_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kj4_EIBH_Kjb_EE11split_mixed
Unexecuted instantiation: _RNvXs5c_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kj5_EIBH_Kja_EE11split_mixed
Unexecuted instantiation: _RNvXs5e_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kj6_EIBH_Kj9_EE11split_mixed
Unexecuted instantiation: _RNvXs5g_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kj7_EIBH_Kj8_EE11split_mixed
Unexecuted instantiation: _RNvXs5i_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kj8_EIBH_Kj7_EE11split_mixed
Unexecuted instantiation: _RNvXs5k_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kj9_EIBH_Kj6_EE11split_mixed
Unexecuted instantiation: _RNvXs5m_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kja_EIBH_Kj5_EE11split_mixed
Unexecuted instantiation: _RNvXs5o_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kjb_EIBH_Kj4_EE11split_mixed
Unexecuted instantiation: _RNvXs5q_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kjc_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs5s_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kjd_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs5u_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjf_EINtNtB8_6traits10SplitMixedIBH_Kje_EIBH_Kj1_EE11split_mixed
Unexecuted instantiation: _RNvXs5w_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kj1_EIBH_Kjf_EE11split_mixed
Unexecuted instantiation: _RNvXs5y_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kj2_EIBH_Kje_EE11split_mixed
Unexecuted instantiation: _RNvXs5A_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kj3_EIBH_Kjd_EE11split_mixed
Unexecuted instantiation: _RNvXs5C_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kj4_EIBH_Kjc_EE11split_mixed
Unexecuted instantiation: _RNvXs5E_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kj5_EIBH_Kjb_EE11split_mixed
Unexecuted instantiation: _RNvXs5G_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kj6_EIBH_Kja_EE11split_mixed
Unexecuted instantiation: _RNvXs5I_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kj7_EIBH_Kj9_EE11split_mixed
Unexecuted instantiation: _RNvXs5K_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kj9_EIBH_Kj7_EE11split_mixed
Unexecuted instantiation: _RNvXs5M_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kja_EIBH_Kj6_EE11split_mixed
Unexecuted instantiation: _RNvXs5O_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kjb_EIBH_Kj5_EE11split_mixed
Unexecuted instantiation: _RNvXs5Q_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kjc_EIBH_Kj4_EE11split_mixed
Unexecuted instantiation: _RNvXs5S_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kjd_EIBH_Kj3_EE11split_mixed
Unexecuted instantiation: _RNvXs5U_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kje_EIBH_Kj2_EE11split_mixed
Unexecuted instantiation: _RNvXs5W_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kjf_EIBH_Kj1_EE11split_mixed
57
        }
58
    };
59
    ($name:ident, [ $($size:literal),+ ]) => {
60
        $(
61
            impl_uint_concat_split_mixed!($name, $size);
62
        )+
63
    };
64
    ($( ($name:ident, $sizes:tt), )+) => {
65
        $(
66
            impl_uint_concat_split_mixed!($name, $sizes);
67
        )+
68
    };
69
}
70
71
macro_rules! impl_uint_concat_split_even {
72
    ($name:ident) => {
73
        impl $crate::traits::ConcatMixed<Uint<{ <$name>::LIMBS / 2 }>> for Uint<{ <$name>::LIMBS / 2 }>
74
        {
75
            type MixedOutput = $name;
76
77
0
            fn concat_mixed(&self, lo: &Uint<{ <$name>::LIMBS / 2 }>) -> Self::MixedOutput {
78
0
                $crate::uint::concat::concat_mixed(lo, self)
79
0
            }
Unexecuted instantiation: _RNvXsJ_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj1_ENtNtB7_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXsO_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj2_ENtNtB7_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXsT_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj3_ENtNtB7_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXsY_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_ENtNtB7_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs13_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs18_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs1d_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs1i_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs1n_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs1s_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs1x_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs1C_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs1H_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj18_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs1M_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1c_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs1R_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj20_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs1W_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj21_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs21_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj22_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs26_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj30_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs2b_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj40_ENtNtB8_6traits11ConcatMixed12concat_mixed
Unexecuted instantiation: _RNvXs2g_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj80_ENtNtB8_6traits11ConcatMixed12concat_mixed
80
        }
81
82
        impl Uint<{ <$name>::LIMBS / 2 }> {
83
            /// Concatenate the two values, with `self` as most significant and `rhs`
84
            /// as the least significant.
85
0
            pub const fn concat(&self, lo: &Uint<{ <$name>::LIMBS / 2 }>) -> $name {
86
0
                $crate::uint::concat::concat_mixed(lo, self)
87
0
            }
Unexecuted instantiation: _RNvMsK_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj1_E6concat
Unexecuted instantiation: _RNvMsP_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj2_E6concat
Unexecuted instantiation: _RNvMsU_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj3_E6concat
Unexecuted instantiation: _RNvMsZ_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_E6concat
Unexecuted instantiation: _RNvMs14_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj5_E6concat
Unexecuted instantiation: _RNvMs19_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj6_E6concat
Unexecuted instantiation: _RNvMs1e_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj7_E6concat
Unexecuted instantiation: _RNvMs1j_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_E6concat
Unexecuted instantiation: _RNvMs1o_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_E6concat
Unexecuted instantiation: _RNvMs1t_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_E6concat
Unexecuted instantiation: _RNvMs1y_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_E6concat
Unexecuted instantiation: _RNvMs1D_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_E6concat
Unexecuted instantiation: _RNvMs1I_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj18_E6concat
Unexecuted instantiation: _RNvMs1N_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1c_E6concat
Unexecuted instantiation: _RNvMs1S_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj20_E6concat
Unexecuted instantiation: _RNvMs1X_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj21_E6concat
Unexecuted instantiation: _RNvMs22_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj22_E6concat
Unexecuted instantiation: _RNvMs27_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj30_E6concat
Unexecuted instantiation: _RNvMs2c_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj40_E6concat
Unexecuted instantiation: _RNvMs2h_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj80_E6concat
88
        }
89
90
        impl $crate::traits::SplitMixed<Uint<{ <$name>::LIMBS / 2 }>, Uint<{ <$name>::LIMBS / 2 }>> for $name
91
        {
92
0
            fn split_mixed(&self) -> (Uint<{ <$name>::LIMBS / 2 }>, Uint<{ <$name>::LIMBS / 2 }>) {
93
0
                $crate::uint::split::split_mixed(self)
94
0
            }
Unexecuted instantiation: _RNvXsL_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj2_EINtNtB7_6traits10SplitMixedIBG_Kj1_EB1m_E11split_mixed
Unexecuted instantiation: _RNvXsQ_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_EINtNtB7_6traits10SplitMixedIBG_Kj2_EB1m_E11split_mixed
Unexecuted instantiation: _RNvXsV_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj6_EINtNtB7_6traits10SplitMixedIBG_Kj3_EB1m_E11split_mixed
Unexecuted instantiation: _RNvXs10_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_EINtNtB8_6traits10SplitMixedIBH_Kj4_EB1n_E11split_mixed
Unexecuted instantiation: _RNvXs15_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_EINtNtB8_6traits10SplitMixedIBH_Kj5_EB1n_E11split_mixed
Unexecuted instantiation: _RNvXs1a_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_EINtNtB8_6traits10SplitMixedIBH_Kj6_EB1n_E11split_mixed
Unexecuted instantiation: _RNvXs1f_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_EINtNtB8_6traits10SplitMixedIBH_Kj7_EB1n_E11split_mixed
Unexecuted instantiation: _RNvXs1k_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_EINtNtB8_6traits10SplitMixedIBH_Kj8_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs1p_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj14_EINtNtB8_6traits10SplitMixedIBH_Kja_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs1u_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj18_EINtNtB8_6traits10SplitMixedIBH_Kjc_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs1z_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1c_EINtNtB8_6traits10SplitMixedIBH_Kje_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs1E_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj20_EINtNtB8_6traits10SplitMixedIBH_Kj10_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs1J_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj30_EINtNtB8_6traits10SplitMixedIBH_Kj18_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs1O_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj38_EINtNtB8_6traits10SplitMixedIBH_Kj1c_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs1T_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj40_EINtNtB8_6traits10SplitMixedIBH_Kj20_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs1Y_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj42_EINtNtB8_6traits10SplitMixedIBH_Kj21_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs23_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj44_EINtNtB8_6traits10SplitMixedIBH_Kj22_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs28_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj60_EINtNtB8_6traits10SplitMixedIBH_Kj30_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs2d_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj80_EINtNtB8_6traits10SplitMixedIBH_Kj40_EB1o_E11split_mixed
Unexecuted instantiation: _RNvXs2i_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj100_EINtNtB8_6traits10SplitMixedIBH_Kj80_EB1p_E11split_mixed
95
        }
96
97
        impl $crate::traits::Split for $name
98
        {
99
            type Output = Uint<{ <$name>::LIMBS / 2 }>;
100
        }
101
102
        impl $name {
103
            /// Split this number in half, returning its high and low components
104
            /// respectively.
105
0
            pub const fn split(&self) -> (Uint<{ <$name>::LIMBS / 2 }>, Uint<{ <$name>::LIMBS / 2 }>) {
106
0
                $crate::uint::split::split_mixed(self)
107
0
            }
Unexecuted instantiation: _RNvMsN_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj2_E5split
Unexecuted instantiation: _RNvMsS_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj4_E5split
Unexecuted instantiation: _RNvMsX_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB5_4UintKj6_E5split
Unexecuted instantiation: _RNvMs12_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj8_E5split
Unexecuted instantiation: _RNvMs17_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKja_E5split
Unexecuted instantiation: _RNvMs1c_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKjc_E5split
Unexecuted instantiation: _RNvMs1h_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKje_E5split
Unexecuted instantiation: _RNvMs1m_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj10_E5split
Unexecuted instantiation: _RNvMs1r_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj14_E5split
Unexecuted instantiation: _RNvMs1w_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj18_E5split
Unexecuted instantiation: _RNvMs1B_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj1c_E5split
Unexecuted instantiation: _RNvMs1G_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj20_E5split
Unexecuted instantiation: _RNvMs1L_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj30_E5split
Unexecuted instantiation: _RNvMs1Q_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj38_E5split
Unexecuted instantiation: _RNvMs1V_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj40_E5split
Unexecuted instantiation: _RNvMs20_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj42_E5split
Unexecuted instantiation: _RNvMs25_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj44_E5split
Unexecuted instantiation: _RNvMs2a_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj60_E5split
Unexecuted instantiation: _RNvMs2f_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj80_E5split
Unexecuted instantiation: _RNvMs2k_NtCshRehcWQJ0wE_13crypto_bigint4uintINtB6_4UintKj100_E5split
108
        }
109
    };
110
    ($($name:ident,)+) => {
111
        $(
112
            impl_uint_concat_split_even!($name);
113
        )+
114
    }
115
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/add.rs
Line
Count
Source
1
use crate::Uint;
2
3
0
pub(crate) const fn add_montgomery_form<const LIMBS: usize>(
4
0
    a: &Uint<LIMBS>,
5
0
    b: &Uint<LIMBS>,
6
0
    modulus: &Uint<LIMBS>,
7
0
) -> Uint<LIMBS> {
8
0
    a.add_mod(b, modulus)
9
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/constant_mod.rs
Line
Count
Source
1
use core::{fmt::Debug, marker::PhantomData};
2
3
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
4
5
use crate::{Limb, Uint, Zero};
6
7
use super::{div_by_2::div_by_2, reduction::montgomery_reduction, Retrieve};
8
9
#[cfg(feature = "rand_core")]
10
use crate::{rand_core::CryptoRngCore, NonZero, Random, RandomMod};
11
12
#[cfg(feature = "serde")]
13
use {
14
    crate::Encoding,
15
    serdect::serde::de::Error,
16
    serdect::serde::{Deserialize, Deserializer, Serialize, Serializer},
17
};
18
19
/// Additions between residues with a constant modulus
20
mod const_add;
21
/// Multiplicative inverses of residues with a constant modulus
22
mod const_inv;
23
/// Multiplications between residues with a constant modulus
24
mod const_mul;
25
/// Negations of residues with a constant modulus
26
mod const_neg;
27
/// Exponentiation of residues with a constant modulus
28
mod const_pow;
29
/// Subtractions between residues with a constant modulus
30
mod const_sub;
31
32
/// Macros to remove the boilerplate code when dealing with constant moduli.
33
#[macro_use]
34
mod macros;
35
36
pub use macros::*;
37
38
/// The parameters to efficiently go to and from the Montgomery form for a given odd modulus. An easy way to generate these parameters is using the `impl_modulus!` macro. These parameters are constant, so they cannot be set at runtime.
39
///
40
/// Unfortunately, `LIMBS` must be generic for now until const generics are stabilized.
41
pub trait ResidueParams<const LIMBS: usize>:
42
    Copy + Debug + Default + Eq + Send + Sync + 'static
43
{
44
    /// Number of limbs required to encode a residue
45
    const LIMBS: usize;
46
47
    /// The constant modulus
48
    const MODULUS: Uint<LIMBS>;
49
    /// Parameter used in Montgomery reduction
50
    const R: Uint<LIMBS>;
51
    /// R^2, used to move into Montgomery form
52
    const R2: Uint<LIMBS>;
53
    /// R^3, used to perform a multiplicative inverse
54
    const R3: Uint<LIMBS>;
55
    /// The lowest limbs of -(MODULUS^-1) mod R
56
    // We only need the LSB because during reduction this value is multiplied modulo 2**Limb::BITS.
57
    const MOD_NEG_INV: Limb;
58
}
59
60
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61
/// A residue mod `MOD`, represented using `LIMBS` limbs. The modulus of this residue is constant, so it cannot be set at runtime.
62
/// Internally, the value is stored in Montgomery form (multiplied by MOD::R) until it is retrieved.
63
pub struct Residue<MOD, const LIMBS: usize>
64
where
65
    MOD: ResidueParams<LIMBS>,
66
{
67
    montgomery_form: Uint<LIMBS>,
68
    phantom: PhantomData<MOD>,
69
}
70
71
#[cfg(feature = "zeroize")]
72
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> zeroize::DefaultIsZeroes
73
    for Residue<MOD, LIMBS>
74
{
75
}
76
77
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Residue<MOD, LIMBS> {
78
    /// The representation of 0 mod `MOD`.
79
    pub const ZERO: Self = Self {
80
        montgomery_form: Uint::<LIMBS>::ZERO,
81
        phantom: PhantomData,
82
    };
83
84
    /// The representation of 1 mod `MOD`.
85
    pub const ONE: Self = Self {
86
        montgomery_form: MOD::R,
87
        phantom: PhantomData,
88
    };
89
90
    // Internal helper function to generate a residue; this lets us wrap the constructors more cleanly
91
0
    const fn generate_residue(integer: &Uint<LIMBS>) -> Self {
92
0
        let product = integer.mul_wide(&MOD::R2);
93
0
        let montgomery_form =
94
0
            montgomery_reduction::<LIMBS>(&product, &MOD::MODULUS, MOD::MOD_NEG_INV);
95
0
96
0
        Self {
97
0
            montgomery_form,
98
0
            phantom: PhantomData,
99
0
        }
100
0
    }
101
102
    /// Instantiates a new `Residue` that represents this `integer` mod `MOD`.
103
    /// If the modulus represented by `MOD` is not odd, this function will panic; use [`new_checked`][`Residue::new_checked`] if you want to be able to detect an invalid modulus.
104
0
    pub const fn new(integer: &Uint<LIMBS>) -> Self {
105
0
        // A valid modulus must be odd
106
0
        if MOD::MODULUS.ct_is_odd().to_u8() == 0 {
107
0
            panic!("modulus must be odd");
108
0
        }
109
0
110
0
        Self::generate_residue(integer)
111
0
    }
112
113
    /// Instantiates a new `Residue` that represents this `integer` mod `MOD` if the modulus is odd.
114
    /// Returns a `CtOption` that is `None` if the provided modulus is not odd; this is a safer version of [`new`][`Residue::new`], which can panic.
115
    // TODO: remove this method when we can use `generic_const_exprs.` to ensure the modulus is
116
    // always valid.
117
0
    pub fn new_checked(integer: &Uint<LIMBS>) -> CtOption<Self> {
118
0
        // A valid modulus must be odd.
119
0
        CtOption::new(
120
0
            Self::generate_residue(integer),
121
0
            MOD::MODULUS.ct_is_odd().into(),
122
0
        )
123
0
    }
124
125
    /// Retrieves the integer currently encoded in this `Residue`, guaranteed to be reduced.
126
0
    pub const fn retrieve(&self) -> Uint<LIMBS> {
127
0
        montgomery_reduction::<LIMBS>(
128
0
            &(self.montgomery_form, Uint::ZERO),
129
0
            &MOD::MODULUS,
130
0
            MOD::MOD_NEG_INV,
131
0
        )
132
0
    }
133
134
    /// Access the `Residue` value in Montgomery form.
135
0
    pub const fn as_montgomery(&self) -> &Uint<LIMBS> {
136
0
        &self.montgomery_form
137
0
    }
138
139
    /// Mutably access the `Residue` value in Montgomery form.
140
0
    pub fn as_montgomery_mut(&mut self) -> &mut Uint<LIMBS> {
141
0
        &mut self.montgomery_form
142
0
    }
143
144
    /// Create a `Residue` from a value in Montgomery form.
145
0
    pub const fn from_montgomery(integer: Uint<LIMBS>) -> Self {
146
0
        Self {
147
0
            montgomery_form: integer,
148
0
            phantom: PhantomData,
149
0
        }
150
0
    }
151
152
    /// Extract the value from the `Residue` in Montgomery form.
153
0
    pub const fn to_montgomery(&self) -> Uint<LIMBS> {
154
0
        self.montgomery_form
155
0
    }
156
157
    /// Performs the modular division by 2, that is for given `x` returns `y`
158
    /// such that `y * 2 = x mod p`. This means:
159
    /// - if `x` is even, returns `x / 2`,
160
    /// - if `x` is odd, returns `(x + p) / 2`
161
    ///   (since the modulus `p` in Montgomery form is always odd, this divides entirely).
162
0
    pub fn div_by_2(&self) -> Self {
163
0
        Self {
164
0
            montgomery_form: div_by_2(&self.montgomery_form, &MOD::MODULUS),
165
0
            phantom: PhantomData,
166
0
        }
167
0
    }
168
}
169
170
impl<MOD: ResidueParams<LIMBS> + Copy, const LIMBS: usize> ConditionallySelectable
171
    for Residue<MOD, LIMBS>
172
{
173
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
174
0
        Residue {
175
0
            montgomery_form: Uint::conditional_select(
176
0
                &a.montgomery_form,
177
0
                &b.montgomery_form,
178
0
                choice,
179
0
            ),
180
0
            phantom: PhantomData,
181
0
        }
182
0
    }
183
}
184
185
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> ConstantTimeEq for Residue<MOD, LIMBS> {
186
0
    fn ct_eq(&self, other: &Self) -> Choice {
187
0
        ConstantTimeEq::ct_eq(&self.montgomery_form, &other.montgomery_form)
188
0
    }
189
}
190
191
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Default for Residue<MOD, LIMBS> {
192
0
    fn default() -> Self {
193
0
        Self::ZERO
194
0
    }
195
}
196
197
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Zero for Residue<MOD, LIMBS> {
198
    const ZERO: Self = Self::ZERO;
199
}
200
201
#[cfg(feature = "rand_core")]
202
impl<MOD, const LIMBS: usize> Random for Residue<MOD, LIMBS>
203
where
204
    MOD: ResidueParams<LIMBS>,
205
{
206
    #[inline]
207
0
    fn random(rng: &mut impl CryptoRngCore) -> Self {
208
0
        Self::new(&Uint::random_mod(rng, &NonZero::from_uint(MOD::MODULUS)))
209
0
    }
210
}
211
212
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Retrieve for Residue<MOD, LIMBS> {
213
    type Output = Uint<LIMBS>;
214
0
    fn retrieve(&self) -> Self::Output {
215
0
        self.retrieve()
216
0
    }
217
}
218
219
#[cfg(feature = "serde")]
220
impl<'de, MOD, const LIMBS: usize> Deserialize<'de> for Residue<MOD, LIMBS>
221
where
222
    MOD: ResidueParams<LIMBS>,
223
    Uint<LIMBS>: Encoding,
224
{
225
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
226
    where
227
        D: Deserializer<'de>,
228
    {
229
        Uint::<LIMBS>::deserialize(deserializer).and_then(|montgomery_form| {
230
            if Uint::ct_lt(&montgomery_form, &MOD::MODULUS).into() {
231
                Ok(Self {
232
                    montgomery_form,
233
                    phantom: PhantomData,
234
                })
235
            } else {
236
                Err(D::Error::custom("montgomery form must be reduced"))
237
            }
238
        })
239
    }
240
}
241
242
#[cfg(feature = "serde")]
243
impl<MOD, const LIMBS: usize> Serialize for Residue<MOD, LIMBS>
244
where
245
    MOD: ResidueParams<LIMBS>,
246
    Uint<LIMBS>: Encoding,
247
{
248
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
249
    where
250
        S: Serializer,
251
    {
252
        self.montgomery_form.serialize(serializer)
253
    }
254
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/constant_mod/const_add.rs
Line
Count
Source
1
use core::ops::{Add, AddAssign};
2
3
use crate::modular::add::add_montgomery_form;
4
5
use super::{Residue, ResidueParams};
6
7
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Residue<MOD, LIMBS> {
8
    /// Adds `rhs`.
9
0
    pub const fn add(&self, rhs: &Residue<MOD, LIMBS>) -> Self {
10
0
        Self {
11
0
            montgomery_form: add_montgomery_form(
12
0
                &self.montgomery_form,
13
0
                &rhs.montgomery_form,
14
0
                &MOD::MODULUS,
15
0
            ),
16
0
            phantom: core::marker::PhantomData,
17
0
        }
18
0
    }
19
}
20
21
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Add<&Residue<MOD, LIMBS>>
22
    for &Residue<MOD, LIMBS>
23
{
24
    type Output = Residue<MOD, LIMBS>;
25
0
    fn add(self, rhs: &Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
26
0
        self.add(rhs)
27
0
    }
28
}
29
30
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Add<Residue<MOD, LIMBS>>
31
    for &Residue<MOD, LIMBS>
32
{
33
    type Output = Residue<MOD, LIMBS>;
34
    #[allow(clippy::op_ref)]
35
0
    fn add(self, rhs: Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
36
0
        self + &rhs
37
0
    }
38
}
39
40
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Add<&Residue<MOD, LIMBS>>
41
    for Residue<MOD, LIMBS>
42
{
43
    type Output = Residue<MOD, LIMBS>;
44
    #[allow(clippy::op_ref)]
45
0
    fn add(self, rhs: &Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
46
0
        &self + rhs
47
0
    }
48
}
49
50
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Add<Residue<MOD, LIMBS>>
51
    for Residue<MOD, LIMBS>
52
{
53
    type Output = Residue<MOD, LIMBS>;
54
0
    fn add(self, rhs: Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
55
0
        &self + &rhs
56
0
    }
57
}
58
59
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> AddAssign<&Self> for Residue<MOD, LIMBS> {
60
0
    fn add_assign(&mut self, rhs: &Self) {
61
0
        *self = *self + rhs;
62
0
    }
63
}
64
65
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> AddAssign<Self> for Residue<MOD, LIMBS> {
66
0
    fn add_assign(&mut self, rhs: Self) {
67
0
        *self += &rhs;
68
0
    }
69
}
70
71
#[cfg(test)]
72
mod tests {
73
    use crate::{const_residue, impl_modulus, modular::constant_mod::ResidueParams, U256};
74
75
    impl_modulus!(
76
        Modulus,
77
        U256,
78
        "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"
79
    );
80
81
    #[test]
82
    fn add_overflow() {
83
        let x =
84
            U256::from_be_hex("44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56");
85
        let mut x_mod = const_residue!(x, Modulus);
86
87
        let y =
88
            U256::from_be_hex("d5777c45019673125ad240f83094d4252d829516fac8601ed01979ec1ec1a251");
89
        let y_mod = const_residue!(y, Modulus);
90
91
        x_mod += &y_mod;
92
93
        let expected =
94
            U256::from_be_hex("1a2472fde50286541d97ca6a3592dd75beb9c9646e40c511b82496cfc3926956");
95
96
        assert_eq!(expected, x_mod.retrieve());
97
    }
98
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/constant_mod/const_inv.rs
Line
Count
Source
1
use core::marker::PhantomData;
2
3
use subtle::CtOption;
4
5
use crate::{modular::inv::inv_montgomery_form, traits::Invert, CtChoice, NonZero};
6
7
use super::{Residue, ResidueParams};
8
9
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Residue<MOD, LIMBS> {
10
    /// Computes the residue `self^-1` representing the multiplicative inverse of `self`.
11
    /// I.e. `self * self^-1 = 1`.
12
    /// If the number was invertible, the second element of the tuple is the truthy value,
13
    /// otherwise it is the falsy value (in which case the first element's value is unspecified).
14
0
    pub const fn invert(&self) -> (Self, CtChoice) {
15
0
        let (montgomery_form, is_some) = inv_montgomery_form(
16
0
            &self.montgomery_form,
17
0
            &MOD::MODULUS,
18
0
            &MOD::R3,
19
0
            MOD::MOD_NEG_INV,
20
0
        );
21
0
22
0
        let value = Self {
23
0
            montgomery_form,
24
0
            phantom: PhantomData,
25
0
        };
26
0
27
0
        (value, is_some)
28
0
    }
29
}
30
31
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Invert for Residue<MOD, LIMBS> {
32
    type Output = CtOption<Self>;
33
0
    fn invert(&self) -> Self::Output {
34
0
        let (value, is_some) = self.invert();
35
0
        CtOption::new(value, is_some.into())
36
0
    }
37
}
38
39
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Invert for NonZero<Residue<MOD, LIMBS>> {
40
    type Output = Self;
41
0
    fn invert(&self) -> Self::Output {
42
0
        // Always succeeds for a non-zero argument
43
0
        let (value, _is_some) = self.as_ref().invert();
44
0
        NonZero::new(value).unwrap()
45
0
    }
46
}
47
48
#[cfg(test)]
49
mod tests {
50
    use crate::{const_residue, impl_modulus, modular::constant_mod::ResidueParams, U256};
51
52
    impl_modulus!(
53
        Modulus,
54
        U256,
55
        "15477BCCEFE197328255BFA79A1217899016D927EF460F4FF404029D24FA4409"
56
    );
57
58
    #[test]
59
    fn test_self_inverse() {
60
        let x =
61
            U256::from_be_hex("77117F1273373C26C700D076B3F780074D03339F56DD0EFB60E7F58441FD3685");
62
        let x_mod = const_residue!(x, Modulus);
63
64
        let (inv, _is_some) = x_mod.invert();
65
        let res = x_mod * inv;
66
67
        assert_eq!(res.retrieve(), U256::ONE);
68
    }
69
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/constant_mod/const_mul.rs
Line
Count
Source
1
use core::{
2
    marker::PhantomData,
3
    ops::{Mul, MulAssign},
4
};
5
6
use crate::{
7
    modular::mul::{mul_montgomery_form, square_montgomery_form},
8
    traits::Square,
9
};
10
11
use super::{Residue, ResidueParams};
12
13
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Residue<MOD, LIMBS> {
14
    /// Multiplies by `rhs`.
15
0
    pub const fn mul(&self, rhs: &Self) -> Self {
16
0
        Self {
17
0
            montgomery_form: mul_montgomery_form(
18
0
                &self.montgomery_form,
19
0
                &rhs.montgomery_form,
20
0
                &MOD::MODULUS,
21
0
                MOD::MOD_NEG_INV,
22
0
            ),
23
0
            phantom: PhantomData,
24
0
        }
25
0
    }
26
27
    /// Computes the (reduced) square of a residue.
28
0
    pub const fn square(&self) -> Self {
29
0
        Self {
30
0
            montgomery_form: square_montgomery_form(
31
0
                &self.montgomery_form,
32
0
                &MOD::MODULUS,
33
0
                MOD::MOD_NEG_INV,
34
0
            ),
35
0
            phantom: PhantomData,
36
0
        }
37
0
    }
38
}
39
40
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Mul<&Residue<MOD, LIMBS>>
41
    for &Residue<MOD, LIMBS>
42
{
43
    type Output = Residue<MOD, LIMBS>;
44
0
    fn mul(self, rhs: &Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
45
0
        self.mul(rhs)
46
0
    }
47
}
48
49
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Mul<Residue<MOD, LIMBS>>
50
    for &Residue<MOD, LIMBS>
51
{
52
    type Output = Residue<MOD, LIMBS>;
53
    #[allow(clippy::op_ref)]
54
0
    fn mul(self, rhs: Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
55
0
        self * &rhs
56
0
    }
57
}
58
59
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Mul<&Residue<MOD, LIMBS>>
60
    for Residue<MOD, LIMBS>
61
{
62
    type Output = Residue<MOD, LIMBS>;
63
    #[allow(clippy::op_ref)]
64
0
    fn mul(self, rhs: &Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
65
0
        &self * rhs
66
0
    }
67
}
68
69
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Mul<Residue<MOD, LIMBS>>
70
    for Residue<MOD, LIMBS>
71
{
72
    type Output = Residue<MOD, LIMBS>;
73
0
    fn mul(self, rhs: Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
74
0
        &self * &rhs
75
0
    }
76
}
77
78
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> MulAssign<&Self> for Residue<MOD, LIMBS> {
79
0
    fn mul_assign(&mut self, rhs: &Residue<MOD, LIMBS>) {
80
0
        *self = *self * rhs;
81
0
    }
82
}
83
84
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> MulAssign<Self> for Residue<MOD, LIMBS> {
85
0
    fn mul_assign(&mut self, rhs: Self) {
86
0
        *self *= &rhs;
87
0
    }
88
}
89
90
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Square for Residue<MOD, LIMBS> {
91
0
    fn square(&self) -> Self {
92
0
        Residue::square(self)
93
0
    }
94
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/constant_mod/const_neg.rs
Line
Count
Source
1
use core::ops::Neg;
2
3
use super::{Residue, ResidueParams};
4
5
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Residue<MOD, LIMBS> {
6
    /// Negates the number.
7
0
    pub const fn neg(&self) -> Self {
8
0
        Self::ZERO.sub(self)
9
0
    }
10
}
11
12
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Neg for Residue<MOD, LIMBS> {
13
    type Output = Self;
14
0
    fn neg(self) -> Self {
15
0
        Residue::neg(&self)
16
0
    }
17
}
18
19
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Neg for &Residue<MOD, LIMBS> {
20
    type Output = Residue<MOD, LIMBS>;
21
0
    fn neg(self) -> Residue<MOD, LIMBS> {
22
0
        Residue::neg(self)
23
0
    }
24
}
25
26
#[cfg(test)]
27
mod tests {
28
    use crate::{const_residue, impl_modulus, modular::constant_mod::ResidueParams, U256};
29
30
    impl_modulus!(
31
        Modulus,
32
        U256,
33
        "15477BCCEFE197328255BFA79A1217899016D927EF460F4FF404029D24FA4409"
34
    );
35
36
    #[test]
37
    fn test_negate() {
38
        let x =
39
            U256::from_be_hex("77117F1273373C26C700D076B3F780074D03339F56DD0EFB60E7F58441FD3685");
40
        let x_mod = const_residue!(x, Modulus);
41
42
        let res = -x_mod;
43
        let expected =
44
            U256::from_be_hex("089B67BB2C124F084701AD76E8750D321385E35044C74CE457301A2A9BE061B1");
45
46
        assert_eq!(res.retrieve(), expected);
47
    }
48
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/constant_mod/const_pow.rs
Line
Count
Source
1
use crate::{modular::pow::pow_montgomery_form, MultiExponentiateBoundedExp, PowBoundedExp, Uint};
2
3
use super::{Residue, ResidueParams};
4
use crate::modular::pow::multi_exponentiate_montgomery_form_array;
5
#[cfg(feature = "alloc")]
6
use crate::modular::pow::multi_exponentiate_montgomery_form_slice;
7
#[cfg(feature = "alloc")]
8
use alloc::vec::Vec;
9
10
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Residue<MOD, LIMBS> {
11
    /// Raises to the `exponent` power.
12
0
    pub const fn pow<const RHS_LIMBS: usize>(
13
0
        &self,
14
0
        exponent: &Uint<RHS_LIMBS>,
15
0
    ) -> Residue<MOD, LIMBS> {
16
0
        self.pow_bounded_exp(exponent, Uint::<RHS_LIMBS>::BITS)
17
0
    }
18
19
    /// Raises to the `exponent` power,
20
    /// with `exponent_bits` representing the number of (least significant) bits
21
    /// to take into account for the exponent.
22
    ///
23
    /// NOTE: `exponent_bits` may be leaked in the time pattern.
24
0
    pub const fn pow_bounded_exp<const RHS_LIMBS: usize>(
25
0
        &self,
26
0
        exponent: &Uint<RHS_LIMBS>,
27
0
        exponent_bits: usize,
28
0
    ) -> Residue<MOD, LIMBS> {
29
0
        Self {
30
0
            montgomery_form: pow_montgomery_form(
31
0
                &self.montgomery_form,
32
0
                exponent,
33
0
                exponent_bits,
34
0
                &MOD::MODULUS,
35
0
                &MOD::R,
36
0
                MOD::MOD_NEG_INV,
37
0
            ),
38
0
            phantom: core::marker::PhantomData,
39
0
        }
40
0
    }
41
}
42
43
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize, const RHS_LIMBS: usize>
44
    PowBoundedExp<Uint<RHS_LIMBS>> for Residue<MOD, LIMBS>
45
{
46
0
    fn pow_bounded_exp(&self, exponent: &Uint<RHS_LIMBS>, exponent_bits: usize) -> Self {
47
0
        self.pow_bounded_exp(exponent, exponent_bits)
48
0
    }
49
}
50
51
impl<const N: usize, MOD: ResidueParams<LIMBS>, const LIMBS: usize, const RHS_LIMBS: usize>
52
    MultiExponentiateBoundedExp<Uint<RHS_LIMBS>, [(Self, Uint<RHS_LIMBS>); N]>
53
    for Residue<MOD, LIMBS>
54
{
55
0
    fn multi_exponentiate_bounded_exp(
56
0
        bases_and_exponents: &[(Self, Uint<RHS_LIMBS>); N],
57
0
        exponent_bits: usize,
58
0
    ) -> Self {
59
0
        let mut bases_and_exponents_montgomery_form =
60
0
            [(Uint::<LIMBS>::ZERO, Uint::<RHS_LIMBS>::ZERO); N];
61
0
62
0
        let mut i = 0;
63
0
        while i < N {
64
0
            let (base, exponent) = bases_and_exponents[i];
65
0
            bases_and_exponents_montgomery_form[i] = (base.montgomery_form, exponent);
66
0
            i += 1;
67
0
        }
68
69
0
        Self {
70
0
            montgomery_form: multi_exponentiate_montgomery_form_array(
71
0
                &bases_and_exponents_montgomery_form,
72
0
                exponent_bits,
73
0
                &MOD::MODULUS,
74
0
                &MOD::R,
75
0
                MOD::MOD_NEG_INV,
76
0
            ),
77
0
            phantom: core::marker::PhantomData,
78
0
        }
79
0
    }
80
}
81
82
#[cfg(feature = "alloc")]
83
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize, const RHS_LIMBS: usize>
84
    MultiExponentiateBoundedExp<Uint<RHS_LIMBS>, [(Self, Uint<RHS_LIMBS>)]>
85
    for Residue<MOD, LIMBS>
86
{
87
    fn multi_exponentiate_bounded_exp(
88
        bases_and_exponents: &[(Self, Uint<RHS_LIMBS>)],
89
        exponent_bits: usize,
90
    ) -> Self {
91
        let bases_and_exponents: Vec<(Uint<LIMBS>, Uint<RHS_LIMBS>)> = bases_and_exponents
92
            .iter()
93
            .map(|(base, exp)| (base.montgomery_form, *exp))
94
            .collect();
95
        Self {
96
            montgomery_form: multi_exponentiate_montgomery_form_slice(
97
                &bases_and_exponents,
98
                exponent_bits,
99
                &MOD::MODULUS,
100
                &MOD::R,
101
                MOD::MOD_NEG_INV,
102
            ),
103
            phantom: core::marker::PhantomData,
104
        }
105
    }
106
}
107
108
#[cfg(test)]
109
mod tests {
110
    use crate::traits::MultiExponentiate;
111
    use crate::{const_residue, impl_modulus, modular::constant_mod::ResidueParams, U256};
112
113
    impl_modulus!(
114
        Modulus,
115
        U256,
116
        "9CC24C5DF431A864188AB905AC751B727C9447A8E99E6366E1AD78A21E8D882B"
117
    );
118
119
    #[test]
120
    fn test_powmod_small_base() {
121
        let base = U256::from(105u64);
122
        let base_mod = const_residue!(base, Modulus);
123
124
        let exponent =
125
            U256::from_be_hex("77117F1273373C26C700D076B3F780074D03339F56DD0EFB60E7F58441FD3685");
126
127
        let res = base_mod.pow(&exponent);
128
129
        let expected =
130
            U256::from_be_hex("7B2CD7BDDD96C271E6F232F2F415BB03FE2A90BD6CCCEA5E94F1BFD064993766");
131
        assert_eq!(res.retrieve(), expected);
132
    }
133
134
    #[test]
135
    fn test_powmod_small_exponent() {
136
        let base =
137
            U256::from_be_hex("3435D18AA8313EBBE4D20002922225B53F75DC4453BB3EEC0378646F79B524A4");
138
        let base_mod = const_residue!(base, Modulus);
139
140
        let exponent = U256::from(105u64);
141
142
        let res = base_mod.pow(&exponent);
143
144
        let expected =
145
            U256::from_be_hex("89E2A4E99F649A5AE2C18068148C355CA927B34A3245C938178ED00D6EF218AA");
146
        assert_eq!(res.retrieve(), expected);
147
    }
148
149
    #[test]
150
    fn test_powmod() {
151
        let base =
152
            U256::from_be_hex("3435D18AA8313EBBE4D20002922225B53F75DC4453BB3EEC0378646F79B524A4");
153
        let base_mod = const_residue!(base, Modulus);
154
155
        let exponent =
156
            U256::from_be_hex("77117F1273373C26C700D076B3F780074D03339F56DD0EFB60E7F58441FD3685");
157
158
        let res = base_mod.pow(&exponent);
159
160
        let expected =
161
            U256::from_be_hex("3681BC0FEA2E5D394EB178155A127B0FD2EF405486D354251C385BDD51B9D421");
162
        assert_eq!(res.retrieve(), expected);
163
    }
164
165
    #[test]
166
    fn test_multi_exp_array() {
167
        let base = U256::from(2u8);
168
        let base_mod = const_residue!(base, Modulus);
169
170
        let exponent = U256::from(33u8);
171
        let bases_and_exponents = [(base_mod, exponent)];
172
        let res =
173
            crate::modular::constant_mod::Residue::<Modulus, { U256::LIMBS }>::multi_exponentiate(
174
                &bases_and_exponents,
175
            );
176
177
        let expected =
178
            U256::from_be_hex("0000000000000000000000000000000000000000000000000000000200000000");
179
180
        assert_eq!(res.retrieve(), expected);
181
182
        let base2 =
183
            U256::from_be_hex("3435D18AA8313EBBE4D20002922225B53F75DC4453BB3EEC0378646F79B524A4");
184
        let base2_mod = const_residue!(base2, Modulus);
185
186
        let exponent2 =
187
            U256::from_be_hex("77117F1273373C26C700D076B3F780074D03339F56DD0EFB60E7F58441FD3685");
188
189
        let expected = base_mod.pow(&exponent) * base2_mod.pow(&exponent2);
190
        let bases_and_exponents = [(base_mod, exponent), (base2_mod, exponent2)];
191
        let res =
192
            crate::modular::constant_mod::Residue::<Modulus, { U256::LIMBS }>::multi_exponentiate(
193
                &bases_and_exponents,
194
            );
195
196
        assert_eq!(res, expected);
197
    }
198
199
    #[cfg(feature = "alloc")]
200
    #[test]
201
    fn test_multi_exp_slice() {
202
        let base = U256::from(2u8);
203
        let base_mod = const_residue!(base, Modulus);
204
205
        let exponent = U256::from(33u8);
206
        let bases_and_exponents = vec![(base_mod, exponent)];
207
        let res =
208
            crate::modular::constant_mod::Residue::<Modulus, { U256::LIMBS }>::multi_exponentiate(
209
                bases_and_exponents.as_slice(),
210
            );
211
212
        let expected =
213
            U256::from_be_hex("0000000000000000000000000000000000000000000000000000000200000000");
214
215
        assert_eq!(res.retrieve(), expected);
216
217
        let base2 =
218
            U256::from_be_hex("3435D18AA8313EBBE4D20002922225B53F75DC4453BB3EEC0378646F79B524A4");
219
        let base2_mod = const_residue!(base2, Modulus);
220
221
        let exponent2 =
222
            U256::from_be_hex("77117F1273373C26C700D076B3F780074D03339F56DD0EFB60E7F58441FD3685");
223
224
        let expected = base_mod.pow(&exponent) * base2_mod.pow(&exponent2);
225
        let bases_and_exponents = vec![(base_mod, exponent), (base2_mod, exponent2)];
226
        let res =
227
            crate::modular::constant_mod::Residue::<Modulus, { U256::LIMBS }>::multi_exponentiate(
228
                bases_and_exponents.as_slice(),
229
            );
230
231
        assert_eq!(res, expected);
232
    }
233
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/constant_mod/const_sub.rs
Line
Count
Source
1
use core::ops::{Sub, SubAssign};
2
3
use crate::modular::sub::sub_montgomery_form;
4
5
use super::{Residue, ResidueParams};
6
7
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Residue<MOD, LIMBS> {
8
    /// Subtracts `rhs`.
9
0
    pub const fn sub(&self, rhs: &Self) -> Self {
10
0
        Self {
11
0
            montgomery_form: sub_montgomery_form(
12
0
                &self.montgomery_form,
13
0
                &rhs.montgomery_form,
14
0
                &MOD::MODULUS,
15
0
            ),
16
0
            phantom: core::marker::PhantomData,
17
0
        }
18
0
    }
19
}
20
21
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Sub<&Residue<MOD, LIMBS>>
22
    for &Residue<MOD, LIMBS>
23
{
24
    type Output = Residue<MOD, LIMBS>;
25
0
    fn sub(self, rhs: &Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
26
0
        self.sub(rhs)
27
0
    }
28
}
29
30
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Sub<Residue<MOD, LIMBS>>
31
    for &Residue<MOD, LIMBS>
32
{
33
    type Output = Residue<MOD, LIMBS>;
34
    #[allow(clippy::op_ref)]
35
0
    fn sub(self, rhs: Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
36
0
        self - &rhs
37
0
    }
38
}
39
40
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Sub<&Residue<MOD, LIMBS>>
41
    for Residue<MOD, LIMBS>
42
{
43
    type Output = Residue<MOD, LIMBS>;
44
    #[allow(clippy::op_ref)]
45
0
    fn sub(self, rhs: &Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
46
0
        &self - rhs
47
0
    }
48
}
49
50
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> Sub<Residue<MOD, LIMBS>>
51
    for Residue<MOD, LIMBS>
52
{
53
    type Output = Residue<MOD, LIMBS>;
54
0
    fn sub(self, rhs: Residue<MOD, LIMBS>) -> Residue<MOD, LIMBS> {
55
0
        &self - &rhs
56
0
    }
57
}
58
59
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> SubAssign<&Self> for Residue<MOD, LIMBS> {
60
0
    fn sub_assign(&mut self, rhs: &Self) {
61
0
        *self = *self - rhs;
62
0
    }
63
}
64
65
impl<MOD: ResidueParams<LIMBS>, const LIMBS: usize> SubAssign<Self> for Residue<MOD, LIMBS> {
66
0
    fn sub_assign(&mut self, rhs: Self) {
67
0
        *self -= &rhs;
68
0
    }
69
}
70
71
#[cfg(test)]
72
mod tests {
73
    use crate::{const_residue, impl_modulus, modular::constant_mod::ResidueParams, U256};
74
75
    impl_modulus!(
76
        Modulus,
77
        U256,
78
        "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"
79
    );
80
81
    #[test]
82
    fn sub_overflow() {
83
        let x =
84
            U256::from_be_hex("44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56");
85
        let mut x_mod = const_residue!(x, Modulus);
86
87
        let y =
88
            U256::from_be_hex("d5777c45019673125ad240f83094d4252d829516fac8601ed01979ec1ec1a251");
89
        let y_mod = const_residue!(y, Modulus);
90
91
        x_mod -= &y_mod;
92
93
        let expected =
94
            U256::from_be_hex("6f357a71e1d5a03167f34879d469352add829491c6df41ddff65387d7ed56f56");
95
96
        assert_eq!(expected, x_mod.retrieve());
97
    }
98
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/div_by_2.rs
Line
Count
Source
1
use crate::Uint;
2
3
0
pub(crate) fn div_by_2<const LIMBS: usize>(a: &Uint<LIMBS>, modulus: &Uint<LIMBS>) -> Uint<LIMBS> {
4
0
    // We are looking for such `x` that `x * 2 = y mod modulus`,
5
0
    // where the given `a = M(y)` is the Montgomery representation of some `y`.
6
0
    // This means that in Montgomery representation it would still apply:
7
0
    // `M(x) + M(x) = a mod modulus`.
8
0
    // So we can just forget about Montgomery representation, and return whatever is
9
0
    // `a` divided by 2, and this will be the Montgomery representation of `x`.
10
0
    // (Which means that this function works regardless of whether `a`
11
0
    // is in Montgomery representation or not, but the algorithm below
12
0
    // does need `modulus` to be odd)
13
0
14
0
    // Two possibilities:
15
0
    // - if `a` is even, we can just divide by 2;
16
0
    // - if `a` is odd, we divide `(a + modulus)` by 2.
17
0
    // To stay within the modulus we open the parentheses turning it into `a / 2 + modulus / 2 + 1`
18
0
    // ("+1" because both `a` and `modulus` are odd, we lose 0.5 in each integer division).
19
0
    // This will not overflow, so we can just use wrapping operations.
20
0
21
0
    let (half, is_odd) = a.shr_1();
22
0
    let half_modulus = modulus.shr_vartime(1);
23
0
24
0
    let if_even = half;
25
0
    let if_odd = half
26
0
        .wrapping_add(&half_modulus)
27
0
        .wrapping_add(&Uint::<LIMBS>::ONE);
28
0
29
0
    Uint::<LIMBS>::ct_select(&if_even, &if_odd, is_odd)
30
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/inv.rs
Line
Count
Source
1
use crate::{modular::reduction::montgomery_reduction, CtChoice, Limb, Uint};
2
3
0
pub const fn inv_montgomery_form<const LIMBS: usize>(
4
0
    x: &Uint<LIMBS>,
5
0
    modulus: &Uint<LIMBS>,
6
0
    r3: &Uint<LIMBS>,
7
0
    mod_neg_inv: Limb,
8
0
) -> (Uint<LIMBS>, CtChoice) {
9
0
    let (inverse, is_some) = x.inv_odd_mod(modulus);
10
0
    (
11
0
        montgomery_reduction(&inverse.mul_wide(r3), modulus, mod_neg_inv),
12
0
        is_some,
13
0
    )
14
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/mul.rs
Line
Count
Source
1
use crate::{Limb, Uint};
2
3
use super::reduction::montgomery_reduction;
4
5
0
pub(crate) const fn mul_montgomery_form<const LIMBS: usize>(
6
0
    a: &Uint<LIMBS>,
7
0
    b: &Uint<LIMBS>,
8
0
    modulus: &Uint<LIMBS>,
9
0
    mod_neg_inv: Limb,
10
0
) -> Uint<LIMBS> {
11
0
    let product = a.mul_wide(b);
12
0
    montgomery_reduction::<LIMBS>(&product, modulus, mod_neg_inv)
13
0
}
14
15
0
pub(crate) const fn square_montgomery_form<const LIMBS: usize>(
16
0
    a: &Uint<LIMBS>,
17
0
    modulus: &Uint<LIMBS>,
18
0
    mod_neg_inv: Limb,
19
0
) -> Uint<LIMBS> {
20
0
    let product = a.square_wide();
21
0
    montgomery_reduction::<LIMBS>(&product, modulus, mod_neg_inv)
22
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/pow.rs
Line
Count
Source
1
use crate::{Limb, Uint, Word};
2
3
use super::mul::{mul_montgomery_form, square_montgomery_form};
4
5
#[cfg(feature = "alloc")]
6
use alloc::vec::Vec;
7
8
const WINDOW: usize = 4;
9
const WINDOW_MASK: Word = (1 << WINDOW) - 1;
10
11
/// Performs modular exponentiation using Montgomery's ladder.
12
/// `exponent_bits` represents the number of bits to take into account for the exponent.
13
///
14
/// NOTE: this value is leaked in the time pattern.
15
0
pub const fn pow_montgomery_form<const LIMBS: usize, const RHS_LIMBS: usize>(
16
0
    x: &Uint<LIMBS>,
17
0
    exponent: &Uint<RHS_LIMBS>,
18
0
    exponent_bits: usize,
19
0
    modulus: &Uint<LIMBS>,
20
0
    r: &Uint<LIMBS>,
21
0
    mod_neg_inv: Limb,
22
0
) -> Uint<LIMBS> {
23
0
    multi_exponentiate_montgomery_form_array(
24
0
        &[(*x, *exponent)],
25
0
        exponent_bits,
26
0
        modulus,
27
0
        r,
28
0
        mod_neg_inv,
29
0
    )
30
0
}
31
32
0
pub const fn multi_exponentiate_montgomery_form_array<
33
0
    const LIMBS: usize,
34
0
    const RHS_LIMBS: usize,
35
0
    const N: usize,
36
0
>(
37
0
    bases_and_exponents: &[(Uint<LIMBS>, Uint<RHS_LIMBS>); N],
38
0
    exponent_bits: usize,
39
0
    modulus: &Uint<LIMBS>,
40
0
    r: &Uint<LIMBS>,
41
0
    mod_neg_inv: Limb,
42
0
) -> Uint<LIMBS> {
43
0
    if exponent_bits == 0 {
44
0
        return *r; // 1 in Montgomery form
45
0
    }
46
0
47
0
    let mut powers_and_exponents =
48
0
        [([Uint::<LIMBS>::ZERO; 1 << WINDOW], Uint::<RHS_LIMBS>::ZERO); N];
49
0
50
0
    let mut i = 0;
51
0
    while i < N {
52
0
        let (base, exponent) = bases_and_exponents[i];
53
0
        powers_and_exponents[i] = (compute_powers(&base, modulus, r, mod_neg_inv), exponent);
54
0
        i += 1;
55
0
    }
56
57
0
    multi_exponentiate_montgomery_form_internal(
58
0
        &powers_and_exponents,
59
0
        exponent_bits,
60
0
        modulus,
61
0
        r,
62
0
        mod_neg_inv,
63
0
    )
64
0
}
65
66
/// Performs modular multi-exponentiation using Montgomery's ladder.
67
/// `exponent_bits` represents the number of bits to take into account for the exponent.
68
///
69
/// See: Straus, E. G. Problems and solutions: Addition chains of vectors. American Mathematical Monthly 71 (1964), 806–808.
70
///
71
/// NOTE: this value is leaked in the time pattern.
72
#[cfg(feature = "alloc")]
73
pub fn multi_exponentiate_montgomery_form_slice<const LIMBS: usize, const RHS_LIMBS: usize>(
74
    bases_and_exponents: &[(Uint<LIMBS>, Uint<RHS_LIMBS>)],
75
    exponent_bits: usize,
76
    modulus: &Uint<LIMBS>,
77
    r: &Uint<LIMBS>,
78
    mod_neg_inv: Limb,
79
) -> Uint<LIMBS> {
80
    if exponent_bits == 0 {
81
        return *r; // 1 in Montgomery form
82
    }
83
84
    let powers_and_exponents: Vec<([Uint<LIMBS>; 1 << WINDOW], Uint<RHS_LIMBS>)> =
85
        bases_and_exponents
86
            .iter()
87
            .map(|(base, exponent)| (compute_powers(base, modulus, r, mod_neg_inv), *exponent))
88
            .collect();
89
90
    multi_exponentiate_montgomery_form_internal(
91
        powers_and_exponents.as_slice(),
92
        exponent_bits,
93
        modulus,
94
        r,
95
        mod_neg_inv,
96
    )
97
}
98
99
0
const fn compute_powers<const LIMBS: usize>(
100
0
    x: &Uint<LIMBS>,
101
0
    modulus: &Uint<LIMBS>,
102
0
    r: &Uint<LIMBS>,
103
0
    mod_neg_inv: Limb,
104
0
) -> [Uint<LIMBS>; 1 << WINDOW] {
105
0
    // powers[i] contains x^i
106
0
    let mut powers = [*r; 1 << WINDOW];
107
0
    powers[1] = *x;
108
0
109
0
    let mut i = 2;
110
0
    while i < powers.len() {
111
0
        powers[i] = mul_montgomery_form(&powers[i - 1], x, modulus, mod_neg_inv);
112
0
        i += 1;
113
0
    }
114
115
0
    powers
116
0
}
117
118
0
const fn multi_exponentiate_montgomery_form_internal<const LIMBS: usize, const RHS_LIMBS: usize>(
119
0
    powers_and_exponents: &[([Uint<LIMBS>; 1 << WINDOW], Uint<RHS_LIMBS>)],
120
0
    exponent_bits: usize,
121
0
    modulus: &Uint<LIMBS>,
122
0
    r: &Uint<LIMBS>,
123
0
    mod_neg_inv: Limb,
124
0
) -> Uint<LIMBS> {
125
0
    let starting_limb = (exponent_bits - 1) / Limb::BITS;
126
0
    let starting_bit_in_limb = (exponent_bits - 1) % Limb::BITS;
127
0
    let starting_window = starting_bit_in_limb / WINDOW;
128
0
    let starting_window_mask = (1 << (starting_bit_in_limb % WINDOW + 1)) - 1;
129
0
130
0
    let mut z = *r; // 1 in Montgomery form
131
0
132
0
    let mut limb_num = starting_limb + 1;
133
0
    while limb_num > 0 {
134
0
        limb_num -= 1;
135
136
0
        let mut window_num = if limb_num == starting_limb {
137
0
            starting_window + 1
138
        } else {
139
0
            Limb::BITS / WINDOW
140
        };
141
0
        while window_num > 0 {
142
0
            window_num -= 1;
143
0
144
0
            if limb_num != starting_limb || window_num != starting_window {
145
0
                let mut i = 0;
146
0
                while i < WINDOW {
147
0
                    i += 1;
148
0
                    z = square_montgomery_form(&z, modulus, mod_neg_inv);
149
0
                }
150
0
            }
151
152
0
            let mut i = 0;
153
0
            while i < powers_and_exponents.len() {
154
0
                let (powers, exponent) = powers_and_exponents[i];
155
0
                let w = exponent.as_limbs()[limb_num].0;
156
0
                let mut idx = (w >> (window_num * WINDOW)) & WINDOW_MASK;
157
0
158
0
                if limb_num == starting_limb && window_num == starting_window {
159
0
                    idx &= starting_window_mask;
160
0
                }
161
162
                // Constant-time lookup in the array of powers
163
0
                let mut power = powers[0];
164
0
                let mut j = 1;
165
0
                while j < 1 << WINDOW {
166
0
                    let choice = Limb::ct_eq(Limb(j as Word), Limb(idx));
167
0
                    power = Uint::<LIMBS>::ct_select(&power, &powers[j], choice);
168
0
                    j += 1;
169
0
                }
170
171
0
                z = mul_montgomery_form(&z, &power, modulus, mod_neg_inv);
172
0
                i += 1;
173
            }
174
        }
175
    }
176
177
0
    z
178
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/reduction.rs
Line
Count
Source
1
use crate::{Limb, Uint, WideWord, Word};
2
3
/// Returns `(hi, lo)` such that `hi * R + lo = x * y + z + w`.
4
#[inline(always)]
5
const fn muladdcarry(x: Word, y: Word, z: Word, w: Word) -> (Word, Word) {
6
    let res = (x as WideWord)
7
        .wrapping_mul(y as WideWord)
8
        .wrapping_add(z as WideWord)
9
        .wrapping_add(w as WideWord);
10
    ((res >> Word::BITS) as Word, res as Word)
11
}
12
13
/// Algorithm 14.32 in Handbook of Applied Cryptography <https://cacr.uwaterloo.ca/hac/about/chap14.pdf>
14
0
pub const fn montgomery_reduction<const LIMBS: usize>(
15
0
    lower_upper: &(Uint<LIMBS>, Uint<LIMBS>),
16
0
    modulus: &Uint<LIMBS>,
17
0
    mod_neg_inv: Limb,
18
0
) -> Uint<LIMBS> {
19
0
    let (mut lower, mut upper) = *lower_upper;
20
0
21
0
    let mut meta_carry = Limb(0);
22
0
    let mut new_sum;
23
0
24
0
    let mut i = 0;
25
0
    while i < LIMBS {
26
0
        let u = lower.limbs[i].0.wrapping_mul(mod_neg_inv.0);
27
0
28
0
        let (mut carry, _) = muladdcarry(u, modulus.limbs[0].0, lower.limbs[i].0, 0);
29
0
        let mut new_limb;
30
0
31
0
        let mut j = 1;
32
0
        while j < (LIMBS - i) {
33
0
            (carry, new_limb) = muladdcarry(u, modulus.limbs[j].0, lower.limbs[i + j].0, carry);
34
0
            lower.limbs[i + j] = Limb(new_limb);
35
0
            j += 1;
36
0
        }
37
0
        while j < LIMBS {
38
0
            (carry, new_limb) =
39
0
                muladdcarry(u, modulus.limbs[j].0, upper.limbs[i + j - LIMBS].0, carry);
40
0
            upper.limbs[i + j - LIMBS] = Limb(new_limb);
41
0
            j += 1;
42
0
        }
43
44
0
        (new_sum, meta_carry) = upper.limbs[i].adc(Limb(carry), meta_carry);
45
0
        upper.limbs[i] = new_sum;
46
0
47
0
        i += 1;
48
    }
49
50
    // Division is simply taking the upper half of the limbs
51
    // Final reduction (at this point, the value is at most 2 * modulus,
52
    // so `meta_carry` is either 0 or 1)
53
54
0
    upper.sub_mod_with_carry(meta_carry, modulus, modulus)
55
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/runtime_mod.rs
Line
Count
Source
1
use crate::{Limb, Uint, Word};
2
3
use super::{
4
    constant_mod::{Residue, ResidueParams},
5
    div_by_2::div_by_2,
6
    reduction::montgomery_reduction,
7
    Retrieve,
8
};
9
10
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
11
12
/// Additions between residues with a modulus set at runtime
13
mod runtime_add;
14
/// Multiplicative inverses of residues with a modulus set at runtime
15
mod runtime_inv;
16
/// Multiplications between residues with a modulus set at runtime
17
mod runtime_mul;
18
/// Negations of residues with a modulus set at runtime
19
mod runtime_neg;
20
/// Exponentiation of residues with a modulus set at runtime
21
mod runtime_pow;
22
/// Subtractions between residues with a modulus set at runtime
23
mod runtime_sub;
24
25
/// The parameters to efficiently go to and from the Montgomery form for an odd modulus provided at runtime.
26
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27
pub struct DynResidueParams<const LIMBS: usize> {
28
    // The constant modulus
29
    modulus: Uint<LIMBS>,
30
    // Parameter used in Montgomery reduction
31
    r: Uint<LIMBS>,
32
    // R^2, used to move into Montgomery form
33
    r2: Uint<LIMBS>,
34
    // R^3, used to compute the multiplicative inverse
35
    r3: Uint<LIMBS>,
36
    // The lowest limbs of -(MODULUS^-1) mod R
37
    // We only need the LSB because during reduction this value is multiplied modulo 2**Limb::BITS.
38
    mod_neg_inv: Limb,
39
}
40
41
impl<const LIMBS: usize> DynResidueParams<LIMBS> {
42
    // Internal helper function to generate parameters; this lets us wrap the constructors more cleanly
43
0
    const fn generate_params(modulus: &Uint<LIMBS>) -> Self {
44
0
        let r = Uint::MAX.const_rem(modulus).0.wrapping_add(&Uint::ONE);
45
0
        let r2 = Uint::const_rem_wide(r.square_wide(), modulus).0;
46
0
47
0
        // Since we are calculating the inverse modulo (Word::MAX+1),
48
0
        // we can take the modulo right away and calculate the inverse of the first limb only.
49
0
        let modulus_lo = Uint::<1>::from_words([modulus.limbs[0].0]);
50
0
        let mod_neg_inv = Limb(
51
0
            Word::MIN.wrapping_sub(modulus_lo.inv_mod2k_vartime(Word::BITS as usize).limbs[0].0),
52
0
        );
53
0
54
0
        let r3 = montgomery_reduction(&r2.square_wide(), modulus, mod_neg_inv);
55
0
56
0
        Self {
57
0
            modulus: *modulus,
58
0
            r,
59
0
            r2,
60
0
            r3,
61
0
            mod_neg_inv,
62
0
        }
63
0
    }
64
65
    /// Instantiates a new set of `ResidueParams` representing the given `modulus`, which _must_ be odd.
66
    /// If `modulus` is not odd, this function will panic; use [`new_checked`][`DynResidueParams::new_checked`] if you want to be able to detect an invalid modulus.
67
0
    pub const fn new(modulus: &Uint<LIMBS>) -> Self {
68
0
        // A valid modulus must be odd
69
0
        if modulus.ct_is_odd().to_u8() == 0 {
70
0
            panic!("modulus must be odd");
71
0
        }
72
0
73
0
        Self::generate_params(modulus)
74
0
    }
75
76
    /// Instantiates a new set of `ResidueParams` representing the given `modulus` if it is odd.
77
    /// Returns a `CtOption` that is `None` if the provided modulus is not odd; this is a safer version of [`new`][`DynResidueParams::new`], which can panic.
78
    #[deprecated(
79
        since = "0.5.3",
80
        note = "This functionality will be moved to `new` in a future release."
81
    )]
82
0
    pub fn new_checked(modulus: &Uint<LIMBS>) -> CtOption<Self> {
83
0
        // A valid modulus must be odd.
84
0
        CtOption::new(Self::generate_params(modulus), modulus.ct_is_odd().into())
85
0
    }
86
87
    /// Returns the modulus which was used to initialize these parameters.
88
0
    pub const fn modulus(&self) -> &Uint<LIMBS> {
89
0
        &self.modulus
90
0
    }
91
92
    /// Create `DynResidueParams` corresponding to a `ResidueParams`.
93
0
    pub const fn from_residue_params<P>() -> Self
94
0
    where
95
0
        P: ResidueParams<LIMBS>,
96
0
    {
97
0
        Self {
98
0
            modulus: P::MODULUS,
99
0
            r: P::R,
100
0
            r2: P::R2,
101
0
            r3: P::R3,
102
0
            mod_neg_inv: P::MOD_NEG_INV,
103
0
        }
104
0
    }
105
}
106
107
impl<const LIMBS: usize> ConditionallySelectable for DynResidueParams<LIMBS> {
108
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
109
0
        Self {
110
0
            modulus: Uint::conditional_select(&a.modulus, &b.modulus, choice),
111
0
            r: Uint::conditional_select(&a.r, &b.r, choice),
112
0
            r2: Uint::conditional_select(&a.r2, &b.r2, choice),
113
0
            r3: Uint::conditional_select(&a.r3, &b.r3, choice),
114
0
            mod_neg_inv: Limb::conditional_select(&a.mod_neg_inv, &b.mod_neg_inv, choice),
115
0
        }
116
0
    }
117
}
118
119
impl<const LIMBS: usize> ConstantTimeEq for DynResidueParams<LIMBS> {
120
0
    fn ct_eq(&self, other: &Self) -> Choice {
121
0
        self.modulus.ct_eq(&other.modulus)
122
0
            & self.r.ct_eq(&other.r)
123
0
            & self.r2.ct_eq(&other.r2)
124
0
            & self.r3.ct_eq(&other.r3)
125
0
            & self.mod_neg_inv.ct_eq(&other.mod_neg_inv)
126
0
    }
127
}
128
129
/// A residue represented using `LIMBS` limbs. The odd modulus of this residue is set at runtime.
130
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
131
pub struct DynResidue<const LIMBS: usize> {
132
    montgomery_form: Uint<LIMBS>,
133
    residue_params: DynResidueParams<LIMBS>,
134
}
135
136
impl<const LIMBS: usize> DynResidue<LIMBS> {
137
    /// Instantiates a new `Residue` that represents this `integer` mod `MOD`.
138
0
    pub const fn new(integer: &Uint<LIMBS>, residue_params: DynResidueParams<LIMBS>) -> Self {
139
0
        let product = integer.mul_wide(&residue_params.r2);
140
0
        let montgomery_form = montgomery_reduction(
141
0
            &product,
142
0
            &residue_params.modulus,
143
0
            residue_params.mod_neg_inv,
144
0
        );
145
0
146
0
        Self {
147
0
            montgomery_form,
148
0
            residue_params,
149
0
        }
150
0
    }
151
152
    /// Retrieves the integer currently encoded in this `Residue`, guaranteed to be reduced.
153
0
    pub const fn retrieve(&self) -> Uint<LIMBS> {
154
0
        montgomery_reduction(
155
0
            &(self.montgomery_form, Uint::ZERO),
156
0
            &self.residue_params.modulus,
157
0
            self.residue_params.mod_neg_inv,
158
0
        )
159
0
    }
160
161
    /// Instantiates a new `Residue` that represents zero.
162
0
    pub const fn zero(residue_params: DynResidueParams<LIMBS>) -> Self {
163
0
        Self {
164
0
            montgomery_form: Uint::<LIMBS>::ZERO,
165
0
            residue_params,
166
0
        }
167
0
    }
168
169
    /// Instantiates a new `Residue` that represents 1.
170
0
    pub const fn one(residue_params: DynResidueParams<LIMBS>) -> Self {
171
0
        Self {
172
0
            montgomery_form: residue_params.r,
173
0
            residue_params,
174
0
        }
175
0
    }
176
177
    /// Returns the parameter struct used to initialize this residue.
178
0
    pub const fn params(&self) -> &DynResidueParams<LIMBS> {
179
0
        &self.residue_params
180
0
    }
181
182
    /// Access the `DynResidue` value in Montgomery form.
183
0
    pub const fn as_montgomery(&self) -> &Uint<LIMBS> {
184
0
        &self.montgomery_form
185
0
    }
186
187
    /// Mutably access the `DynResidue` value in Montgomery form.
188
0
    pub fn as_montgomery_mut(&mut self) -> &mut Uint<LIMBS> {
189
0
        &mut self.montgomery_form
190
0
    }
191
192
    /// Create a `DynResidue` from a value in Montgomery form.
193
0
    pub const fn from_montgomery(
194
0
        integer: Uint<LIMBS>,
195
0
        residue_params: DynResidueParams<LIMBS>,
196
0
    ) -> Self {
197
0
        Self {
198
0
            montgomery_form: integer,
199
0
            residue_params,
200
0
        }
201
0
    }
202
203
    /// Extract the value from the `DynResidue` in Montgomery form.
204
0
    pub const fn to_montgomery(&self) -> Uint<LIMBS> {
205
0
        self.montgomery_form
206
0
    }
207
208
    /// Performs the modular division by 2, that is for given `x` returns `y`
209
    /// such that `y * 2 = x mod p`. This means:
210
    /// - if `x` is even, returns `x / 2`,
211
    /// - if `x` is odd, returns `(x + p) / 2`
212
    ///   (since the modulus `p` in Montgomery form is always odd, this divides entirely).
213
0
    pub fn div_by_2(&self) -> Self {
214
0
        Self {
215
0
            montgomery_form: div_by_2(&self.montgomery_form, &self.residue_params.modulus),
216
0
            residue_params: self.residue_params,
217
0
        }
218
0
    }
219
}
220
221
impl<const LIMBS: usize> Retrieve for DynResidue<LIMBS> {
222
    type Output = Uint<LIMBS>;
223
0
    fn retrieve(&self) -> Self::Output {
224
0
        self.retrieve()
225
0
    }
226
}
227
228
impl<const LIMBS: usize, P: ResidueParams<LIMBS>> From<&Residue<P, LIMBS>> for DynResidue<LIMBS> {
229
0
    fn from(residue: &Residue<P, LIMBS>) -> Self {
230
0
        Self {
231
0
            montgomery_form: residue.to_montgomery(),
232
0
            residue_params: DynResidueParams::from_residue_params::<P>(),
233
0
        }
234
0
    }
235
}
236
237
impl<const LIMBS: usize> ConditionallySelectable for DynResidue<LIMBS> {
238
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
239
0
        Self {
240
0
            montgomery_form: Uint::conditional_select(
241
0
                &a.montgomery_form,
242
0
                &b.montgomery_form,
243
0
                choice,
244
0
            ),
245
0
            residue_params: DynResidueParams::conditional_select(
246
0
                &a.residue_params,
247
0
                &b.residue_params,
248
0
                choice,
249
0
            ),
250
0
        }
251
0
    }
252
}
253
254
impl<const LIMBS: usize> ConstantTimeEq for DynResidue<LIMBS> {
255
0
    fn ct_eq(&self, other: &Self) -> Choice {
256
0
        self.montgomery_form.ct_eq(&other.montgomery_form)
257
0
            & self.residue_params.ct_eq(&other.residue_params)
258
0
    }
259
}
260
261
/// NOTE: this does _not_ zeroize the parameters, in order to maintain some form of type consistency
262
#[cfg(feature = "zeroize")]
263
impl<const LIMBS: usize> zeroize::Zeroize for DynResidue<LIMBS> {
264
0
    fn zeroize(&mut self) {
265
0
        self.montgomery_form.zeroize()
266
0
    }
267
}
268
269
#[cfg(test)]
270
mod test {
271
    use super::*;
272
273
    const LIMBS: usize = nlimbs!(64);
274
275
    #[test]
276
    #[allow(deprecated)]
277
    // Test that a valid modulus yields `DynResidueParams`
278
    fn test_valid_modulus() {
279
        let valid_modulus = Uint::<LIMBS>::from(3u8);
280
281
        DynResidueParams::<LIMBS>::new_checked(&valid_modulus).unwrap();
282
        DynResidueParams::<LIMBS>::new(&valid_modulus);
283
    }
284
285
    #[test]
286
    #[allow(deprecated)]
287
    // Test that an invalid checked modulus does not yield `DynResidueParams`
288
    fn test_invalid_checked_modulus() {
289
        assert!(bool::from(
290
            DynResidueParams::<LIMBS>::new_checked(&Uint::from(2u8)).is_none()
291
        ))
292
    }
293
294
    #[test]
295
    #[should_panic]
296
    // Tets that an invalid modulus panics
297
    fn test_invalid_modulus() {
298
        DynResidueParams::<LIMBS>::new(&Uint::from(2u8));
299
    }
300
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/runtime_mod/runtime_add.rs
Line
Count
Source
1
use core::ops::{Add, AddAssign};
2
3
use crate::modular::add::add_montgomery_form;
4
5
use super::DynResidue;
6
7
impl<const LIMBS: usize> DynResidue<LIMBS> {
8
    /// Adds `rhs`.
9
0
    pub const fn add(&self, rhs: &Self) -> Self {
10
0
        Self {
11
0
            montgomery_form: add_montgomery_form(
12
0
                &self.montgomery_form,
13
0
                &rhs.montgomery_form,
14
0
                &self.residue_params.modulus,
15
0
            ),
16
0
            residue_params: self.residue_params,
17
0
        }
18
0
    }
19
}
20
21
impl<const LIMBS: usize> Add<&DynResidue<LIMBS>> for &DynResidue<LIMBS> {
22
    type Output = DynResidue<LIMBS>;
23
0
    fn add(self, rhs: &DynResidue<LIMBS>) -> DynResidue<LIMBS> {
24
0
        debug_assert_eq!(self.residue_params, rhs.residue_params);
25
0
        self.add(rhs)
26
0
    }
27
}
28
29
impl<const LIMBS: usize> Add<DynResidue<LIMBS>> for &DynResidue<LIMBS> {
30
    type Output = DynResidue<LIMBS>;
31
    #[allow(clippy::op_ref)]
32
0
    fn add(self, rhs: DynResidue<LIMBS>) -> DynResidue<LIMBS> {
33
0
        self + &rhs
34
0
    }
35
}
36
37
impl<const LIMBS: usize> Add<&DynResidue<LIMBS>> for DynResidue<LIMBS> {
38
    type Output = DynResidue<LIMBS>;
39
    #[allow(clippy::op_ref)]
40
0
    fn add(self, rhs: &DynResidue<LIMBS>) -> DynResidue<LIMBS> {
41
0
        &self + rhs
42
0
    }
43
}
44
45
impl<const LIMBS: usize> Add<DynResidue<LIMBS>> for DynResidue<LIMBS> {
46
    type Output = DynResidue<LIMBS>;
47
0
    fn add(self, rhs: DynResidue<LIMBS>) -> DynResidue<LIMBS> {
48
0
        &self + &rhs
49
0
    }
50
}
51
52
impl<const LIMBS: usize> AddAssign<&DynResidue<LIMBS>> for DynResidue<LIMBS> {
53
0
    fn add_assign(&mut self, rhs: &DynResidue<LIMBS>) {
54
0
        *self = *self + rhs;
55
0
    }
56
}
57
58
impl<const LIMBS: usize> AddAssign<DynResidue<LIMBS>> for DynResidue<LIMBS> {
59
0
    fn add_assign(&mut self, rhs: DynResidue<LIMBS>) {
60
0
        *self += &rhs;
61
0
    }
62
}
63
64
#[cfg(test)]
65
mod tests {
66
    use crate::{
67
        modular::runtime_mod::{DynResidue, DynResidueParams},
68
        U256,
69
    };
70
71
    #[test]
72
    fn add_overflow() {
73
        let params = DynResidueParams::new(&U256::from_be_hex(
74
            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
75
        ));
76
77
        let x =
78
            U256::from_be_hex("44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56");
79
        let mut x_mod = DynResidue::new(&x, params);
80
81
        let y =
82
            U256::from_be_hex("d5777c45019673125ad240f83094d4252d829516fac8601ed01979ec1ec1a251");
83
        let y_mod = DynResidue::new(&y, params);
84
85
        x_mod += &y_mod;
86
87
        let expected =
88
            U256::from_be_hex("1a2472fde50286541d97ca6a3592dd75beb9c9646e40c511b82496cfc3926956");
89
90
        assert_eq!(expected, x_mod.retrieve());
91
    }
92
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/runtime_mod/runtime_inv.rs
Line
Count
Source
1
use subtle::CtOption;
2
3
use crate::{modular::inv::inv_montgomery_form, traits::Invert, CtChoice};
4
5
use super::DynResidue;
6
7
impl<const LIMBS: usize> DynResidue<LIMBS> {
8
    /// Computes the residue `self^-1` representing the multiplicative inverse of `self`.
9
    /// I.e. `self * self^-1 = 1`.
10
    /// If the number was invertible, the second element of the tuple is the truthy value,
11
    /// otherwise it is the falsy value (in which case the first element's value is unspecified).
12
0
    pub const fn invert(&self) -> (Self, CtChoice) {
13
0
        let (montgomery_form, is_some) = inv_montgomery_form(
14
0
            &self.montgomery_form,
15
0
            &self.residue_params.modulus,
16
0
            &self.residue_params.r3,
17
0
            self.residue_params.mod_neg_inv,
18
0
        );
19
0
20
0
        let value = Self {
21
0
            montgomery_form,
22
0
            residue_params: self.residue_params,
23
0
        };
24
0
25
0
        (value, is_some)
26
0
    }
27
}
28
29
impl<const LIMBS: usize> Invert for DynResidue<LIMBS> {
30
    type Output = CtOption<Self>;
31
0
    fn invert(&self) -> Self::Output {
32
0
        let (value, is_some) = self.invert();
33
0
        CtOption::new(value, is_some.into())
34
0
    }
35
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/runtime_mod/runtime_mul.rs
Line
Count
Source
1
use core::ops::{Mul, MulAssign};
2
3
use crate::{
4
    modular::mul::{mul_montgomery_form, square_montgomery_form},
5
    traits::Square,
6
};
7
8
use super::DynResidue;
9
10
impl<const LIMBS: usize> DynResidue<LIMBS> {
11
    /// Multiplies by `rhs`.
12
0
    pub const fn mul(&self, rhs: &Self) -> Self {
13
0
        Self {
14
0
            montgomery_form: mul_montgomery_form(
15
0
                &self.montgomery_form,
16
0
                &rhs.montgomery_form,
17
0
                &self.residue_params.modulus,
18
0
                self.residue_params.mod_neg_inv,
19
0
            ),
20
0
            residue_params: self.residue_params,
21
0
        }
22
0
    }
23
24
    /// Computes the (reduced) square of a residue.
25
0
    pub const fn square(&self) -> Self {
26
0
        Self {
27
0
            montgomery_form: square_montgomery_form(
28
0
                &self.montgomery_form,
29
0
                &self.residue_params.modulus,
30
0
                self.residue_params.mod_neg_inv,
31
0
            ),
32
0
            residue_params: self.residue_params,
33
0
        }
34
0
    }
35
}
36
37
impl<const LIMBS: usize> Mul<&DynResidue<LIMBS>> for &DynResidue<LIMBS> {
38
    type Output = DynResidue<LIMBS>;
39
0
    fn mul(self, rhs: &DynResidue<LIMBS>) -> DynResidue<LIMBS> {
40
0
        debug_assert_eq!(self.residue_params, rhs.residue_params);
41
0
        self.mul(rhs)
42
0
    }
43
}
44
45
impl<const LIMBS: usize> Mul<DynResidue<LIMBS>> for &DynResidue<LIMBS> {
46
    type Output = DynResidue<LIMBS>;
47
    #[allow(clippy::op_ref)]
48
0
    fn mul(self, rhs: DynResidue<LIMBS>) -> DynResidue<LIMBS> {
49
0
        self * &rhs
50
0
    }
51
}
52
53
impl<const LIMBS: usize> Mul<&DynResidue<LIMBS>> for DynResidue<LIMBS> {
54
    type Output = DynResidue<LIMBS>;
55
    #[allow(clippy::op_ref)]
56
0
    fn mul(self, rhs: &DynResidue<LIMBS>) -> DynResidue<LIMBS> {
57
0
        &self * rhs
58
0
    }
59
}
60
61
impl<const LIMBS: usize> Mul<DynResidue<LIMBS>> for DynResidue<LIMBS> {
62
    type Output = DynResidue<LIMBS>;
63
0
    fn mul(self, rhs: DynResidue<LIMBS>) -> DynResidue<LIMBS> {
64
0
        &self * &rhs
65
0
    }
66
}
67
68
impl<const LIMBS: usize> MulAssign<&DynResidue<LIMBS>> for DynResidue<LIMBS> {
69
0
    fn mul_assign(&mut self, rhs: &DynResidue<LIMBS>) {
70
0
        *self = *self * rhs;
71
0
    }
72
}
73
74
impl<const LIMBS: usize> MulAssign<DynResidue<LIMBS>> for DynResidue<LIMBS> {
75
0
    fn mul_assign(&mut self, rhs: DynResidue<LIMBS>) {
76
0
        *self *= &rhs;
77
0
    }
78
}
79
80
impl<const LIMBS: usize> Square for DynResidue<LIMBS> {
81
0
    fn square(&self) -> Self {
82
0
        DynResidue::square(self)
83
0
    }
84
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/runtime_mod/runtime_neg.rs
Line
Count
Source
1
use core::ops::Neg;
2
3
use super::DynResidue;
4
5
impl<const LIMBS: usize> DynResidue<LIMBS> {
6
    /// Negates the number.
7
0
    pub const fn neg(&self) -> Self {
8
0
        Self::zero(self.residue_params).sub(self)
9
0
    }
10
}
11
12
impl<const LIMBS: usize> Neg for DynResidue<LIMBS> {
13
    type Output = Self;
14
0
    fn neg(self) -> Self {
15
0
        DynResidue::neg(&self)
16
0
    }
17
}
18
19
impl<const LIMBS: usize> Neg for &DynResidue<LIMBS> {
20
    type Output = DynResidue<LIMBS>;
21
0
    fn neg(self) -> DynResidue<LIMBS> {
22
0
        DynResidue::neg(self)
23
0
    }
24
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/runtime_mod/runtime_pow.rs
Line
Count
Source
1
use super::DynResidue;
2
use crate::modular::pow::multi_exponentiate_montgomery_form_array;
3
#[cfg(feature = "alloc")]
4
use crate::modular::pow::multi_exponentiate_montgomery_form_slice;
5
use crate::{modular::pow::pow_montgomery_form, MultiExponentiateBoundedExp, PowBoundedExp, Uint};
6
#[cfg(feature = "alloc")]
7
use alloc::vec::Vec;
8
9
impl<const LIMBS: usize> DynResidue<LIMBS> {
10
    /// Raises to the `exponent` power.
11
0
    pub const fn pow<const RHS_LIMBS: usize>(
12
0
        &self,
13
0
        exponent: &Uint<RHS_LIMBS>,
14
0
    ) -> DynResidue<LIMBS> {
15
0
        self.pow_bounded_exp(exponent, Uint::<RHS_LIMBS>::BITS)
16
0
    }
17
18
    /// Raises to the `exponent` power,
19
    /// with `exponent_bits` representing the number of (least significant) bits
20
    /// to take into account for the exponent.
21
    ///
22
    /// NOTE: `exponent_bits` may be leaked in the time pattern.
23
0
    pub const fn pow_bounded_exp<const RHS_LIMBS: usize>(
24
0
        &self,
25
0
        exponent: &Uint<RHS_LIMBS>,
26
0
        exponent_bits: usize,
27
0
    ) -> Self {
28
0
        Self {
29
0
            montgomery_form: pow_montgomery_form(
30
0
                &self.montgomery_form,
31
0
                exponent,
32
0
                exponent_bits,
33
0
                &self.residue_params.modulus,
34
0
                &self.residue_params.r,
35
0
                self.residue_params.mod_neg_inv,
36
0
            ),
37
0
            residue_params: self.residue_params,
38
0
        }
39
0
    }
40
}
41
42
impl<const LIMBS: usize, const RHS_LIMBS: usize> PowBoundedExp<Uint<RHS_LIMBS>>
43
    for DynResidue<LIMBS>
44
{
45
0
    fn pow_bounded_exp(&self, exponent: &Uint<RHS_LIMBS>, exponent_bits: usize) -> Self {
46
0
        self.pow_bounded_exp(exponent, exponent_bits)
47
0
    }
48
}
49
50
impl<const N: usize, const LIMBS: usize, const RHS_LIMBS: usize>
51
    MultiExponentiateBoundedExp<Uint<RHS_LIMBS>, [(Self, Uint<RHS_LIMBS>); N]>
52
    for DynResidue<LIMBS>
53
{
54
0
    fn multi_exponentiate_bounded_exp(
55
0
        bases_and_exponents: &[(Self, Uint<RHS_LIMBS>); N],
56
0
        exponent_bits: usize,
57
0
    ) -> Self {
58
0
        const_assert_ne!(N, 0, "bases_and_exponents must not be empty");
59
0
        let residue_params = bases_and_exponents[0].0.residue_params;
60
0
61
0
        let mut bases_and_exponents_montgomery_form =
62
0
            [(Uint::<LIMBS>::ZERO, Uint::<RHS_LIMBS>::ZERO); N];
63
0
64
0
        let mut i = 0;
65
0
        while i < N {
66
0
            let (base, exponent) = bases_and_exponents[i];
67
0
            bases_and_exponents_montgomery_form[i] = (base.montgomery_form, exponent);
68
0
            i += 1;
69
0
        }
70
71
0
        Self {
72
0
            montgomery_form: multi_exponentiate_montgomery_form_array(
73
0
                &bases_and_exponents_montgomery_form,
74
0
                exponent_bits,
75
0
                &residue_params.modulus,
76
0
                &residue_params.r,
77
0
                residue_params.mod_neg_inv,
78
0
            ),
79
0
            residue_params,
80
0
        }
81
0
    }
82
}
83
84
#[cfg(feature = "alloc")]
85
impl<const LIMBS: usize, const RHS_LIMBS: usize>
86
    MultiExponentiateBoundedExp<Uint<RHS_LIMBS>, [(Self, Uint<RHS_LIMBS>)]> for DynResidue<LIMBS>
87
{
88
    fn multi_exponentiate_bounded_exp(
89
        bases_and_exponents: &[(Self, Uint<RHS_LIMBS>)],
90
        exponent_bits: usize,
91
    ) -> Self {
92
        assert!(
93
            !bases_and_exponents.is_empty(),
94
            "bases_and_exponents must not be empty"
95
        );
96
        let residue_params = bases_and_exponents[0].0.residue_params;
97
98
        let bases_and_exponents: Vec<(Uint<LIMBS>, Uint<RHS_LIMBS>)> = bases_and_exponents
99
            .iter()
100
            .map(|(base, exp)| (base.montgomery_form, *exp))
101
            .collect();
102
        Self {
103
            montgomery_form: multi_exponentiate_montgomery_form_slice(
104
                &bases_and_exponents,
105
                exponent_bits,
106
                &residue_params.modulus,
107
                &residue_params.r,
108
                residue_params.mod_neg_inv,
109
            ),
110
            residue_params,
111
        }
112
    }
113
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/runtime_mod/runtime_sub.rs
Line
Count
Source
1
use core::ops::{Sub, SubAssign};
2
3
use crate::modular::sub::sub_montgomery_form;
4
5
use super::DynResidue;
6
7
impl<const LIMBS: usize> DynResidue<LIMBS> {
8
    /// Subtracts `rhs`.
9
0
    pub const fn sub(&self, rhs: &Self) -> Self {
10
0
        Self {
11
0
            montgomery_form: sub_montgomery_form(
12
0
                &self.montgomery_form,
13
0
                &rhs.montgomery_form,
14
0
                &self.residue_params.modulus,
15
0
            ),
16
0
            residue_params: self.residue_params,
17
0
        }
18
0
    }
19
}
20
21
impl<const LIMBS: usize> Sub<&DynResidue<LIMBS>> for &DynResidue<LIMBS> {
22
    type Output = DynResidue<LIMBS>;
23
0
    fn sub(self, rhs: &DynResidue<LIMBS>) -> DynResidue<LIMBS> {
24
0
        debug_assert_eq!(self.residue_params, rhs.residue_params);
25
0
        self.sub(rhs)
26
0
    }
27
}
28
29
impl<const LIMBS: usize> Sub<DynResidue<LIMBS>> for &DynResidue<LIMBS> {
30
    type Output = DynResidue<LIMBS>;
31
    #[allow(clippy::op_ref)]
32
0
    fn sub(self, rhs: DynResidue<LIMBS>) -> DynResidue<LIMBS> {
33
0
        self - &rhs
34
0
    }
35
}
36
37
impl<const LIMBS: usize> Sub<&DynResidue<LIMBS>> for DynResidue<LIMBS> {
38
    type Output = DynResidue<LIMBS>;
39
    #[allow(clippy::op_ref)]
40
0
    fn sub(self, rhs: &DynResidue<LIMBS>) -> DynResidue<LIMBS> {
41
0
        &self - rhs
42
0
    }
43
}
44
45
impl<const LIMBS: usize> Sub<DynResidue<LIMBS>> for DynResidue<LIMBS> {
46
    type Output = DynResidue<LIMBS>;
47
0
    fn sub(self, rhs: DynResidue<LIMBS>) -> DynResidue<LIMBS> {
48
0
        &self - &rhs
49
0
    }
50
}
51
52
impl<const LIMBS: usize> SubAssign<&DynResidue<LIMBS>> for DynResidue<LIMBS> {
53
0
    fn sub_assign(&mut self, rhs: &DynResidue<LIMBS>) {
54
0
        *self = *self - rhs;
55
0
    }
56
}
57
58
impl<const LIMBS: usize> SubAssign<DynResidue<LIMBS>> for DynResidue<LIMBS> {
59
0
    fn sub_assign(&mut self, rhs: DynResidue<LIMBS>) {
60
0
        *self -= &rhs;
61
0
    }
62
}
63
64
#[cfg(test)]
65
mod tests {
66
    use crate::{
67
        modular::runtime_mod::{DynResidue, DynResidueParams},
68
        U256,
69
    };
70
71
    #[test]
72
    fn sub_overflow() {
73
        let params = DynResidueParams::new(&U256::from_be_hex(
74
            "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
75
        ));
76
77
        let x =
78
            U256::from_be_hex("44acf6b7e36c1342c2c5897204fe09504e1e2efb1a900377dbc4e7a6a133ec56");
79
        let mut x_mod = DynResidue::new(&x, params);
80
81
        let y =
82
            U256::from_be_hex("d5777c45019673125ad240f83094d4252d829516fac8601ed01979ec1ec1a251");
83
        let y_mod = DynResidue::new(&y, params);
84
85
        x_mod -= &y_mod;
86
87
        let expected =
88
            U256::from_be_hex("6f357a71e1d5a03167f34879d469352add829491c6df41ddff65387d7ed56f56");
89
90
        assert_eq!(expected, x_mod.retrieve());
91
    }
92
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/modular/sub.rs
Line
Count
Source
1
use crate::Uint;
2
3
0
pub(crate) const fn sub_montgomery_form<const LIMBS: usize>(
4
0
    a: &Uint<LIMBS>,
5
0
    b: &Uint<LIMBS>,
6
0
    modulus: &Uint<LIMBS>,
7
0
) -> Uint<LIMBS> {
8
0
    a.sub_mod(b, modulus)
9
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/mul.rs
Line
Count
Source
1
//! [`Uint`] addition operations.
2
3
use crate::{Checked, CheckedMul, Concat, ConcatMixed, Limb, Uint, WideWord, Word, Wrapping, Zero};
4
use core::ops::{Mul, MulAssign};
5
use subtle::CtOption;
6
7
impl<const LIMBS: usize> Uint<LIMBS> {
8
    /// Multiply `self` by `rhs`, returning a concatenated "wide" result.
9
0
    pub fn mul<const HLIMBS: usize>(
10
0
        &self,
11
0
        rhs: &Uint<HLIMBS>,
12
0
    ) -> <Uint<HLIMBS> as ConcatMixed<Self>>::MixedOutput
13
0
    where
14
0
        Uint<HLIMBS>: ConcatMixed<Self>,
15
0
    {
16
0
        let (lo, hi) = self.mul_wide(rhs);
17
0
        hi.concat_mixed(&lo)
18
0
    }
19
20
    /// Compute "wide" multiplication, with a product twice the size of the input.
21
    ///
22
    /// Returns a tuple containing the `(lo, hi)` components of the product.
23
    ///
24
    /// # Ordering note
25
    ///
26
    /// Releases of `crypto-bigint` prior to v0.3 used `(hi, lo)` ordering
27
    /// instead. This has been changed for better consistency with the rest of
28
    /// the APIs in this crate.
29
    ///
30
    /// For more info see: <https://github.com/RustCrypto/crypto-bigint/issues/4>
31
1.67k
    pub const fn mul_wide<const HLIMBS: usize>(&self, rhs: &Uint<HLIMBS>) -> (Self, Uint<HLIMBS>) {
32
1.67k
        let mut i = 0;
33
1.67k
        let mut lo = Self::ZERO;
34
1.67k
        let mut hi = Uint::<HLIMBS>::ZERO;
35
36
        // Schoolbook multiplication.
37
        // TODO(tarcieri): use Karatsuba for better performance?
38
8.38k
        while i < LIMBS {
39
6.70k
            let mut j = 0;
40
6.70k
            let mut carry = Limb::ZERO;
41
42
33.5k
            while j < HLIMBS {
43
26.8k
                let k = i + j;
44
26.8k
45
26.8k
                if k >= LIMBS {
46
10.0k
                    let (n, c) = hi.limbs[k - LIMBS].mac(self.limbs[i], rhs.limbs[j], carry);
47
10.0k
                    hi.limbs[k - LIMBS] = n;
48
10.0k
                    carry = c;
49
16.7k
                } else {
50
16.7k
                    let (n, c) = lo.limbs[k].mac(self.limbs[i], rhs.limbs[j], carry);
51
16.7k
                    lo.limbs[k] = n;
52
16.7k
                    carry = c;
53
16.7k
                }
54
55
26.8k
                j += 1;
56
            }
57
58
6.70k
            if i + j >= LIMBS {
59
6.70k
                hi.limbs[i + j - LIMBS] = carry;
60
6.70k
            } else {
61
0
                lo.limbs[i + j] = carry;
62
0
            }
63
6.70k
            i += 1;
64
        }
65
66
1.67k
        (lo, hi)
67
1.67k
    }
Unexecuted instantiation: _RINvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3mulINtB5_4UintKpE8mul_wideKpEB7_
_RINvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3mulINtB5_4UintKj4_E8mul_wideKBV_ECsaHRNXv1Y9Bq_4p256
Line
Count
Source
31
1.67k
    pub const fn mul_wide<const HLIMBS: usize>(&self, rhs: &Uint<HLIMBS>) -> (Self, Uint<HLIMBS>) {
32
1.67k
        let mut i = 0;
33
1.67k
        let mut lo = Self::ZERO;
34
1.67k
        let mut hi = Uint::<HLIMBS>::ZERO;
35
36
        // Schoolbook multiplication.
37
        // TODO(tarcieri): use Karatsuba for better performance?
38
8.38k
        while i < LIMBS {
39
6.70k
            let mut j = 0;
40
6.70k
            let mut carry = Limb::ZERO;
41
42
33.5k
            while j < HLIMBS {
43
26.8k
                let k = i + j;
44
26.8k
45
26.8k
                if k >= LIMBS {
46
10.0k
                    let (n, c) = hi.limbs[k - LIMBS].mac(self.limbs[i], rhs.limbs[j], carry);
47
10.0k
                    hi.limbs[k - LIMBS] = n;
48
10.0k
                    carry = c;
49
16.7k
                } else {
50
16.7k
                    let (n, c) = lo.limbs[k].mac(self.limbs[i], rhs.limbs[j], carry);
51
16.7k
                    lo.limbs[k] = n;
52
16.7k
                    carry = c;
53
16.7k
                }
54
55
26.8k
                j += 1;
56
            }
57
58
6.70k
            if i + j >= LIMBS {
59
6.70k
                hi.limbs[i + j - LIMBS] = carry;
60
6.70k
            } else {
61
0
                lo.limbs[i + j] = carry;
62
0
            }
63
6.70k
            i += 1;
64
        }
65
66
1.67k
        (lo, hi)
67
1.67k
    }
68
69
    /// Perform saturating multiplication, returning `MAX` on overflow.
70
0
    pub const fn saturating_mul<const HLIMBS: usize>(&self, rhs: &Uint<HLIMBS>) -> Self {
71
0
        let (res, overflow) = self.mul_wide(rhs);
72
0
        Self::ct_select(&res, &Self::MAX, overflow.ct_is_nonzero())
73
0
    }
74
75
    /// Perform wrapping multiplication, discarding overflow.
76
0
    pub const fn wrapping_mul<const H: usize>(&self, rhs: &Uint<H>) -> Self {
77
0
        self.mul_wide(rhs).0
78
0
    }
79
80
    /// Square self, returning a concatenated "wide" result.
81
0
    pub fn square(&self) -> <Self as Concat>::Output
82
0
    where
83
0
        Self: Concat,
84
0
    {
85
0
        let (lo, hi) = self.square_wide();
86
0
        hi.concat(&lo)
87
0
    }
88
89
    /// Square self, returning a "wide" result in two parts as (lo, hi).
90
0
    pub const fn square_wide(&self) -> (Self, Self) {
91
0
        // Translated from https://github.com/ucbrise/jedi-pairing/blob/c4bf151/include/core/bigint.hpp#L410
92
0
        //
93
0
        // Permission to relicense the resulting translation as Apache 2.0 + MIT was given
94
0
        // by the original author Sam Kumar: https://github.com/RustCrypto/crypto-bigint/pull/133#discussion_r1056870411
95
0
        let mut lo = Self::ZERO;
96
0
        let mut hi = Self::ZERO;
97
0
98
0
        // Schoolbook multiplication, but only considering half of the multiplication grid
99
0
        let mut i = 1;
100
0
        while i < LIMBS {
101
0
            let mut j = 0;
102
0
            let mut carry = Limb::ZERO;
103
104
0
            while j < i {
105
0
                let k = i + j;
106
0
107
0
                if k >= LIMBS {
108
0
                    let (n, c) = hi.limbs[k - LIMBS].mac(self.limbs[i], self.limbs[j], carry);
109
0
                    hi.limbs[k - LIMBS] = n;
110
0
                    carry = c;
111
0
                } else {
112
0
                    let (n, c) = lo.limbs[k].mac(self.limbs[i], self.limbs[j], carry);
113
0
                    lo.limbs[k] = n;
114
0
                    carry = c;
115
0
                }
116
117
0
                j += 1;
118
            }
119
120
0
            if (2 * i) < LIMBS {
121
0
                lo.limbs[2 * i] = carry;
122
0
            } else {
123
0
                hi.limbs[2 * i - LIMBS] = carry;
124
0
            }
125
126
0
            i += 1;
127
        }
128
129
        // Double the current result, this accounts for the other half of the multiplication grid.
130
        // TODO: The top word is empty so we can also use a special purpose shl.
131
0
        (lo, hi) = Self::shl_vartime_wide((lo, hi), 1);
132
0
133
0
        // Handle the diagonal of the multiplication grid, which finishes the multiplication grid.
134
0
        let mut carry = Limb::ZERO;
135
0
        let mut i = 0;
136
0
        while i < LIMBS {
137
0
            if (i * 2) < LIMBS {
138
0
                let (n, c) = lo.limbs[i * 2].mac(self.limbs[i], self.limbs[i], carry);
139
0
                lo.limbs[i * 2] = n;
140
0
                carry = c;
141
0
            } else {
142
0
                let (n, c) = hi.limbs[i * 2 - LIMBS].mac(self.limbs[i], self.limbs[i], carry);
143
0
                hi.limbs[i * 2 - LIMBS] = n;
144
0
                carry = c;
145
0
            }
146
147
0
            if (i * 2 + 1) < LIMBS {
148
0
                let n = lo.limbs[i * 2 + 1].0 as WideWord + carry.0 as WideWord;
149
0
                lo.limbs[i * 2 + 1] = Limb(n as Word);
150
0
                carry = Limb((n >> Word::BITS) as Word);
151
0
            } else {
152
0
                let n = hi.limbs[i * 2 + 1 - LIMBS].0 as WideWord + carry.0 as WideWord;
153
0
                hi.limbs[i * 2 + 1 - LIMBS] = Limb(n as Word);
154
0
                carry = Limb((n >> Word::BITS) as Word);
155
0
            }
156
157
0
            i += 1;
158
        }
159
160
0
        (lo, hi)
161
0
    }
162
}
163
164
impl<const LIMBS: usize, const HLIMBS: usize> CheckedMul<&Uint<HLIMBS>> for Uint<LIMBS> {
165
    type Output = Self;
166
167
0
    fn checked_mul(&self, rhs: &Uint<HLIMBS>) -> CtOption<Self> {
168
0
        let (lo, hi) = self.mul_wide(rhs);
169
0
        CtOption::new(lo, hi.is_zero())
170
0
    }
171
}
172
173
impl<const LIMBS: usize, const HLIMBS: usize> Mul<Wrapping<Uint<HLIMBS>>>
174
    for Wrapping<Uint<LIMBS>>
175
{
176
    type Output = Self;
177
178
0
    fn mul(self, rhs: Wrapping<Uint<HLIMBS>>) -> Wrapping<Uint<LIMBS>> {
179
0
        Wrapping(self.0.wrapping_mul(&rhs.0))
180
0
    }
181
}
182
183
impl<const LIMBS: usize, const HLIMBS: usize> Mul<&Wrapping<Uint<HLIMBS>>>
184
    for Wrapping<Uint<LIMBS>>
185
{
186
    type Output = Self;
187
188
0
    fn mul(self, rhs: &Wrapping<Uint<HLIMBS>>) -> Wrapping<Uint<LIMBS>> {
189
0
        Wrapping(self.0.wrapping_mul(&rhs.0))
190
0
    }
191
}
192
193
impl<const LIMBS: usize, const HLIMBS: usize> Mul<Wrapping<Uint<HLIMBS>>>
194
    for &Wrapping<Uint<LIMBS>>
195
{
196
    type Output = Wrapping<Uint<LIMBS>>;
197
198
0
    fn mul(self, rhs: Wrapping<Uint<HLIMBS>>) -> Wrapping<Uint<LIMBS>> {
199
0
        Wrapping(self.0.wrapping_mul(&rhs.0))
200
0
    }
201
}
202
203
impl<const LIMBS: usize, const HLIMBS: usize> Mul<&Wrapping<Uint<HLIMBS>>>
204
    for &Wrapping<Uint<LIMBS>>
205
{
206
    type Output = Wrapping<Uint<LIMBS>>;
207
208
0
    fn mul(self, rhs: &Wrapping<Uint<HLIMBS>>) -> Wrapping<Uint<LIMBS>> {
209
0
        Wrapping(self.0.wrapping_mul(&rhs.0))
210
0
    }
211
}
212
213
impl<const LIMBS: usize, const HLIMBS: usize> MulAssign<Wrapping<Uint<HLIMBS>>>
214
    for Wrapping<Uint<LIMBS>>
215
{
216
0
    fn mul_assign(&mut self, other: Wrapping<Uint<HLIMBS>>) {
217
0
        *self = *self * other;
218
0
    }
219
}
220
221
impl<const LIMBS: usize, const HLIMBS: usize> MulAssign<&Wrapping<Uint<HLIMBS>>>
222
    for Wrapping<Uint<LIMBS>>
223
{
224
0
    fn mul_assign(&mut self, other: &Wrapping<Uint<HLIMBS>>) {
225
0
        *self = *self * other;
226
0
    }
227
}
228
229
impl<const LIMBS: usize, const HLIMBS: usize> Mul<Checked<Uint<HLIMBS>>> for Checked<Uint<LIMBS>> {
230
    type Output = Self;
231
232
0
    fn mul(self, rhs: Checked<Uint<HLIMBS>>) -> Checked<Uint<LIMBS>> {
233
0
        Checked(self.0.and_then(|a| rhs.0.and_then(|b| a.checked_mul(&b))))
234
0
    }
235
}
236
237
impl<const LIMBS: usize, const HLIMBS: usize> Mul<&Checked<Uint<HLIMBS>>> for Checked<Uint<LIMBS>> {
238
    type Output = Checked<Uint<LIMBS>>;
239
240
0
    fn mul(self, rhs: &Checked<Uint<HLIMBS>>) -> Checked<Uint<LIMBS>> {
241
0
        Checked(self.0.and_then(|a| rhs.0.and_then(|b| a.checked_mul(&b))))
242
0
    }
243
}
244
245
impl<const LIMBS: usize, const HLIMBS: usize> Mul<Checked<Uint<HLIMBS>>> for &Checked<Uint<LIMBS>> {
246
    type Output = Checked<Uint<LIMBS>>;
247
248
0
    fn mul(self, rhs: Checked<Uint<HLIMBS>>) -> Checked<Uint<LIMBS>> {
249
0
        Checked(self.0.and_then(|a| rhs.0.and_then(|b| a.checked_mul(&b))))
250
0
    }
251
}
252
253
impl<const LIMBS: usize, const HLIMBS: usize> Mul<&Checked<Uint<HLIMBS>>>
254
    for &Checked<Uint<LIMBS>>
255
{
256
    type Output = Checked<Uint<LIMBS>>;
257
258
0
    fn mul(self, rhs: &Checked<Uint<HLIMBS>>) -> Checked<Uint<LIMBS>> {
259
0
        Checked(self.0.and_then(|a| rhs.0.and_then(|b| a.checked_mul(&b))))
260
0
    }
261
}
262
263
impl<const LIMBS: usize, const HLIMBS: usize> MulAssign<Checked<Uint<HLIMBS>>>
264
    for Checked<Uint<LIMBS>>
265
{
266
0
    fn mul_assign(&mut self, other: Checked<Uint<HLIMBS>>) {
267
0
        *self = *self * other;
268
0
    }
269
}
270
271
impl<const LIMBS: usize, const HLIMBS: usize> MulAssign<&Checked<Uint<HLIMBS>>>
272
    for Checked<Uint<LIMBS>>
273
{
274
0
    fn mul_assign(&mut self, other: &Checked<Uint<HLIMBS>>) {
275
0
        *self = *self * other;
276
0
    }
277
}
278
279
impl<const LIMBS: usize, const HLIMBS: usize> Mul<Uint<HLIMBS>> for Uint<LIMBS>
280
where
281
    Uint<HLIMBS>: ConcatMixed<Uint<LIMBS>>,
282
{
283
    type Output = <Uint<HLIMBS> as ConcatMixed<Self>>::MixedOutput;
284
285
0
    fn mul(self, other: Uint<HLIMBS>) -> Self::Output {
286
0
        Uint::mul(&self, &other)
287
0
    }
288
}
289
290
impl<const LIMBS: usize, const HLIMBS: usize> Mul<&Uint<HLIMBS>> for Uint<LIMBS>
291
where
292
    Uint<HLIMBS>: ConcatMixed<Uint<LIMBS>>,
293
{
294
    type Output = <Uint<HLIMBS> as ConcatMixed<Self>>::MixedOutput;
295
296
0
    fn mul(self, other: &Uint<HLIMBS>) -> Self::Output {
297
0
        Uint::mul(&self, other)
298
0
    }
299
}
300
301
impl<const LIMBS: usize, const HLIMBS: usize> Mul<Uint<HLIMBS>> for &Uint<LIMBS>
302
where
303
    Uint<HLIMBS>: ConcatMixed<Uint<LIMBS>>,
304
{
305
    type Output = <Uint<HLIMBS> as ConcatMixed<Uint<LIMBS>>>::MixedOutput;
306
307
0
    fn mul(self, other: Uint<HLIMBS>) -> Self::Output {
308
0
        Uint::mul(self, &other)
309
0
    }
310
}
311
312
impl<const LIMBS: usize, const HLIMBS: usize> Mul<&Uint<HLIMBS>> for &Uint<LIMBS>
313
where
314
    Uint<HLIMBS>: ConcatMixed<Uint<LIMBS>>,
315
{
316
    type Output = <Uint<HLIMBS> as ConcatMixed<Uint<LIMBS>>>::MixedOutput;
317
318
0
    fn mul(self, other: &Uint<HLIMBS>) -> Self::Output {
319
0
        Uint::mul(self, other)
320
0
    }
321
}
322
323
#[cfg(test)]
324
mod tests {
325
    use crate::{CheckedMul, Zero, U128, U192, U256, U64};
326
327
    #[test]
328
    fn mul_wide_zero_and_one() {
329
        assert_eq!(U64::ZERO.mul_wide(&U64::ZERO), (U64::ZERO, U64::ZERO));
330
        assert_eq!(U64::ZERO.mul_wide(&U64::ONE), (U64::ZERO, U64::ZERO));
331
        assert_eq!(U64::ONE.mul_wide(&U64::ZERO), (U64::ZERO, U64::ZERO));
332
        assert_eq!(U64::ONE.mul_wide(&U64::ONE), (U64::ONE, U64::ZERO));
333
    }
334
335
    #[test]
336
    fn mul_wide_lo_only() {
337
        let primes: &[u32] = &[3, 5, 17, 257, 65537];
338
339
        for &a_int in primes {
340
            for &b_int in primes {
341
                let (lo, hi) = U64::from_u32(a_int).mul_wide(&U64::from_u32(b_int));
342
                let expected = U64::from_u64(a_int as u64 * b_int as u64);
343
                assert_eq!(lo, expected);
344
                assert!(bool::from(hi.is_zero()));
345
            }
346
        }
347
    }
348
349
    #[test]
350
    fn mul_concat_even() {
351
        assert_eq!(U64::ZERO * U64::MAX, U128::ZERO);
352
        assert_eq!(U64::MAX * U64::ZERO, U128::ZERO);
353
        assert_eq!(
354
            U64::MAX * U64::MAX,
355
            U128::from_u128(0xfffffffffffffffe_0000000000000001)
356
        );
357
        assert_eq!(
358
            U64::ONE * U64::MAX,
359
            U128::from_u128(0x0000000000000000_ffffffffffffffff)
360
        );
361
    }
362
363
    #[test]
364
    fn mul_concat_mixed() {
365
        let a = U64::from_u64(0x0011223344556677);
366
        let b = U128::from_u128(0x8899aabbccddeeff_8899aabbccddeeff);
367
        assert_eq!(a * b, U192::from(&a).saturating_mul(&b));
368
        assert_eq!(b * a, U192::from(&b).saturating_mul(&a));
369
    }
370
371
    #[test]
372
    fn checked_mul_ok() {
373
        let n = U64::from_u32(0xffff_ffff);
374
        assert_eq!(
375
            n.checked_mul(&n).unwrap(),
376
            U64::from_u64(0xffff_fffe_0000_0001)
377
        );
378
    }
379
380
    #[test]
381
    fn checked_mul_overflow() {
382
        let n = U64::from_u64(0xffff_ffff_ffff_ffff);
383
        assert!(bool::from(n.checked_mul(&n).is_none()));
384
    }
385
386
    #[test]
387
    fn saturating_mul_no_overflow() {
388
        let n = U64::from_u8(8);
389
        assert_eq!(n.saturating_mul(&n), U64::from_u8(64));
390
    }
391
392
    #[test]
393
    fn saturating_mul_overflow() {
394
        let a = U64::from(0xffff_ffff_ffff_ffffu64);
395
        let b = U64::from(2u8);
396
        assert_eq!(a.saturating_mul(&b), U64::MAX);
397
    }
398
399
    #[test]
400
    fn square() {
401
        let n = U64::from_u64(0xffff_ffff_ffff_ffff);
402
        let (hi, lo) = n.square().split();
403
        assert_eq!(lo, U64::from_u64(1));
404
        assert_eq!(hi, U64::from_u64(0xffff_ffff_ffff_fffe));
405
    }
406
407
    #[test]
408
    fn square_larger() {
409
        let n = U256::MAX;
410
        let (hi, lo) = n.square().split();
411
        assert_eq!(lo, U256::ONE);
412
        assert_eq!(hi, U256::MAX.wrapping_sub(&U256::ONE));
413
    }
414
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/mul_mod.rs
Line
Count
Source
1
//! [`Uint`] multiplication modulus operations.
2
3
use crate::{Limb, Uint, WideWord, Word};
4
5
impl<const LIMBS: usize> Uint<LIMBS> {
6
    /// Computes `self * rhs mod p` for the special modulus
7
    /// `p = MAX+1-c` where `c` is small enough to fit in a single [`Limb`].
8
    /// For the modulus reduction, this function implements Algorithm 14.47 from
9
    /// the "Handbook of Applied Cryptography", by A. Menezes, P. van Oorschot,
10
    /// and S. Vanstone, CRC Press, 1996.
11
0
    pub const fn mul_mod_special(&self, rhs: &Self, c: Limb) -> Self {
12
0
        // We implicitly assume `LIMBS > 0`, because `Uint<0>` doesn't compile.
13
0
        // Still the case `LIMBS == 1` needs special handling.
14
0
        if LIMBS == 1 {
15
0
            let prod = self.limbs[0].0 as WideWord * rhs.limbs[0].0 as WideWord;
16
0
            let reduced = prod % Word::MIN.wrapping_sub(c.0) as WideWord;
17
0
            return Self::from_word(reduced as Word);
18
0
        }
19
0
20
0
        let (lo, hi) = self.mul_wide(rhs);
21
0
22
0
        // Now use Algorithm 14.47 for the reduction
23
0
        let (lo, carry) = mac_by_limb(&lo, &hi, c, Limb::ZERO);
24
0
25
0
        let (lo, carry) = {
26
0
            let rhs = (carry.0 + 1) as WideWord * c.0 as WideWord;
27
0
            lo.adc(&Self::from_wide_word(rhs), Limb::ZERO)
28
0
        };
29
0
30
0
        let (lo, _) = {
31
0
            let rhs = carry.0.wrapping_sub(1) & c.0;
32
0
            lo.sbb(&Self::from_word(rhs), Limb::ZERO)
33
0
        };
34
0
35
0
        lo
36
0
    }
37
}
38
39
/// Computes `a + (b * c) + carry`, returning the result along with the new carry.
40
0
const fn mac_by_limb<const LIMBS: usize>(
41
0
    a: &Uint<LIMBS>,
42
0
    b: &Uint<LIMBS>,
43
0
    c: Limb,
44
0
    carry: Limb,
45
0
) -> (Uint<LIMBS>, Limb) {
46
0
    let mut i = 0;
47
0
    let mut a = *a;
48
0
    let mut carry = carry;
49
50
0
    while i < LIMBS {
51
0
        let (n, c) = a.limbs[i].mac(b.limbs[i], c, carry);
52
0
        a.limbs[i] = n;
53
0
        carry = c;
54
0
        i += 1;
55
0
    }
56
57
0
    (a, carry)
58
0
}
59
60
#[cfg(all(test, feature = "rand"))]
61
mod tests {
62
    use crate::{Limb, NonZero, Random, RandomMod, Uint};
63
    use rand_core::SeedableRng;
64
65
    macro_rules! test_mul_mod_special {
66
        ($size:expr, $test_name:ident) => {
67
            #[test]
68
            fn $test_name() {
69
                let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(1);
70
                let moduli = [
71
                    NonZero::<Limb>::random(&mut rng),
72
                    NonZero::<Limb>::random(&mut rng),
73
                ];
74
75
                for special in &moduli {
76
                    let p = &NonZero::new(Uint::ZERO.wrapping_sub(&Uint::from_word(special.0)))
77
                        .unwrap();
78
79
                    let minus_one = p.wrapping_sub(&Uint::ONE);
80
81
                    let base_cases = [
82
                        (Uint::ZERO, Uint::ZERO, Uint::ZERO),
83
                        (Uint::ONE, Uint::ZERO, Uint::ZERO),
84
                        (Uint::ZERO, Uint::ONE, Uint::ZERO),
85
                        (Uint::ONE, Uint::ONE, Uint::ONE),
86
                        (minus_one, minus_one, Uint::ONE),
87
                        (minus_one, Uint::ONE, minus_one),
88
                        (Uint::ONE, minus_one, minus_one),
89
                    ];
90
                    for (a, b, c) in &base_cases {
91
                        let x = a.mul_mod_special(&b, *special.as_ref());
92
                        assert_eq!(*c, x, "{} * {} mod {} = {} != {}", a, b, p, x, c);
93
                    }
94
95
                    for _i in 0..100 {
96
                        let a = Uint::<$size>::random_mod(&mut rng, p);
97
                        let b = Uint::<$size>::random_mod(&mut rng, p);
98
99
                        let c = a.mul_mod_special(&b, *special.as_ref());
100
                        assert!(c < **p, "not reduced: {} >= {} ", c, p);
101
102
                        let expected = {
103
                            let (lo, hi) = a.mul_wide(&b);
104
                            let mut prod = Uint::<{ 2 * $size }>::ZERO;
105
                            prod.limbs[..$size].clone_from_slice(&lo.limbs);
106
                            prod.limbs[$size..].clone_from_slice(&hi.limbs);
107
                            let mut modulus = Uint::ZERO;
108
                            modulus.limbs[..$size].clone_from_slice(&p.as_ref().limbs);
109
                            let reduced = prod.rem(&NonZero::new(modulus).unwrap());
110
                            let mut expected = Uint::ZERO;
111
                            expected.limbs[..].clone_from_slice(&reduced.limbs[..$size]);
112
                            expected
113
                        };
114
                        assert_eq!(c, expected, "incorrect result");
115
                    }
116
                }
117
            }
118
        };
119
    }
120
121
    test_mul_mod_special!(1, mul_mod_special_1);
122
    test_mul_mod_special!(2, mul_mod_special_2);
123
    test_mul_mod_special!(3, mul_mod_special_3);
124
    test_mul_mod_special!(4, mul_mod_special_4);
125
    test_mul_mod_special!(5, mul_mod_special_5);
126
    test_mul_mod_special!(6, mul_mod_special_6);
127
    test_mul_mod_special!(7, mul_mod_special_7);
128
    test_mul_mod_special!(8, mul_mod_special_8);
129
    test_mul_mod_special!(9, mul_mod_special_9);
130
    test_mul_mod_special!(10, mul_mod_special_10);
131
    test_mul_mod_special!(11, mul_mod_special_11);
132
    test_mul_mod_special!(12, mul_mod_special_12);
133
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/neg.rs
Line
Count
Source
1
use core::ops::Neg;
2
3
use crate::{CtChoice, Limb, Uint, WideWord, Word, Wrapping};
4
5
impl<const LIMBS: usize> Neg for Wrapping<Uint<LIMBS>> {
6
    type Output = Self;
7
8
0
    fn neg(self) -> Self::Output {
9
0
        Self(self.0.wrapping_neg())
10
0
    }
11
}
12
13
impl<const LIMBS: usize> Uint<LIMBS> {
14
    /// Negates based on `choice` by wrapping the integer.
15
0
    pub(crate) const fn conditional_wrapping_neg(&self, choice: CtChoice) -> Uint<LIMBS> {
16
0
        Uint::ct_select(self, &self.wrapping_neg(), choice)
17
0
    }
18
19
    /// Perform wrapping negation.
20
0
    pub const fn wrapping_neg(&self) -> Self {
21
0
        let mut ret = [Limb::ZERO; LIMBS];
22
0
        let mut carry = 1;
23
0
        let mut i = 0;
24
0
        while i < LIMBS {
25
0
            let r = (!self.limbs[i].0 as WideWord) + carry;
26
0
            ret[i] = Limb(r as Word);
27
0
            carry = r >> Limb::BITS;
28
0
            i += 1;
29
0
        }
30
0
        Uint::new(ret)
31
0
    }
32
}
33
34
#[cfg(test)]
35
mod tests {
36
    use crate::U256;
37
38
    #[test]
39
    fn wrapping_neg() {
40
        assert_eq!(U256::ZERO.wrapping_neg(), U256::ZERO);
41
        assert_eq!(U256::MAX.wrapping_neg(), U256::ONE);
42
        assert_eq!(
43
            U256::from_u64(13).wrapping_neg(),
44
            U256::from_u64(13).not().saturating_add(&U256::ONE)
45
        );
46
        assert_eq!(
47
            U256::from_u64(42).wrapping_neg(),
48
            U256::from_u64(42).saturating_sub(&U256::ONE).not()
49
        );
50
    }
51
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/neg_mod.rs
Line
Count
Source
1
//! [`Uint`] negation modulus operations.
2
3
use crate::{Limb, NegMod, Uint};
4
5
impl<const LIMBS: usize> Uint<LIMBS> {
6
    /// Computes `-a mod p`.
7
    /// Assumes `self` is in `[0, p)`.
8
2.09k
    pub const fn neg_mod(&self, p: &Self) -> Self {
9
2.09k
        let z = self.ct_is_nonzero();
10
2.09k
        let mut ret = p.sbb(self, Limb::ZERO).0;
11
2.09k
        let mut i = 0;
12
10.4k
        while i < LIMBS {
13
8.36k
            // Set ret to 0 if the original value was 0, in which
14
8.36k
            // case ret would be p.
15
8.36k
            ret.limbs[i].0 = z.if_true(ret.limbs[i].0);
16
8.36k
            i += 1;
17
8.36k
        }
18
2.09k
        ret
19
2.09k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint7neg_modINtB4_4UintKpE7neg_modB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint7neg_modINtB4_4UintKj4_E7neg_modCsjewTDwKBbyD_4k256
Line
Count
Source
8
2.09k
    pub const fn neg_mod(&self, p: &Self) -> Self {
9
2.09k
        let z = self.ct_is_nonzero();
10
2.09k
        let mut ret = p.sbb(self, Limb::ZERO).0;
11
2.09k
        let mut i = 0;
12
10.4k
        while i < LIMBS {
13
8.36k
            // Set ret to 0 if the original value was 0, in which
14
8.36k
            // case ret would be p.
15
8.36k
            ret.limbs[i].0 = z.if_true(ret.limbs[i].0);
16
8.36k
            i += 1;
17
8.36k
        }
18
2.09k
        ret
19
2.09k
    }
20
21
    /// Computes `-a mod p` for the special modulus
22
    /// `p = MAX+1-c` where `c` is small enough to fit in a single [`Limb`].
23
0
    pub const fn neg_mod_special(&self, c: Limb) -> Self {
24
0
        Self::ZERO.sub_mod_special(self, c)
25
0
    }
26
}
27
28
impl<const LIMBS: usize> NegMod for Uint<LIMBS> {
29
    type Output = Self;
30
31
0
    fn neg_mod(&self, p: &Self) -> Self {
32
0
        debug_assert!(self < p);
33
0
        self.neg_mod(p)
34
0
    }
35
}
36
37
#[cfg(test)]
38
mod tests {
39
    use crate::U256;
40
41
    #[test]
42
    fn neg_mod_random() {
43
        let x =
44
            U256::from_be_hex("8d16e171674b4e6d8529edba4593802bf30b8cb161dd30aa8e550d41380007c2");
45
        let p =
46
            U256::from_be_hex("928334a4e4be0843ec225a4c9c61df34bdc7a81513e4b6f76f2bfa3148e2e1b5");
47
48
        let actual = x.neg_mod(&p);
49
        let expected =
50
            U256::from_be_hex("056c53337d72b9d666f86c9256ce5f08cabc1b63b207864ce0d6ecf010e2d9f3");
51
52
        assert_eq!(expected, actual);
53
    }
54
55
    #[test]
56
    fn neg_mod_zero() {
57
        let x =
58
            U256::from_be_hex("0000000000000000000000000000000000000000000000000000000000000000");
59
        let p =
60
            U256::from_be_hex("928334a4e4be0843ec225a4c9c61df34bdc7a81513e4b6f76f2bfa3148e2e1b5");
61
62
        let actual = x.neg_mod(&p);
63
        let expected =
64
            U256::from_be_hex("0000000000000000000000000000000000000000000000000000000000000000");
65
66
        assert_eq!(expected, actual);
67
    }
68
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/rand.rs
Line
Count
Source
1
//! Random number generator support
2
3
use super::Uint;
4
use crate::{Encoding, Limb, NonZero, Random, RandomMod};
5
use rand_core::CryptoRngCore;
6
use subtle::ConstantTimeLess;
7
8
impl<const LIMBS: usize> Random for Uint<LIMBS> {
9
    /// Generate a cryptographically secure random [`Uint`].
10
0
    fn random(mut rng: &mut impl CryptoRngCore) -> Self {
11
0
        let mut limbs = [Limb::ZERO; LIMBS];
12
13
0
        for limb in &mut limbs {
14
0
            *limb = Limb::random(&mut rng)
15
        }
16
17
0
        limbs.into()
18
0
    }
19
}
20
21
impl<const LIMBS: usize> RandomMod for Uint<LIMBS> {
22
    /// Generate a cryptographically secure random [`Uint`] which is less than
23
    /// a given `modulus`.
24
    ///
25
    /// This function uses rejection sampling, a method which produces an
26
    /// unbiased distribution of in-range values provided the underlying
27
    /// CSRNG is unbiased, but runs in variable-time.
28
    ///
29
    /// The variable-time nature of the algorithm should not pose a security
30
    /// issue so long as the underlying random number generator is truly a
31
    /// CSRNG, where previous outputs are unrelated to subsequent
32
    /// outputs and do not reveal information about the RNG's internal state.
33
0
    fn random_mod(rng: &mut impl CryptoRngCore, modulus: &NonZero<Self>) -> Self {
34
0
        let mut n = Self::ZERO;
35
0
36
0
        let n_bits = modulus.as_ref().bits_vartime();
37
0
        let n_bytes = (n_bits + 7) / 8;
38
0
        let n_limbs = (n_bits + Limb::BITS - 1) / Limb::BITS;
39
0
        let hi_bytes = n_bytes - (n_limbs - 1) * Limb::BYTES;
40
0
41
0
        let mut bytes = Limb::ZERO.to_le_bytes();
42
43
        loop {
44
0
            for i in 0..n_limbs - 1 {
45
0
                rng.fill_bytes(bytes.as_mut());
46
0
                // Need to deserialize from little-endian to make sure that two 32-bit limbs
47
0
                // deserialized sequentially are equal to one 64-bit limb produced from the same
48
0
                // byte stream.
49
0
                n.limbs[i] = Limb::from_le_bytes(bytes);
50
0
            }
51
52
            // Generate the high limb which may need to only be filled partially.
53
0
            bytes.as_mut().fill(0);
54
0
            rng.fill_bytes(&mut (bytes.as_mut()[0..hi_bytes]));
55
0
            n.limbs[n_limbs - 1] = Limb::from_le_bytes(bytes);
56
0
57
0
            if n.ct_lt(modulus).into() {
58
0
                return n;
59
0
            }
60
        }
61
0
    }
62
}
63
64
#[cfg(test)]
65
mod tests {
66
    use crate::{NonZero, RandomMod, U256};
67
    use rand_core::SeedableRng;
68
69
    #[test]
70
    fn random_mod() {
71
        let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(1);
72
73
        // Ensure `random_mod` runs in a reasonable amount of time
74
        let modulus = NonZero::new(U256::from(42u8)).unwrap();
75
        let res = U256::random_mod(&mut rng, &modulus);
76
77
        // Check that the value is in range
78
        assert!(res >= U256::ZERO);
79
        assert!(res < U256::from(42u8));
80
81
        // Ensure `random_mod` runs in a reasonable amount of time
82
        // when the modulus is larger than 1 limb
83
        let modulus = NonZero::new(U256::from(0x10000000000000001u128)).unwrap();
84
        let res = U256::random_mod(&mut rng, &modulus);
85
86
        // Check that the value is in range
87
        assert!(res >= U256::ZERO);
88
        assert!(res < U256::from(0x10000000000000001u128));
89
    }
90
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/resize.rs
Line
Count
Source
1
use super::Uint;
2
3
impl<const LIMBS: usize> Uint<LIMBS> {
4
    /// Construct a `Uint<T>` from the unsigned integer value,
5
    /// truncating the upper bits if the value is too large to be
6
    /// represented.
7
    #[inline(always)]
8
0
    pub const fn resize<const T: usize>(&self) -> Uint<T> {
9
0
        let mut res = Uint::ZERO;
10
0
        let mut i = 0;
11
0
        let dim = if T < LIMBS { T } else { LIMBS };
12
0
        while i < dim {
13
0
            res.limbs[i] = self.limbs[i];
14
0
            i += 1;
15
0
        }
16
0
        res
17
0
    }
18
}
19
20
#[cfg(test)]
21
mod tests {
22
    use crate::{U128, U64};
23
24
    #[test]
25
    fn resize_larger() {
26
        let u = U64::from_be_hex("AAAAAAAABBBBBBBB");
27
        let u2: U128 = u.resize();
28
        assert_eq!(u2, U128::from_be_hex("0000000000000000AAAAAAAABBBBBBBB"));
29
    }
30
31
    #[test]
32
    fn resize_smaller() {
33
        let u = U128::from_be_hex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
34
        let u2: U64 = u.resize();
35
        assert_eq!(u2, U64::from_be_hex("CCCCCCCCDDDDDDDD"));
36
    }
37
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/shl.rs
Line
Count
Source
1
//! [`Uint`] bitwise left shift operations.
2
3
use crate::{CtChoice, Limb, Uint, Word};
4
use core::ops::{Shl, ShlAssign};
5
6
impl<const LIMBS: usize> Uint<LIMBS> {
7
    /// Computes `self << shift` where `0 <= shift < Limb::BITS`,
8
    /// returning the result and the carry.
9
    #[inline(always)]
10
0
    pub(crate) const fn shl_limb(&self, n: usize) -> (Self, Limb) {
11
0
        let mut limbs = [Limb::ZERO; LIMBS];
12
0
13
0
        let nz = Limb(n as Word).ct_is_nonzero();
14
0
        let lshift = n as Word;
15
0
        let rshift = Limb::ct_select(Limb::ZERO, Limb((Limb::BITS - n) as Word), nz).0;
16
0
        let carry = Limb::ct_select(
17
0
            Limb::ZERO,
18
0
            Limb(self.limbs[LIMBS - 1].0.wrapping_shr(Word::BITS - n as u32)),
19
0
            nz,
20
0
        );
21
0
22
0
        let mut i = LIMBS - 1;
23
0
        while i > 0 {
24
0
            let mut limb = self.limbs[i].0 << lshift;
25
0
            let hi = self.limbs[i - 1].0 >> rshift;
26
0
            limb |= nz.if_true(hi);
27
0
            limbs[i] = Limb(limb);
28
0
            i -= 1
29
        }
30
0
        limbs[0] = Limb(self.limbs[0].0 << lshift);
31
0
32
0
        (Uint::<LIMBS>::new(limbs), carry)
33
0
    }
34
35
    /// Computes `self << shift`.
36
    ///
37
    /// NOTE: this operation is variable time with respect to `n` *ONLY*.
38
    ///
39
    /// When used with a fixed `n`, this function is constant-time with respect
40
    /// to `self`.
41
    #[inline(always)]
42
0
    pub const fn shl_vartime(&self, n: usize) -> Self {
43
0
        let mut limbs = [Limb::ZERO; LIMBS];
44
0
45
0
        if n >= Limb::BITS * LIMBS {
46
0
            return Self { limbs };
47
0
        }
48
0
49
0
        let shift_num = n / Limb::BITS;
50
0
        let rem = n % Limb::BITS;
51
0
52
0
        let mut i = LIMBS;
53
0
        while i > shift_num {
54
0
            i -= 1;
55
0
            limbs[i] = self.limbs[i - shift_num];
56
0
        }
57
58
0
        let (new_lower, _carry) = (Self { limbs }).shl_limb(rem);
59
0
        new_lower
60
0
    }
61
62
    /// Computes a left shift on a wide input as `(lo, hi)`.
63
    ///
64
    /// NOTE: this operation is variable time with respect to `n` *ONLY*.
65
    ///
66
    /// When used with a fixed `n`, this function is constant-time with respect
67
    /// to `self`.
68
    #[inline(always)]
69
0
    pub const fn shl_vartime_wide(lower_upper: (Self, Self), n: usize) -> (Self, Self) {
70
0
        let (lower, mut upper) = lower_upper;
71
0
        let new_lower = lower.shl_vartime(n);
72
0
        upper = upper.shl_vartime(n);
73
0
        if n >= Self::BITS {
74
0
            upper = upper.bitor(&lower.shl_vartime(n - Self::BITS));
75
0
        } else {
76
0
            upper = upper.bitor(&lower.shr_vartime(Self::BITS - n));
77
0
        }
78
79
0
        (new_lower, upper)
80
0
    }
81
82
    /// Computes `self << n`.
83
    /// Returns zero if `n >= Self::BITS`.
84
0
    pub const fn shl(&self, shift: usize) -> Self {
85
0
        let overflow = CtChoice::from_usize_lt(shift, Self::BITS).not();
86
0
        let shift = shift % Self::BITS;
87
0
        let mut result = *self;
88
0
        let mut i = 0;
89
0
        while i < Self::LOG2_BITS {
90
0
            let bit = CtChoice::from_lsb((shift as Word >> i) & 1);
91
0
            result = Uint::ct_select(&result, &result.shl_vartime(1 << i), bit);
92
0
            i += 1;
93
0
        }
94
95
0
        Uint::ct_select(&result, &Self::ZERO, overflow)
96
0
    }
97
}
98
99
impl<const LIMBS: usize> Shl<usize> for Uint<LIMBS> {
100
    type Output = Uint<LIMBS>;
101
102
    /// NOTE: this operation is variable time with respect to `rhs` *ONLY*.
103
    ///
104
    /// When used with a fixed `rhs`, this function is constant-time with respect
105
    /// to `self`.
106
0
    fn shl(self, rhs: usize) -> Uint<LIMBS> {
107
0
        Uint::<LIMBS>::shl(&self, rhs)
108
0
    }
109
}
110
111
impl<const LIMBS: usize> Shl<usize> for &Uint<LIMBS> {
112
    type Output = Uint<LIMBS>;
113
114
    /// NOTE: this operation is variable time with respect to `rhs` *ONLY*.
115
    ///
116
    /// When used with a fixed `rhs`, this function is constant-time with respect
117
    /// to `self`.
118
0
    fn shl(self, rhs: usize) -> Uint<LIMBS> {
119
0
        self.shl(rhs)
120
0
    }
121
}
122
123
impl<const LIMBS: usize> ShlAssign<usize> for Uint<LIMBS> {
124
    /// NOTE: this operation is variable time with respect to `rhs` *ONLY*.
125
    ///
126
    /// When used with a fixed `rhs`, this function is constant-time with respect
127
    /// to `self`.
128
0
    fn shl_assign(&mut self, rhs: usize) {
129
0
        *self = self.shl(rhs)
130
0
    }
131
}
132
133
#[cfg(test)]
134
mod tests {
135
    use crate::{Limb, Uint, U128, U256};
136
137
    const N: U256 =
138
        U256::from_be_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
139
140
    const TWO_N: U256 =
141
        U256::from_be_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD755DB9CD5E9140777FA4BD19A06C8282");
142
143
    const FOUR_N: U256 =
144
        U256::from_be_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEABB739ABD2280EEFF497A3340D90504");
145
146
    const SIXTY_FIVE: U256 =
147
        U256::from_be_hex("FFFFFFFFFFFFFFFD755DB9CD5E9140777FA4BD19A06C82820000000000000000");
148
149
    const EIGHTY_EIGHT: U256 =
150
        U256::from_be_hex("FFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD03641410000000000000000000000");
151
152
    const SIXTY_FOUR: U256 =
153
        U256::from_be_hex("FFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD03641410000000000000000");
154
155
    #[test]
156
    fn shl_simple() {
157
        let mut t = U256::from(1u8);
158
        assert_eq!(t << 1, U256::from(2u8));
159
        t = U256::from(3u8);
160
        assert_eq!(t << 8, U256::from(0x300u16));
161
    }
162
163
    #[test]
164
    fn shl1() {
165
        assert_eq!(N << 1, TWO_N);
166
    }
167
168
    #[test]
169
    fn shl2() {
170
        assert_eq!(N << 2, FOUR_N);
171
    }
172
173
    #[test]
174
    fn shl65() {
175
        assert_eq!(N << 65, SIXTY_FIVE);
176
    }
177
178
    #[test]
179
    fn shl88() {
180
        assert_eq!(N << 88, EIGHTY_EIGHT);
181
    }
182
183
    #[test]
184
    fn shl256() {
185
        assert_eq!(N << 256, U256::default());
186
    }
187
188
    #[test]
189
    fn shl64() {
190
        assert_eq!(N << 64, SIXTY_FOUR);
191
    }
192
193
    #[test]
194
    fn shl_wide_1_1_128() {
195
        assert_eq!(
196
            Uint::shl_vartime_wide((U128::ONE, U128::ONE), 128),
197
            (U128::ZERO, U128::ONE)
198
        );
199
    }
200
201
    #[test]
202
    fn shl_wide_max_0_1() {
203
        assert_eq!(
204
            Uint::shl_vartime_wide((U128::MAX, U128::ZERO), 1),
205
            (U128::MAX.sbb(&U128::ONE, Limb::ZERO).0, U128::ONE)
206
        );
207
    }
208
209
    #[test]
210
    fn shl_wide_max_max_256() {
211
        assert_eq!(
212
            Uint::shl_vartime_wide((U128::MAX, U128::MAX), 256),
213
            (U128::ZERO, U128::ZERO)
214
        );
215
    }
216
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/shr.rs
Line
Count
Source
1
//! [`Uint`] bitwise right shift operations.
2
3
use super::Uint;
4
use crate::{limb::HI_BIT, CtChoice, Limb, Word};
5
use core::ops::{Shr, ShrAssign};
6
7
impl<const LIMBS: usize> Uint<LIMBS> {
8
    /// Computes `self >> 1` in constant-time, returning [`CtChoice::TRUE`] if the overflowing bit
9
    /// was set, and [`CtChoice::FALSE`] otherwise.
10
0
    pub(crate) const fn shr_1(&self) -> (Self, CtChoice) {
11
0
        let mut shifted_bits = [0; LIMBS];
12
0
        let mut i = 0;
13
0
        while i < LIMBS {
14
0
            shifted_bits[i] = self.limbs[i].0 >> 1;
15
0
            i += 1;
16
0
        }
17
18
0
        let mut carry_bits = [0; LIMBS];
19
0
        let mut i = 0;
20
0
        while i < LIMBS {
21
0
            carry_bits[i] = self.limbs[i].0 << HI_BIT;
22
0
            i += 1;
23
0
        }
24
25
0
        let mut limbs = [Limb(0); LIMBS];
26
0
27
0
        let mut i = 0;
28
0
        while i < (LIMBS - 1) {
29
0
            limbs[i] = Limb(shifted_bits[i] | carry_bits[i + 1]);
30
0
            i += 1;
31
0
        }
32
0
        limbs[LIMBS - 1] = Limb(shifted_bits[LIMBS - 1]);
33
0
34
0
        debug_assert!(carry_bits[LIMBS - 1] == 0 || carry_bits[LIMBS - 1] == (1 << HI_BIT));
35
0
        (
36
0
            Uint::new(limbs),
37
0
            CtChoice::from_lsb(carry_bits[0] >> HI_BIT),
38
0
        )
39
0
    }
40
41
    /// Computes `self >> n`.
42
    ///
43
    /// NOTE: this operation is variable time with respect to `n` *ONLY*.
44
    ///
45
    /// When used with a fixed `n`, this function is constant-time with respect
46
    /// to `self`.
47
    #[inline(always)]
48
972k
    pub const fn shr_vartime(&self, shift: usize) -> Self {
49
972k
        let full_shifts = shift / Limb::BITS;
50
972k
        let small_shift = shift & (Limb::BITS - 1);
51
972k
        let mut limbs = [Limb::ZERO; LIMBS];
52
972k
53
972k
        if shift > Limb::BITS * LIMBS {
54
0
            return Self { limbs };
55
972k
        }
56
972k
57
972k
        let n = LIMBS - full_shifts;
58
972k
        let mut i = 0;
59
972k
60
972k
        if small_shift == 0 {
61
6.27k
            while i < n {
62
4.18k
                limbs[i] = Limb(self.limbs[i + full_shifts].0);
63
4.18k
                i += 1;
64
4.18k
            }
65
        } else {
66
4.85M
            while i < n {
67
3.88M
                let mut lo = self.limbs[i + full_shifts].0 >> small_shift;
68
3.88M
69
3.88M
                if i < (LIMBS - 1) - full_shifts {
70
2.91M
                    lo |= self.limbs[i + full_shifts + 1].0 << (Limb::BITS - small_shift);
71
2.91M
                }
72
73
3.88M
                limbs[i] = Limb(lo);
74
3.88M
                i += 1;
75
            }
76
        }
77
78
972k
        Self { limbs }
79
972k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3shrINtB4_4UintKpE11shr_vartimeB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3shrINtB4_4UintKj4_E11shr_vartimeCsjewTDwKBbyD_4k256
Line
Count
Source
48
375k
    pub const fn shr_vartime(&self, shift: usize) -> Self {
49
375k
        let full_shifts = shift / Limb::BITS;
50
375k
        let small_shift = shift & (Limb::BITS - 1);
51
375k
        let mut limbs = [Limb::ZERO; LIMBS];
52
375k
53
375k
        if shift > Limb::BITS * LIMBS {
54
0
            return Self { limbs };
55
375k
        }
56
375k
57
375k
        let n = LIMBS - full_shifts;
58
375k
        let mut i = 0;
59
375k
60
375k
        if small_shift == 0 {
61
6.27k
            while i < n {
62
4.18k
                limbs[i] = Limb(self.limbs[i + full_shifts].0);
63
4.18k
                i += 1;
64
4.18k
            }
65
        } else {
66
1.86M
            while i < n {
67
1.49M
                let mut lo = self.limbs[i + full_shifts].0 >> small_shift;
68
1.49M
69
1.49M
                if i < (LIMBS - 1) - full_shifts {
70
1.12M
                    lo |= self.limbs[i + full_shifts + 1].0 << (Limb::BITS - small_shift);
71
1.12M
                }
72
73
1.49M
                limbs[i] = Limb(lo);
74
1.49M
                i += 1;
75
            }
76
        }
77
78
375k
        Self { limbs }
79
375k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3shrINtB4_4UintKj4_E11shr_vartimeCsaHRNXv1Y9Bq_4p256
Line
Count
Source
48
597k
    pub const fn shr_vartime(&self, shift: usize) -> Self {
49
597k
        let full_shifts = shift / Limb::BITS;
50
597k
        let small_shift = shift & (Limb::BITS - 1);
51
597k
        let mut limbs = [Limb::ZERO; LIMBS];
52
597k
53
597k
        if shift > Limb::BITS * LIMBS {
54
0
            return Self { limbs };
55
597k
        }
56
597k
57
597k
        let n = LIMBS - full_shifts;
58
597k
        let mut i = 0;
59
597k
60
597k
        if small_shift == 0 {
61
0
            while i < n {
62
0
                limbs[i] = Limb(self.limbs[i + full_shifts].0);
63
0
                i += 1;
64
0
            }
65
        } else {
66
2.98M
            while i < n {
67
2.38M
                let mut lo = self.limbs[i + full_shifts].0 >> small_shift;
68
2.38M
69
2.38M
                if i < (LIMBS - 1) - full_shifts {
70
1.79M
                    lo |= self.limbs[i + full_shifts + 1].0 << (Limb::BITS - small_shift);
71
1.79M
                }
72
73
2.38M
                limbs[i] = Limb(lo);
74
2.38M
                i += 1;
75
            }
76
        }
77
78
597k
        Self { limbs }
79
597k
    }
80
81
    /// Computes a right shift on a wide input as `(lo, hi)`.
82
    ///
83
    /// NOTE: this operation is variable time with respect to `n` *ONLY*.
84
    ///
85
    /// When used with a fixed `n`, this function is constant-time with respect
86
    /// to `self`.
87
    #[inline(always)]
88
0
    pub const fn shr_vartime_wide(lower_upper: (Self, Self), n: usize) -> (Self, Self) {
89
0
        let (mut lower, upper) = lower_upper;
90
0
        let new_upper = upper.shr_vartime(n);
91
0
        lower = lower.shr_vartime(n);
92
0
        if n >= Self::BITS {
93
0
            lower = lower.bitor(&upper.shr_vartime(n - Self::BITS));
94
0
        } else {
95
0
            lower = lower.bitor(&upper.shl_vartime(Self::BITS - n));
96
0
        }
97
98
0
        (lower, new_upper)
99
0
    }
100
101
    /// Computes `self << n`.
102
    /// Returns zero if `n >= Self::BITS`.
103
0
    pub const fn shr(&self, shift: usize) -> Self {
104
0
        let overflow = CtChoice::from_usize_lt(shift, Self::BITS).not();
105
0
        let shift = shift % Self::BITS;
106
0
        let mut result = *self;
107
0
        let mut i = 0;
108
0
        while i < Self::LOG2_BITS {
109
0
            let bit = CtChoice::from_lsb((shift as Word >> i) & 1);
110
0
            result = Uint::ct_select(&result, &result.shr_vartime(1 << i), bit);
111
0
            i += 1;
112
0
        }
113
114
0
        Uint::ct_select(&result, &Self::ZERO, overflow)
115
0
    }
116
}
117
118
impl<const LIMBS: usize> Shr<usize> for Uint<LIMBS> {
119
    type Output = Uint<LIMBS>;
120
121
    /// NOTE: this operation is variable time with respect to `rhs` *ONLY*.
122
    ///
123
    /// When used with a fixed `rhs`, this function is constant-time with respect
124
    /// to `self`.
125
0
    fn shr(self, rhs: usize) -> Uint<LIMBS> {
126
0
        Uint::<LIMBS>::shr(&self, rhs)
127
0
    }
128
}
129
130
impl<const LIMBS: usize> Shr<usize> for &Uint<LIMBS> {
131
    type Output = Uint<LIMBS>;
132
133
    /// NOTE: this operation is variable time with respect to `rhs` *ONLY*.
134
    ///
135
    /// When used with a fixed `rhs`, this function is constant-time with respect
136
    /// to `self`.
137
0
    fn shr(self, rhs: usize) -> Uint<LIMBS> {
138
0
        self.shr(rhs)
139
0
    }
140
}
141
142
impl<const LIMBS: usize> ShrAssign<usize> for Uint<LIMBS> {
143
0
    fn shr_assign(&mut self, rhs: usize) {
144
0
        *self = self.shr(rhs);
145
0
    }
146
}
147
148
#[cfg(test)]
149
mod tests {
150
    use crate::{Uint, U128, U256};
151
152
    const N: U256 =
153
        U256::from_be_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
154
155
    const N_2: U256 =
156
        U256::from_be_hex("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0");
157
158
    #[test]
159
    fn shr1() {
160
        assert_eq!(N >> 1, N_2);
161
    }
162
163
    #[test]
164
    fn shr_wide_1_1_128() {
165
        assert_eq!(
166
            Uint::shr_vartime_wide((U128::ONE, U128::ONE), 128),
167
            (U128::ONE, U128::ZERO)
168
        );
169
    }
170
171
    #[test]
172
    fn shr_wide_0_max_1() {
173
        assert_eq!(
174
            Uint::shr_vartime_wide((U128::ZERO, U128::MAX), 1),
175
            (U128::ONE << 127, U128::MAX >> 1)
176
        );
177
    }
178
179
    #[test]
180
    fn shr_wide_max_max_256() {
181
        assert_eq!(
182
            Uint::shr_vartime_wide((U128::MAX, U128::MAX), 256),
183
            (U128::ZERO, U128::ZERO)
184
        );
185
    }
186
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/split.rs
Line
Count
Source
1
use crate::{Limb, Uint};
2
3
/// Split this number in half, returning its high and low components
4
/// respectively.
5
#[inline]
6
0
pub(crate) const fn split_mixed<const L: usize, const H: usize, const O: usize>(
7
0
    n: &Uint<O>,
8
0
) -> (Uint<H>, Uint<L>) {
9
0
    let top = L + H;
10
0
    let top = if top < O { top } else { O };
11
0
    let mut lo = [Limb::ZERO; L];
12
0
    let mut hi = [Limb::ZERO; H];
13
0
    let mut i = 0;
14
15
0
    while i < top {
16
0
        if i < L {
17
0
            lo[i] = n.limbs[i];
18
0
        } else {
19
0
            hi[i - L] = n.limbs[i];
20
0
        }
21
0
        i += 1;
22
    }
23
24
0
    (Uint { limbs: hi }, Uint { limbs: lo })
25
0
}
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj10_KBY_Kj20_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj18_KBY_Kj30_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_KBY_Kj2_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kj2_Kj3_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kj3_Kj4_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kj4_Kj5_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kj5_Kj6_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kj6_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kj7_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kj8_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kj9_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kja_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kjb_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kjc_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kjd_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kje_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1_Kjf_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj1c_KBY_Kj38_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj20_KBY_Kj40_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj21_KBY_Kj42_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj22_KBY_Kj44_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_KBY_Kj4_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kj1_Kj3_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kj3_Kj5_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kj4_Kj6_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kj5_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kj6_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kj7_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kj8_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kj9_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kja_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kjb_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kjc_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kjd_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj2_Kje_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj30_KBY_Kj60_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_KBY_Kj6_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kj1_Kj4_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kj2_Kj5_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kj4_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kj5_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kj6_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kj7_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kj8_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kj9_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kja_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kjb_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kjc_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj3_Kjd_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj40_KBY_Kj80_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_KBY_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_Kj1_Kj5_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_Kj2_Kj6_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_Kj3_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_Kj5_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_Kj6_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_Kj7_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_Kj8_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_Kj9_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_Kja_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_Kjb_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj4_Kjc_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj5_KBY_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj5_Kj1_Kj6_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj5_Kj2_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj5_Kj3_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj5_Kj4_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj5_Kj6_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj5_Kj7_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj5_Kj8_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj5_Kj9_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj5_Kja_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj5_Kjb_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj6_KBY_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj6_Kj1_Kj7_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj6_Kj2_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj6_Kj3_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj6_Kj4_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj6_Kj5_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj6_Kj7_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj6_Kj8_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj6_Kj9_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj6_Kja_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj7_KBY_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj7_Kj1_Kj8_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj7_Kj2_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj7_Kj3_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj7_Kj4_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj7_Kj5_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj7_Kj6_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj7_Kj8_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj7_Kj9_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj80_KBY_Kj100_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj8_KBY_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj8_Kj1_Kj9_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj8_Kj2_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj8_Kj3_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj8_Kj4_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj8_Kj5_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj8_Kj6_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj8_Kj7_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj9_Kj1_Kja_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj9_Kj2_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj9_Kj3_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj9_Kj4_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj9_Kj5_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj9_Kj6_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKj9_Kj7_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKja_KBY_Kj14_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKja_Kj1_Kjb_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKja_Kj2_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKja_Kj3_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKja_Kj4_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKja_Kj5_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKja_Kj6_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjb_Kj1_Kjc_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjb_Kj2_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjb_Kj3_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjb_Kj4_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjb_Kj5_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjc_KBY_Kj18_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjc_Kj1_Kjd_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjc_Kj2_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjc_Kj3_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjc_Kj4_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjd_Kj1_Kje_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjd_Kj2_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjd_Kj3_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKje_KBY_Kj1c_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKje_Kj1_Kjf_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKje_Kj2_Kj10_EB6_
Unexecuted instantiation: _RINvNtNtCshRehcWQJ0wE_13crypto_bigint4uint5split11split_mixedKjf_Kj1_Kj10_EB6_
26
27
#[cfg(test)]
28
mod tests {
29
    use crate::{U128, U64};
30
31
    #[test]
32
    fn split() {
33
        let (hi, lo) = U128::from_be_hex("00112233445566778899aabbccddeeff").split();
34
        assert_eq!(hi, U64::from_u64(0x0011223344556677));
35
        assert_eq!(lo, U64::from_u64(0x8899aabbccddeeff));
36
    }
37
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/sqrt.rs
Line
Count
Source
1
//! [`Uint`] square root operations.
2
3
use super::Uint;
4
use crate::{Limb, Word};
5
use subtle::{ConstantTimeEq, CtOption};
6
7
impl<const LIMBS: usize> Uint<LIMBS> {
8
    /// See [`Self::sqrt_vartime`].
9
    #[deprecated(
10
        since = "0.5.3",
11
        note = "This functionality will be moved to `sqrt_vartime` in a future release."
12
    )]
13
0
    pub const fn sqrt(&self) -> Self {
14
0
        self.sqrt_vartime()
15
0
    }
16
17
    /// Computes √(`self`)
18
    /// Uses Brent & Zimmermann, Modern Computer Arithmetic, v0.5.9, Algorithm 1.13
19
    ///
20
    /// Callers can check if `self` is a square by squaring the result
21
0
    pub const fn sqrt_vartime(&self) -> Self {
22
0
        let max_bits = (self.bits_vartime() + 1) >> 1;
23
0
        let cap = Self::ONE.shl_vartime(max_bits);
24
0
        let mut guess = cap; // ≥ √(`self`)
25
0
        let mut xn = {
26
0
            let q = self.wrapping_div(&guess);
27
0
            let t = guess.wrapping_add(&q);
28
0
            t.shr_vartime(1)
29
        };
30
31
        // If guess increased, the initial guess was low.
32
        // Repeat until reverse course.
33
0
        while Uint::ct_lt(&guess, &xn).is_true_vartime() {
34
0
            // Sometimes an increase is too far, especially with large
35
0
            // powers, and then takes a long time to walk back.  The upper
36
0
            // bound is based on bit size, so saturate on that.
37
0
            let le = Limb::ct_le(Limb(xn.bits_vartime() as Word), Limb(max_bits as Word));
38
0
            guess = Self::ct_select(&cap, &xn, le);
39
0
            xn = {
40
0
                let q = self.wrapping_div(&guess);
41
0
                let t = guess.wrapping_add(&q);
42
0
                t.shr_vartime(1)
43
0
            };
44
0
        }
45
46
        // Repeat while guess decreases.
47
0
        while Uint::ct_gt(&guess, &xn).is_true_vartime() && xn.ct_is_nonzero().is_true_vartime() {
48
0
            guess = xn;
49
0
            xn = {
50
0
                let q = self.wrapping_div(&guess);
51
0
                let t = guess.wrapping_add(&q);
52
0
                t.shr_vartime(1)
53
0
            };
54
0
        }
55
56
0
        Self::ct_select(&Self::ZERO, &guess, self.ct_is_nonzero())
57
0
    }
58
59
    /// See [`Self::wrapping_sqrt_vartime`].
60
    #[deprecated(
61
        since = "0.5.3",
62
        note = "This functionality will be moved to `wrapping_sqrt_vartime` in a future release."
63
    )]
64
0
    pub const fn wrapping_sqrt(&self) -> Self {
65
0
        self.wrapping_sqrt_vartime()
66
0
    }
67
68
    /// Wrapped sqrt is just normal √(`self`)
69
    /// There’s no way wrapping could ever happen.
70
    /// This function exists, so that all operations are accounted for in the wrapping operations.
71
0
    pub const fn wrapping_sqrt_vartime(&self) -> Self {
72
0
        self.sqrt_vartime()
73
0
    }
74
75
    /// See [`Self::checked_sqrt_vartime`].
76
    #[deprecated(
77
        since = "0.5.3",
78
        note = "This functionality will be moved to `checked_sqrt_vartime` in a future release."
79
    )]
80
0
    pub fn checked_sqrt(&self) -> CtOption<Self> {
81
0
        self.checked_sqrt_vartime()
82
0
    }
83
84
    /// Perform checked sqrt, returning a [`CtOption`] which `is_some`
85
    /// only if the √(`self`)² == self
86
0
    pub fn checked_sqrt_vartime(&self) -> CtOption<Self> {
87
0
        let r = self.sqrt_vartime();
88
0
        let s = r.wrapping_mul(&r);
89
0
        CtOption::new(r, ConstantTimeEq::ct_eq(self, &s))
90
0
    }
91
}
92
93
#[cfg(test)]
94
mod tests {
95
    use crate::{Limb, U256};
96
97
    #[cfg(feature = "rand")]
98
    use {
99
        crate::{CheckedMul, Random, U512},
100
        rand_chacha::ChaChaRng,
101
        rand_core::{RngCore, SeedableRng},
102
    };
103
104
    #[test]
105
    fn edge() {
106
        assert_eq!(U256::ZERO.sqrt_vartime(), U256::ZERO);
107
        assert_eq!(U256::ONE.sqrt_vartime(), U256::ONE);
108
        let mut half = U256::ZERO;
109
        for i in 0..half.limbs.len() / 2 {
110
            half.limbs[i] = Limb::MAX;
111
        }
112
        assert_eq!(U256::MAX.sqrt_vartime(), half,);
113
    }
114
115
    #[test]
116
    fn simple() {
117
        let tests = [
118
            (4u8, 2u8),
119
            (9, 3),
120
            (16, 4),
121
            (25, 5),
122
            (36, 6),
123
            (49, 7),
124
            (64, 8),
125
            (81, 9),
126
            (100, 10),
127
            (121, 11),
128
            (144, 12),
129
            (169, 13),
130
        ];
131
        for (a, e) in &tests {
132
            let l = U256::from(*a);
133
            let r = U256::from(*e);
134
            assert_eq!(l.sqrt_vartime(), r);
135
            assert_eq!(l.checked_sqrt_vartime().is_some().unwrap_u8(), 1u8);
136
        }
137
    }
138
139
    #[test]
140
    fn nonsquares() {
141
        assert_eq!(U256::from(2u8).sqrt_vartime(), U256::from(1u8));
142
        assert_eq!(
143
            U256::from(2u8).checked_sqrt_vartime().is_some().unwrap_u8(),
144
            0
145
        );
146
        assert_eq!(U256::from(3u8).sqrt_vartime(), U256::from(1u8));
147
        assert_eq!(
148
            U256::from(3u8).checked_sqrt_vartime().is_some().unwrap_u8(),
149
            0
150
        );
151
        assert_eq!(U256::from(5u8).sqrt_vartime(), U256::from(2u8));
152
        assert_eq!(U256::from(6u8).sqrt_vartime(), U256::from(2u8));
153
        assert_eq!(U256::from(7u8).sqrt_vartime(), U256::from(2u8));
154
        assert_eq!(U256::from(8u8).sqrt_vartime(), U256::from(2u8));
155
        assert_eq!(U256::from(10u8).sqrt_vartime(), U256::from(3u8));
156
    }
157
158
    #[cfg(feature = "rand")]
159
    #[test]
160
    fn fuzz() {
161
        let mut rng = ChaChaRng::from_seed([7u8; 32]);
162
        for _ in 0..50 {
163
            let t = rng.next_u32() as u64;
164
            let s = U256::from(t);
165
            let s2 = s.checked_mul(&s).unwrap();
166
            assert_eq!(s2.sqrt_vartime(), s);
167
            assert_eq!(s2.checked_sqrt_vartime().is_some().unwrap_u8(), 1);
168
        }
169
170
        for _ in 0..50 {
171
            let s = U256::random(&mut rng);
172
            let mut s2 = U512::ZERO;
173
            s2.limbs[..s.limbs.len()].copy_from_slice(&s.limbs);
174
            assert_eq!(s.square().sqrt_vartime(), s2);
175
        }
176
    }
177
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/sub.rs
Line
Count
Source
1
//! [`Uint`] addition operations.
2
3
use super::Uint;
4
use crate::{Checked, CheckedSub, CtChoice, Limb, Wrapping, Zero};
5
use core::ops::{Sub, SubAssign};
6
use subtle::CtOption;
7
8
impl<const LIMBS: usize> Uint<LIMBS> {
9
    /// Computes `a - (b + borrow)`, returning the result along with the new borrow.
10
    #[inline(always)]
11
997k
    pub const fn sbb(&self, rhs: &Self, mut borrow: Limb) -> (Self, Limb) {
12
997k
        let mut limbs = [Limb::ZERO; LIMBS];
13
997k
        let mut i = 0;
14
15
4.98M
        while i < LIMBS {
16
3.99M
            let (w, b) = self.limbs[i].sbb(rhs.limbs[i], borrow);
17
3.99M
            limbs[i] = w;
18
3.99M
            borrow = b;
19
3.99M
            i += 1;
20
3.99M
        }
21
22
997k
        (Self { limbs }, borrow)
23
997k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3subINtB4_4UintKj4_E3sbbCs4RkbDk9WRL5_5clvmr
Line
Count
Source
11
2.86k
    pub const fn sbb(&self, rhs: &Self, mut borrow: Limb) -> (Self, Limb) {
12
2.86k
        let mut limbs = [Limb::ZERO; LIMBS];
13
2.86k
        let mut i = 0;
14
15
14.3k
        while i < LIMBS {
16
11.4k
            let (w, b) = self.limbs[i].sbb(rhs.limbs[i], borrow);
17
11.4k
            limbs[i] = w;
18
11.4k
            borrow = b;
19
11.4k
            i += 1;
20
11.4k
        }
21
22
2.86k
        (Self { limbs }, borrow)
23
2.86k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3subINtB4_4UintKpE3sbbB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3subINtB4_4UintKj4_E3sbbCsjewTDwKBbyD_4k256
Line
Count
Source
11
396k
    pub const fn sbb(&self, rhs: &Self, mut borrow: Limb) -> (Self, Limb) {
12
396k
        let mut limbs = [Limb::ZERO; LIMBS];
13
396k
        let mut i = 0;
14
15
1.98M
        while i < LIMBS {
16
1.58M
            let (w, b) = self.limbs[i].sbb(rhs.limbs[i], borrow);
17
1.58M
            limbs[i] = w;
18
1.58M
            borrow = b;
19
1.58M
            i += 1;
20
1.58M
        }
21
22
396k
        (Self { limbs }, borrow)
23
396k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3subINtB4_4UintKj4_E3sbbCsaHRNXv1Y9Bq_4p256
Line
Count
Source
11
598k
    pub const fn sbb(&self, rhs: &Self, mut borrow: Limb) -> (Self, Limb) {
12
598k
        let mut limbs = [Limb::ZERO; LIMBS];
13
598k
        let mut i = 0;
14
15
2.99M
        while i < LIMBS {
16
2.39M
            let (w, b) = self.limbs[i].sbb(rhs.limbs[i], borrow);
17
2.39M
            limbs[i] = w;
18
2.39M
            borrow = b;
19
2.39M
            i += 1;
20
2.39M
        }
21
22
598k
        (Self { limbs }, borrow)
23
598k
    }
24
25
    /// Perform saturating subtraction, returning `ZERO` on underflow.
26
0
    pub const fn saturating_sub(&self, rhs: &Self) -> Self {
27
0
        let (res, underflow) = self.sbb(rhs, Limb::ZERO);
28
0
        Self::ct_select(&res, &Self::ZERO, CtChoice::from_mask(underflow.0))
29
0
    }
30
31
    /// Perform wrapping subtraction, discarding underflow and wrapping around
32
    /// the boundary of the type.
33
0
    pub const fn wrapping_sub(&self, rhs: &Self) -> Self {
34
0
        self.sbb(rhs, Limb::ZERO).0
35
0
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3subINtB4_4UintKpE12wrapping_subB6_
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint3subINtB4_4UintKj4_E12wrapping_subCsjewTDwKBbyD_4k256
36
37
    /// Perform wrapping subtraction, returning the truthy value as the second element of the tuple
38
    /// if an underflow has occurred.
39
0
    pub(crate) const fn conditional_wrapping_sub(
40
0
        &self,
41
0
        rhs: &Self,
42
0
        choice: CtChoice,
43
0
    ) -> (Self, CtChoice) {
44
0
        let actual_rhs = Uint::ct_select(&Uint::ZERO, rhs, choice);
45
0
        let (res, borrow) = self.sbb(&actual_rhs, Limb::ZERO);
46
0
        (res, CtChoice::from_mask(borrow.0))
47
0
    }
48
}
49
50
impl<const LIMBS: usize> CheckedSub<&Uint<LIMBS>> for Uint<LIMBS> {
51
    type Output = Self;
52
53
0
    fn checked_sub(&self, rhs: &Self) -> CtOption<Self> {
54
0
        let (result, underflow) = self.sbb(rhs, Limb::ZERO);
55
0
        CtOption::new(result, underflow.is_zero())
56
0
    }
57
}
58
59
impl<const LIMBS: usize> Sub for Wrapping<Uint<LIMBS>> {
60
    type Output = Self;
61
62
0
    fn sub(self, rhs: Self) -> Wrapping<Uint<LIMBS>> {
63
0
        Wrapping(self.0.wrapping_sub(&rhs.0))
64
0
    }
65
}
66
67
impl<const LIMBS: usize> Sub<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
68
    type Output = Wrapping<Uint<LIMBS>>;
69
70
0
    fn sub(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
71
0
        Wrapping(self.0.wrapping_sub(&rhs.0))
72
0
    }
73
}
74
75
impl<const LIMBS: usize> Sub<Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
76
    type Output = Wrapping<Uint<LIMBS>>;
77
78
0
    fn sub(self, rhs: Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
79
0
        Wrapping(self.0.wrapping_sub(&rhs.0))
80
0
    }
81
}
82
83
impl<const LIMBS: usize> Sub<&Wrapping<Uint<LIMBS>>> for &Wrapping<Uint<LIMBS>> {
84
    type Output = Wrapping<Uint<LIMBS>>;
85
86
0
    fn sub(self, rhs: &Wrapping<Uint<LIMBS>>) -> Wrapping<Uint<LIMBS>> {
87
0
        Wrapping(self.0.wrapping_sub(&rhs.0))
88
0
    }
89
}
90
91
impl<const LIMBS: usize> SubAssign for Wrapping<Uint<LIMBS>> {
92
0
    fn sub_assign(&mut self, other: Self) {
93
0
        *self = *self - other;
94
0
    }
95
}
96
97
impl<const LIMBS: usize> SubAssign<&Wrapping<Uint<LIMBS>>> for Wrapping<Uint<LIMBS>> {
98
0
    fn sub_assign(&mut self, other: &Self) {
99
0
        *self = *self - other;
100
0
    }
101
}
102
103
impl<const LIMBS: usize> Sub for Checked<Uint<LIMBS>> {
104
    type Output = Self;
105
106
0
    fn sub(self, rhs: Self) -> Checked<Uint<LIMBS>> {
107
0
        Checked(
108
0
            self.0
109
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_sub(&rhs))),
110
0
        )
111
0
    }
112
}
113
114
impl<const LIMBS: usize> Sub<&Checked<Uint<LIMBS>>> for Checked<Uint<LIMBS>> {
115
    type Output = Checked<Uint<LIMBS>>;
116
117
0
    fn sub(self, rhs: &Checked<Uint<LIMBS>>) -> Checked<Uint<LIMBS>> {
118
0
        Checked(
119
0
            self.0
120
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_sub(&rhs))),
121
0
        )
122
0
    }
123
}
124
125
impl<const LIMBS: usize> Sub<Checked<Uint<LIMBS>>> for &Checked<Uint<LIMBS>> {
126
    type Output = Checked<Uint<LIMBS>>;
127
128
0
    fn sub(self, rhs: Checked<Uint<LIMBS>>) -> Checked<Uint<LIMBS>> {
129
0
        Checked(
130
0
            self.0
131
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_sub(&rhs))),
132
0
        )
133
0
    }
134
}
135
136
impl<const LIMBS: usize> Sub<&Checked<Uint<LIMBS>>> for &Checked<Uint<LIMBS>> {
137
    type Output = Checked<Uint<LIMBS>>;
138
139
0
    fn sub(self, rhs: &Checked<Uint<LIMBS>>) -> Checked<Uint<LIMBS>> {
140
0
        Checked(
141
0
            self.0
142
0
                .and_then(|lhs| rhs.0.and_then(|rhs| lhs.checked_sub(&rhs))),
143
0
        )
144
0
    }
145
}
146
147
impl<const LIMBS: usize> SubAssign for Checked<Uint<LIMBS>> {
148
0
    fn sub_assign(&mut self, other: Self) {
149
0
        *self = *self - other;
150
0
    }
151
}
152
153
impl<const LIMBS: usize> SubAssign<&Checked<Uint<LIMBS>>> for Checked<Uint<LIMBS>> {
154
0
    fn sub_assign(&mut self, other: &Self) {
155
0
        *self = *self - other;
156
0
    }
157
}
158
159
#[cfg(test)]
160
mod tests {
161
    use crate::{CheckedSub, Limb, U128};
162
163
    #[test]
164
    fn sbb_no_borrow() {
165
        let (res, borrow) = U128::ONE.sbb(&U128::ONE, Limb::ZERO);
166
        assert_eq!(res, U128::ZERO);
167
        assert_eq!(borrow, Limb::ZERO);
168
    }
169
170
    #[test]
171
    fn sbb_with_borrow() {
172
        let (res, borrow) = U128::ZERO.sbb(&U128::ONE, Limb::ZERO);
173
174
        assert_eq!(res, U128::MAX);
175
        assert_eq!(borrow, Limb::MAX);
176
    }
177
178
    #[test]
179
    fn saturating_sub_no_borrow() {
180
        assert_eq!(
181
            U128::from(5u64).saturating_sub(&U128::ONE),
182
            U128::from(4u64)
183
        );
184
    }
185
186
    #[test]
187
    fn saturating_sub_with_borrow() {
188
        assert_eq!(
189
            U128::from(4u64).saturating_sub(&U128::from(5u64)),
190
            U128::ZERO
191
        );
192
    }
193
194
    #[test]
195
    fn wrapping_sub_no_borrow() {
196
        assert_eq!(U128::ONE.wrapping_sub(&U128::ONE), U128::ZERO);
197
    }
198
199
    #[test]
200
    fn wrapping_sub_with_borrow() {
201
        assert_eq!(U128::ZERO.wrapping_sub(&U128::ONE), U128::MAX);
202
    }
203
204
    #[test]
205
    fn checked_sub_ok() {
206
        let result = U128::ONE.checked_sub(&U128::ONE);
207
        assert_eq!(result.unwrap(), U128::ZERO);
208
    }
209
210
    #[test]
211
    fn checked_sub_overflow() {
212
        let result = U128::ZERO.checked_sub(&U128::ONE);
213
        assert!(!bool::from(result.is_some()));
214
    }
215
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/sub_mod.rs
Line
Count
Source
1
//! [`Uint`] subtraction modulus operations.
2
3
use crate::{Limb, SubMod, Uint};
4
5
impl<const LIMBS: usize> Uint<LIMBS> {
6
    /// Computes `self - rhs mod p`.
7
    ///
8
    /// Assumes `self - rhs` as unbounded signed integer is in `[-p, p)`.
9
495k
    pub const fn sub_mod(&self, rhs: &Uint<LIMBS>, p: &Uint<LIMBS>) -> Uint<LIMBS> {
10
495k
        let (out, borrow) = self.sbb(rhs, Limb::ZERO);
11
495k
12
495k
        // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise
13
495k
        // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the modulus.
14
495k
        let mask = Uint::from_words([borrow.0; LIMBS]);
15
495k
16
495k
        out.wrapping_add(&p.bitand(&mask))
17
495k
    }
Unexecuted instantiation: _RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint7sub_modINtB4_4UintKpE7sub_modB6_
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint7sub_modINtB4_4UintKj4_E7sub_modCsjewTDwKBbyD_4k256
Line
Count
Source
9
187k
    pub const fn sub_mod(&self, rhs: &Uint<LIMBS>, p: &Uint<LIMBS>) -> Uint<LIMBS> {
10
187k
        let (out, borrow) = self.sbb(rhs, Limb::ZERO);
11
187k
12
187k
        // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise
13
187k
        // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the modulus.
14
187k
        let mask = Uint::from_words([borrow.0; LIMBS]);
15
187k
16
187k
        out.wrapping_add(&p.bitand(&mask))
17
187k
    }
_RNvMNtNtCshRehcWQJ0wE_13crypto_bigint4uint7sub_modINtB4_4UintKj4_E7sub_modCsaHRNXv1Y9Bq_4p256
Line
Count
Source
9
308k
    pub const fn sub_mod(&self, rhs: &Uint<LIMBS>, p: &Uint<LIMBS>) -> Uint<LIMBS> {
10
308k
        let (out, borrow) = self.sbb(rhs, Limb::ZERO);
11
308k
12
308k
        // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise
13
308k
        // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the modulus.
14
308k
        let mask = Uint::from_words([borrow.0; LIMBS]);
15
308k
16
308k
        out.wrapping_add(&p.bitand(&mask))
17
308k
    }
18
19
    /// Returns `(self..., carry) - (rhs...) mod (p...)`, where `carry <= 1`.
20
    /// Assumes `-(p...) <= (self..., carry) - (rhs...) < (p...)`.
21
    #[inline(always)]
22
0
    pub(crate) const fn sub_mod_with_carry(&self, carry: Limb, rhs: &Self, p: &Self) -> Self {
23
0
        debug_assert!(carry.0 <= 1);
24
25
0
        let (out, borrow) = self.sbb(rhs, Limb::ZERO);
26
0
27
0
        // The new `borrow = Word::MAX` iff `carry == 0` and `borrow == Word::MAX`.
28
0
        let borrow = (!carry.0.wrapping_neg()) & borrow.0;
29
0
30
0
        // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise
31
0
        // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the modulus.
32
0
        let mask = Uint::from_words([borrow; LIMBS]);
33
0
34
0
        out.wrapping_add(&p.bitand(&mask))
35
0
    }
36
37
    /// Computes `self - rhs mod p` for the special modulus
38
    /// `p = MAX+1-c` where `c` is small enough to fit in a single [`Limb`].
39
    ///
40
    /// Assumes `self - rhs` as unbounded signed integer is in `[-p, p)`.
41
0
    pub const fn sub_mod_special(&self, rhs: &Self, c: Limb) -> Self {
42
0
        let (out, borrow) = self.sbb(rhs, Limb::ZERO);
43
0
44
0
        // If underflow occurred, then we need to subtract `c` to account for
45
0
        // the underflow. This cannot underflow due to the assumption
46
0
        // `self - rhs >= -p`.
47
0
        let l = borrow.0 & c.0;
48
0
        out.wrapping_sub(&Uint::from_word(l))
49
0
    }
50
}
51
52
impl<const LIMBS: usize> SubMod for Uint<LIMBS> {
53
    type Output = Self;
54
55
0
    fn sub_mod(&self, rhs: &Self, p: &Self) -> Self {
56
0
        debug_assert!(self < p);
57
0
        debug_assert!(rhs < p);
58
0
        self.sub_mod(rhs, p)
59
0
    }
60
}
61
62
#[cfg(all(test, feature = "rand"))]
63
mod tests {
64
    use crate::{Limb, NonZero, Random, RandomMod, Uint};
65
    use rand_core::SeedableRng;
66
67
    macro_rules! test_sub_mod {
68
        ($size:expr, $test_name:ident) => {
69
            #[test]
70
            fn $test_name() {
71
                let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(1);
72
                let moduli = [
73
                    NonZero::<Uint<$size>>::random(&mut rng),
74
                    NonZero::<Uint<$size>>::random(&mut rng),
75
                ];
76
77
                for p in &moduli {
78
                    let base_cases = [
79
                        (1u64, 0u64, 1u64.into()),
80
                        (0, 1, p.wrapping_sub(&1u64.into())),
81
                        (0, 0, 0u64.into()),
82
                    ];
83
                    for (a, b, c) in &base_cases {
84
                        let a: Uint<$size> = (*a).into();
85
                        let b: Uint<$size> = (*b).into();
86
87
                        let x = a.sub_mod(&b, p);
88
                        assert_eq!(*c, x, "{} - {} mod {} = {} != {}", a, b, p, x, c);
89
                    }
90
91
                    if $size > 1 {
92
                        for _i in 0..100 {
93
                            let a: Uint<$size> = Limb::random(&mut rng).into();
94
                            let b: Uint<$size> = Limb::random(&mut rng).into();
95
                            let (a, b) = if a < b { (b, a) } else { (a, b) };
96
97
                            let c = a.sub_mod(&b, p);
98
                            assert!(c < **p, "not reduced");
99
                            assert_eq!(c, a.wrapping_sub(&b), "result incorrect");
100
                        }
101
                    }
102
103
                    for _i in 0..100 {
104
                        let a = Uint::<$size>::random_mod(&mut rng, p);
105
                        let b = Uint::<$size>::random_mod(&mut rng, p);
106
107
                        let c = a.sub_mod(&b, p);
108
                        assert!(c < **p, "not reduced: {} >= {} ", c, p);
109
110
                        let x = a.wrapping_sub(&b);
111
                        if a >= b && x < **p {
112
                            assert_eq!(c, x, "incorrect result");
113
                        }
114
                    }
115
                }
116
            }
117
        };
118
    }
119
120
    macro_rules! test_sub_mod_special {
121
        ($size:expr, $test_name:ident) => {
122
            #[test]
123
            fn $test_name() {
124
                let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(1);
125
                let moduli = [
126
                    NonZero::<Limb>::random(&mut rng),
127
                    NonZero::<Limb>::random(&mut rng),
128
                ];
129
130
                for special in &moduli {
131
                    let p = &NonZero::new(Uint::ZERO.wrapping_sub(&Uint::from_word(special.0)))
132
                        .unwrap();
133
134
                    let minus_one = p.wrapping_sub(&Uint::ONE);
135
136
                    let base_cases = [
137
                        (Uint::ZERO, Uint::ZERO, Uint::ZERO),
138
                        (Uint::ONE, Uint::ZERO, Uint::ONE),
139
                        (Uint::ZERO, Uint::ONE, minus_one),
140
                        (minus_one, minus_one, Uint::ZERO),
141
                        (Uint::ZERO, minus_one, Uint::ONE),
142
                    ];
143
                    for (a, b, c) in &base_cases {
144
                        let x = a.sub_mod_special(&b, *special.as_ref());
145
                        assert_eq!(*c, x, "{} - {} mod {} = {} != {}", a, b, p, x, c);
146
                    }
147
148
                    for _i in 0..100 {
149
                        let a = Uint::<$size>::random_mod(&mut rng, p);
150
                        let b = Uint::<$size>::random_mod(&mut rng, p);
151
152
                        let c = a.sub_mod_special(&b, *special.as_ref());
153
                        assert!(c < **p, "not reduced: {} >= {} ", c, p);
154
155
                        let expected = a.sub_mod(&b, p);
156
                        assert_eq!(c, expected, "incorrect result");
157
                    }
158
                }
159
            }
160
        };
161
    }
162
163
    // Test requires 1-limb is capable of representing a 64-bit integer
164
    #[cfg(target_pointer_width = "64")]
165
    test_sub_mod!(1, sub1);
166
167
    test_sub_mod!(2, sub2);
168
    test_sub_mod!(3, sub3);
169
    test_sub_mod!(4, sub4);
170
    test_sub_mod!(5, sub5);
171
    test_sub_mod!(6, sub6);
172
    test_sub_mod!(7, sub7);
173
    test_sub_mod!(8, sub8);
174
    test_sub_mod!(9, sub9);
175
    test_sub_mod!(10, sub10);
176
    test_sub_mod!(11, sub11);
177
    test_sub_mod!(12, sub12);
178
179
    test_sub_mod_special!(1, sub_mod_special_1);
180
    test_sub_mod_special!(2, sub_mod_special_2);
181
    test_sub_mod_special!(3, sub_mod_special_3);
182
    test_sub_mod_special!(4, sub_mod_special_4);
183
    test_sub_mod_special!(5, sub_mod_special_5);
184
    test_sub_mod_special!(6, sub_mod_special_6);
185
    test_sub_mod_special!(7, sub_mod_special_7);
186
    test_sub_mod_special!(8, sub_mod_special_8);
187
    test_sub_mod_special!(9, sub_mod_special_9);
188
    test_sub_mod_special!(10, sub_mod_special_10);
189
    test_sub_mod_special!(11, sub_mod_special_11);
190
    test_sub_mod_special!(12, sub_mod_special_12);
191
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/wrapping.rs
Line
Count
Source
1
//! Wrapping arithmetic.
2
3
use crate::Zero;
4
use core::fmt;
5
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
6
7
#[cfg(feature = "rand_core")]
8
use {crate::Random, rand_core::CryptoRngCore};
9
10
#[cfg(feature = "serde")]
11
use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer};
12
13
/// Provides intentionally-wrapped arithmetic on `T`.
14
///
15
/// This is analogous to [`core::num::Wrapping`] but allows this crate to
16
/// define trait impls for this type.
17
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
18
pub struct Wrapping<T>(pub T);
19
20
impl<T: Zero> Zero for Wrapping<T> {
21
    const ZERO: Self = Self(T::ZERO);
22
}
23
24
impl<T: fmt::Display> fmt::Display for Wrapping<T> {
25
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26
0
        self.0.fmt(f)
27
0
    }
28
}
29
30
impl<T: fmt::Binary> fmt::Binary for Wrapping<T> {
31
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32
0
        self.0.fmt(f)
33
0
    }
34
}
35
36
impl<T: fmt::Octal> fmt::Octal for Wrapping<T> {
37
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38
0
        self.0.fmt(f)
39
0
    }
40
}
41
42
impl<T: fmt::LowerHex> fmt::LowerHex for Wrapping<T> {
43
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44
0
        self.0.fmt(f)
45
0
    }
46
}
47
48
impl<T: fmt::UpperHex> fmt::UpperHex for Wrapping<T> {
49
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50
0
        self.0.fmt(f)
51
0
    }
52
}
53
54
impl<T: ConditionallySelectable> ConditionallySelectable for Wrapping<T> {
55
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
56
0
        Wrapping(T::conditional_select(&a.0, &b.0, choice))
57
0
    }
58
}
59
60
impl<T: ConstantTimeEq> ConstantTimeEq for Wrapping<T> {
61
0
    fn ct_eq(&self, other: &Self) -> Choice {
62
0
        self.0.ct_eq(&other.0)
63
0
    }
64
}
65
66
#[cfg(feature = "rand_core")]
67
impl<T: Random> Random for Wrapping<T> {
68
0
    fn random(rng: &mut impl CryptoRngCore) -> Self {
69
0
        Wrapping(Random::random(rng))
70
0
    }
71
}
72
73
#[cfg(feature = "serde")]
74
impl<'de, T: Deserialize<'de>> Deserialize<'de> for Wrapping<T> {
75
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
76
    where
77
        D: Deserializer<'de>,
78
    {
79
        Ok(Self(T::deserialize(deserializer)?))
80
    }
81
}
82
83
#[cfg(feature = "serde")]
84
impl<T: Serialize> Serialize for Wrapping<T> {
85
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86
    where
87
        S: Serializer,
88
    {
89
        self.0.serialize(serializer)
90
    }
91
}
92
93
#[cfg(all(test, feature = "serde"))]
94
#[allow(clippy::unwrap_used)]
95
mod tests {
96
    use crate::{Wrapping, U64};
97
98
    #[test]
99
    fn serde() {
100
        const TEST: Wrapping<U64> = Wrapping(U64::from_u64(0x0011223344556677));
101
102
        let serialized = bincode::serialize(&TEST).unwrap();
103
        let deserialized: Wrapping<U64> = bincode::deserialize(&serialized).unwrap();
104
105
        assert_eq!(TEST, deserialized);
106
    }
107
108
    #[test]
109
    fn serde_owned() {
110
        const TEST: Wrapping<U64> = Wrapping(U64::from_u64(0x0011223344556677));
111
112
        let serialized = bincode::serialize(&TEST).unwrap();
113
        let deserialized: Wrapping<U64> = bincode::deserialize_from(serialized.as_slice()).unwrap();
114
115
        assert_eq!(TEST, deserialized);
116
    }
117
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crypto-common-0.1.6/src/lib.rs
Line
Count
Source
1
//! Common cryptographic traits.
2
3
#![no_std]
4
#![cfg_attr(docsrs, feature(doc_cfg))]
5
#![doc(
6
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
7
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
8
)]
9
#![forbid(unsafe_code)]
10
#![warn(missing_docs, rust_2018_idioms)]
11
12
#[cfg(feature = "std")]
13
extern crate std;
14
15
#[cfg(feature = "rand_core")]
16
pub use rand_core;
17
18
pub use generic_array;
19
pub use generic_array::typenum;
20
21
use core::fmt;
22
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
23
#[cfg(feature = "rand_core")]
24
use rand_core::{CryptoRng, RngCore};
25
26
/// Block on which [`BlockSizeUser`] implementors operate.
27
pub type Block<B> = GenericArray<u8, <B as BlockSizeUser>::BlockSize>;
28
29
/// Parallel blocks on which [`ParBlocksSizeUser`] implementors operate.
30
pub type ParBlocks<T> = GenericArray<Block<T>, <T as ParBlocksSizeUser>::ParBlocksSize>;
31
32
/// Output array of [`OutputSizeUser`] implementors.
33
pub type Output<T> = GenericArray<u8, <T as OutputSizeUser>::OutputSize>;
34
35
/// Key used by [`KeySizeUser`] implementors.
36
pub type Key<B> = GenericArray<u8, <B as KeySizeUser>::KeySize>;
37
38
/// Initialization vector (nonce) used by [`IvSizeUser`] implementors.
39
pub type Iv<B> = GenericArray<u8, <B as IvSizeUser>::IvSize>;
40
41
/// Types which process data in blocks.
42
pub trait BlockSizeUser {
43
    /// Size of the block in bytes.
44
    type BlockSize: ArrayLength<u8> + 'static;
45
46
    /// Return block size in bytes.
47
0
    fn block_size() -> usize {
48
0
        Self::BlockSize::USIZE
49
0
    }
Unexecuted instantiation: _RNvYpNtCslUxhuGmkrsg_13crypto_common13BlockSizeUser10block_sizeB5_
Unexecuted instantiation: _RNvYNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreNtCslUxhuGmkrsg_13crypto_common13BlockSizeUser10block_sizeB6_
Unexecuted instantiation: _RNvYNtNtCs23lnNM1woOA_4sha28core_api13Sha512VarCoreNtCslUxhuGmkrsg_13crypto_common13BlockSizeUser10block_sizeB6_
50
}
51
52
impl<T: BlockSizeUser> BlockSizeUser for &T {
53
    type BlockSize = T::BlockSize;
54
}
55
56
impl<T: BlockSizeUser> BlockSizeUser for &mut T {
57
    type BlockSize = T::BlockSize;
58
}
59
60
/// Types which can process blocks in parallel.
61
pub trait ParBlocksSizeUser: BlockSizeUser {
62
    /// Number of blocks which can be processed in parallel.
63
    type ParBlocksSize: ArrayLength<Block<Self>>;
64
}
65
66
/// Types which return data with the given size.
67
pub trait OutputSizeUser {
68
    /// Size of the output in bytes.
69
    type OutputSize: ArrayLength<u8> + 'static;
70
71
    /// Return output size in bytes.
72
0
    fn output_size() -> usize {
73
0
        Self::OutputSize::USIZE
74
0
    }
Unexecuted instantiation: _RNvYpNtCslUxhuGmkrsg_13crypto_common14OutputSizeUser11output_sizeB5_
Unexecuted instantiation: _RNvYNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreNtCslUxhuGmkrsg_13crypto_common14OutputSizeUser11output_sizeB6_
Unexecuted instantiation: _RNvYNtNtCs23lnNM1woOA_4sha28core_api13Sha512VarCoreNtCslUxhuGmkrsg_13crypto_common14OutputSizeUser11output_sizeB6_
75
}
76
77
/// Types which use key for initialization.
78
///
79
/// Generally it's used indirectly via [`KeyInit`] or [`KeyIvInit`].
80
pub trait KeySizeUser {
81
    /// Key size in bytes.
82
    type KeySize: ArrayLength<u8> + 'static;
83
84
    /// Return key size in bytes.
85
0
    fn key_size() -> usize {
86
0
        Self::KeySize::USIZE
87
0
    }
88
}
89
90
/// Types which use initialization vector (nonce) for initialization.
91
///
92
/// Generally it's used indirectly via [`KeyIvInit`] or [`InnerIvInit`].
93
pub trait IvSizeUser {
94
    /// Initialization vector size in bytes.
95
    type IvSize: ArrayLength<u8> + 'static;
96
97
    /// Return IV size in bytes.
98
0
    fn iv_size() -> usize {
99
0
        Self::IvSize::USIZE
100
0
    }
101
}
102
103
/// Types which use another type for initialization.
104
///
105
/// Generally it's used indirectly via [`InnerInit`] or [`InnerIvInit`].
106
pub trait InnerUser {
107
    /// Inner type.
108
    type Inner;
109
}
110
111
/// Resettable types.
112
pub trait Reset {
113
    /// Reset state to its initial value.
114
    fn reset(&mut self);
115
}
116
117
/// Trait which stores algorithm name constant, used in `Debug` implementations.
118
pub trait AlgorithmName {
119
    /// Write algorithm name into `f`.
120
    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result;
121
}
122
123
/// Types which can be initialized from key.
124
pub trait KeyInit: KeySizeUser + Sized {
125
    /// Create new value from fixed size key.
126
    fn new(key: &Key<Self>) -> Self;
127
128
    /// Create new value from variable size key.
129
0
    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
130
0
        if key.len() != Self::KeySize::to_usize() {
131
0
            Err(InvalidLength)
132
        } else {
133
0
            Ok(Self::new(Key::<Self>::from_slice(key)))
134
        }
135
0
    }
136
137
    /// Generate random key using the provided [`CryptoRng`].
138
    #[cfg(feature = "rand_core")]
139
    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
140
    #[inline]
141
    fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key<Self> {
142
        let mut key = Key::<Self>::default();
143
        rng.fill_bytes(&mut key);
144
        key
145
    }
146
}
147
148
/// Types which can be initialized from key and initialization vector (nonce).
149
pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
150
    /// Create new value from fixed length key and nonce.
151
    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
152
153
    /// Create new value from variable length key and nonce.
154
    #[inline]
155
0
    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
156
0
        let key_len = Self::KeySize::USIZE;
157
0
        let iv_len = Self::IvSize::USIZE;
158
0
        if key.len() != key_len || iv.len() != iv_len {
159
0
            Err(InvalidLength)
160
        } else {
161
0
            Ok(Self::new(
162
0
                Key::<Self>::from_slice(key),
163
0
                Iv::<Self>::from_slice(iv),
164
0
            ))
165
        }
166
0
    }
167
168
    /// Generate random key using the provided [`CryptoRng`].
169
    #[cfg(feature = "rand_core")]
170
    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
171
    #[inline]
172
    fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key<Self> {
173
        let mut key = Key::<Self>::default();
174
        rng.fill_bytes(&mut key);
175
        key
176
    }
177
178
    /// Generate random IV using the provided [`CryptoRng`].
179
    #[cfg(feature = "rand_core")]
180
    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
181
    #[inline]
182
    fn generate_iv(mut rng: impl CryptoRng + RngCore) -> Iv<Self> {
183
        let mut iv = Iv::<Self>::default();
184
        rng.fill_bytes(&mut iv);
185
        iv
186
    }
187
188
    /// Generate random key and nonce using the provided [`CryptoRng`].
189
    #[cfg(feature = "rand_core")]
190
    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
191
    #[inline]
192
    fn generate_key_iv(mut rng: impl CryptoRng + RngCore) -> (Key<Self>, Iv<Self>) {
193
        (Self::generate_key(&mut rng), Self::generate_iv(&mut rng))
194
    }
195
}
196
197
/// Types which can be initialized from another type (usually block ciphers).
198
///
199
/// Usually used for initializing types from block ciphers.
200
pub trait InnerInit: InnerUser + Sized {
201
    /// Initialize value from the `inner`.
202
    fn inner_init(inner: Self::Inner) -> Self;
203
}
204
205
/// Types which can be initialized from another type and additional initialization
206
/// vector/nonce.
207
///
208
/// Usually used for initializing types from block ciphers.
209
pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
210
    /// Initialize value using `inner` and `iv` array.
211
    fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
212
213
    /// Initialize value using `inner` and `iv` slice.
214
0
    fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
215
0
        if iv.len() != Self::IvSize::to_usize() {
216
0
            Err(InvalidLength)
217
        } else {
218
0
            Ok(Self::inner_iv_init(inner, Iv::<Self>::from_slice(iv)))
219
        }
220
0
    }
221
222
    /// Generate random IV using the provided [`CryptoRng`].
223
    #[cfg(feature = "rand_core")]
224
    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
225
    #[inline]
226
    fn generate_iv(mut rng: impl CryptoRng + RngCore) -> Iv<Self> {
227
        let mut iv = Iv::<Self>::default();
228
        rng.fill_bytes(&mut iv);
229
        iv
230
    }
231
}
232
233
impl<T> KeySizeUser for T
234
where
235
    T: InnerUser,
236
    T::Inner: KeySizeUser,
237
{
238
    type KeySize = <T::Inner as KeySizeUser>::KeySize;
239
}
240
241
impl<T> KeyIvInit for T
242
where
243
    T: InnerIvInit,
244
    T::Inner: KeyInit,
245
{
246
    #[inline]
247
0
    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
248
0
        Self::inner_iv_init(T::Inner::new(key), iv)
249
0
    }
250
251
    #[inline]
252
0
    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
253
0
        T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
254
0
    }
255
}
256
257
impl<T> KeyInit for T
258
where
259
    T: InnerInit,
260
    T::Inner: KeyInit,
261
{
262
    #[inline]
263
0
    fn new(key: &Key<Self>) -> Self {
264
0
        Self::inner_init(T::Inner::new(key))
265
0
    }
266
267
    #[inline]
268
0
    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
269
0
        T::Inner::new_from_slice(key)
270
0
            .map_err(|_| InvalidLength)
271
0
            .map(Self::inner_init)
272
0
    }
273
}
274
275
// Unfortunately this blanket impl is impossible without mutually
276
// exclusive traits, see: https://github.com/rust-lang/rfcs/issues/1053
277
// or at the very least without: https://github.com/rust-lang/rust/issues/20400
278
/*
279
impl<T> KeyIvInit for T
280
where
281
    T: InnerInit,
282
    T::Inner: KeyIvInit,
283
{
284
    #[inline]
285
    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
286
        Self::inner_init(T::Inner::new(key, iv))
287
    }
288
289
    #[inline]
290
    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
291
        T::Inner::new_from_slice(key)
292
            .map_err(|_| InvalidLength)
293
            .map(Self::inner_init)
294
    }
295
}
296
*/
297
298
/// The error type returned when key and/or IV used in the [`KeyInit`],
299
/// [`KeyIvInit`], and [`InnerIvInit`] slice-based methods had
300
/// an invalid length.
301
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
302
pub struct InvalidLength;
303
304
impl fmt::Display for InvalidLength {
305
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
306
0
        f.write_str("Invalid Length")
307
0
    }
308
}
309
310
#[cfg(feature = "std")]
311
impl std::error::Error for InvalidLength {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/arrayvec.rs
Line
Count
Source
1
//! Array-backed append-only vector type.
2
// TODO(tarcieri): use `core` impl of `ArrayVec`
3
// See: https://github.com/rust-lang/rfcs/pull/2990
4
5
use crate::{ErrorKind, Result};
6
7
/// Array-backed append-only vector type.
8
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
9
pub(crate) struct ArrayVec<T, const N: usize> {
10
    /// Elements of the set.
11
    elements: [Option<T>; N],
12
13
    /// Last populated element.
14
    length: usize,
15
}
16
17
impl<T, const N: usize> ArrayVec<T, N> {
18
    /// Create a new [`ArrayVec`].
19
0
    pub fn new() -> Self {
20
0
        Self {
21
0
            elements: [(); N].map(|_| None),
22
0
            length: 0,
23
0
        }
24
0
    }
25
26
    /// Push an item into this [`ArrayVec`].
27
0
    pub fn push(&mut self, item: T) -> Result<()> {
28
0
        match self.length.checked_add(1) {
29
0
            Some(n) if n <= N => {
30
0
                self.elements[self.length] = Some(item);
31
0
                self.length = n;
32
0
                Ok(())
33
            }
34
0
            _ => Err(ErrorKind::Overlength.into()),
35
        }
36
0
    }
37
38
    /// Get an element from this [`ArrayVec`].
39
0
    pub fn get(&self, index: usize) -> Option<&T> {
40
0
        match self.elements.get(index) {
41
0
            Some(Some(ref item)) => Some(item),
42
0
            _ => None,
43
        }
44
0
    }
45
46
    /// Iterate over the elements in this [`ArrayVec`].
47
0
    pub fn iter(&self) -> Iter<'_, T> {
48
0
        Iter::new(&self.elements)
49
0
    }
50
51
    /// Is this [`ArrayVec`] empty?
52
0
    pub fn is_empty(&self) -> bool {
53
0
        self.length == 0
54
0
    }
55
56
    /// Get the number of elements in this [`ArrayVec`].
57
0
    pub fn len(&self) -> usize {
58
0
        self.length
59
0
    }
60
61
    /// Get the last item from this [`ArrayVec`].
62
0
    pub fn last(&self) -> Option<&T> {
63
0
        self.length.checked_sub(1).and_then(|n| self.get(n))
64
0
    }
65
66
    /// Extract the inner array.
67
0
    pub fn into_array(self) -> [Option<T>; N] {
68
0
        self.elements
69
0
    }
70
}
71
72
impl<T, const N: usize> AsRef<[Option<T>]> for ArrayVec<T, N> {
73
0
    fn as_ref(&self) -> &[Option<T>] {
74
0
        &self.elements[..self.length]
75
0
    }
76
}
77
78
impl<T, const N: usize> AsMut<[Option<T>]> for ArrayVec<T, N> {
79
0
    fn as_mut(&mut self) -> &mut [Option<T>] {
80
0
        &mut self.elements[..self.length]
81
0
    }
82
}
83
84
impl<T, const N: usize> Default for ArrayVec<T, N> {
85
0
    fn default() -> Self {
86
0
        Self::new()
87
0
    }
88
}
89
90
/// Iterator over the elements of an [`ArrayVec`].
91
#[derive(Clone, Debug)]
92
pub struct Iter<'a, T> {
93
    /// Decoder which iterates over the elements of the message.
94
    elements: &'a [Option<T>],
95
96
    /// Position within the iterator.
97
    position: usize,
98
}
99
100
impl<'a, T> Iter<'a, T> {
101
0
    pub(crate) fn new(elements: &'a [Option<T>]) -> Self {
102
0
        Self {
103
0
            elements,
104
0
            position: 0,
105
0
        }
106
0
    }
107
}
108
109
impl<'a, T> Iterator for Iter<'a, T> {
110
    type Item = &'a T;
111
112
0
    fn next(&mut self) -> Option<&'a T> {
113
0
        match self.elements.get(self.position) {
114
0
            Some(Some(res)) => {
115
0
                self.position = self.position.checked_add(1)?;
116
0
                Some(res)
117
            }
118
0
            _ => None,
119
        }
120
0
    }
121
122
0
    fn size_hint(&self) -> (usize, Option<usize>) {
123
0
        let len = self.elements.len().saturating_sub(self.position);
124
0
        (len, Some(len))
125
0
    }
126
}
127
128
impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
129
130
#[cfg(test)]
131
mod tests {
132
    use super::ArrayVec;
133
    use crate::ErrorKind;
134
135
    #[test]
136
    fn add() {
137
        let mut vec = ArrayVec::<u8, 3>::new();
138
        vec.push(1).unwrap();
139
        vec.push(2).unwrap();
140
        vec.push(3).unwrap();
141
142
        assert_eq!(vec.push(4).err().unwrap(), ErrorKind::Overlength.into());
143
        assert_eq!(vec.len(), 3);
144
    }
145
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/any.rs
Line
Count
Source
1
//! ASN.1 `ANY` type.
2
3
#![cfg_attr(feature = "arbitrary", allow(clippy::integer_arithmetic))]
4
5
use crate::{
6
    BytesRef, Choice, Decode, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, Header, Length,
7
    Reader, Result, SliceReader, Tag, Tagged, ValueOrd, Writer,
8
};
9
use core::cmp::Ordering;
10
11
#[cfg(feature = "alloc")]
12
use crate::SliceWriter;
13
14
/// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value.
15
///
16
/// This is a zero-copy reference type which borrows from the input data.
17
///
18
/// Technically `ANY` hasn't been a recommended part of ASN.1 since the X.209
19
/// revision from 1988. It was deprecated and replaced by Information Object
20
/// Classes in X.680 in 1994, and X.690 no longer refers to it whatsoever.
21
///
22
/// Nevertheless, this crate defines an `ANY` type as it remains a familiar
23
/// and useful concept which is still extensively used in things like
24
/// PKI-related RFCs.
25
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
26
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
27
pub struct AnyRef<'a> {
28
    /// Tag representing the type of the encoded value.
29
    tag: Tag,
30
31
    /// Inner value encoded as bytes.
32
    value: BytesRef<'a>,
33
}
34
35
impl<'a> AnyRef<'a> {
36
    /// [`AnyRef`] representation of the ASN.1 `NULL` type.
37
    pub const NULL: Self = Self {
38
        tag: Tag::Null,
39
        value: BytesRef::EMPTY,
40
    };
41
42
    /// Create a new [`AnyRef`] from the provided [`Tag`] and DER bytes.
43
0
    pub fn new(tag: Tag, bytes: &'a [u8]) -> Result<Self> {
44
0
        let value = BytesRef::new(bytes).map_err(|_| ErrorKind::Length { tag })?;
45
0
        Ok(Self { tag, value })
46
0
    }
47
48
    /// Infallible creation of an [`AnyRef`] from a [`BytesRef`].
49
0
    pub(crate) fn from_tag_and_value(tag: Tag, value: BytesRef<'a>) -> Self {
50
0
        Self { tag, value }
51
0
    }
52
53
    /// Get the raw value for this [`AnyRef`] type as a byte slice.
54
0
    pub fn value(self) -> &'a [u8] {
55
0
        self.value.as_slice()
56
0
    }
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn13anyNtB2_6AnyRef5valueB6_
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn13anyNtB2_6AnyRef5valueCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn13anyNtB2_6AnyRef5valueCskctcMqaO4X4_4spki
57
58
    /// Attempt to decode this [`AnyRef`] type into the inner value.
59
0
    pub fn decode_as<T>(self) -> Result<T>
60
0
    where
61
0
        T: Choice<'a> + DecodeValue<'a>,
62
0
    {
63
0
        if !T::can_decode(self.tag) {
64
0
            return Err(self.tag.unexpected_error(None));
65
0
        }
66
0
67
0
        let header = Header {
68
0
            tag: self.tag,
69
0
            length: self.value.len(),
70
0
        };
71
72
0
        let mut decoder = SliceReader::new(self.value())?;
73
0
        let result = T::decode_value(&mut decoder, header)?;
74
0
        decoder.finish(result)
75
0
    }
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtB5_10bit_string12BitStringRefEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtB5_10ia5_string12Ia5StringRefEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtB5_11utf8_string13Utf8StringRefEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtB5_12octet_string14OctetStringRefEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtB5_14teletex_string16TeletexStringRefEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtB5_15videotex_string17VideotexStringRefEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtB5_16generalized_time15GeneralizedTimeEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtB5_16printable_string18PrintableStringRefEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtB5_4null4NullEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtB5_8utc_time7UtcTimeEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtNtB5_10bit_string10allocating9BitStringEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtNtB5_10ia5_string10allocation9Ia5StringEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtNtB5_12octet_string10allocating11OctetStringEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtNtB5_14teletex_string10allocation13TeletexStringEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtNtB5_16printable_string10allocation15PrintableStringEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtNtB5_7integer3int6IntRefEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtNtB5_7integer4uint7UintRefEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtNtNtB5_7integer3int10allocating3IntEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtNtNtNtB5_7integer4uint10allocating4UintEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asaEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_ashEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_aslEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asmEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asnEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asoEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_assEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_astEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asxEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asyEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn13anyNtB3_6AnyRef9decode_asNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierECskctcMqaO4X4_4spki
76
77
    /// Is this value an ASN.1 `NULL` value?
78
0
    pub fn is_null(self) -> bool {
79
0
        self == Self::NULL
80
0
    }
81
82
    /// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new
83
    /// nested reader and calling the provided argument with it.
84
0
    pub fn sequence<F, T>(self, f: F) -> Result<T>
85
0
    where
86
0
        F: FnOnce(&mut SliceReader<'a>) -> Result<T>,
87
0
    {
88
0
        self.tag.assert_eq(Tag::Sequence)?;
89
0
        let mut reader = SliceReader::new(self.value.as_slice())?;
90
0
        let result = f(&mut reader)?;
91
0
        reader.finish(result)
92
0
    }
93
}
94
95
impl<'a> Choice<'a> for AnyRef<'a> {
96
0
    fn can_decode(_: Tag) -> bool {
97
0
        true
98
0
    }
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der4asn13anyNtB4_6AnyRefNtNtB6_6choice6Choice10can_decodeB8_
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der4asn13anyNtB4_6AnyRefNtNtB6_6choice6Choice10can_decodeCssr1zNgi7Nt_5pkcs8
99
}
100
101
impl<'a> Decode<'a> for AnyRef<'a> {
102
0
    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<AnyRef<'a>> {
103
0
        let header = Header::decode(reader)?;
104
0
        Self::decode_value(reader, header)
105
0
    }
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn13anyNtB6_6AnyRefNtNtBa_6decode6Decode6decodeNtNtNtBa_6reader5slice11SliceReaderEBa_
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn13anyNtB6_6AnyRefNtNtBa_6decode6Decode6decodeINtNtNtBa_6reader6nested12NestedReaderIB1g_NtNtB1k_5slice11SliceReaderEEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn13anyNtB6_6AnyRefNtNtBa_6decode6Decode6decodeINtNtNtBa_6reader6nested12NestedReaderNtNtB1k_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn13anyNtB6_6AnyRefNtNtBa_6decode6Decode6decodeINtNtNtBa_6reader6nested12NestedReaderNtNtB1k_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
106
}
107
108
impl<'a> DecodeValue<'a> for AnyRef<'a> {
109
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
110
0
        Ok(Self {
111
0
            tag: header.tag,
112
0
            value: BytesRef::decode_value(reader, header)?,
113
        })
114
0
    }
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn13anyNtB6_6AnyRefNtNtBa_6decode11DecodeValue12decode_valueNtNtNtBa_6reader5slice11SliceReaderEBa_
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn13anyNtB6_6AnyRefNtNtBa_6decode11DecodeValue12decode_valueINtNtNtBa_6reader6nested12NestedReaderIB1t_NtNtB1x_5slice11SliceReaderEEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn13anyNtB6_6AnyRefNtNtBa_6decode11DecodeValue12decode_valueINtNtNtBa_6reader6nested12NestedReaderNtNtB1x_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn13anyNtB6_6AnyRefNtNtBa_6decode11DecodeValue12decode_valueINtNtNtBa_6reader6nested12NestedReaderNtNtB1x_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
115
}
116
117
impl EncodeValue for AnyRef<'_> {
118
0
    fn value_len(&self) -> Result<Length> {
119
0
        Ok(self.value.len())
120
0
    }
Unexecuted instantiation: _RNvXs2_NtNtCscrZQdumITES_3der4asn13anyNtB5_6AnyRefNtNtB9_6encode11EncodeValue9value_lenB9_
Unexecuted instantiation: _RNvXs2_NtNtCscrZQdumITES_3der4asn13anyNtB5_6AnyRefNtNtB9_6encode11EncodeValue9value_lenCssr1zNgi7Nt_5pkcs8
121
122
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
123
0
        writer.write(self.value())
124
0
    }
Unexecuted instantiation: _RINvXs2_NtNtCscrZQdumITES_3der4asn13anyNtB6_6AnyRefNtNtBa_6encode11EncodeValue12encode_valuepEBa_
Unexecuted instantiation: _RINvXs2_NtNtCscrZQdumITES_3der4asn13anyNtB6_6AnyRefNtNtBa_6encode11EncodeValue12encode_valueNtNtNtBa_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
125
}
126
127
impl Tagged for AnyRef<'_> {
128
0
    fn tag(&self) -> Tag {
129
0
        self.tag
130
0
    }
Unexecuted instantiation: _RNvXs3_NtNtCscrZQdumITES_3der4asn13anyNtB5_6AnyRefNtNtB9_3tag6Tagged3tagB9_
Unexecuted instantiation: _RNvXs3_NtNtCscrZQdumITES_3der4asn13anyNtB5_6AnyRefNtNtB9_3tag6Tagged3tagCssr1zNgi7Nt_5pkcs8
131
}
132
133
impl ValueOrd for AnyRef<'_> {
134
0
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
135
0
        self.value.der_cmp(&other.value)
136
0
    }
137
}
138
139
impl<'a> From<AnyRef<'a>> for BytesRef<'a> {
140
0
    fn from(any: AnyRef<'a>) -> BytesRef<'a> {
141
0
        any.value
142
0
    }
143
}
144
145
impl<'a> TryFrom<&'a [u8]> for AnyRef<'a> {
146
    type Error = Error;
147
148
0
    fn try_from(bytes: &'a [u8]) -> Result<AnyRef<'a>> {
149
0
        AnyRef::from_der(bytes)
150
0
    }
151
}
152
153
#[cfg(feature = "alloc")]
154
pub use self::allocating::Any;
155
156
#[cfg(feature = "alloc")]
157
mod allocating {
158
    use super::*;
159
    use crate::{referenced::*, BytesOwned};
160
    use alloc::boxed::Box;
161
162
    /// ASN.1 `ANY`: represents any explicitly tagged ASN.1 value.
163
    ///
164
    /// This type provides the same functionality as [`AnyRef`] but owns the
165
    /// backing data.
166
    #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
167
    #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
168
    pub struct Any {
169
        /// Tag representing the type of the encoded value.
170
        tag: Tag,
171
172
        /// Inner value encoded as bytes.
173
        value: BytesOwned,
174
    }
175
176
    impl Any {
177
        /// Create a new [`Any`] from the provided [`Tag`] and DER bytes.
178
0
        pub fn new(tag: Tag, bytes: impl Into<Box<[u8]>>) -> Result<Self> {
179
0
            let value = BytesOwned::new(bytes)?;
180
181
            // Ensure the tag and value are a valid `AnyRef`.
182
0
            AnyRef::new(tag, value.as_slice())?;
183
0
            Ok(Self { tag, value })
184
0
        }
185
186
        /// Allow access to value
187
0
        pub fn value(&self) -> &[u8] {
188
0
            self.value.as_slice()
189
0
        }
190
191
        /// Attempt to decode this [`Any`] type into the inner value.
192
0
        pub fn decode_as<'a, T>(&'a self) -> Result<T>
193
0
        where
194
0
            T: Choice<'a> + DecodeValue<'a>,
195
0
        {
196
0
            AnyRef::from(self).decode_as()
197
0
        }
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtB7_10bit_string12BitStringRefEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtNtB7_10bit_string10allocating9BitStringEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtB7_16generalized_time15GeneralizedTimeEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtB7_10ia5_string12Ia5StringRefEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtNtB7_10ia5_string10allocation9Ia5StringEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtNtB7_7integer3int6IntRefEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtNtNtB7_7integer3int10allocating3IntEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtNtB7_7integer4uint7UintRefEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtNtNtB7_7integer4uint10allocating4UintEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtB7_4null4NullEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtB7_12octet_string14OctetStringRefEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtNtB7_12octet_string10allocating11OctetStringEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtB7_16printable_string18PrintableStringRefEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtNtB7_16printable_string10allocation15PrintableStringEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtB7_14teletex_string16TeletexStringRefEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtNtB7_14teletex_string10allocation13TeletexStringEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtB7_8utc_time7UtcTimeEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtB7_11utf8_string13Utf8StringRefEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn13any10allocatingNtB3_3Any9decode_asNtNtB7_15videotex_string17VideotexStringRefEB9_
198
199
        /// Encode the provided type as an [`Any`] value.
200
0
        pub fn encode_from<T>(msg: &T) -> Result<Self>
201
0
        where
202
0
            T: Tagged + EncodeValue,
203
0
        {
204
0
            let encoded_len = usize::try_from(msg.value_len()?)?;
205
0
            let mut buf = vec![0u8; encoded_len];
206
0
            let mut writer = SliceWriter::new(&mut buf);
207
0
            msg.encode_value(&mut writer)?;
208
0
            writer.finish()?;
209
0
            Any::new(msg.tag(), buf)
210
0
        }
211
212
        /// Attempt to decode this value an ASN.1 `SEQUENCE`, creating a new
213
        /// nested reader and calling the provided argument with it.
214
0
        pub fn sequence<'a, F, T>(&'a self, f: F) -> Result<T>
215
0
        where
216
0
            F: FnOnce(&mut SliceReader<'a>) -> Result<T>,
217
0
        {
218
0
            AnyRef::from(self).sequence(f)
219
0
        }
220
221
        /// [`Any`] representation of the ASN.1 `NULL` type.
222
0
        pub fn null() -> Self {
223
0
            Self {
224
0
                tag: Tag::Null,
225
0
                value: BytesOwned::default(),
226
0
            }
227
0
        }
228
    }
229
230
    impl Choice<'_> for Any {
231
0
        fn can_decode(_: Tag) -> bool {
232
0
            true
233
0
        }
234
    }
235
236
    impl<'a> Decode<'a> for Any {
237
0
        fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self> {
238
0
            let header = Header::decode(reader)?;
239
0
            Self::decode_value(reader, header)
240
0
        }
241
    }
242
243
    impl<'a> DecodeValue<'a> for Any {
244
0
        fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
245
0
            let value = reader.read_vec(header.length)?;
246
0
            Self::new(header.tag, value)
247
0
        }
248
    }
249
250
    impl EncodeValue for Any {
251
0
        fn value_len(&self) -> Result<Length> {
252
0
            Ok(self.value.len())
253
0
        }
254
255
0
        fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
256
0
            writer.write(self.value.as_slice())
257
0
        }
258
    }
259
260
    impl<'a> From<&'a Any> for AnyRef<'a> {
261
0
        fn from(any: &'a Any) -> AnyRef<'a> {
262
0
            // Ensured to parse successfully in constructor
263
0
            AnyRef::new(any.tag, any.value.as_slice()).expect("invalid ANY")
264
0
        }
265
    }
266
267
    impl Tagged for Any {
268
0
        fn tag(&self) -> Tag {
269
0
            self.tag
270
0
        }
271
    }
272
273
    impl ValueOrd for Any {
274
0
        fn value_cmp(&self, other: &Self) -> Result<Ordering> {
275
0
            self.value.der_cmp(&other.value)
276
0
        }
277
    }
278
279
    impl<'a, T> From<T> for Any
280
    where
281
        T: Into<AnyRef<'a>>,
282
    {
283
0
        fn from(input: T) -> Any {
284
0
            let anyref: AnyRef<'a> = input.into();
285
0
            Self {
286
0
                tag: anyref.tag(),
287
0
                value: BytesOwned::from(anyref.value),
288
0
            }
289
0
        }
290
    }
291
292
    impl<'a> RefToOwned<'a> for AnyRef<'a> {
293
        type Owned = Any;
294
0
        fn ref_to_owned(&self) -> Self::Owned {
295
0
            Any {
296
0
                tag: self.tag(),
297
0
                value: BytesOwned::from(self.value),
298
0
            }
299
0
        }
300
    }
301
302
    impl OwnedToRef for Any {
303
        type Borrowed<'a> = AnyRef<'a>;
304
0
        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
305
0
            self.into()
306
0
        }
307
    }
308
309
    impl Any {
310
        /// Is this value an ASN.1 `NULL` value?
311
0
        pub fn is_null(&self) -> bool {
312
0
            self.owned_to_ref() == AnyRef::NULL
313
0
        }
314
    }
315
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/bit_string.rs
Line
Count
Source
1
//! ASN.1 `BIT STRING` support.
2
3
use crate::{
4
    BytesRef, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader,
5
    Result, Tag, ValueOrd, Writer,
6
};
7
use core::{cmp::Ordering, iter::FusedIterator};
8
9
/// ASN.1 `BIT STRING` type.
10
///
11
/// This type contains a sequence of any number of bits, modeled internally as
12
/// a sequence of bytes with a known number of "unused bits".
13
///
14
/// This is a zero-copy reference type which borrows from the input data.
15
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
16
pub struct BitStringRef<'a> {
17
    /// Number of unused bits in the final octet.
18
    unused_bits: u8,
19
20
    /// Length of this `BIT STRING` in bits.
21
    bit_length: usize,
22
23
    /// Bitstring represented as a slice of bytes.
24
    inner: BytesRef<'a>,
25
}
26
27
impl<'a> BitStringRef<'a> {
28
    /// Maximum number of unused bits allowed.
29
    pub const MAX_UNUSED_BITS: u8 = 7;
30
31
    /// Create a new ASN.1 `BIT STRING` from a byte slice.
32
    ///
33
    /// Accepts an optional number of "unused bits" (0-7) which are omitted
34
    /// from the final octet. This number is 0 if the value is octet-aligned.
35
0
    pub fn new(unused_bits: u8, bytes: &'a [u8]) -> Result<Self> {
36
0
        if (unused_bits > Self::MAX_UNUSED_BITS) || (unused_bits != 0 && bytes.is_empty()) {
37
0
            return Err(Self::TAG.value_error());
38
0
        }
39
40
0
        let inner = BytesRef::new(bytes).map_err(|_| Self::TAG.length_error())?;
41
42
0
        let bit_length = usize::try_from(inner.len())?
43
0
            .checked_mul(8)
44
0
            .and_then(|n| n.checked_sub(usize::from(unused_bits)))
45
0
            .ok_or(ErrorKind::Overflow)?;
46
47
0
        Ok(Self {
48
0
            unused_bits,
49
0
            bit_length,
50
0
            inner,
51
0
        })
52
0
    }
53
54
    /// Create a new ASN.1 `BIT STRING` from the given bytes.
55
    ///
56
    /// The "unused bits" are set to 0.
57
0
    pub fn from_bytes(bytes: &'a [u8]) -> Result<Self> {
58
0
        Self::new(0, bytes)
59
0
    }
60
61
    /// Get the number of unused bits in this byte slice.
62
0
    pub fn unused_bits(&self) -> u8 {
63
0
        self.unused_bits
64
0
    }
65
66
    /// Is the number of unused bits a value other than 0?
67
0
    pub fn has_unused_bits(&self) -> bool {
68
0
        self.unused_bits != 0
69
0
    }
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn110bit_stringNtB2_12BitStringRef15has_unused_bitsB6_
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn110bit_stringNtB2_12BitStringRef15has_unused_bitsCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn110bit_stringNtB2_12BitStringRef15has_unused_bitsCsj9qtwLkMHqH_4sec1
70
71
    /// Get the length of this `BIT STRING` in bits.
72
0
    pub fn bit_len(&self) -> usize {
73
0
        self.bit_length
74
0
    }
75
76
    /// Get the number of bytes/octets needed to represent this `BIT STRING`
77
    /// when serialized in an octet-aligned manner.
78
0
    pub fn byte_len(&self) -> Length {
79
0
        self.inner.len()
80
0
    }
81
82
    /// Is the inner byte slice empty?
83
0
    pub fn is_empty(&self) -> bool {
84
0
        self.inner.is_empty()
85
0
    }
86
87
    /// Borrow the inner byte slice.
88
    ///
89
    /// Returns `None` if the number of unused bits is *not* equal to zero,
90
    /// i.e. if the `BIT STRING` is not octet aligned.
91
    ///
92
    /// Use [`BitString::raw_bytes`] to obtain access to the raw value
93
    /// regardless of the presence of unused bits.
94
0
    pub fn as_bytes(&self) -> Option<&'a [u8]> {
95
0
        if self.has_unused_bits() {
96
0
            None
97
        } else {
98
0
            Some(self.raw_bytes())
99
        }
100
0
    }
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn110bit_stringNtB2_12BitStringRef8as_bytesB6_
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn110bit_stringNtB2_12BitStringRef8as_bytesCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn110bit_stringNtB2_12BitStringRef8as_bytesCsj9qtwLkMHqH_4sec1
101
102
    /// Borrow the raw bytes of this `BIT STRING`.
103
    ///
104
    /// Note that the byte string may contain extra unused bits in the final
105
    /// octet. If the number of unused bits is expected to be 0, the
106
    /// [`BitStringRef::as_bytes`] function can be used instead.
107
0
    pub fn raw_bytes(&self) -> &'a [u8] {
108
0
        self.inner.as_slice()
109
0
    }
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn110bit_stringNtB2_12BitStringRef9raw_bytesB6_
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn110bit_stringNtB2_12BitStringRef9raw_bytesCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn110bit_stringNtB2_12BitStringRef9raw_bytesCsj9qtwLkMHqH_4sec1
110
111
    /// Iterator over the bits of this `BIT STRING`.
112
0
    pub fn bits(self) -> BitStringIter<'a> {
113
0
        BitStringIter {
114
0
            bit_string: self,
115
0
            position: 0,
116
0
        }
117
0
    }
118
}
119
120
impl_any_conversions!(BitStringRef<'a>, 'a);
121
122
impl<'a> DecodeValue<'a> for BitStringRef<'a> {
123
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
124
0
        let header = Header {
125
0
            tag: header.tag,
126
0
            length: (header.length - Length::ONE)?,
127
        };
128
129
0
        let unused_bits = reader.read_byte()?;
130
0
        let inner = BytesRef::decode_value(reader, header)?;
131
0
        Self::new(unused_bits, inner.as_slice())
132
0
    }
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der4asn110bit_stringNtB5_12BitStringRefNtNtB9_6decode11DecodeValue12decode_valueNtNtNtB9_6reader5slice11SliceReaderEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der4asn110bit_stringNtB5_12BitStringRefNtNtB9_6decode11DecodeValue12decode_valueINtNtNtB9_6reader6nested12NestedReaderIB1H_NtNtB1L_5slice11SliceReaderEEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der4asn110bit_stringNtB5_12BitStringRefNtNtB9_6decode11DecodeValue12decode_valueINtNtNtB9_6reader6nested12NestedReaderNtNtB1L_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der4asn110bit_stringNtB5_12BitStringRefNtNtB9_6decode11DecodeValue12decode_valueINtNtNtB9_6reader6nested12NestedReaderIB1H_NtNtB1L_5slice11SliceReaderEEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der4asn110bit_stringNtB5_12BitStringRefNtNtB9_6decode11DecodeValue12decode_valueINtNtNtB9_6reader6nested12NestedReaderNtNtB1L_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
133
}
134
135
impl EncodeValue for BitStringRef<'_> {
136
0
    fn value_len(&self) -> Result<Length> {
137
0
        self.byte_len() + Length::ONE
138
0
    }
139
140
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
141
0
        writer.write_byte(self.unused_bits)?;
142
0
        writer.write(self.raw_bytes())
143
0
    }
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn110bit_stringNtB6_12BitStringRefNtNtBa_6encode11EncodeValue12encode_valuepEBa_
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn110bit_stringNtB6_12BitStringRefNtNtBa_6encode11EncodeValue12encode_valueNtNtNtBa_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn110bit_stringNtB6_12BitStringRefNtNtBa_6encode11EncodeValue12encode_valueNtNtNtBa_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
144
}
145
146
impl ValueOrd for BitStringRef<'_> {
147
0
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
148
0
        match self.unused_bits.cmp(&other.unused_bits) {
149
0
            Ordering::Equal => self.inner.der_cmp(&other.inner),
150
0
            ordering => Ok(ordering),
151
        }
152
0
    }
153
}
154
155
impl<'a> From<&BitStringRef<'a>> for BitStringRef<'a> {
156
0
    fn from(value: &BitStringRef<'a>) -> BitStringRef<'a> {
157
0
        *value
158
0
    }
159
}
160
161
impl<'a> TryFrom<&'a [u8]> for BitStringRef<'a> {
162
    type Error = Error;
163
164
0
    fn try_from(bytes: &'a [u8]) -> Result<BitStringRef<'a>> {
165
0
        BitStringRef::from_bytes(bytes)
166
0
    }
167
}
168
169
/// Hack for simplifying the custom derive use case.
170
impl<'a> TryFrom<&&'a [u8]> for BitStringRef<'a> {
171
    type Error = Error;
172
173
0
    fn try_from(bytes: &&'a [u8]) -> Result<BitStringRef<'a>> {
174
0
        BitStringRef::from_bytes(bytes)
175
0
    }
176
}
177
178
impl<'a> TryFrom<BitStringRef<'a>> for &'a [u8] {
179
    type Error = Error;
180
181
0
    fn try_from(bit_string: BitStringRef<'a>) -> Result<&'a [u8]> {
182
0
        bit_string
183
0
            .as_bytes()
184
0
            .ok_or_else(|| Tag::BitString.value_error())
185
0
    }
186
}
187
188
impl<'a> FixedTag for BitStringRef<'a> {
189
    const TAG: Tag = Tag::BitString;
190
}
191
192
// Implement by hand because the derive would create invalid values.
193
// Use the constructor to create a valid value.
194
#[cfg(feature = "arbitrary")]
195
impl<'a> arbitrary::Arbitrary<'a> for BitStringRef<'a> {
196
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
197
        Self::new(
198
            u.int_in_range(0..=Self::MAX_UNUSED_BITS)?,
199
            BytesRef::arbitrary(u)?.as_slice(),
200
        )
201
        .map_err(|_| arbitrary::Error::IncorrectFormat)
202
    }
203
204
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
205
        arbitrary::size_hint::and(u8::size_hint(depth), BytesRef::size_hint(depth))
206
    }
207
}
208
209
#[cfg(feature = "alloc")]
210
pub use self::allocating::BitString;
211
212
#[cfg(feature = "alloc")]
213
mod allocating {
214
    use super::*;
215
    use crate::referenced::*;
216
    use alloc::vec::Vec;
217
218
    /// Owned form of ASN.1 `BIT STRING` type.
219
    ///
220
    /// This type provides the same functionality as [`BitStringRef`] but owns the
221
    /// backing data.
222
    #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
223
    pub struct BitString {
224
        /// Number of unused bits in the final octet.
225
        unused_bits: u8,
226
227
        /// Length of this `BIT STRING` in bits.
228
        bit_length: usize,
229
230
        /// Bitstring represented as a slice of bytes.
231
        inner: Vec<u8>,
232
    }
233
234
    impl BitString {
235
        /// Maximum number of unused bits allowed.
236
        pub const MAX_UNUSED_BITS: u8 = 7;
237
238
        /// Create a new ASN.1 `BIT STRING` from a byte slice.
239
        ///
240
        /// Accepts an optional number of "unused bits" (0-7) which are omitted
241
        /// from the final octet. This number is 0 if the value is octet-aligned.
242
0
        pub fn new(unused_bits: u8, bytes: impl Into<Vec<u8>>) -> Result<Self> {
243
0
            let inner = bytes.into();
244
245
            // Ensure parameters parse successfully as a `BitStringRef`.
246
0
            let bit_length = BitStringRef::new(unused_bits, &inner)?.bit_length;
247
248
0
            Ok(BitString {
249
0
                unused_bits,
250
0
                bit_length,
251
0
                inner,
252
0
            })
253
0
        }
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn110bit_string10allocatingNtB3_9BitString3newINtNtCsiBl6Lc3cFal_5alloc3vec3VechEEB9_
Unexecuted instantiation: _RINvMNtNtNtCscrZQdumITES_3der4asn110bit_string10allocatingNtB3_9BitString3newRShEB9_
254
255
        /// Create a new ASN.1 `BIT STRING` from the given bytes.
256
        ///
257
        /// The "unused bits" are set to 0.
258
0
        pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
259
0
            Self::new(0, bytes)
260
0
        }
261
262
        /// Get the number of unused bits in the octet serialization of this
263
        /// `BIT STRING`.
264
0
        pub fn unused_bits(&self) -> u8 {
265
0
            self.unused_bits
266
0
        }
267
268
        /// Is the number of unused bits a value other than 0?
269
0
        pub fn has_unused_bits(&self) -> bool {
270
0
            self.unused_bits != 0
271
0
        }
272
273
        /// Get the length of this `BIT STRING` in bits.
274
0
        pub fn bit_len(&self) -> usize {
275
0
            self.bit_length
276
0
        }
277
278
        /// Is the inner byte slice empty?
279
0
        pub fn is_empty(&self) -> bool {
280
0
            self.inner.is_empty()
281
0
        }
282
283
        /// Borrow the inner byte slice.
284
        ///
285
        /// Returns `None` if the number of unused bits is *not* equal to zero,
286
        /// i.e. if the `BIT STRING` is not octet aligned.
287
        ///
288
        /// Use [`BitString::raw_bytes`] to obtain access to the raw value
289
        /// regardless of the presence of unused bits.
290
0
        pub fn as_bytes(&self) -> Option<&[u8]> {
291
0
            if self.has_unused_bits() {
292
0
                None
293
            } else {
294
0
                Some(self.raw_bytes())
295
            }
296
0
        }
297
298
        /// Borrow the raw bytes of this `BIT STRING`.
299
0
        pub fn raw_bytes(&self) -> &[u8] {
300
0
            self.inner.as_slice()
301
0
        }
302
303
        /// Iterator over the bits of this `BIT STRING`.
304
0
        pub fn bits(&self) -> BitStringIter<'_> {
305
0
            BitStringRef::from(self).bits()
306
0
        }
307
    }
308
309
    impl_any_conversions!(BitString);
310
311
    impl<'a> DecodeValue<'a> for BitString {
312
0
        fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
313
0
            let inner_len = (header.length - Length::ONE)?;
314
0
            let unused_bits = reader.read_byte()?;
315
0
            let inner = reader.read_vec(inner_len)?;
316
0
            Self::new(unused_bits, inner)
317
0
        }
318
    }
319
320
    impl EncodeValue for BitString {
321
0
        fn value_len(&self) -> Result<Length> {
322
0
            Length::ONE + Length::try_from(self.inner.len())?
323
0
        }
324
325
0
        fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
326
0
            writer.write_byte(self.unused_bits)?;
327
0
            writer.write(&self.inner)
328
0
        }
329
    }
330
331
    impl FixedTag for BitString {
332
        const TAG: Tag = Tag::BitString;
333
    }
334
335
    impl<'a> From<&'a BitString> for BitStringRef<'a> {
336
0
        fn from(bit_string: &'a BitString) -> BitStringRef<'a> {
337
0
            // Ensured to parse successfully in constructor
338
0
            BitStringRef::new(bit_string.unused_bits, &bit_string.inner)
339
0
                .expect("invalid BIT STRING")
340
0
        }
341
    }
342
343
    impl ValueOrd for BitString {
344
0
        fn value_cmp(&self, other: &Self) -> Result<Ordering> {
345
0
            match self.unused_bits.cmp(&other.unused_bits) {
346
0
                Ordering::Equal => self.inner.der_cmp(&other.inner),
347
0
                ordering => Ok(ordering),
348
            }
349
0
        }
350
    }
351
352
    // Implement by hand because the derive would create invalid values.
353
    // Use the constructor to create a valid value.
354
    #[cfg(feature = "arbitrary")]
355
    impl<'a> arbitrary::Arbitrary<'a> for BitString {
356
        fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
357
            Self::new(
358
                u.int_in_range(0..=Self::MAX_UNUSED_BITS)?,
359
                BytesRef::arbitrary(u)?.as_slice(),
360
            )
361
            .map_err(|_| arbitrary::Error::IncorrectFormat)
362
        }
363
364
        fn size_hint(depth: usize) -> (usize, Option<usize>) {
365
            arbitrary::size_hint::and(u8::size_hint(depth), BytesRef::size_hint(depth))
366
        }
367
    }
368
369
    impl<'a> RefToOwned<'a> for BitStringRef<'a> {
370
        type Owned = BitString;
371
0
        fn ref_to_owned(&self) -> Self::Owned {
372
0
            BitString {
373
0
                unused_bits: self.unused_bits,
374
0
                bit_length: self.bit_length,
375
0
                inner: Vec::from(self.inner.as_slice()),
376
0
            }
377
0
        }
378
    }
379
380
    impl OwnedToRef for BitString {
381
        type Borrowed<'a> = BitStringRef<'a>;
382
0
        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
383
0
            self.into()
384
0
        }
385
    }
386
}
387
388
/// Iterator over the bits of a [`BitString`].
389
pub struct BitStringIter<'a> {
390
    /// [`BitString`] being iterated over.
391
    bit_string: BitStringRef<'a>,
392
393
    /// Current bit position within the iterator.
394
    position: usize,
395
}
396
397
impl<'a> Iterator for BitStringIter<'a> {
398
    type Item = bool;
399
400
    #[allow(clippy::integer_arithmetic)]
401
0
    fn next(&mut self) -> Option<bool> {
402
0
        if self.position >= self.bit_string.bit_len() {
403
0
            return None;
404
0
        }
405
406
0
        let byte = self.bit_string.raw_bytes().get(self.position / 8)?;
407
0
        let bit = 1u8 << (7 - (self.position % 8));
408
0
        self.position = self.position.checked_add(1)?;
409
0
        Some(byte & bit != 0)
410
0
    }
411
}
412
413
impl<'a> ExactSizeIterator for BitStringIter<'a> {
414
0
    fn len(&self) -> usize {
415
0
        self.bit_string.bit_len()
416
0
    }
417
}
418
419
impl<'a> FusedIterator for BitStringIter<'a> {}
420
421
#[cfg(feature = "flagset")]
422
impl<T: flagset::Flags> FixedTag for flagset::FlagSet<T> {
423
    const TAG: Tag = BitStringRef::TAG;
424
}
425
426
#[cfg(feature = "flagset")]
427
impl<T> ValueOrd for flagset::FlagSet<T>
428
where
429
    T: flagset::Flags,
430
    T::Type: Ord,
431
{
432
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
433
        Ok(self.bits().cmp(&other.bits()))
434
    }
435
}
436
437
#[cfg(feature = "flagset")]
438
#[allow(clippy::integer_arithmetic)]
439
impl<'a, T> DecodeValue<'a> for flagset::FlagSet<T>
440
where
441
    T: flagset::Flags,
442
    T::Type: From<bool>,
443
    T::Type: core::ops::Shl<usize, Output = T::Type>,
444
{
445
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
446
        let position = reader.position();
447
        let bits = BitStringRef::decode_value(reader, header)?;
448
449
        let mut flags = T::none().bits();
450
451
        if bits.bit_len() > core::mem::size_of_val(&flags) * 8 {
452
            return Err(Error::new(ErrorKind::Overlength, position));
453
        }
454
455
        for (i, bit) in bits.bits().enumerate() {
456
            flags |= T::Type::from(bit) << i;
457
        }
458
459
        Ok(Self::new_truncated(flags))
460
    }
461
}
462
463
#[cfg(feature = "flagset")]
464
#[allow(clippy::integer_arithmetic)]
465
#[inline(always)]
466
fn encode_flagset<T>(set: &flagset::FlagSet<T>) -> (usize, [u8; 16])
467
where
468
    T: flagset::Flags,
469
    u128: From<T::Type>,
470
{
471
    let bits: u128 = set.bits().into();
472
    let mut swap = 0u128;
473
474
    for i in 0..128 {
475
        let on = bits & (1 << i);
476
        swap |= on >> i << (128 - i - 1);
477
    }
478
479
    (bits.leading_zeros() as usize, swap.to_be_bytes())
480
}
481
482
#[cfg(feature = "flagset")]
483
#[allow(clippy::cast_possible_truncation, clippy::integer_arithmetic)]
484
impl<T: flagset::Flags> EncodeValue for flagset::FlagSet<T>
485
where
486
    T::Type: From<bool>,
487
    T::Type: core::ops::Shl<usize, Output = T::Type>,
488
    u128: From<T::Type>,
489
{
490
    fn value_len(&self) -> Result<Length> {
491
        let (lead, buff) = encode_flagset(self);
492
        let buff = &buff[..buff.len() - lead / 8];
493
        BitStringRef::new((lead % 8) as u8, buff)?.value_len()
494
    }
495
496
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
497
        let (lead, buff) = encode_flagset(self);
498
        let buff = &buff[..buff.len() - lead / 8];
499
        BitStringRef::new((lead % 8) as u8, buff)?.encode_value(writer)
500
    }
501
}
502
503
#[cfg(test)]
504
mod tests {
505
    use super::{BitStringRef, Result, Tag};
506
    use crate::asn1::AnyRef;
507
    use hex_literal::hex;
508
509
    /// Parse a `BitString` from an ASN.1 `Any` value to test decoding behaviors.
510
    fn parse_bitstring(bytes: &[u8]) -> Result<BitStringRef<'_>> {
511
        AnyRef::new(Tag::BitString, bytes)?.try_into()
512
    }
513
514
    #[test]
515
    fn decode_empty_bitstring() {
516
        let bs = parse_bitstring(&hex!("00")).unwrap();
517
        assert_eq!(bs.as_bytes().unwrap(), &[]);
518
    }
519
520
    #[test]
521
    fn decode_non_empty_bitstring() {
522
        let bs = parse_bitstring(&hex!("00010203")).unwrap();
523
        assert_eq!(bs.as_bytes().unwrap(), &[0x01, 0x02, 0x03]);
524
    }
525
526
    #[test]
527
    fn decode_bitstring_with_unused_bits() {
528
        let bs = parse_bitstring(&hex!("066e5dc0")).unwrap();
529
        assert_eq!(bs.unused_bits(), 6);
530
        assert_eq!(bs.raw_bytes(), &hex!("6e5dc0"));
531
532
        // Expected: 011011100101110111
533
        let mut bits = bs.bits();
534
        assert_eq!(bits.len(), 18);
535
536
        for bit in [0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1] {
537
            assert_eq!(u8::from(bits.next().unwrap()), bit)
538
        }
539
540
        // Ensure `None` is returned on successive calls
541
        assert_eq!(bits.next(), None);
542
        assert_eq!(bits.next(), None);
543
    }
544
545
    #[test]
546
    fn reject_unused_bits_in_empty_string() {
547
        assert_eq!(
548
            parse_bitstring(&[0x03]).err().unwrap().kind(),
549
            Tag::BitString.value_error().kind()
550
        )
551
    }
552
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/bmp_string.rs
Line
Count
Source
1
//! ASN.1 `BMPString` support.
2
3
use crate::{
4
    BytesOwned, DecodeValue, EncodeValue, Error, FixedTag, Header, Length, Reader, Result, Tag,
5
    Writer,
6
};
7
use alloc::{boxed::Box, vec::Vec};
8
use core::{fmt, str::FromStr};
9
10
/// ASN.1 `BMPString` type.
11
///
12
/// Encodes Basic Multilingual Plane (BMP) subset of Unicode (ISO 10646),
13
/// a.k.a. UCS-2.
14
#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
15
pub struct BmpString {
16
    bytes: BytesOwned,
17
}
18
19
impl BmpString {
20
    /// Create a new [`BmpString`] from its UCS-2 encoding.
21
0
    pub fn from_ucs2(bytes: impl Into<Box<[u8]>>) -> Result<Self> {
22
0
        let bytes = bytes.into();
23
0
24
0
        if bytes.len() % 2 != 0 {
25
0
            return Err(Tag::BmpString.length_error());
26
0
        }
27
28
0
        let ret = Self {
29
0
            bytes: bytes.try_into()?,
30
        };
31
32
0
        for maybe_char in char::decode_utf16(ret.codepoints()) {
33
0
            match maybe_char {
34
                // All surrogates paired and character is in the Basic Multilingual Plane
35
0
                Ok(c) if (c as u64) < u64::from(u16::MAX) => (),
36
                // Unpaired surrogates or characters outside Basic Multilingual Plane
37
0
                _ => return Err(Tag::BmpString.value_error()),
38
            }
39
        }
40
41
0
        Ok(ret)
42
0
    }
43
44
    /// Create a new [`BmpString`] from a UTF-8 string.
45
0
    pub fn from_utf8(utf8: &str) -> Result<Self> {
46
0
        let capacity = utf8
47
0
            .len()
48
0
            .checked_mul(2)
49
0
            .ok_or_else(|| Tag::BmpString.length_error())?;
50
51
0
        let mut bytes = Vec::with_capacity(capacity);
52
53
0
        for code_point in utf8.encode_utf16() {
54
0
            bytes.extend(code_point.to_be_bytes());
55
0
        }
56
57
0
        Self::from_ucs2(bytes)
58
0
    }
59
60
    /// Borrow the encoded UCS-2 as bytes.
61
0
    pub fn as_bytes(&self) -> &[u8] {
62
0
        self.bytes.as_ref()
63
0
    }
64
65
    /// Obtain the inner bytes.
66
    #[inline]
67
0
    pub fn into_bytes(self) -> Box<[u8]> {
68
0
        self.bytes.into()
69
0
    }
70
71
    /// Get an iterator over characters in the string.
72
0
    pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
73
0
        char::decode_utf16(self.codepoints())
74
0
            .map(|maybe_char| maybe_char.expect("unpaired surrogates checked in constructor"))
75
0
    }
76
77
    /// Get an iterator over the `u16` codepoints.
78
0
    pub fn codepoints(&self) -> impl Iterator<Item = u16> + '_ {
79
0
        // TODO(tarcieri): use `array_chunks`
80
0
        self.as_bytes()
81
0
            .chunks_exact(2)
82
0
            .map(|chunk| u16::from_be_bytes([chunk[0], chunk[1]]))
83
0
    }
84
}
85
86
impl AsRef<[u8]> for BmpString {
87
0
    fn as_ref(&self) -> &[u8] {
88
0
        self.as_bytes()
89
0
    }
90
}
91
92
impl<'a> DecodeValue<'a> for BmpString {
93
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
94
0
        Self::from_ucs2(reader.read_vec(header.length)?)
95
0
    }
96
}
97
98
impl EncodeValue for BmpString {
99
0
    fn value_len(&self) -> Result<Length> {
100
0
        Ok(self.bytes.len())
101
0
    }
102
103
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
104
0
        writer.write(self.as_bytes())
105
0
    }
106
}
107
108
impl FixedTag for BmpString {
109
    const TAG: Tag = Tag::BmpString;
110
}
111
112
impl FromStr for BmpString {
113
    type Err = Error;
114
115
0
    fn from_str(s: &str) -> Result<Self> {
116
0
        Self::from_utf8(s)
117
0
    }
118
}
119
120
impl fmt::Debug for BmpString {
121
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122
0
        write!(f, "BmpString(\"{}\")", self)
123
0
    }
124
}
125
126
impl fmt::Display for BmpString {
127
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128
0
        for c in self.chars() {
129
0
            write!(f, "{}", c)?;
130
        }
131
0
        Ok(())
132
0
    }
133
}
134
135
#[cfg(test)]
136
mod tests {
137
    use super::BmpString;
138
    use crate::{Decode, Encode};
139
    use alloc::string::ToString;
140
    use hex_literal::hex;
141
142
    const EXAMPLE_BYTES: &[u8] = &hex!(
143
        "1e 26 00 43 00 65 00 72 00 74"
144
        "      00 69 00 66 00 69 00 63"
145
        "      00 61 00 74 00 65 00 54"
146
        "      00 65 00 6d 00 70 00 6c"
147
        "      00 61 00 74 00 65"
148
    );
149
150
    const EXAMPLE_UTF8: &str = "CertificateTemplate";
151
152
    #[test]
153
    fn decode() {
154
        let bmp_string = BmpString::from_der(EXAMPLE_BYTES).unwrap();
155
        assert_eq!(bmp_string.to_string(), EXAMPLE_UTF8);
156
    }
157
158
    #[test]
159
    fn encode() {
160
        let bmp_string = BmpString::from_utf8(EXAMPLE_UTF8).unwrap();
161
        let encoded = bmp_string.to_der().unwrap();
162
        assert_eq!(encoded, EXAMPLE_BYTES);
163
    }
164
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/boolean.rs
Line
Count
Source
1
//! ASN.1 `BOOLEAN` support.
2
3
use crate::{
4
    asn1::AnyRef, ord::OrdIsValueOrd, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header,
5
    Length, Reader, Result, Tag, Writer,
6
};
7
8
/// Byte used to encode `true` in ASN.1 DER. From X.690 Section 11.1:
9
///
10
/// > If the encoding represents the boolean value TRUE, its single contents
11
/// > octet shall have all eight bits set to one.
12
const TRUE_OCTET: u8 = 0b11111111;
13
14
/// Byte used to encode `false` in ASN.1 DER.
15
const FALSE_OCTET: u8 = 0b00000000;
16
17
impl<'a> DecodeValue<'a> for bool {
18
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
19
0
        if header.length != Length::ONE {
20
0
            return Err(reader.error(ErrorKind::Length { tag: Self::TAG }));
21
0
        }
22
0
23
0
        match reader.read_byte()? {
24
0
            FALSE_OCTET => Ok(false),
25
0
            TRUE_OCTET => Ok(true),
26
0
            _ => Err(Self::TAG.non_canonical_error()),
27
        }
28
0
    }
29
}
30
31
impl EncodeValue for bool {
32
0
    fn value_len(&self) -> Result<Length> {
33
0
        Ok(Length::ONE)
34
0
    }
35
36
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
37
0
        writer.write_byte(if *self { TRUE_OCTET } else { FALSE_OCTET })
38
0
    }
39
}
40
41
impl FixedTag for bool {
42
    const TAG: Tag = Tag::Boolean;
43
}
44
45
impl OrdIsValueOrd for bool {}
46
47
impl TryFrom<AnyRef<'_>> for bool {
48
    type Error = Error;
49
50
0
    fn try_from(any: AnyRef<'_>) -> Result<bool> {
51
0
        any.try_into()
52
0
    }
53
}
54
55
#[cfg(test)]
56
mod tests {
57
    use crate::{Decode, Encode};
58
59
    #[test]
60
    fn decode() {
61
        assert_eq!(true, bool::from_der(&[0x01, 0x01, 0xFF]).unwrap());
62
        assert_eq!(false, bool::from_der(&[0x01, 0x01, 0x00]).unwrap());
63
    }
64
65
    #[test]
66
    fn encode() {
67
        let mut buffer = [0u8; 3];
68
        assert_eq!(
69
            &[0x01, 0x01, 0xFF],
70
            true.encode_to_slice(&mut buffer).unwrap()
71
        );
72
        assert_eq!(
73
            &[0x01, 0x01, 0x00],
74
            false.encode_to_slice(&mut buffer).unwrap()
75
        );
76
    }
77
78
    #[test]
79
    fn reject_non_canonical() {
80
        assert!(bool::from_der(&[0x01, 0x01, 0x01]).is_err());
81
    }
82
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/choice.rs
Line
Count
Source
1
//! ASN.1 `CHOICE` support.
2
3
use crate::{Decode, FixedTag, Tag, Tagged};
4
5
/// ASN.1 `CHOICE` denotes a union of one or more possible alternatives.
6
///
7
/// The types MUST have distinct tags.
8
///
9
/// This crate models choice as a trait, with a blanket impl for all types
10
/// which impl `Decode + FixedTag` (i.e. they are modeled as a `CHOICE`
11
/// with only one possible variant)
12
pub trait Choice<'a>: Decode<'a> + Tagged {
13
    /// Is the provided [`Tag`] decodable as a variant of this `CHOICE`?
14
    fn can_decode(tag: Tag) -> bool;
15
}
16
17
/// This blanket impl allows any [`Tagged`] type to function as a [`Choice`]
18
/// with a single alternative.
19
impl<'a, T> Choice<'a> for T
20
where
21
    T: Decode<'a> + FixedTag,
22
{
23
0
    fn can_decode(tag: Tag) -> bool {
24
0
        T::TAG == tag
25
0
    }
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtB4_10bit_string12BitStringRefNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtB4_10ia5_string12Ia5StringRefNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtB4_11utf8_string13Utf8StringRefNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtB4_12octet_string14OctetStringRefNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtB4_14teletex_string16TeletexStringRefNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtB4_15videotex_string17VideotexStringRefNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtB4_16generalized_time15GeneralizedTimeNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtB4_16printable_string18PrintableStringRefNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtB4_4null4NullNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtB4_8utc_time7UtcTimeNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtNtB4_10bit_string10allocating9BitStringNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtNtB4_10ia5_string10allocation9Ia5StringNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtNtB4_12octet_string10allocating11OctetStringNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtNtB4_14teletex_string10allocation13TeletexStringNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtNtB4_16printable_string10allocation15PrintableStringNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtNtB4_7integer3int6IntRefNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtNtB4_7integer4uint7UintRefNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtNtNtB4_7integer3int10allocating3IntNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtNtNtNtB4_7integer4uint10allocating4UintNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceaNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choicehNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choicelNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choicemNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choicenNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceoNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choicesNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choicetNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choicexNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceyNtB2_6Choice10can_decodeB6_
Unexecuted instantiation: _RNvXNtNtCscrZQdumITES_3der4asn16choiceNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtB2_6Choice10can_decodeCskctcMqaO4X4_4spki
26
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/context_specific.rs
Line
Count
Source
1
//! Context-specific field.
2
3
use crate::{
4
    asn1::AnyRef, Choice, Decode, DecodeValue, DerOrd, Encode, EncodeValue, EncodeValueRef, Error,
5
    Header, Length, Reader, Result, Tag, TagMode, TagNumber, Tagged, ValueOrd, Writer,
6
};
7
use core::cmp::Ordering;
8
9
/// Context-specific field which wraps an owned inner value.
10
///
11
/// This type decodes/encodes a field which is specific to a particular context
12
/// and is identified by a [`TagNumber`].
13
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
14
pub struct ContextSpecific<T> {
15
    /// Context-specific tag number sans the leading `0b10000000` class
16
    /// identifier bit and `0b100000` constructed flag.
17
    pub tag_number: TagNumber,
18
19
    /// Tag mode: `EXPLICIT` VS `IMPLICIT`.
20
    pub tag_mode: TagMode,
21
22
    /// Value of the field.
23
    pub value: T,
24
}
25
26
impl<T> ContextSpecific<T> {
27
    /// Attempt to decode an `EXPLICIT` ASN.1 `CONTEXT-SPECIFIC` field with the
28
    /// provided [`TagNumber`].
29
    ///
30
    /// This method has the following behavior which is designed to simplify
31
    /// handling of extension fields, which are denoted in an ASN.1 schema
32
    /// using the `...` ellipsis extension marker:
33
    ///
34
    /// - Skips over [`ContextSpecific`] fields with a tag number lower than
35
    ///   the current one, consuming and ignoring them.
36
    /// - Returns `Ok(None)` if a [`ContextSpecific`] field with a higher tag
37
    ///   number is encountered. These fields are not consumed in this case,
38
    ///   allowing a field with a lower tag number to be omitted, then the
39
    ///   higher numbered field consumed as a follow-up.
40
    /// - Returns `Ok(None)` if anything other than a [`ContextSpecific`] field
41
    ///   is encountered.
42
0
    pub fn decode_explicit<'a, R: Reader<'a>>(
43
0
        reader: &mut R,
44
0
        tag_number: TagNumber,
45
0
    ) -> Result<Option<Self>>
46
0
    where
47
0
        T: Decode<'a>,
48
0
    {
49
0
        Self::decode_with(reader, tag_number, |reader| Self::decode(reader))
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificpE15decode_explicitpE0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificNtNtB7_10bit_string12BitStringRefE15decode_explicitINtNtNtB9_6reader6nested12NestedReaderNtNtB25_5slice11SliceReaderEE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificNtNtB7_10bit_string12BitStringRefE15decode_explicitINtNtNtB9_6reader6nested12NestedReaderNtNtB25_5slice11SliceReaderEE0Csj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersE15decode_explicitINtNtNtB9_6reader6nested12NestedReaderNtNtB2l_5slice11SliceReaderEE0B1f_
50
0
    }
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificpE15decode_explicitpEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtB5_10bit_string12BitStringRefE15decode_explicitINtNtNtB7_6reader6nested12NestedReaderNtNtB23_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersE15decode_explicitINtNtNtB7_6reader6nested12NestedReaderNtNtB2j_5slice11SliceReaderEEB1d_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtB5_10bit_string12BitStringRefE15decode_explicitINtNtNtB7_6reader6nested12NestedReaderNtNtB23_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
51
52
    /// Attempt to decode an `IMPLICIT` ASN.1 `CONTEXT-SPECIFIC` field with the
53
    /// provided [`TagNumber`].
54
    ///
55
    /// This method otherwise behaves the same as `decode_explicit`,
56
    /// but should be used in cases where the particular fields are `IMPLICIT`
57
    /// as opposed to `EXPLICIT`.
58
0
    pub fn decode_implicit<'a, R: Reader<'a>>(
59
0
        reader: &mut R,
60
0
        tag_number: TagNumber,
61
0
    ) -> Result<Option<Self>>
62
0
    where
63
0
        T: DecodeValue<'a> + Tagged,
64
0
    {
65
0
        Self::decode_with(reader, tag_number, |reader| {
66
0
            let header = Header::decode(reader)?;
67
0
            let value = T::decode_value(reader, header)?;
68
69
0
            if header.tag.is_constructed() != value.tag().is_constructed() {
70
0
                return Err(header.tag.non_canonical_error());
71
0
            }
72
0
73
0
            Ok(Self {
74
0
                tag_number,
75
0
                tag_mode: TagMode::Implicit,
76
0
                value,
77
0
            })
78
0
        })
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificpE15decode_implicitpE0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificNtNtB7_10bit_string12BitStringRefE15decode_implicitINtNtNtB9_6reader6nested12NestedReaderNtNtB25_5slice11SliceReaderEE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificNtNtB7_10bit_string12BitStringRefE15decode_implicitINtNtNtB9_6reader6nested12NestedReaderNtNtB25_5slice11SliceReaderEE0Csj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersE15decode_implicitINtNtNtB9_6reader6nested12NestedReaderNtNtB2l_5slice11SliceReaderEE0B1f_
79
0
    }
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificpE15decode_implicitpEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtB5_10bit_string12BitStringRefE15decode_implicitINtNtNtB7_6reader6nested12NestedReaderNtNtB23_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersE15decode_implicitINtNtNtB7_6reader6nested12NestedReaderNtNtB2j_5slice11SliceReaderEEB1d_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtB5_10bit_string12BitStringRefE15decode_implicitINtNtNtB7_6reader6nested12NestedReaderNtNtB23_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
80
81
    /// Attempt to decode a context-specific field with the given
82
    /// helper callback.
83
0
    fn decode_with<'a, F, R: Reader<'a>>(
84
0
        reader: &mut R,
85
0
        tag_number: TagNumber,
86
0
        f: F,
87
0
    ) -> Result<Option<Self>>
88
0
    where
89
0
        F: FnOnce(&mut R) -> Result<Self>,
90
0
    {
91
0
        while let Some(octet) = reader.peek_byte() {
92
0
            let tag = Tag::try_from(octet)?;
93
94
0
            if !tag.is_context_specific() || (tag.number() > tag_number) {
95
0
                break;
96
0
            } else if tag.number() == tag_number {
97
0
                return Some(f(reader)).transpose();
98
            } else {
99
0
                AnyRef::decode(reader)?;
100
            }
101
        }
102
103
0
        Ok(None)
104
0
    }
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificpE11decode_withppEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtB5_10bit_string12BitStringRefE11decode_withNCINvB2_15decode_explicitINtNtNtB7_6reader6nested12NestedReaderNtNtB2o_5slice11SliceReaderEE0B2j_ECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtB5_10bit_string12BitStringRefE11decode_withNCINvB2_15decode_implicitINtNtNtB7_6reader6nested12NestedReaderNtNtB2o_5slice11SliceReaderEE0B2j_ECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtB5_10bit_string12BitStringRefE11decode_withNCINvB2_15decode_explicitINtNtNtB7_6reader6nested12NestedReaderNtNtB2o_5slice11SliceReaderEE0B2j_ECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtB5_10bit_string12BitStringRefE11decode_withNCINvB2_15decode_implicitINtNtNtB7_6reader6nested12NestedReaderNtNtB2o_5slice11SliceReaderEE0B2j_ECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersE11decode_withNCINvB2_15decode_explicitINtNtNtB7_6reader6nested12NestedReaderNtNtB2E_5slice11SliceReaderEE0B2z_EB1d_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116context_specificINtB3_15ContextSpecificNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersE11decode_withNCINvB2_15decode_implicitINtNtNtB7_6reader6nested12NestedReaderNtNtB2E_5slice11SliceReaderEE0B2z_EB1d_
105
}
106
107
impl<'a, T> Choice<'a> for ContextSpecific<T>
108
where
109
    T: Decode<'a> + Tagged,
110
{
111
0
    fn can_decode(tag: Tag) -> bool {
112
0
        tag.is_context_specific()
113
0
    }
114
}
115
116
impl<'a, T> Decode<'a> for ContextSpecific<T>
117
where
118
    T: Decode<'a>,
119
{
120
0
    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self> {
121
0
        let header = Header::decode(reader)?;
122
123
0
        match header.tag {
124
            Tag::ContextSpecific {
125
0
                number,
126
0
                constructed: true,
127
0
            } => Ok(Self {
128
0
                tag_number: number,
129
0
                tag_mode: TagMode::default(),
130
0
                value: reader.read_nested(header.length, |reader| T::decode(reader))?,
Unexecuted instantiation: _RNCINvXININtNtCscrZQdumITES_3der4asn116context_specifics0_0pEINtB8_15ContextSpecificpENtNtBc_6decode6Decode6decodepE0Bc_
Unexecuted instantiation: _RNCINvXs0_NtNtCscrZQdumITES_3der4asn116context_specificINtB8_15ContextSpecificNtNtBa_10bit_string12BitStringRefENtNtBc_6decode6Decode6decodeINtNtNtBc_6reader6nested12NestedReaderNtNtB2j_5slice11SliceReaderEE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvXs0_NtNtCscrZQdumITES_3der4asn116context_specificINtB8_15ContextSpecificNtNtBa_3any6AnyRefENtNtBc_6decode6Decode6decodeINtNtNtBc_6reader6nested12NestedReaderNtNtB24_5slice11SliceReaderEE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvXs0_NtNtCscrZQdumITES_3der4asn116context_specificINtB8_15ContextSpecificNtNtBa_10bit_string12BitStringRefENtNtBc_6decode6Decode6decodeINtNtNtBc_6reader6nested12NestedReaderNtNtB2j_5slice11SliceReaderEE0Csj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNCINvXs0_NtNtCscrZQdumITES_3der4asn116context_specificINtB8_15ContextSpecificNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtNtBc_6decode6Decode6decodeINtNtNtBc_6reader6nested12NestedReaderNtNtB2z_5slice11SliceReaderEE0B1i_
131
            }),
132
0
            tag => Err(tag.unexpected_error(None)),
133
        }
134
0
    }
Unexecuted instantiation: _RINvXININtNtCscrZQdumITES_3der4asn116context_specifics0_0pEINtB6_15ContextSpecificpENtNtBa_6decode6Decode6decodepEBa_
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn116context_specificINtB6_15ContextSpecificNtNtB8_10bit_string12BitStringRefENtNtBa_6decode6Decode6decodeINtNtNtBa_6reader6nested12NestedReaderNtNtB2h_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn116context_specificINtB6_15ContextSpecificNtNtB8_3any6AnyRefENtNtBa_6decode6Decode6decodeINtNtNtBa_6reader6nested12NestedReaderNtNtB22_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn116context_specificINtB6_15ContextSpecificNtNtB8_10bit_string12BitStringRefENtNtBa_6decode6Decode6decodeINtNtNtBa_6reader6nested12NestedReaderNtNtB2h_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn116context_specificINtB6_15ContextSpecificNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtNtBa_6decode6Decode6decodeINtNtNtBa_6reader6nested12NestedReaderNtNtB2x_5slice11SliceReaderEEB1g_
135
}
136
137
impl<T> EncodeValue for ContextSpecific<T>
138
where
139
    T: EncodeValue + Tagged,
140
{
141
0
    fn value_len(&self) -> Result<Length> {
142
0
        match self.tag_mode {
143
0
            TagMode::Explicit => self.value.encoded_len(),
144
0
            TagMode::Implicit => self.value.value_len(),
145
        }
146
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der4asn116context_specifics1_0pEINtB5_15ContextSpecificpENtNtB9_6encode11EncodeValue9value_lenB9_
Unexecuted instantiation: _RNvXs1_NtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificNtNtB7_10bit_string12BitStringRefENtNtB9_6encode11EncodeValue9value_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs1_NtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificINtNtB9_10encode_ref14EncodeValueRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersEENtNtB9_6encode11EncodeValue9value_lenB1P_
Unexecuted instantiation: _RNvXs1_NtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificNtNtB7_10bit_string12BitStringRefENtNtB9_6encode11EncodeValue9value_lenCsj9qtwLkMHqH_4sec1
147
148
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
149
0
        match self.tag_mode {
150
0
            TagMode::Explicit => self.value.encode(writer),
151
0
            TagMode::Implicit => self.value.encode_value(writer),
152
        }
153
0
    }
Unexecuted instantiation: _RINvXININtNtCscrZQdumITES_3der4asn116context_specifics1_0pEINtB6_15ContextSpecificpENtNtBa_6encode11EncodeValue12encode_valuepEBa_
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn116context_specificINtB6_15ContextSpecificNtNtB8_10bit_string12BitStringRefENtNtBa_6encode11EncodeValue12encode_valueNtNtNtBa_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn116context_specificINtB6_15ContextSpecificINtNtBa_10encode_ref14EncodeValueRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersEENtNtBa_6encode11EncodeValue12encode_valueNtNtNtBa_6writer5slice11SliceWriterEB1Q_
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn116context_specificINtB6_15ContextSpecificNtNtB8_10bit_string12BitStringRefENtNtBa_6encode11EncodeValue12encode_valueNtNtNtBa_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
154
}
155
156
impl<T> Tagged for ContextSpecific<T>
157
where
158
    T: Tagged,
159
{
160
0
    fn tag(&self) -> Tag {
161
0
        let constructed = match self.tag_mode {
162
0
            TagMode::Explicit => true,
163
0
            TagMode::Implicit => self.value.tag().is_constructed(),
164
        };
165
166
0
        Tag::ContextSpecific {
167
0
            number: self.tag_number,
168
0
            constructed,
169
0
        }
170
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der4asn116context_specifics2_0pEINtB5_15ContextSpecificpENtNtB9_3tag6Tagged3tagB9_
Unexecuted instantiation: _RNvXs2_NtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificNtNtB7_10bit_string12BitStringRefENtNtB9_3tag6Tagged3tagCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs2_NtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificINtNtB9_10encode_ref14EncodeValueRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersEENtNtB9_3tag6Tagged3tagB1P_
Unexecuted instantiation: _RNvXs2_NtNtCscrZQdumITES_3der4asn116context_specificINtB5_15ContextSpecificNtNtB7_10bit_string12BitStringRefENtNtB9_3tag6Tagged3tagCsj9qtwLkMHqH_4sec1
171
}
172
173
impl<'a, T> TryFrom<AnyRef<'a>> for ContextSpecific<T>
174
where
175
    T: Decode<'a>,
176
{
177
    type Error = Error;
178
179
0
    fn try_from(any: AnyRef<'a>) -> Result<ContextSpecific<T>> {
180
0
        match any.tag() {
181
            Tag::ContextSpecific {
182
0
                number,
183
0
                constructed: true,
184
0
            } => Ok(Self {
185
0
                tag_number: number,
186
0
                tag_mode: TagMode::default(),
187
0
                value: T::from_der(any.value())?,
188
            }),
189
0
            tag => Err(tag.unexpected_error(None)),
190
        }
191
0
    }
192
}
193
194
impl<T> ValueOrd for ContextSpecific<T>
195
where
196
    T: EncodeValue + ValueOrd + Tagged,
197
{
198
0
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
199
0
        match self.tag_mode {
200
0
            TagMode::Explicit => self.der_cmp(other),
201
0
            TagMode::Implicit => self.value_cmp(other),
202
        }
203
0
    }
204
}
205
206
/// Context-specific field reference.
207
///
208
/// This type encodes a field which is specific to a particular context
209
/// and is identified by a [`TagNumber`].
210
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
211
pub struct ContextSpecificRef<'a, T> {
212
    /// Context-specific tag number sans the leading `0b10000000` class
213
    /// identifier bit and `0b100000` constructed flag.
214
    pub tag_number: TagNumber,
215
216
    /// Tag mode: `EXPLICIT` VS `IMPLICIT`.
217
    pub tag_mode: TagMode,
218
219
    /// Value of the field.
220
    pub value: &'a T,
221
}
222
223
impl<'a, T> ContextSpecificRef<'a, T> {
224
    /// Convert to a [`ContextSpecific`].
225
0
    fn encoder(&self) -> ContextSpecific<EncodeValueRef<'a, T>> {
226
0
        ContextSpecific {
227
0
            tag_number: self.tag_number,
228
0
            tag_mode: self.tag_mode,
229
0
            value: EncodeValueRef(self.value),
230
0
        }
231
0
    }
Unexecuted instantiation: _RNvMs5_NtNtCscrZQdumITES_3der4asn116context_specificINtB5_18ContextSpecificRefpE7encoderB9_
Unexecuted instantiation: _RNvMs5_NtNtCscrZQdumITES_3der4asn116context_specificINtB5_18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersE7encoderB1i_
232
}
233
234
impl<'a, T> EncodeValue for ContextSpecificRef<'a, T>
235
where
236
    T: EncodeValue + Tagged,
237
{
238
0
    fn value_len(&self) -> Result<Length> {
239
0
        self.encoder().value_len()
240
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der4asn116context_specifics6_0pEINtB5_18ContextSpecificRefpENtNtB9_6encode11EncodeValue9value_lenB9_
Unexecuted instantiation: _RNvXs6_NtNtCscrZQdumITES_3der4asn116context_specificINtB5_18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtNtB9_6encode11EncodeValue9value_lenB1i_
241
242
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
243
0
        self.encoder().encode_value(writer)
244
0
    }
Unexecuted instantiation: _RINvXININtNtCscrZQdumITES_3der4asn116context_specifics6_0pEINtB6_18ContextSpecificRefpENtNtBa_6encode11EncodeValue12encode_valuepEBa_
Unexecuted instantiation: _RINvXs6_NtNtCscrZQdumITES_3der4asn116context_specificINtB6_18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtNtBa_6encode11EncodeValue12encode_valueNtNtNtBa_6writer5slice11SliceWriterEB1j_
245
}
246
247
impl<'a, T> Tagged for ContextSpecificRef<'a, T>
248
where
249
    T: Tagged,
250
{
251
0
    fn tag(&self) -> Tag {
252
0
        self.encoder().tag()
253
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der4asn116context_specifics7_0pEINtB5_18ContextSpecificRefpENtNtB9_3tag6Tagged3tagB9_
Unexecuted instantiation: _RNvXs7_NtNtCscrZQdumITES_3der4asn116context_specificINtB5_18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtNtB9_3tag6Tagged3tagB1i_
254
}
255
256
#[cfg(test)]
257
mod tests {
258
    use super::ContextSpecific;
259
    use crate::{asn1::BitStringRef, Decode, Encode, SliceReader, TagMode, TagNumber};
260
    use hex_literal::hex;
261
262
    // Public key data from `pkcs8` crate's `ed25519-pkcs8-v2.der`
263
    const EXAMPLE_BYTES: &[u8] =
264
        &hex!("A123032100A3A7EAE3A8373830BC47E1167BC50E1DB551999651E0E2DC587623438EAC3F31");
265
266
    #[test]
267
    fn round_trip() {
268
        let field = ContextSpecific::<BitStringRef<'_>>::from_der(EXAMPLE_BYTES).unwrap();
269
        assert_eq!(field.tag_number.value(), 1);
270
        assert_eq!(
271
            field.value,
272
            BitStringRef::from_bytes(&EXAMPLE_BYTES[5..]).unwrap()
273
        );
274
275
        let mut buf = [0u8; 128];
276
        let encoded = field.encode_to_slice(&mut buf).unwrap();
277
        assert_eq!(encoded, EXAMPLE_BYTES);
278
    }
279
280
    #[test]
281
    fn context_specific_with_explicit_field() {
282
        let tag_number = TagNumber::new(0);
283
284
        // Empty message
285
        let mut reader = SliceReader::new(&[]).unwrap();
286
        assert_eq!(
287
            ContextSpecific::<u8>::decode_explicit(&mut reader, tag_number).unwrap(),
288
            None
289
        );
290
291
        // Message containing a non-context-specific type
292
        let mut reader = SliceReader::new(&hex!("020100")).unwrap();
293
        assert_eq!(
294
            ContextSpecific::<u8>::decode_explicit(&mut reader, tag_number).unwrap(),
295
            None
296
        );
297
298
        // Message containing an EXPLICIT context-specific field
299
        let mut reader = SliceReader::new(&hex!("A003020100")).unwrap();
300
        let field = ContextSpecific::<u8>::decode_explicit(&mut reader, tag_number)
301
            .unwrap()
302
            .unwrap();
303
304
        assert_eq!(field.tag_number, tag_number);
305
        assert_eq!(field.tag_mode, TagMode::Explicit);
306
        assert_eq!(field.value, 0);
307
    }
308
309
    #[test]
310
    fn context_specific_with_implicit_field() {
311
        // From RFC8410 Section 10.3:
312
        // <https://datatracker.ietf.org/doc/html/rfc8410#section-10.3>
313
        //
314
        //    81  33:   [1] 00 19 BF 44 09 69 84 CD FE 85 41 BA C1 67 DC 3B
315
        //                  96 C8 50 86 AA 30 B6 B6 CB 0C 5C 38 AD 70 31 66
316
        //                  E1
317
        let context_specific_implicit_bytes =
318
            hex!("81210019BF44096984CDFE8541BAC167DC3B96C85086AA30B6B6CB0C5C38AD703166E1");
319
320
        let tag_number = TagNumber::new(1);
321
322
        let mut reader = SliceReader::new(&context_specific_implicit_bytes).unwrap();
323
        let field = ContextSpecific::<BitStringRef<'_>>::decode_implicit(&mut reader, tag_number)
324
            .unwrap()
325
            .unwrap();
326
327
        assert_eq!(field.tag_number, tag_number);
328
        assert_eq!(field.tag_mode, TagMode::Implicit);
329
        assert_eq!(
330
            field.value.as_bytes().unwrap(),
331
            &context_specific_implicit_bytes[3..]
332
        );
333
    }
334
335
    #[test]
336
    fn context_specific_skipping_unknown_field() {
337
        let tag = TagNumber::new(1);
338
        let mut reader = SliceReader::new(&hex!("A003020100A103020101")).unwrap();
339
        let field = ContextSpecific::<u8>::decode_explicit(&mut reader, tag)
340
            .unwrap()
341
            .unwrap();
342
        assert_eq!(field.value, 1);
343
    }
344
345
    #[test]
346
    fn context_specific_returns_none_on_greater_tag_number() {
347
        let tag = TagNumber::new(0);
348
        let mut reader = SliceReader::new(&hex!("A103020101")).unwrap();
349
        assert_eq!(
350
            ContextSpecific::<u8>::decode_explicit(&mut reader, tag).unwrap(),
351
            None
352
        );
353
    }
354
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/generalized_time.rs
Line
Count
Source
1
//! ASN.1 `GeneralizedTime` support.
2
#![cfg_attr(feature = "arbitrary", allow(clippy::integer_arithmetic))]
3
4
use crate::{
5
    datetime::{self, DateTime},
6
    ord::OrdIsValueOrd,
7
    DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result, Tag, Writer,
8
};
9
use core::time::Duration;
10
11
#[cfg(feature = "std")]
12
use {
13
    crate::{asn1::AnyRef, Error},
14
    std::time::SystemTime,
15
};
16
17
#[cfg(feature = "time")]
18
use time::PrimitiveDateTime;
19
20
/// ASN.1 `GeneralizedTime` type.
21
///
22
/// This type implements the validity requirements specified in
23
/// [RFC 5280 Section 4.1.2.5.2][1], namely:
24
///
25
/// > For the purposes of this profile, GeneralizedTime values MUST be
26
/// > expressed in Greenwich Mean Time (Zulu) and MUST include seconds
27
/// > (i.e., times are `YYYYMMDDHHMMSSZ`), even where the number of seconds
28
/// > is zero.  GeneralizedTime values MUST NOT include fractional seconds.
29
///
30
/// [1]: https://tools.ietf.org/html/rfc5280#section-4.1.2.5.2
31
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
32
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
33
pub struct GeneralizedTime(DateTime);
34
35
impl GeneralizedTime {
36
    /// Length of an RFC 5280-flavored ASN.1 DER-encoded [`GeneralizedTime`].
37
    const LENGTH: usize = 15;
38
39
    /// Create a [`GeneralizedTime`] from a [`DateTime`].
40
0
    pub const fn from_date_time(datetime: DateTime) -> Self {
41
0
        Self(datetime)
42
0
    }
43
44
    /// Convert this [`GeneralizedTime`] into a [`DateTime`].
45
0
    pub fn to_date_time(&self) -> DateTime {
46
0
        self.0
47
0
    }
48
49
    /// Create a new [`GeneralizedTime`] given a [`Duration`] since `UNIX_EPOCH`
50
    /// (a.k.a. "Unix time")
51
0
    pub fn from_unix_duration(unix_duration: Duration) -> Result<Self> {
52
0
        DateTime::from_unix_duration(unix_duration)
53
0
            .map(Into::into)
54
0
            .map_err(|_| Self::TAG.value_error())
55
0
    }
56
57
    /// Get the duration of this timestamp since `UNIX_EPOCH`.
58
0
    pub fn to_unix_duration(&self) -> Duration {
59
0
        self.0.unix_duration()
60
0
    }
61
62
    /// Instantiate from [`SystemTime`].
63
    #[cfg(feature = "std")]
64
0
    pub fn from_system_time(time: SystemTime) -> Result<Self> {
65
0
        DateTime::try_from(time)
66
0
            .map(Into::into)
67
0
            .map_err(|_| Self::TAG.value_error())
68
0
    }
69
70
    /// Convert to [`SystemTime`].
71
    #[cfg(feature = "std")]
72
0
    pub fn to_system_time(&self) -> SystemTime {
73
0
        self.0.to_system_time()
74
0
    }
75
}
76
77
impl_any_conversions!(GeneralizedTime);
78
79
impl<'a> DecodeValue<'a> for GeneralizedTime {
80
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
81
0
        if Self::LENGTH != usize::try_from(header.length)? {
82
0
            return Err(Self::TAG.value_error());
83
0
        }
84
0
85
0
        let mut bytes = [0u8; Self::LENGTH];
86
0
        reader.read_into(&mut bytes)?;
87
88
0
        match bytes {
89
            // RFC 5280 requires mandatory seconds and Z-normalized time zone
90
0
            [y1, y2, y3, y4, mon1, mon2, day1, day2, hour1, hour2, min1, min2, sec1, sec2, b'Z'] => {
91
0
                let year = u16::from(datetime::decode_decimal(Self::TAG, y1, y2)?)
92
0
                    .checked_mul(100)
93
0
                    .and_then(|y| {
94
0
                        y.checked_add(datetime::decode_decimal(Self::TAG, y3, y4).ok()?.into())
95
0
                    })
96
0
                    .ok_or(ErrorKind::DateTime)?;
97
0
                let month = datetime::decode_decimal(Self::TAG, mon1, mon2)?;
98
0
                let day = datetime::decode_decimal(Self::TAG, day1, day2)?;
99
0
                let hour = datetime::decode_decimal(Self::TAG, hour1, hour2)?;
100
0
                let minute = datetime::decode_decimal(Self::TAG, min1, min2)?;
101
0
                let second = datetime::decode_decimal(Self::TAG, sec1, sec2)?;
102
103
0
                DateTime::new(year, month, day, hour, minute, second)
104
0
                    .map_err(|_| Self::TAG.value_error())
105
0
                    .and_then(|dt| Self::from_unix_duration(dt.unix_duration()))
106
            }
107
0
            _ => Err(Self::TAG.value_error()),
108
        }
109
0
    }
110
}
111
112
impl EncodeValue for GeneralizedTime {
113
0
    fn value_len(&self) -> Result<Length> {
114
0
        Self::LENGTH.try_into()
115
0
    }
116
117
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
118
0
        let year_hi = u8::try_from(self.0.year() / 100)?;
119
0
        let year_lo = u8::try_from(self.0.year() % 100)?;
120
121
0
        datetime::encode_decimal(writer, Self::TAG, year_hi)?;
122
0
        datetime::encode_decimal(writer, Self::TAG, year_lo)?;
123
0
        datetime::encode_decimal(writer, Self::TAG, self.0.month())?;
124
0
        datetime::encode_decimal(writer, Self::TAG, self.0.day())?;
125
0
        datetime::encode_decimal(writer, Self::TAG, self.0.hour())?;
126
0
        datetime::encode_decimal(writer, Self::TAG, self.0.minutes())?;
127
0
        datetime::encode_decimal(writer, Self::TAG, self.0.seconds())?;
128
0
        writer.write_byte(b'Z')
129
0
    }
130
}
131
132
impl FixedTag for GeneralizedTime {
133
    const TAG: Tag = Tag::GeneralizedTime;
134
}
135
136
impl OrdIsValueOrd for GeneralizedTime {}
137
138
impl From<&GeneralizedTime> for GeneralizedTime {
139
0
    fn from(value: &GeneralizedTime) -> GeneralizedTime {
140
0
        *value
141
0
    }
142
}
143
144
impl From<GeneralizedTime> for DateTime {
145
0
    fn from(utc_time: GeneralizedTime) -> DateTime {
146
0
        utc_time.0
147
0
    }
148
}
149
150
impl From<&GeneralizedTime> for DateTime {
151
0
    fn from(utc_time: &GeneralizedTime) -> DateTime {
152
0
        utc_time.0
153
0
    }
154
}
155
156
impl From<DateTime> for GeneralizedTime {
157
0
    fn from(datetime: DateTime) -> Self {
158
0
        Self::from_date_time(datetime)
159
0
    }
160
}
161
162
impl From<&DateTime> for GeneralizedTime {
163
0
    fn from(datetime: &DateTime) -> Self {
164
0
        Self::from_date_time(*datetime)
165
0
    }
166
}
167
168
impl<'a> DecodeValue<'a> for DateTime {
169
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
170
0
        Ok(GeneralizedTime::decode_value(reader, header)?.into())
171
0
    }
172
}
173
174
impl EncodeValue for DateTime {
175
0
    fn value_len(&self) -> Result<Length> {
176
0
        GeneralizedTime::from(self).value_len()
177
0
    }
178
179
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
180
0
        GeneralizedTime::from(self).encode_value(writer)
181
0
    }
182
}
183
184
impl FixedTag for DateTime {
185
    const TAG: Tag = Tag::GeneralizedTime;
186
}
187
188
impl OrdIsValueOrd for DateTime {}
189
190
#[cfg(feature = "std")]
191
impl<'a> DecodeValue<'a> for SystemTime {
192
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
193
0
        Ok(GeneralizedTime::decode_value(reader, header)?.into())
194
0
    }
195
}
196
197
#[cfg(feature = "std")]
198
impl EncodeValue for SystemTime {
199
0
    fn value_len(&self) -> Result<Length> {
200
0
        GeneralizedTime::try_from(self)?.value_len()
201
0
    }
202
203
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
204
0
        GeneralizedTime::try_from(self)?.encode_value(writer)
205
0
    }
206
}
207
208
#[cfg(feature = "std")]
209
impl From<GeneralizedTime> for SystemTime {
210
0
    fn from(time: GeneralizedTime) -> SystemTime {
211
0
        time.to_system_time()
212
0
    }
213
}
214
215
#[cfg(feature = "std")]
216
impl From<&GeneralizedTime> for SystemTime {
217
0
    fn from(time: &GeneralizedTime) -> SystemTime {
218
0
        time.to_system_time()
219
0
    }
220
}
221
222
#[cfg(feature = "std")]
223
impl TryFrom<SystemTime> for GeneralizedTime {
224
    type Error = Error;
225
226
0
    fn try_from(time: SystemTime) -> Result<GeneralizedTime> {
227
0
        GeneralizedTime::from_system_time(time)
228
0
    }
229
}
230
231
#[cfg(feature = "std")]
232
impl TryFrom<&SystemTime> for GeneralizedTime {
233
    type Error = Error;
234
235
0
    fn try_from(time: &SystemTime) -> Result<GeneralizedTime> {
236
0
        GeneralizedTime::from_system_time(*time)
237
0
    }
238
}
239
240
#[cfg(feature = "std")]
241
impl<'a> TryFrom<AnyRef<'a>> for SystemTime {
242
    type Error = Error;
243
244
0
    fn try_from(any: AnyRef<'a>) -> Result<SystemTime> {
245
0
        GeneralizedTime::try_from(any).map(|s| s.to_system_time())
246
0
    }
247
}
248
249
#[cfg(feature = "std")]
250
impl FixedTag for SystemTime {
251
    const TAG: Tag = Tag::GeneralizedTime;
252
}
253
254
#[cfg(feature = "std")]
255
impl OrdIsValueOrd for SystemTime {}
256
257
#[cfg(feature = "time")]
258
impl<'a> DecodeValue<'a> for PrimitiveDateTime {
259
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
260
        GeneralizedTime::decode_value(reader, header)?.try_into()
261
    }
262
}
263
264
#[cfg(feature = "time")]
265
impl EncodeValue for PrimitiveDateTime {
266
    fn value_len(&self) -> Result<Length> {
267
        GeneralizedTime::try_from(self)?.value_len()
268
    }
269
270
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
271
        GeneralizedTime::try_from(self)?.encode_value(writer)
272
    }
273
}
274
275
#[cfg(feature = "time")]
276
impl FixedTag for PrimitiveDateTime {
277
    const TAG: Tag = Tag::GeneralizedTime;
278
}
279
280
#[cfg(feature = "time")]
281
impl OrdIsValueOrd for PrimitiveDateTime {}
282
283
#[cfg(feature = "time")]
284
impl TryFrom<PrimitiveDateTime> for GeneralizedTime {
285
    type Error = Error;
286
287
    fn try_from(time: PrimitiveDateTime) -> Result<GeneralizedTime> {
288
        Ok(GeneralizedTime::from_date_time(DateTime::try_from(time)?))
289
    }
290
}
291
292
#[cfg(feature = "time")]
293
impl TryFrom<&PrimitiveDateTime> for GeneralizedTime {
294
    type Error = Error;
295
296
    fn try_from(time: &PrimitiveDateTime) -> Result<GeneralizedTime> {
297
        Self::try_from(*time)
298
    }
299
}
300
301
#[cfg(feature = "time")]
302
impl TryFrom<GeneralizedTime> for PrimitiveDateTime {
303
    type Error = Error;
304
305
    fn try_from(time: GeneralizedTime) -> Result<PrimitiveDateTime> {
306
        time.to_date_time().try_into()
307
    }
308
}
309
310
#[cfg(test)]
311
mod tests {
312
    use super::GeneralizedTime;
313
    use crate::{Decode, Encode, SliceWriter};
314
    use hex_literal::hex;
315
316
    #[test]
317
    fn round_trip() {
318
        let example_bytes = hex!("18 0f 31 39 39 31 30 35 30 36 32 33 34 35 34 30 5a");
319
        let utc_time = GeneralizedTime::from_der(&example_bytes).unwrap();
320
        assert_eq!(utc_time.to_unix_duration().as_secs(), 673573540);
321
322
        let mut buf = [0u8; 128];
323
        let mut encoder = SliceWriter::new(&mut buf);
324
        utc_time.encode(&mut encoder).unwrap();
325
        assert_eq!(example_bytes, encoder.finish().unwrap());
326
    }
327
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/ia5_string.rs
Line
Count
Source
1
//! ASN.1 `IA5String` support.
2
3
use crate::{asn1::AnyRef, FixedTag, Result, StrRef, Tag};
4
use core::{fmt, ops::Deref};
5
6
macro_rules! impl_ia5_string {
7
    ($type: ty) => {
8
        impl_ia5_string!($type,);
9
    };
10
    ($type: ty, $($li: lifetime)?) => {
11
        impl_string_type!($type, $($li),*);
12
13
        impl<$($li),*> FixedTag for $type {
14
            const TAG: Tag = Tag::Ia5String;
15
        }
16
17
        impl<$($li),*> fmt::Debug for $type {
18
0
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19
0
                write!(f, "Ia5String({:?})", self.as_str())
20
0
            }
Unexecuted instantiation: _RNvXsa_NtNtCscrZQdumITES_3der4asn110ia5_stringNtB5_12Ia5StringRefNtNtCsbQ8arDwx5Xq_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsc_NtNtNtCscrZQdumITES_3der4asn110ia5_string10allocationNtB5_9Ia5StringNtNtCsbQ8arDwx5Xq_4core3fmt5Debug3fmt
21
        }
22
    };
23
}
24
25
/// ASN.1 `IA5String` type.
26
///
27
/// Supports the [International Alphabet No. 5 (IA5)] character encoding, i.e.
28
/// the lower 128 characters of the ASCII alphabet. (Note: IA5 is now
29
/// technically known as the International Reference Alphabet or IRA as
30
/// specified in the ITU-T's T.50 recommendation).
31
///
32
/// For UTF-8, use [`Utf8StringRef`][`crate::asn1::Utf8StringRef`].
33
///
34
/// This is a zero-copy reference type which borrows from the input data.
35
///
36
/// [International Alphabet No. 5 (IA5)]: https://en.wikipedia.org/wiki/T.50_%28standard%29
37
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
38
pub struct Ia5StringRef<'a> {
39
    /// Inner value
40
    inner: StrRef<'a>,
41
}
42
43
impl<'a> Ia5StringRef<'a> {
44
    /// Create a new `IA5String`.
45
0
    pub fn new<T>(input: &'a T) -> Result<Self>
46
0
    where
47
0
        T: AsRef<[u8]> + ?Sized,
48
0
    {
49
0
        let input = input.as_ref();
50
0
51
0
        // Validate all characters are within IA5String's allowed set
52
0
        if input.iter().any(|&c| c > 0x7F) {
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn110ia5_stringNtB5_12Ia5StringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringE0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn110ia5_stringNtB5_12Ia5StringRef3newShE0B9_
53
0
            return Err(Self::TAG.value_error());
54
0
        }
55
0
56
0
        StrRef::from_bytes(input)
57
0
            .map(|inner| Self { inner })
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn110ia5_stringNtB5_12Ia5StringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringEs_0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn110ia5_stringNtB5_12Ia5StringRef3newShEs_0B9_
58
0
            .map_err(|_| Self::TAG.value_error())
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn110ia5_stringNtB5_12Ia5StringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringEs0_0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn110ia5_stringNtB5_12Ia5StringRef3newShEs0_0B9_
59
0
    }
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn110ia5_stringNtB3_12Ia5StringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn110ia5_stringNtB3_12Ia5StringRef3newShEB7_
60
}
61
62
impl_ia5_string!(Ia5StringRef<'a>, 'a);
63
64
impl<'a> Deref for Ia5StringRef<'a> {
65
    type Target = StrRef<'a>;
66
67
0
    fn deref(&self) -> &Self::Target {
68
0
        &self.inner
69
0
    }
70
}
71
72
impl<'a> From<&Ia5StringRef<'a>> for Ia5StringRef<'a> {
73
0
    fn from(value: &Ia5StringRef<'a>) -> Ia5StringRef<'a> {
74
0
        *value
75
0
    }
76
}
77
78
impl<'a> From<Ia5StringRef<'a>> for AnyRef<'a> {
79
0
    fn from(internationalized_string: Ia5StringRef<'a>) -> AnyRef<'a> {
80
0
        AnyRef::from_tag_and_value(Tag::Ia5String, internationalized_string.inner.into())
81
0
    }
82
}
83
84
#[cfg(feature = "alloc")]
85
pub use self::allocation::Ia5String;
86
87
#[cfg(feature = "alloc")]
88
mod allocation {
89
    use super::Ia5StringRef;
90
    use crate::{
91
        asn1::AnyRef,
92
        referenced::{OwnedToRef, RefToOwned},
93
        Error, FixedTag, Result, StrOwned, Tag,
94
    };
95
    use alloc::string::String;
96
    use core::{fmt, ops::Deref};
97
98
    /// ASN.1 `IA5String` type.
99
    ///
100
    /// Supports the [International Alphabet No. 5 (IA5)] character encoding, i.e.
101
    /// the lower 128 characters of the ASCII alphabet. (Note: IA5 is now
102
    /// technically known as the International Reference Alphabet or IRA as
103
    /// specified in the ITU-T's T.50 recommendation).
104
    ///
105
    /// For UTF-8, use [`String`][`alloc::string::String`].
106
    ///
107
    /// [International Alphabet No. 5 (IA5)]: https://en.wikipedia.org/wiki/T.50_%28standard%29
108
    #[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
109
    pub struct Ia5String {
110
        /// Inner value
111
        inner: StrOwned,
112
    }
113
114
    impl Ia5String {
115
        /// Create a new `IA5String`.
116
0
        pub fn new<T>(input: &T) -> Result<Self>
117
0
        where
118
0
            T: AsRef<[u8]> + ?Sized,
119
0
        {
120
0
            let input = input.as_ref();
121
0
            Ia5StringRef::new(input)?;
122
123
0
            StrOwned::from_bytes(input)
124
0
                .map(|inner| Self { inner })
125
0
                .map_err(|_| Self::TAG.value_error())
126
0
        }
127
    }
128
129
    impl_ia5_string!(Ia5String);
130
131
    impl Deref for Ia5String {
132
        type Target = StrOwned;
133
134
0
        fn deref(&self) -> &Self::Target {
135
0
            &self.inner
136
0
        }
137
    }
138
139
    impl<'a> From<Ia5StringRef<'a>> for Ia5String {
140
0
        fn from(international_string: Ia5StringRef<'a>) -> Ia5String {
141
0
            let inner = international_string.inner.into();
142
0
            Self { inner }
143
0
        }
144
    }
145
146
    impl<'a> From<&'a Ia5String> for AnyRef<'a> {
147
0
        fn from(international_string: &'a Ia5String) -> AnyRef<'a> {
148
0
            AnyRef::from_tag_and_value(Tag::Ia5String, (&international_string.inner).into())
149
0
        }
150
    }
151
152
    impl<'a> RefToOwned<'a> for Ia5StringRef<'a> {
153
        type Owned = Ia5String;
154
0
        fn ref_to_owned(&self) -> Self::Owned {
155
0
            Ia5String {
156
0
                inner: self.inner.ref_to_owned(),
157
0
            }
158
0
        }
159
    }
160
161
    impl OwnedToRef for Ia5String {
162
        type Borrowed<'a> = Ia5StringRef<'a>;
163
0
        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
164
0
            Ia5StringRef {
165
0
                inner: self.inner.owned_to_ref(),
166
0
            }
167
0
        }
168
    }
169
170
    impl TryFrom<String> for Ia5String {
171
        type Error = Error;
172
173
0
        fn try_from(input: String) -> Result<Self> {
174
0
            Ia5StringRef::new(&input)?;
175
176
0
            StrOwned::new(input)
177
0
                .map(|inner| Self { inner })
178
0
                .map_err(|_| Self::TAG.value_error())
179
0
        }
180
    }
181
}
182
183
#[cfg(test)]
184
mod tests {
185
    use super::Ia5StringRef;
186
    use crate::Decode;
187
    use hex_literal::hex;
188
189
    #[test]
190
    fn parse_bytes() {
191
        let example_bytes = hex!("16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d");
192
        let internationalized_string = Ia5StringRef::from_der(&example_bytes).unwrap();
193
        assert_eq!(internationalized_string.as_str(), "test1@rsa.com");
194
    }
195
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/integer.rs
Line
Count
Source
1
//! ASN.1 `INTEGER` support.
2
3
pub(super) mod int;
4
pub(super) mod uint;
5
6
use core::{cmp::Ordering, mem};
7
8
use crate::{EncodeValue, Result, SliceWriter};
9
10
/// Is the highest bit of the first byte in the slice set to `1`? (if present)
11
#[inline]
12
0
fn is_highest_bit_set(bytes: &[u8]) -> bool {
13
0
    bytes
14
0
        .first()
15
0
        .map(|byte| byte & 0b10000000 != 0)
16
0
        .unwrap_or(false)
17
0
}
18
19
/// Compare two integer values
20
0
fn value_cmp<T>(a: T, b: T) -> Result<Ordering>
21
0
where
22
0
    T: Copy + EncodeValue + Sized,
23
0
{
24
    const MAX_INT_SIZE: usize = 16;
25
0
    debug_assert!(mem::size_of::<T>() <= MAX_INT_SIZE);
26
27
0
    let mut buf1 = [0u8; MAX_INT_SIZE];
28
0
    let mut encoder1 = SliceWriter::new(&mut buf1);
29
0
    a.encode_value(&mut encoder1)?;
30
31
0
    let mut buf2 = [0u8; MAX_INT_SIZE];
32
0
    let mut encoder2 = SliceWriter::new(&mut buf2);
33
0
    b.encode_value(&mut encoder2)?;
34
35
0
    Ok(encoder1.finish()?.cmp(encoder2.finish()?))
36
0
}
Unexecuted instantiation: _RINvNtNtCscrZQdumITES_3der4asn17integer9value_cmpaEB6_
Unexecuted instantiation: _RINvNtNtCscrZQdumITES_3der4asn17integer9value_cmphEB6_
Unexecuted instantiation: _RINvNtNtCscrZQdumITES_3der4asn17integer9value_cmplEB6_
Unexecuted instantiation: _RINvNtNtCscrZQdumITES_3der4asn17integer9value_cmpmEB6_
Unexecuted instantiation: _RINvNtNtCscrZQdumITES_3der4asn17integer9value_cmpnEB6_
Unexecuted instantiation: _RINvNtNtCscrZQdumITES_3der4asn17integer9value_cmpoEB6_
Unexecuted instantiation: _RINvNtNtCscrZQdumITES_3der4asn17integer9value_cmpsEB6_
Unexecuted instantiation: _RINvNtNtCscrZQdumITES_3der4asn17integer9value_cmptEB6_
Unexecuted instantiation: _RINvNtNtCscrZQdumITES_3der4asn17integer9value_cmpxEB6_
Unexecuted instantiation: _RINvNtNtCscrZQdumITES_3der4asn17integer9value_cmpyEB6_
37
38
#[cfg(test)]
39
pub(crate) mod tests {
40
    use crate::{Decode, Encode};
41
42
    // Vectors from Section 5.7 of:
43
    // https://luca.ntop.org/Teaching/Appunti/asn1.html
44
    pub(crate) const I0_BYTES: &[u8] = &[0x02, 0x01, 0x00];
45
    pub(crate) const I127_BYTES: &[u8] = &[0x02, 0x01, 0x7F];
46
    pub(crate) const I128_BYTES: &[u8] = &[0x02, 0x02, 0x00, 0x80];
47
    pub(crate) const I256_BYTES: &[u8] = &[0x02, 0x02, 0x01, 0x00];
48
    pub(crate) const INEG128_BYTES: &[u8] = &[0x02, 0x01, 0x80];
49
    pub(crate) const INEG129_BYTES: &[u8] = &[0x02, 0x02, 0xFF, 0x7F];
50
51
    // Additional vectors
52
    pub(crate) const I255_BYTES: &[u8] = &[0x02, 0x02, 0x00, 0xFF];
53
    pub(crate) const I32767_BYTES: &[u8] = &[0x02, 0x02, 0x7F, 0xFF];
54
    pub(crate) const I65535_BYTES: &[u8] = &[0x02, 0x03, 0x00, 0xFF, 0xFF];
55
    pub(crate) const INEG32768_BYTES: &[u8] = &[0x02, 0x02, 0x80, 0x00];
56
57
    #[test]
58
    fn decode_i8() {
59
        assert_eq!(0, i8::from_der(I0_BYTES).unwrap());
60
        assert_eq!(127, i8::from_der(I127_BYTES).unwrap());
61
        assert_eq!(-128, i8::from_der(INEG128_BYTES).unwrap());
62
    }
63
64
    #[test]
65
    fn decode_i16() {
66
        assert_eq!(0, i16::from_der(I0_BYTES).unwrap());
67
        assert_eq!(127, i16::from_der(I127_BYTES).unwrap());
68
        assert_eq!(128, i16::from_der(I128_BYTES).unwrap());
69
        assert_eq!(255, i16::from_der(I255_BYTES).unwrap());
70
        assert_eq!(256, i16::from_der(I256_BYTES).unwrap());
71
        assert_eq!(32767, i16::from_der(I32767_BYTES).unwrap());
72
        assert_eq!(-128, i16::from_der(INEG128_BYTES).unwrap());
73
        assert_eq!(-129, i16::from_der(INEG129_BYTES).unwrap());
74
        assert_eq!(-32768, i16::from_der(INEG32768_BYTES).unwrap());
75
    }
76
77
    #[test]
78
    fn decode_u8() {
79
        assert_eq!(0, u8::from_der(I0_BYTES).unwrap());
80
        assert_eq!(127, u8::from_der(I127_BYTES).unwrap());
81
        assert_eq!(255, u8::from_der(I255_BYTES).unwrap());
82
    }
83
84
    #[test]
85
    fn decode_u16() {
86
        assert_eq!(0, u16::from_der(I0_BYTES).unwrap());
87
        assert_eq!(127, u16::from_der(I127_BYTES).unwrap());
88
        assert_eq!(255, u16::from_der(I255_BYTES).unwrap());
89
        assert_eq!(256, u16::from_der(I256_BYTES).unwrap());
90
        assert_eq!(32767, u16::from_der(I32767_BYTES).unwrap());
91
        assert_eq!(65535, u16::from_der(I65535_BYTES).unwrap());
92
    }
93
94
    #[test]
95
    fn encode_i8() {
96
        let mut buffer = [0u8; 3];
97
98
        assert_eq!(I0_BYTES, 0i8.encode_to_slice(&mut buffer).unwrap());
99
        assert_eq!(I127_BYTES, 127i8.encode_to_slice(&mut buffer).unwrap());
100
101
        assert_eq!(
102
            INEG128_BYTES,
103
            (-128i8).encode_to_slice(&mut buffer).unwrap()
104
        );
105
    }
106
107
    #[test]
108
    fn encode_i16() {
109
        let mut buffer = [0u8; 4];
110
        assert_eq!(I0_BYTES, 0i16.encode_to_slice(&mut buffer).unwrap());
111
        assert_eq!(I127_BYTES, 127i16.encode_to_slice(&mut buffer).unwrap());
112
        assert_eq!(I128_BYTES, 128i16.encode_to_slice(&mut buffer).unwrap());
113
        assert_eq!(I255_BYTES, 255i16.encode_to_slice(&mut buffer).unwrap());
114
        assert_eq!(I256_BYTES, 256i16.encode_to_slice(&mut buffer).unwrap());
115
        assert_eq!(I32767_BYTES, 32767i16.encode_to_slice(&mut buffer).unwrap());
116
117
        assert_eq!(
118
            INEG128_BYTES,
119
            (-128i16).encode_to_slice(&mut buffer).unwrap()
120
        );
121
122
        assert_eq!(
123
            INEG129_BYTES,
124
            (-129i16).encode_to_slice(&mut buffer).unwrap()
125
        );
126
127
        assert_eq!(
128
            INEG32768_BYTES,
129
            (-32768i16).encode_to_slice(&mut buffer).unwrap()
130
        );
131
    }
132
133
    #[test]
134
    fn encode_u8() {
135
        let mut buffer = [0u8; 4];
136
        assert_eq!(I0_BYTES, 0u8.encode_to_slice(&mut buffer).unwrap());
137
        assert_eq!(I127_BYTES, 127u8.encode_to_slice(&mut buffer).unwrap());
138
        assert_eq!(I255_BYTES, 255u8.encode_to_slice(&mut buffer).unwrap());
139
    }
140
141
    #[test]
142
    fn encode_u16() {
143
        let mut buffer = [0u8; 5];
144
        assert_eq!(I0_BYTES, 0u16.encode_to_slice(&mut buffer).unwrap());
145
        assert_eq!(I127_BYTES, 127u16.encode_to_slice(&mut buffer).unwrap());
146
        assert_eq!(I128_BYTES, 128u16.encode_to_slice(&mut buffer).unwrap());
147
        assert_eq!(I255_BYTES, 255u16.encode_to_slice(&mut buffer).unwrap());
148
        assert_eq!(I256_BYTES, 256u16.encode_to_slice(&mut buffer).unwrap());
149
        assert_eq!(I32767_BYTES, 32767u16.encode_to_slice(&mut buffer).unwrap());
150
        assert_eq!(I65535_BYTES, 65535u16.encode_to_slice(&mut buffer).unwrap());
151
    }
152
153
    /// Integers must be encoded with a minimum number of octets
154
    #[test]
155
    fn reject_non_canonical() {
156
        assert!(i8::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
157
        assert!(i16::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
158
        assert!(u8::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
159
        assert!(u16::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
160
    }
161
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/integer/int.rs
Line
Count
Source
1
//! Support for encoding signed integers
2
3
use super::{is_highest_bit_set, uint, value_cmp};
4
use crate::{
5
    ord::OrdIsValueOrd, AnyRef, BytesRef, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag,
6
    Header, Length, Reader, Result, Tag, ValueOrd, Writer,
7
};
8
use core::cmp::Ordering;
9
10
#[cfg(feature = "alloc")]
11
pub use allocating::Int;
12
13
macro_rules! impl_encoding_traits {
14
    ($($int:ty => $uint:ty),+) => {
15
        $(
16
            impl<'a> DecodeValue<'a> for $int {
17
0
                fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
18
0
                    let mut buf = [0u8; Self::BITS as usize / 8];
19
0
                    let max_length = u32::from(header.length) as usize;
20
0
21
0
                    if max_length > buf.len() {
22
0
                        return Err(Self::TAG.non_canonical_error());
23
0
                    }
24
25
0
                    let bytes = reader.read_into(&mut buf[..max_length])?;
26
27
0
                    let result = if is_highest_bit_set(bytes) {
28
0
                        <$uint>::from_be_bytes(decode_to_array(bytes)?) as $int
29
                    } else {
30
0
                        Self::from_be_bytes(uint::decode_to_array(bytes)?)
31
                    };
32
33
                    // Ensure we compute the same encoded length as the original any value
34
0
                    if header.length != result.value_len()? {
35
0
                        return Err(Self::TAG.non_canonical_error());
36
0
                    }
37
0
38
0
                    Ok(result)
39
0
                }
Unexecuted instantiation: _RINvXs4_NtNtNtCscrZQdumITES_3der4asn17integer3intaNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXs9_NtNtNtCscrZQdumITES_3der4asn17integer3intsNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXse_NtNtNtCscrZQdumITES_3der4asn17integer3intlNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXsj_NtNtNtCscrZQdumITES_3der4asn17integer3intxNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXso_NtNtNtCscrZQdumITES_3der4asn17integer3intnNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
40
            }
41
42
            impl EncodeValue for $int {
43
0
                fn value_len(&self) -> Result<Length> {
44
0
                    if *self < 0 {
45
0
                        negative_encoded_len(&(*self as $uint).to_be_bytes())
46
                    } else {
47
0
                        uint::encoded_len(&self.to_be_bytes())
48
                    }
49
0
                }
Unexecuted instantiation: _RNvXs5_NtNtNtCscrZQdumITES_3der4asn17integer3intaNtNtBb_6encode11EncodeValue9value_len
Unexecuted instantiation: _RNvXsa_NtNtNtCscrZQdumITES_3der4asn17integer3intsNtNtBb_6encode11EncodeValue9value_len
Unexecuted instantiation: _RNvXsf_NtNtNtCscrZQdumITES_3der4asn17integer3intlNtNtBb_6encode11EncodeValue9value_len
Unexecuted instantiation: _RNvXsk_NtNtNtCscrZQdumITES_3der4asn17integer3intxNtNtBb_6encode11EncodeValue9value_len
Unexecuted instantiation: _RNvXsp_NtNtNtCscrZQdumITES_3der4asn17integer3intnNtNtBb_6encode11EncodeValue9value_len
50
51
0
                fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
52
0
                    if *self < 0 {
53
0
                        encode_bytes(writer, &(*self as $uint).to_be_bytes())
54
                    } else {
55
0
                        uint::encode_bytes(writer, &self.to_be_bytes())
56
                    }
57
0
                }
Unexecuted instantiation: _RINvXs5_NtNtNtCscrZQdumITES_3der4asn17integer3intaNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterEBc_
Unexecuted instantiation: _RINvXsa_NtNtNtCscrZQdumITES_3der4asn17integer3intsNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterEBc_
Unexecuted instantiation: _RINvXsf_NtNtNtCscrZQdumITES_3der4asn17integer3intlNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterEBc_
Unexecuted instantiation: _RINvXsk_NtNtNtCscrZQdumITES_3der4asn17integer3intxNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterEBc_
Unexecuted instantiation: _RINvXsp_NtNtNtCscrZQdumITES_3der4asn17integer3intnNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterEBc_
58
            }
59
60
            impl FixedTag for $int {
61
                const TAG: Tag = Tag::Integer;
62
            }
63
64
            impl ValueOrd for $int {
65
0
                fn value_cmp(&self, other: &Self) -> Result<Ordering> {
66
0
                    value_cmp(*self, *other)
67
0
                }
Unexecuted instantiation: _RNvXs7_NtNtNtCscrZQdumITES_3der4asn17integer3intaNtNtBb_3ord8ValueOrd9value_cmp
Unexecuted instantiation: _RNvXsc_NtNtNtCscrZQdumITES_3der4asn17integer3intsNtNtBb_3ord8ValueOrd9value_cmp
Unexecuted instantiation: _RNvXsh_NtNtNtCscrZQdumITES_3der4asn17integer3intlNtNtBb_3ord8ValueOrd9value_cmp
Unexecuted instantiation: _RNvXsm_NtNtNtCscrZQdumITES_3der4asn17integer3intxNtNtBb_3ord8ValueOrd9value_cmp
Unexecuted instantiation: _RNvXsr_NtNtNtCscrZQdumITES_3der4asn17integer3intnNtNtBb_3ord8ValueOrd9value_cmp
68
            }
69
70
            impl TryFrom<AnyRef<'_>> for $int {
71
                type Error = Error;
72
73
0
                fn try_from(any: AnyRef<'_>) -> Result<Self> {
74
0
                    any.decode_as()
75
0
                }
Unexecuted instantiation: _RNvXs8_NtNtNtCscrZQdumITES_3der4asn17integer3intaINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsd_NtNtNtCscrZQdumITES_3der4asn17integer3intsINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsi_NtNtNtCscrZQdumITES_3der4asn17integer3intlINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsn_NtNtNtCscrZQdumITES_3der4asn17integer3intxINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXss_NtNtNtCscrZQdumITES_3der4asn17integer3intnINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
76
            }
77
        )+
78
    };
79
}
80
81
impl_encoding_traits!(i8 => u8, i16 => u16, i32 => u32, i64 => u64, i128 => u128);
82
83
/// Signed arbitrary precision ASN.1 `INTEGER` reference type.
84
///
85
/// Provides direct access to the underlying big endian bytes which comprise
86
/// an signed integer value.
87
///
88
/// Intended for use cases like very large integers that are used in
89
/// cryptographic applications (e.g. keys, signatures).
90
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
91
pub struct IntRef<'a> {
92
    /// Inner value
93
    inner: BytesRef<'a>,
94
}
95
96
impl<'a> IntRef<'a> {
97
    /// Create a new [`IntRef`] from a byte slice.
98
0
    pub fn new(bytes: &'a [u8]) -> Result<Self> {
99
0
        let inner = BytesRef::new(strip_leading_ones(bytes))
100
0
            .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
101
102
0
        Ok(Self { inner })
103
0
    }
104
105
    /// Borrow the inner byte slice which contains the least significant bytes
106
    /// of a big endian integer value with all leading ones stripped.
107
0
    pub fn as_bytes(&self) -> &'a [u8] {
108
0
        self.inner.as_slice()
109
0
    }
110
111
    /// Get the length of this [`IntRef`] in bytes.
112
0
    pub fn len(&self) -> Length {
113
0
        self.inner.len()
114
0
    }
115
116
    /// Is the inner byte slice empty?
117
0
    pub fn is_empty(&self) -> bool {
118
0
        self.inner.is_empty()
119
0
    }
120
}
121
122
impl_any_conversions!(IntRef<'a>, 'a);
123
124
impl<'a> DecodeValue<'a> for IntRef<'a> {
125
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
126
0
        let bytes = BytesRef::decode_value(reader, header)?;
127
0
        validate_canonical(bytes.as_slice())?;
128
129
0
        let result = Self::new(bytes.as_slice())?;
130
131
        // Ensure we compute the same encoded length as the original any value.
132
0
        if result.value_len()? != header.length {
133
0
            return Err(Self::TAG.non_canonical_error());
134
0
        }
135
0
136
0
        Ok(result)
137
0
    }
138
}
139
140
impl<'a> EncodeValue for IntRef<'a> {
141
0
    fn value_len(&self) -> Result<Length> {
142
0
        // Signed integers always hold their full encoded form.
143
0
        Ok(self.inner.len())
144
0
    }
145
146
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
147
0
        writer.write(self.as_bytes())
148
0
    }
149
}
150
151
impl<'a> From<&IntRef<'a>> for IntRef<'a> {
152
0
    fn from(value: &IntRef<'a>) -> IntRef<'a> {
153
0
        *value
154
0
    }
155
}
156
157
impl<'a> FixedTag for IntRef<'a> {
158
    const TAG: Tag = Tag::Integer;
159
}
160
161
impl<'a> OrdIsValueOrd for IntRef<'a> {}
162
163
#[cfg(feature = "alloc")]
164
mod allocating {
165
    use super::{strip_leading_ones, validate_canonical, IntRef};
166
    use crate::{
167
        asn1::Uint,
168
        ord::OrdIsValueOrd,
169
        referenced::{OwnedToRef, RefToOwned},
170
        BytesOwned, DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result,
171
        Tag, Writer,
172
    };
173
    use alloc::vec::Vec;
174
175
    /// Signed arbitrary precision ASN.1 `INTEGER` type.
176
    ///
177
    /// Provides heap-allocated storage for big endian bytes which comprise an
178
    /// signed integer value.
179
    ///
180
    /// Intended for use cases like very large integers that are used in
181
    /// cryptographic applications (e.g. keys, signatures).
182
    #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
183
    pub struct Int {
184
        /// Inner value
185
        inner: BytesOwned,
186
    }
187
188
    impl Int {
189
        /// Create a new [`Int`] from a byte slice.
190
0
        pub fn new(bytes: &[u8]) -> Result<Self> {
191
0
            let inner = BytesOwned::new(strip_leading_ones(bytes))
192
0
                .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
193
194
0
            Ok(Self { inner })
195
0
        }
196
197
        /// Borrow the inner byte slice which contains the least significant bytes
198
        /// of a big endian integer value with all leading ones stripped.
199
0
        pub fn as_bytes(&self) -> &[u8] {
200
0
            self.inner.as_slice()
201
0
        }
202
203
        /// Get the length of this [`Int`] in bytes.
204
0
        pub fn len(&self) -> Length {
205
0
            self.inner.len()
206
0
        }
207
208
        /// Is the inner byte slice empty?
209
0
        pub fn is_empty(&self) -> bool {
210
0
            self.inner.is_empty()
211
0
        }
212
    }
213
214
    impl_any_conversions!(Int);
215
216
    impl<'a> DecodeValue<'a> for Int {
217
0
        fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
218
0
            let bytes = BytesOwned::decode_value(reader, header)?;
219
0
            validate_canonical(bytes.as_slice())?;
220
221
0
            let result = Self::new(bytes.as_slice())?;
222
223
            // Ensure we compute the same encoded length as the original any value.
224
0
            if result.value_len()? != header.length {
225
0
                return Err(Self::TAG.non_canonical_error());
226
0
            }
227
0
228
0
            Ok(result)
229
0
        }
230
    }
231
232
    impl EncodeValue for Int {
233
0
        fn value_len(&self) -> Result<Length> {
234
0
            // Signed integers always hold their full encoded form.
235
0
            Ok(self.inner.len())
236
0
        }
237
238
0
        fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
239
0
            writer.write(self.as_bytes())
240
0
        }
241
    }
242
243
    impl<'a> From<&IntRef<'a>> for Int {
244
0
        fn from(value: &IntRef<'a>) -> Int {
245
0
            let inner = BytesOwned::new(value.as_bytes()).expect("Invalid Int");
246
0
            Int { inner }
247
0
        }
248
    }
249
250
    impl From<Uint> for Int {
251
0
        fn from(value: Uint) -> Self {
252
0
            let mut inner: Vec<u8> = Vec::new();
253
0
254
0
            // Add leading `0x00` byte if required
255
0
            if value.value_len().expect("invalid Uint") > value.len() {
256
0
                inner.push(0x00);
257
0
            }
258
259
0
            inner.extend_from_slice(value.as_bytes());
260
0
            let inner = BytesOwned::new(inner).expect("invalid Uint");
261
0
262
0
            Int { inner }
263
0
        }
264
    }
265
266
    impl FixedTag for Int {
267
        const TAG: Tag = Tag::Integer;
268
    }
269
270
    impl OrdIsValueOrd for Int {}
271
272
    impl<'a> RefToOwned<'a> for IntRef<'a> {
273
        type Owned = Int;
274
0
        fn ref_to_owned(&self) -> Self::Owned {
275
0
            let inner = self.inner.ref_to_owned();
276
0
277
0
            Int { inner }
278
0
        }
279
    }
280
281
    impl OwnedToRef for Int {
282
        type Borrowed<'a> = IntRef<'a>;
283
0
        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
284
0
            let inner = self.inner.owned_to_ref();
285
0
286
0
            IntRef { inner }
287
0
        }
288
    }
289
}
290
291
/// Ensure `INTEGER` is canonically encoded.
292
0
fn validate_canonical(bytes: &[u8]) -> Result<()> {
293
    // The `INTEGER` type always encodes a signed value and we're decoding
294
    // as signed here, so we allow a zero extension or sign extension byte,
295
    // but only as permitted under DER canonicalization.
296
0
    match bytes {
297
0
        [] => Err(Tag::Integer.non_canonical_error()),
298
0
        [0x00, byte, ..] if *byte < 0x80 => Err(Tag::Integer.non_canonical_error()),
299
0
        [0xFF, byte, ..] if *byte >= 0x80 => Err(Tag::Integer.non_canonical_error()),
300
0
        _ => Ok(()),
301
    }
302
0
}
303
304
/// Decode an signed integer of the specified size.
305
///
306
/// Returns a byte array of the requested size containing a big endian integer.
307
0
fn decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]> {
308
0
    match N.checked_sub(bytes.len()) {
309
0
        Some(offset) => {
310
0
            let mut output = [0xFFu8; N];
311
0
            output[offset..].copy_from_slice(bytes);
312
0
            Ok(output)
313
        }
314
        None => {
315
0
            let expected_len = Length::try_from(N)?;
316
0
            let actual_len = Length::try_from(bytes.len())?;
317
318
0
            Err(ErrorKind::Incomplete {
319
0
                expected_len,
320
0
                actual_len,
321
0
            }
322
0
            .into())
323
        }
324
    }
325
0
}
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer3int15decode_to_arrayKj10_EB8_
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer3int15decode_to_arrayKj1_EB8_
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer3int15decode_to_arrayKj2_EB8_
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer3int15decode_to_arrayKj4_EB8_
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer3int15decode_to_arrayKj8_EB8_
326
327
/// Encode the given big endian bytes representing an integer as ASN.1 DER.
328
0
fn encode_bytes<W>(writer: &mut W, bytes: &[u8]) -> Result<()>
329
0
where
330
0
    W: Writer + ?Sized,
331
0
{
332
0
    writer.write(strip_leading_ones(bytes))
333
0
}
334
335
/// Get the encoded length for the given **negative** integer serialized as bytes.
336
#[inline]
337
0
fn negative_encoded_len(bytes: &[u8]) -> Result<Length> {
338
0
    Length::try_from(strip_leading_ones(bytes).len())
339
0
}
340
341
/// Strip the leading all-ones bytes from the given byte slice.
342
0
pub(crate) fn strip_leading_ones(mut bytes: &[u8]) -> &[u8] {
343
0
    while let Some((byte, rest)) = bytes.split_first() {
344
0
        if *byte == 0xFF && is_highest_bit_set(rest) {
345
0
            bytes = rest;
346
0
            continue;
347
0
        }
348
0
349
0
        break;
350
    }
351
352
0
    bytes
353
0
}
354
355
#[cfg(test)]
356
mod tests {
357
    use super::{validate_canonical, IntRef};
358
    use crate::{asn1::integer::tests::*, Decode, Encode, SliceWriter};
359
360
    #[test]
361
    fn validate_canonical_ok() {
362
        assert_eq!(validate_canonical(&[0x00]), Ok(()));
363
        assert_eq!(validate_canonical(&[0x01]), Ok(()));
364
        assert_eq!(validate_canonical(&[0x00, 0x80]), Ok(()));
365
        assert_eq!(validate_canonical(&[0xFF, 0x00]), Ok(()));
366
    }
367
368
    #[test]
369
    fn validate_canonical_err() {
370
        // Empty integers are always non-canonical.
371
        assert!(validate_canonical(&[]).is_err());
372
373
        // Positives with excessive zero extension are non-canonical.
374
        assert!(validate_canonical(&[0x00, 0x00]).is_err());
375
376
        // Negatives with excessive sign extension are non-canonical.
377
        assert!(validate_canonical(&[0xFF, 0x80]).is_err());
378
    }
379
380
    #[test]
381
    fn decode_intref() {
382
        // Positive numbers decode, but have zero extensions as necessary
383
        // (to distinguish them from negative representations).
384
        assert_eq!(&[0], IntRef::from_der(I0_BYTES).unwrap().as_bytes());
385
        assert_eq!(&[127], IntRef::from_der(I127_BYTES).unwrap().as_bytes());
386
        assert_eq!(&[0, 128], IntRef::from_der(I128_BYTES).unwrap().as_bytes());
387
        assert_eq!(&[0, 255], IntRef::from_der(I255_BYTES).unwrap().as_bytes());
388
389
        assert_eq!(
390
            &[0x01, 0x00],
391
            IntRef::from_der(I256_BYTES).unwrap().as_bytes()
392
        );
393
394
        assert_eq!(
395
            &[0x7F, 0xFF],
396
            IntRef::from_der(I32767_BYTES).unwrap().as_bytes()
397
        );
398
399
        // Negative integers decode.
400
        assert_eq!(&[128], IntRef::from_der(INEG128_BYTES).unwrap().as_bytes());
401
        assert_eq!(
402
            &[255, 127],
403
            IntRef::from_der(INEG129_BYTES).unwrap().as_bytes()
404
        );
405
        assert_eq!(
406
            &[128, 0],
407
            IntRef::from_der(INEG32768_BYTES).unwrap().as_bytes()
408
        );
409
    }
410
411
    #[test]
412
    fn encode_intref() {
413
        for &example in &[
414
            I0_BYTES,
415
            I127_BYTES,
416
            I128_BYTES,
417
            I255_BYTES,
418
            I256_BYTES,
419
            I32767_BYTES,
420
        ] {
421
            let uint = IntRef::from_der(example).unwrap();
422
423
            let mut buf = [0u8; 128];
424
            let mut encoder = SliceWriter::new(&mut buf);
425
            uint.encode(&mut encoder).unwrap();
426
427
            let result = encoder.finish().unwrap();
428
            assert_eq!(example, result);
429
        }
430
431
        for &example in &[INEG128_BYTES, INEG129_BYTES, INEG32768_BYTES] {
432
            let uint = IntRef::from_der(example).unwrap();
433
434
            let mut buf = [0u8; 128];
435
            let mut encoder = SliceWriter::new(&mut buf);
436
            uint.encode(&mut encoder).unwrap();
437
438
            let result = encoder.finish().unwrap();
439
            assert_eq!(example, result);
440
        }
441
    }
442
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/integer/uint.rs
Line
Count
Source
1
//! Unsigned integer decoders/encoders.
2
3
use super::value_cmp;
4
use crate::{
5
    ord::OrdIsValueOrd, AnyRef, BytesRef, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag,
6
    Header, Length, Reader, Result, Tag, ValueOrd, Writer,
7
};
8
use core::cmp::Ordering;
9
10
#[cfg(feature = "alloc")]
11
pub use allocating::Uint;
12
13
macro_rules! impl_encoding_traits {
14
    ($($uint:ty),+) => {
15
        $(
16
            impl<'a> DecodeValue<'a> for $uint {
17
0
                fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
18
                    // Integers always encodes as a signed value, unsigned gets a leading 0x00 that
19
                    // needs to be stripped off. We need to provide room for it.
20
                    const UNSIGNED_HEADROOM: usize = 1;
21
22
0
                    let mut buf = [0u8; (Self::BITS as usize / 8) + UNSIGNED_HEADROOM];
23
0
                    let max_length = u32::from(header.length) as usize;
24
0
25
0
                    if max_length > buf.len() {
26
0
                        return Err(Self::TAG.non_canonical_error());
27
0
                    }
28
29
0
                    let bytes = reader.read_into(&mut buf[..max_length])?;
30
31
0
                    let result = Self::from_be_bytes(decode_to_array(bytes)?);
32
33
                    // Ensure we compute the same encoded length as the original any value
34
0
                    if header.length != result.value_len()? {
35
0
                        return Err(Self::TAG.non_canonical_error());
36
0
                    }
37
0
38
0
                    Ok(result)
39
0
                }
Unexecuted instantiation: _RINvXs4_NtNtNtCscrZQdumITES_3der4asn17integer4uinthNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXs9_NtNtNtCscrZQdumITES_3der4asn17integer4uinttNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXse_NtNtNtCscrZQdumITES_3der4asn17integer4uintmNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXsj_NtNtNtCscrZQdumITES_3der4asn17integer4uintyNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXso_NtNtNtCscrZQdumITES_3der4asn17integer4uintoNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXs4_NtNtNtCscrZQdumITES_3der4asn17integer4uinthNtNtBc_6decode11DecodeValue12decode_valueINtNtNtBc_6reader6nested12NestedReaderNtNtB1x_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs4_NtNtNtCscrZQdumITES_3der4asn17integer4uinthNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs4_NtNtNtCscrZQdumITES_3der4asn17integer4uinthNtNtBc_6decode11DecodeValue12decode_valueINtNtNtBc_6reader6nested12NestedReaderNtNtB1x_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
40
            }
41
42
            impl EncodeValue for $uint {
43
0
                fn value_len(&self) -> Result<Length> {
44
0
                    encoded_len(&self.to_be_bytes())
45
0
                }
Unexecuted instantiation: _RNvXs5_NtNtNtCscrZQdumITES_3der4asn17integer4uinthNtNtBb_6encode11EncodeValue9value_len
Unexecuted instantiation: _RNvXsa_NtNtNtCscrZQdumITES_3der4asn17integer4uinttNtNtBb_6encode11EncodeValue9value_len
Unexecuted instantiation: _RNvXsf_NtNtNtCscrZQdumITES_3der4asn17integer4uintmNtNtBb_6encode11EncodeValue9value_len
Unexecuted instantiation: _RNvXsk_NtNtNtCscrZQdumITES_3der4asn17integer4uintyNtNtBb_6encode11EncodeValue9value_len
Unexecuted instantiation: _RNvXsp_NtNtNtCscrZQdumITES_3der4asn17integer4uintoNtNtBb_6encode11EncodeValue9value_len
46
47
0
                fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
48
0
                    encode_bytes(writer, &self.to_be_bytes())
49
0
                }
Unexecuted instantiation: _RINvXs5_NtNtNtCscrZQdumITES_3der4asn17integer4uinthNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterEBc_
Unexecuted instantiation: _RINvXsa_NtNtNtCscrZQdumITES_3der4asn17integer4uinttNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterEBc_
Unexecuted instantiation: _RINvXsf_NtNtNtCscrZQdumITES_3der4asn17integer4uintmNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterEBc_
Unexecuted instantiation: _RINvXsk_NtNtNtCscrZQdumITES_3der4asn17integer4uintyNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterEBc_
Unexecuted instantiation: _RINvXsp_NtNtNtCscrZQdumITES_3der4asn17integer4uintoNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterEBc_
Unexecuted instantiation: _RINvXs5_NtNtNtCscrZQdumITES_3der4asn17integer4uinthNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs5_NtNtNtCscrZQdumITES_3der4asn17integer4uinthNtNtBc_6encode11EncodeValue12encode_valueNtNtNtBc_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
50
            }
51
52
            impl FixedTag for $uint {
53
                const TAG: Tag = Tag::Integer;
54
            }
55
56
            impl ValueOrd for $uint {
57
0
                fn value_cmp(&self, other: &Self) -> Result<Ordering> {
58
0
                    value_cmp(*self, *other)
59
0
                }
Unexecuted instantiation: _RNvXs7_NtNtNtCscrZQdumITES_3der4asn17integer4uinthNtNtBb_3ord8ValueOrd9value_cmp
Unexecuted instantiation: _RNvXsc_NtNtNtCscrZQdumITES_3der4asn17integer4uinttNtNtBb_3ord8ValueOrd9value_cmp
Unexecuted instantiation: _RNvXsh_NtNtNtCscrZQdumITES_3der4asn17integer4uintmNtNtBb_3ord8ValueOrd9value_cmp
Unexecuted instantiation: _RNvXsm_NtNtNtCscrZQdumITES_3der4asn17integer4uintyNtNtBb_3ord8ValueOrd9value_cmp
Unexecuted instantiation: _RNvXsr_NtNtNtCscrZQdumITES_3der4asn17integer4uintoNtNtBb_3ord8ValueOrd9value_cmp
60
            }
61
62
            impl TryFrom<AnyRef<'_>> for $uint {
63
                type Error = Error;
64
65
0
                fn try_from(any: AnyRef<'_>) -> Result<Self> {
66
0
                    any.decode_as()
67
0
                }
Unexecuted instantiation: _RNvXs8_NtNtNtCscrZQdumITES_3der4asn17integer4uinthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsd_NtNtNtCscrZQdumITES_3der4asn17integer4uinttINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsi_NtNtNtCscrZQdumITES_3der4asn17integer4uintmINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsn_NtNtNtCscrZQdumITES_3der4asn17integer4uintyINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXss_NtNtNtCscrZQdumITES_3der4asn17integer4uintoINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
68
            }
69
        )+
70
    };
71
}
72
73
impl_encoding_traits!(u8, u16, u32, u64, u128);
74
75
/// Unsigned arbitrary precision ASN.1 `INTEGER` reference type.
76
///
77
/// Provides direct access to the underlying big endian bytes which comprise an
78
/// unsigned integer value.
79
///
80
/// Intended for use cases like very large integers that are used in
81
/// cryptographic applications (e.g. keys, signatures).
82
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
83
pub struct UintRef<'a> {
84
    /// Inner value
85
    inner: BytesRef<'a>,
86
}
87
88
impl<'a> UintRef<'a> {
89
    /// Create a new [`UintRef`] from a byte slice.
90
0
    pub fn new(bytes: &'a [u8]) -> Result<Self> {
91
0
        let inner = BytesRef::new(strip_leading_zeroes(bytes))
92
0
            .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
93
94
0
        Ok(Self { inner })
95
0
    }
96
97
    /// Borrow the inner byte slice which contains the least significant bytes
98
    /// of a big endian integer value with all leading zeros stripped.
99
0
    pub fn as_bytes(&self) -> &'a [u8] {
100
0
        self.inner.as_slice()
101
0
    }
102
103
    /// Get the length of this [`UintRef`] in bytes.
104
0
    pub fn len(&self) -> Length {
105
0
        self.inner.len()
106
0
    }
107
108
    /// Is the inner byte slice empty?
109
0
    pub fn is_empty(&self) -> bool {
110
0
        self.inner.is_empty()
111
0
    }
112
}
113
114
impl_any_conversions!(UintRef<'a>, 'a);
115
116
impl<'a> DecodeValue<'a> for UintRef<'a> {
117
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
118
0
        let bytes = BytesRef::decode_value(reader, header)?.as_slice();
119
0
        let result = Self::new(decode_to_slice(bytes)?)?;
120
121
        // Ensure we compute the same encoded length as the original any value.
122
0
        if result.value_len()? != header.length {
123
0
            return Err(Self::TAG.non_canonical_error());
124
0
        }
125
0
126
0
        Ok(result)
127
0
    }
Unexecuted instantiation: _RINvXs_NtNtNtCscrZQdumITES_3der4asn17integer4uintNtB5_7UintRefNtNtBb_6decode11DecodeValue12decode_valueNtNtNtBb_6reader5slice11SliceReaderEBb_
Unexecuted instantiation: _RINvXs_NtNtNtCscrZQdumITES_3der4asn17integer4uintNtB5_7UintRefNtNtBb_6decode11DecodeValue12decode_valueINtNtNtBb_6reader6nested12NestedReaderNtNtB1I_5slice11SliceReaderEECs56dDIOPvtI3_5ecdsa
128
}
129
130
impl<'a> EncodeValue for UintRef<'a> {
131
0
    fn value_len(&self) -> Result<Length> {
132
0
        encoded_len(self.inner.as_slice())
133
0
    }
134
135
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
136
0
        // Add leading `0x00` byte if required
137
0
        if self.value_len()? > self.len() {
138
0
            writer.write_byte(0)?;
139
0
        }
140
141
0
        writer.write(self.as_bytes())
142
0
    }
143
}
144
145
impl<'a> From<&UintRef<'a>> for UintRef<'a> {
146
0
    fn from(value: &UintRef<'a>) -> UintRef<'a> {
147
0
        *value
148
0
    }
149
}
150
151
impl<'a> FixedTag for UintRef<'a> {
152
    const TAG: Tag = Tag::Integer;
153
}
154
155
impl<'a> OrdIsValueOrd for UintRef<'a> {}
156
157
#[cfg(feature = "alloc")]
158
mod allocating {
159
    use super::{decode_to_slice, encoded_len, strip_leading_zeroes, UintRef};
160
    use crate::{
161
        ord::OrdIsValueOrd,
162
        referenced::{OwnedToRef, RefToOwned},
163
        BytesOwned, DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result,
164
        Tag, Writer,
165
    };
166
167
    /// Unsigned arbitrary precision ASN.1 `INTEGER` type.
168
    ///
169
    /// Provides heap-allocated storage for big endian bytes which comprise an
170
    /// unsigned integer value.
171
    ///
172
    /// Intended for use cases like very large integers that are used in
173
    /// cryptographic applications (e.g. keys, signatures).
174
    #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
175
    pub struct Uint {
176
        /// Inner value
177
        inner: BytesOwned,
178
    }
179
180
    impl Uint {
181
        /// Create a new [`Uint`] from a byte slice.
182
0
        pub fn new(bytes: &[u8]) -> Result<Self> {
183
0
            let inner = BytesOwned::new(strip_leading_zeroes(bytes))
184
0
                .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
185
186
0
            Ok(Self { inner })
187
0
        }
188
189
        /// Borrow the inner byte slice which contains the least significant bytes
190
        /// of a big endian integer value with all leading zeros stripped.
191
0
        pub fn as_bytes(&self) -> &[u8] {
192
0
            self.inner.as_slice()
193
0
        }
194
195
        /// Get the length of this [`Uint`] in bytes.
196
0
        pub fn len(&self) -> Length {
197
0
            self.inner.len()
198
0
        }
199
200
        /// Is the inner byte slice empty?
201
0
        pub fn is_empty(&self) -> bool {
202
0
            self.inner.is_empty()
203
0
        }
204
    }
205
206
    impl_any_conversions!(Uint);
207
208
    impl<'a> DecodeValue<'a> for Uint {
209
0
        fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
210
0
            let bytes = BytesOwned::decode_value(reader, header)?;
211
0
            let result = Self::new(decode_to_slice(bytes.as_slice())?)?;
212
213
            // Ensure we compute the same encoded length as the original any value.
214
0
            if result.value_len()? != header.length {
215
0
                return Err(Self::TAG.non_canonical_error());
216
0
            }
217
0
218
0
            Ok(result)
219
0
        }
220
    }
221
222
    impl EncodeValue for Uint {
223
0
        fn value_len(&self) -> Result<Length> {
224
0
            encoded_len(self.inner.as_slice())
225
0
        }
226
227
0
        fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
228
0
            // Add leading `0x00` byte if required
229
0
            if self.value_len()? > self.len() {
230
0
                writer.write_byte(0)?;
231
0
            }
232
233
0
            writer.write(self.as_bytes())
234
0
        }
235
    }
236
237
    impl<'a> From<&UintRef<'a>> for Uint {
238
0
        fn from(value: &UintRef<'a>) -> Uint {
239
0
            let inner = BytesOwned::new(value.as_bytes()).expect("Invalid Uint");
240
0
            Uint { inner }
241
0
        }
242
    }
243
244
    impl FixedTag for Uint {
245
        const TAG: Tag = Tag::Integer;
246
    }
247
248
    impl OrdIsValueOrd for Uint {}
249
250
    impl<'a> RefToOwned<'a> for UintRef<'a> {
251
        type Owned = Uint;
252
0
        fn ref_to_owned(&self) -> Self::Owned {
253
0
            let inner = self.inner.ref_to_owned();
254
0
255
0
            Uint { inner }
256
0
        }
257
    }
258
259
    impl OwnedToRef for Uint {
260
        type Borrowed<'a> = UintRef<'a>;
261
0
        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
262
0
            let inner = self.inner.owned_to_ref();
263
0
264
0
            UintRef { inner }
265
0
        }
266
    }
267
}
268
269
/// Decode an unsigned integer into a big endian byte slice with all leading
270
/// zeroes removed.
271
///
272
/// Returns a byte array of the requested size containing a big endian integer.
273
0
pub(crate) fn decode_to_slice(bytes: &[u8]) -> Result<&[u8]> {
274
    // The `INTEGER` type always encodes a signed value, so for unsigned
275
    // values the leading `0x00` byte may need to be removed.
276
    //
277
    // We also disallow a leading byte which would overflow a signed ASN.1
278
    // integer (since we're decoding an unsigned integer).
279
    // We expect all such cases to have a leading `0x00` byte.
280
0
    match bytes {
281
0
        [] => Err(Tag::Integer.non_canonical_error()),
282
0
        [0] => Ok(bytes),
283
0
        [0, byte, ..] if *byte < 0x80 => Err(Tag::Integer.non_canonical_error()),
284
0
        [0, rest @ ..] => Ok(rest),
285
0
        [byte, ..] if *byte >= 0x80 => Err(Tag::Integer.value_error()),
286
0
        _ => Ok(bytes),
287
    }
288
0
}
Unexecuted instantiation: _RNvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_sliceB7_
Unexecuted instantiation: _RNvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_sliceCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_sliceCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_sliceCsj9qtwLkMHqH_4sec1
289
290
/// Decode an unsigned integer into a byte array of the requested size
291
/// containing a big endian integer.
292
0
pub(super) fn decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]> {
293
0
    let input = decode_to_slice(bytes)?;
294
295
    // Compute number of leading zeroes to add
296
0
    let num_zeroes = N
297
0
        .checked_sub(input.len())
298
0
        .ok_or_else(|| Tag::Integer.length_error())?;
Unexecuted instantiation: _RNCINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj10_E0Ba_
Unexecuted instantiation: _RNCINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj1_E0Ba_
Unexecuted instantiation: _RNCINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj2_E0Ba_
Unexecuted instantiation: _RNCINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj4_E0Ba_
Unexecuted instantiation: _RNCINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj8_E0Ba_
Unexecuted instantiation: _RNCINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj1_E0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj1_E0Csj9qtwLkMHqH_4sec1
299
300
    // Copy input into `N`-sized output buffer with leading zeroes
301
0
    let mut output = [0u8; N];
302
0
    output[num_zeroes..].copy_from_slice(input);
303
0
    Ok(output)
304
0
}
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj10_EB8_
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj1_EB8_
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj2_EB8_
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj4_EB8_
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj8_EB8_
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj1_ECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer4uint15decode_to_arrayKj1_ECsj9qtwLkMHqH_4sec1
305
306
/// Encode the given big endian bytes representing an integer as ASN.1 DER.
307
0
pub(crate) fn encode_bytes<W>(encoder: &mut W, bytes: &[u8]) -> Result<()>
308
0
where
309
0
    W: Writer + ?Sized,
310
0
{
311
0
    let bytes = strip_leading_zeroes(bytes);
312
0
313
0
    if needs_leading_zero(bytes) {
314
0
        encoder.write_byte(0)?;
315
0
    }
316
317
0
    encoder.write(bytes)
318
0
}
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer4uint12encode_bytesNtNtNtB8_6writer5slice11SliceWriterEB8_
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer4uint12encode_bytesNtNtNtB8_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvNtNtNtCscrZQdumITES_3der4asn17integer4uint12encode_bytesNtNtNtB8_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
319
320
/// Get the encoded length for the given unsigned integer serialized as bytes.
321
#[inline]
322
0
pub(crate) fn encoded_len(bytes: &[u8]) -> Result<Length> {
323
0
    let bytes = strip_leading_zeroes(bytes);
324
0
    Length::try_from(bytes.len())? + u8::from(needs_leading_zero(bytes))
325
0
}
326
327
/// Strip the leading zeroes from the given byte slice
328
0
pub(crate) fn strip_leading_zeroes(mut bytes: &[u8]) -> &[u8] {
329
0
    while let Some((byte, rest)) = bytes.split_first() {
330
0
        if *byte == 0 && !rest.is_empty() {
331
0
            bytes = rest;
332
0
        } else {
333
0
            break;
334
        }
335
    }
336
337
0
    bytes
338
0
}
Unexecuted instantiation: _RNvNtNtNtCscrZQdumITES_3der4asn17integer4uint20strip_leading_zeroesB7_
Unexecuted instantiation: _RNvNtNtNtCscrZQdumITES_3der4asn17integer4uint20strip_leading_zeroesCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvNtNtNtCscrZQdumITES_3der4asn17integer4uint20strip_leading_zeroesCsj9qtwLkMHqH_4sec1
339
340
/// Does the given integer need a leading zero?
341
0
fn needs_leading_zero(bytes: &[u8]) -> bool {
342
0
    matches!(bytes.first(), Some(byte) if *byte >= 0x80)
343
0
}
Unexecuted instantiation: _RNvNtNtNtCscrZQdumITES_3der4asn17integer4uint18needs_leading_zeroB7_
Unexecuted instantiation: _RNvNtNtNtCscrZQdumITES_3der4asn17integer4uint18needs_leading_zeroCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvNtNtNtCscrZQdumITES_3der4asn17integer4uint18needs_leading_zeroCsj9qtwLkMHqH_4sec1
344
345
#[cfg(test)]
346
mod tests {
347
    use super::{decode_to_array, UintRef};
348
    use crate::{asn1::integer::tests::*, AnyRef, Decode, Encode, ErrorKind, SliceWriter, Tag};
349
350
    #[test]
351
    fn decode_to_array_no_leading_zero() {
352
        let arr = decode_to_array::<4>(&[1, 2]).unwrap();
353
        assert_eq!(arr, [0, 0, 1, 2]);
354
    }
355
356
    #[test]
357
    fn decode_to_array_leading_zero() {
358
        let arr = decode_to_array::<4>(&[0x00, 0xFF, 0xFE]).unwrap();
359
        assert_eq!(arr, [0x00, 0x00, 0xFF, 0xFE]);
360
    }
361
362
    #[test]
363
    fn decode_to_array_extra_zero() {
364
        let err = decode_to_array::<4>(&[0, 1, 2]).err().unwrap();
365
        assert_eq!(err.kind(), ErrorKind::Noncanonical { tag: Tag::Integer });
366
    }
367
368
    #[test]
369
    fn decode_to_array_missing_zero() {
370
        // We're decoding an unsigned integer, but this value would be signed
371
        let err = decode_to_array::<4>(&[0xFF, 0xFE]).err().unwrap();
372
        assert_eq!(err.kind(), ErrorKind::Value { tag: Tag::Integer });
373
    }
374
375
    #[test]
376
    fn decode_to_array_oversized_input() {
377
        let err = decode_to_array::<1>(&[1, 2, 3]).err().unwrap();
378
        assert_eq!(err.kind(), ErrorKind::Length { tag: Tag::Integer });
379
    }
380
381
    #[test]
382
    fn decode_uintref() {
383
        assert_eq!(&[0], UintRef::from_der(I0_BYTES).unwrap().as_bytes());
384
        assert_eq!(&[127], UintRef::from_der(I127_BYTES).unwrap().as_bytes());
385
        assert_eq!(&[128], UintRef::from_der(I128_BYTES).unwrap().as_bytes());
386
        assert_eq!(&[255], UintRef::from_der(I255_BYTES).unwrap().as_bytes());
387
388
        assert_eq!(
389
            &[0x01, 0x00],
390
            UintRef::from_der(I256_BYTES).unwrap().as_bytes()
391
        );
392
393
        assert_eq!(
394
            &[0x7F, 0xFF],
395
            UintRef::from_der(I32767_BYTES).unwrap().as_bytes()
396
        );
397
    }
398
399
    #[test]
400
    fn encode_uintref() {
401
        for &example in &[
402
            I0_BYTES,
403
            I127_BYTES,
404
            I128_BYTES,
405
            I255_BYTES,
406
            I256_BYTES,
407
            I32767_BYTES,
408
        ] {
409
            let uint = UintRef::from_der(example).unwrap();
410
411
            let mut buf = [0u8; 128];
412
            let mut encoder = SliceWriter::new(&mut buf);
413
            uint.encode(&mut encoder).unwrap();
414
415
            let result = encoder.finish().unwrap();
416
            assert_eq!(example, result);
417
        }
418
    }
419
420
    #[test]
421
    fn reject_oversize_without_extra_zero() {
422
        let err = UintRef::try_from(AnyRef::new(Tag::Integer, &[0x81]).unwrap())
423
            .err()
424
            .unwrap();
425
426
        assert_eq!(err.kind(), ErrorKind::Value { tag: Tag::Integer });
427
    }
428
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/internal_macros.rs
Line
Count
Source
1
macro_rules! impl_any_conversions {
2
    ($type: ty) => {
3
        impl_any_conversions!($type, );
4
    };
5
    ($type: ty, $($li: lifetime)?) => {
6
        impl<'__der: $($li),*, $($li),*> TryFrom<$crate::AnyRef<'__der>> for $type {
7
            type Error = $crate::Error;
8
9
0
            fn try_from(any: $crate::AnyRef<'__der>) -> Result<$type> {
10
0
                any.decode_as()
11
0
            }
Unexecuted instantiation: _RNvXsi_NtNtCscrZQdumITES_3der4asn110bit_stringNtB5_12BitStringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB7_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsd_NtNtNtCscrZQdumITES_3der4asn110bit_string10allocatingNtB5_9BitStringINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXst_NtNtCscrZQdumITES_3der4asn116generalized_timeNtB5_15GeneralizedTimeINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB7_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsb_NtNtCscrZQdumITES_3der4asn110ia5_stringNtB5_12Ia5StringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB7_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsd_NtNtNtCscrZQdumITES_3der4asn110ia5_string10allocationNtB5_9Ia5StringINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsB_NtNtNtCscrZQdumITES_3der4asn17integer3intNtB5_6IntRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXse_NtNtNtNtCscrZQdumITES_3der4asn17integer3int10allocatingNtB5_3IntINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtBb_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsB_NtNtNtCscrZQdumITES_3der4asn17integer4uintNtB5_7UintRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsd_NtNtNtNtCscrZQdumITES_3der4asn17integer4uint10allocatingNtB5_4UintINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtBb_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsg_NtNtCscrZQdumITES_3der4asn14nullNtB5_4NullINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB7_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsf_NtNtCscrZQdumITES_3der4asn112octet_stringNtB5_14OctetStringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB7_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXse_NtNtNtCscrZQdumITES_3der4asn112octet_string10allocatingNtB5_11OctetStringINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsb_NtNtCscrZQdumITES_3der4asn116printable_stringNtB5_18PrintableStringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB7_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsd_NtNtNtCscrZQdumITES_3der4asn116printable_string10allocationNtB5_15PrintableStringINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsb_NtNtCscrZQdumITES_3der4asn114teletex_stringNtB5_16TeletexStringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB7_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsd_NtNtNtCscrZQdumITES_3der4asn114teletex_string10allocationNtB5_13TeletexStringINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB9_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsh_NtNtCscrZQdumITES_3der4asn18utc_timeNtB5_7UtcTimeINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB7_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsl_NtNtCscrZQdumITES_3der4asn111utf8_stringNtB5_13Utf8StringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB7_3any6AnyRefE8try_from
Unexecuted instantiation: _RNvXsc_NtNtCscrZQdumITES_3der4asn115videotex_stringNtB5_17VideotexStringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtNtB7_3any6AnyRefE8try_from
12
        }
13
14
        #[cfg(feature = "alloc")]
15
        impl<'__der: $($li),*, $($li),*> TryFrom<&'__der $crate::Any> for $type {
16
            type Error = $crate::Error;
17
18
0
            fn try_from(any: &'__der $crate::Any) -> Result<$type> {
19
0
                any.decode_as()
20
0
            }
Unexecuted instantiation: _RNvXsj_NtNtCscrZQdumITES_3der4asn110bit_stringNtB5_12BitStringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB7_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXse_NtNtNtCscrZQdumITES_3der4asn110bit_string10allocatingNtB5_9BitStringINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB9_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsu_NtNtCscrZQdumITES_3der4asn116generalized_timeNtB5_15GeneralizedTimeINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB7_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsc_NtNtCscrZQdumITES_3der4asn110ia5_stringNtB5_12Ia5StringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB7_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXse_NtNtNtCscrZQdumITES_3der4asn110ia5_string10allocationNtB5_9Ia5StringINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB9_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsC_NtNtNtCscrZQdumITES_3der4asn17integer3intNtB5_6IntRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB9_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsf_NtNtNtNtCscrZQdumITES_3der4asn17integer3int10allocatingNtB5_3IntINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtBb_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsC_NtNtNtCscrZQdumITES_3der4asn17integer4uintNtB5_7UintRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB9_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXse_NtNtNtNtCscrZQdumITES_3der4asn17integer4uint10allocatingNtB5_4UintINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtBb_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsh_NtNtCscrZQdumITES_3der4asn14nullNtB5_4NullINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB7_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsg_NtNtCscrZQdumITES_3der4asn112octet_stringNtB5_14OctetStringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB7_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsf_NtNtNtCscrZQdumITES_3der4asn112octet_string10allocatingNtB5_11OctetStringINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB9_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsc_NtNtCscrZQdumITES_3der4asn116printable_stringNtB5_18PrintableStringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB7_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXse_NtNtNtCscrZQdumITES_3der4asn116printable_string10allocationNtB5_15PrintableStringINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB9_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsc_NtNtCscrZQdumITES_3der4asn114teletex_stringNtB5_16TeletexStringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB7_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXse_NtNtNtCscrZQdumITES_3der4asn114teletex_string10allocationNtB5_13TeletexStringINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB9_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsi_NtNtCscrZQdumITES_3der4asn18utc_timeNtB5_7UtcTimeINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB7_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsm_NtNtCscrZQdumITES_3der4asn111utf8_stringNtB5_13Utf8StringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB7_3any10allocating3AnyE8try_from
Unexecuted instantiation: _RNvXsd_NtNtCscrZQdumITES_3der4asn115videotex_stringNtB5_17VideotexStringRefINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtNtNtB7_3any10allocating3AnyE8try_from
21
        }
22
    };
23
}
24
25
macro_rules! impl_string_type {
26
    ($type: ty, $($li: lifetime)?) => {
27
        impl_any_conversions!($type, $($li),*);
28
29
        mod __impl_string {
30
            use super::*;
31
32
            use crate::{
33
                ord::OrdIsValueOrd, BytesRef, DecodeValue, EncodeValue, Header, Length, Reader,
34
                Result, Writer,
35
            };
36
            use core::{fmt, str};
37
38
            impl<$($li),*> AsRef<str> for $type {
39
0
                fn as_ref(&self) -> &str {
40
0
                    self.as_str()
41
0
                }
Unexecuted instantiation: _RNvXNtNtNtCscrZQdumITES_3der4asn110ia5_string13___impl_stringNtB4_12Ia5StringRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefeE6as_refB8_
Unexecuted instantiation: _RNvXNtNtNtNtCscrZQdumITES_3der4asn110ia5_string10allocation13___impl_stringNtB4_9Ia5StringINtNtCsbQ8arDwx5Xq_4core7convert5AsRefeE6as_ref
Unexecuted instantiation: _RNvXNtNtNtCscrZQdumITES_3der4asn116printable_string13___impl_stringNtB4_18PrintableStringRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefeE6as_refB8_
Unexecuted instantiation: _RNvXNtNtNtNtCscrZQdumITES_3der4asn116printable_string10allocation13___impl_stringNtB4_15PrintableStringINtNtCsbQ8arDwx5Xq_4core7convert5AsRefeE6as_ref
Unexecuted instantiation: _RNvXNtNtNtCscrZQdumITES_3der4asn114teletex_string13___impl_stringNtB4_16TeletexStringRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefeE6as_refB8_
Unexecuted instantiation: _RNvXNtNtNtNtCscrZQdumITES_3der4asn114teletex_string10allocation13___impl_stringNtB4_13TeletexStringINtNtCsbQ8arDwx5Xq_4core7convert5AsRefeE6as_ref
Unexecuted instantiation: _RNvXNtNtNtCscrZQdumITES_3der4asn111utf8_string13___impl_stringNtB4_13Utf8StringRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefeE6as_refB8_
Unexecuted instantiation: _RNvXNtNtNtCscrZQdumITES_3der4asn115videotex_string13___impl_stringNtB4_17VideotexStringRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefeE6as_refB8_
42
            }
43
44
            impl<$($li),*> AsRef<[u8]> for $type {
45
0
                fn as_ref(&self) -> &[u8] {
46
0
                    self.as_bytes()
47
0
                }
Unexecuted instantiation: _RNvXs_NtNtNtCscrZQdumITES_3der4asn110ia5_string13___impl_stringNtB6_12Ia5StringRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_refBa_
Unexecuted instantiation: _RNvXs_NtNtNtNtCscrZQdumITES_3der4asn110ia5_string10allocation13___impl_stringNtB6_9Ia5StringINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_ref
Unexecuted instantiation: _RNvXs_NtNtNtCscrZQdumITES_3der4asn116printable_string13___impl_stringNtB6_18PrintableStringRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_refBa_
Unexecuted instantiation: _RNvXs_NtNtNtNtCscrZQdumITES_3der4asn116printable_string10allocation13___impl_stringNtB6_15PrintableStringINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_ref
Unexecuted instantiation: _RNvXs_NtNtNtCscrZQdumITES_3der4asn114teletex_string13___impl_stringNtB6_16TeletexStringRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_refBa_
Unexecuted instantiation: _RNvXs_NtNtNtNtCscrZQdumITES_3der4asn114teletex_string10allocation13___impl_stringNtB6_13TeletexStringINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_ref
Unexecuted instantiation: _RNvXs_NtNtNtCscrZQdumITES_3der4asn111utf8_string13___impl_stringNtB6_13Utf8StringRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_refBa_
Unexecuted instantiation: _RNvXs_NtNtNtCscrZQdumITES_3der4asn115videotex_string13___impl_stringNtB6_17VideotexStringRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_refBa_
48
            }
49
50
            impl<'__der: $($li),*, $($li),*> DecodeValue<'__der> for $type {
51
0
                fn decode_value<R: Reader<'__der>>(reader: &mut R, header: Header) -> Result<Self> {
52
0
                    Self::new(BytesRef::decode_value(reader, header)?.as_slice())
53
0
                }
Unexecuted instantiation: _RINvXs0_NtNtNtCscrZQdumITES_3der4asn110ia5_string13___impl_stringNtB8_12Ia5StringRefNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXs0_NtNtNtNtCscrZQdumITES_3der4asn110ia5_string10allocation13___impl_stringNtB8_9Ia5StringNtNtBe_6decode11DecodeValue12decode_valueNtNtNtBe_6reader5slice11SliceReaderEBe_
Unexecuted instantiation: _RINvXs0_NtNtNtCscrZQdumITES_3der4asn116printable_string13___impl_stringNtB8_18PrintableStringRefNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXs0_NtNtNtNtCscrZQdumITES_3der4asn116printable_string10allocation13___impl_stringNtB8_15PrintableStringNtNtBe_6decode11DecodeValue12decode_valueNtNtNtBe_6reader5slice11SliceReaderEBe_
Unexecuted instantiation: _RINvXs0_NtNtNtCscrZQdumITES_3der4asn114teletex_string13___impl_stringNtB8_16TeletexStringRefNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXs0_NtNtNtNtCscrZQdumITES_3der4asn114teletex_string10allocation13___impl_stringNtB8_13TeletexStringNtNtBe_6decode11DecodeValue12decode_valueNtNtNtBe_6reader5slice11SliceReaderEBe_
Unexecuted instantiation: _RINvXs0_NtNtNtCscrZQdumITES_3der4asn111utf8_string13___impl_stringNtB8_13Utf8StringRefNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
Unexecuted instantiation: _RINvXs0_NtNtNtCscrZQdumITES_3der4asn115videotex_string13___impl_stringNtB8_17VideotexStringRefNtNtBc_6decode11DecodeValue12decode_valueNtNtNtBc_6reader5slice11SliceReaderEBc_
54
            }
55
56
            impl<$($li),*> EncodeValue for $type {
57
0
                fn value_len(&self) -> Result<Length> {
58
0
                    self.inner.value_len()
59
0
                }
Unexecuted instantiation: _RNvXs1_NtNtNtCscrZQdumITES_3der4asn111utf8_string13___impl_stringNtB7_13Utf8StringRefNtNtBb_6encode11EncodeValue9value_lenBb_
Unexecuted instantiation: _RNvXs1_NtNtNtCscrZQdumITES_3der4asn110ia5_string13___impl_stringNtB7_12Ia5StringRefNtNtBb_6encode11EncodeValue9value_lenBb_
Unexecuted instantiation: _RNvXs1_NtNtNtNtCscrZQdumITES_3der4asn110ia5_string10allocation13___impl_stringNtB7_9Ia5StringNtNtBd_6encode11EncodeValue9value_lenBd_
Unexecuted instantiation: _RNvXs1_NtNtNtCscrZQdumITES_3der4asn116printable_string13___impl_stringNtB7_18PrintableStringRefNtNtBb_6encode11EncodeValue9value_lenBb_
Unexecuted instantiation: _RNvXs1_NtNtNtNtCscrZQdumITES_3der4asn116printable_string10allocation13___impl_stringNtB7_15PrintableStringNtNtBd_6encode11EncodeValue9value_lenBd_
Unexecuted instantiation: _RNvXs1_NtNtNtCscrZQdumITES_3der4asn114teletex_string13___impl_stringNtB7_16TeletexStringRefNtNtBb_6encode11EncodeValue9value_lenBb_
Unexecuted instantiation: _RNvXs1_NtNtNtNtCscrZQdumITES_3der4asn114teletex_string10allocation13___impl_stringNtB7_13TeletexStringNtNtBd_6encode11EncodeValue9value_lenBd_
Unexecuted instantiation: _RNvXs1_NtNtNtCscrZQdumITES_3der4asn115videotex_string13___impl_stringNtB7_17VideotexStringRefNtNtBb_6encode11EncodeValue9value_lenBb_
60
61
0
                fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
62
0
                    self.inner.encode_value(writer)
63
0
                }
Unexecuted instantiation: _RINvXs1_NtNtNtCscrZQdumITES_3der4asn110ia5_string13___impl_stringNtB8_12Ia5StringRefNtNtBc_6encode11EncodeValue12encode_valuepEBc_
Unexecuted instantiation: _RINvXs1_NtNtNtNtCscrZQdumITES_3der4asn110ia5_string10allocation13___impl_stringNtB8_9Ia5StringNtNtBe_6encode11EncodeValue12encode_valuepEBe_
Unexecuted instantiation: _RINvXs1_NtNtNtCscrZQdumITES_3der4asn116printable_string13___impl_stringNtB8_18PrintableStringRefNtNtBc_6encode11EncodeValue12encode_valuepEBc_
Unexecuted instantiation: _RINvXs1_NtNtNtNtCscrZQdumITES_3der4asn116printable_string10allocation13___impl_stringNtB8_15PrintableStringNtNtBe_6encode11EncodeValue12encode_valuepEBe_
Unexecuted instantiation: _RINvXs1_NtNtNtCscrZQdumITES_3der4asn114teletex_string13___impl_stringNtB8_16TeletexStringRefNtNtBc_6encode11EncodeValue12encode_valuepEBc_
Unexecuted instantiation: _RINvXs1_NtNtNtNtCscrZQdumITES_3der4asn114teletex_string10allocation13___impl_stringNtB8_13TeletexStringNtNtBe_6encode11EncodeValue12encode_valuepEBe_
Unexecuted instantiation: _RINvXs1_NtNtNtCscrZQdumITES_3der4asn111utf8_string13___impl_stringNtB8_13Utf8StringRefNtNtBc_6encode11EncodeValue12encode_valuepEBc_
Unexecuted instantiation: _RINvXs1_NtNtNtCscrZQdumITES_3der4asn115videotex_string13___impl_stringNtB8_17VideotexStringRefNtNtBc_6encode11EncodeValue12encode_valuepEBc_
64
            }
65
66
            impl<$($li),*> OrdIsValueOrd for $type {}
67
68
            impl<$($li),*> fmt::Display for $type {
69
0
                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70
0
                    f.write_str(self.as_str())
71
0
                }
Unexecuted instantiation: _RNvXs3_NtNtNtCscrZQdumITES_3der4asn110ia5_string13___impl_stringNtB7_12Ia5StringRefNtNtCsbQ8arDwx5Xq_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs3_NtNtNtNtCscrZQdumITES_3der4asn110ia5_string10allocation13___impl_stringNtB7_9Ia5StringNtNtCsbQ8arDwx5Xq_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs3_NtNtNtCscrZQdumITES_3der4asn116printable_string13___impl_stringNtB7_18PrintableStringRefNtNtCsbQ8arDwx5Xq_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs3_NtNtNtNtCscrZQdumITES_3der4asn116printable_string10allocation13___impl_stringNtB7_15PrintableStringNtNtCsbQ8arDwx5Xq_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs3_NtNtNtCscrZQdumITES_3der4asn114teletex_string13___impl_stringNtB7_16TeletexStringRefNtNtCsbQ8arDwx5Xq_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs3_NtNtNtNtCscrZQdumITES_3der4asn114teletex_string10allocation13___impl_stringNtB7_13TeletexStringNtNtCsbQ8arDwx5Xq_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs3_NtNtNtCscrZQdumITES_3der4asn111utf8_string13___impl_stringNtB7_13Utf8StringRefNtNtCsbQ8arDwx5Xq_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs3_NtNtNtCscrZQdumITES_3der4asn115videotex_string13___impl_stringNtB7_17VideotexStringRefNtNtCsbQ8arDwx5Xq_4core3fmt7Display3fmt
72
            }
73
        }
74
    };
75
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/null.rs
Line
Count
Source
1
//! ASN.1 `NULL` support.
2
3
use crate::{
4
    asn1::AnyRef, ord::OrdIsValueOrd, BytesRef, DecodeValue, EncodeValue, Error, ErrorKind,
5
    FixedTag, Header, Length, Reader, Result, Tag, Writer,
6
};
7
8
/// ASN.1 `NULL` type.
9
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
10
pub struct Null;
11
12
impl_any_conversions!(Null);
13
14
impl<'a> DecodeValue<'a> for Null {
15
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
16
0
        if header.length.is_zero() {
17
0
            Ok(Null)
18
        } else {
19
0
            Err(reader.error(ErrorKind::Length { tag: Self::TAG }))
20
        }
21
0
    }
22
}
23
24
impl EncodeValue for Null {
25
0
    fn value_len(&self) -> Result<Length> {
26
0
        Ok(Length::ZERO)
27
0
    }
28
29
0
    fn encode_value(&self, _writer: &mut impl Writer) -> Result<()> {
30
0
        Ok(())
31
0
    }
32
}
33
34
impl FixedTag for Null {
35
    const TAG: Tag = Tag::Null;
36
}
37
38
impl OrdIsValueOrd for Null {}
39
40
impl<'a> From<Null> for AnyRef<'a> {
41
0
    fn from(_: Null) -> AnyRef<'a> {
42
0
        AnyRef::from_tag_and_value(Tag::Null, BytesRef::default())
43
0
    }
44
}
45
46
impl TryFrom<AnyRef<'_>> for () {
47
    type Error = Error;
48
49
0
    fn try_from(any: AnyRef<'_>) -> Result<()> {
50
0
        Null::try_from(any).map(|_| ())
51
0
    }
52
}
53
54
impl<'a> From<()> for AnyRef<'a> {
55
0
    fn from(_: ()) -> AnyRef<'a> {
56
0
        Null.into()
57
0
    }
58
}
59
60
impl<'a> DecodeValue<'a> for () {
61
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
62
0
        Null::decode_value(reader, header)?;
63
0
        Ok(())
64
0
    }
65
}
66
67
impl EncodeValue for () {
68
0
    fn value_len(&self) -> Result<Length> {
69
0
        Ok(Length::ZERO)
70
0
    }
71
72
0
    fn encode_value(&self, _writer: &mut impl Writer) -> Result<()> {
73
0
        Ok(())
74
0
    }
75
}
76
77
impl FixedTag for () {
78
    const TAG: Tag = Tag::Null;
79
}
80
81
#[cfg(test)]
82
mod tests {
83
    use super::Null;
84
    use crate::{Decode, Encode};
85
86
    #[test]
87
    fn decode() {
88
        Null::from_der(&[0x05, 0x00]).unwrap();
89
    }
90
91
    #[test]
92
    fn encode() {
93
        let mut buffer = [0u8; 2];
94
        assert_eq!(&[0x05, 0x00], Null.encode_to_slice(&mut buffer).unwrap());
95
        assert_eq!(&[0x05, 0x00], ().encode_to_slice(&mut buffer).unwrap());
96
    }
97
98
    #[test]
99
    fn reject_non_canonical() {
100
        assert!(Null::from_der(&[0x05, 0x81, 0x00]).is_err());
101
    }
102
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/octet_string.rs
Line
Count
Source
1
//! ASN.1 `OCTET STRING` support.
2
3
use crate::{
4
    asn1::AnyRef, ord::OrdIsValueOrd, BytesRef, Decode, DecodeValue, EncodeValue, ErrorKind,
5
    FixedTag, Header, Length, Reader, Result, Tag, Writer,
6
};
7
8
/// ASN.1 `OCTET STRING` type: borrowed form.
9
///
10
/// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
11
///
12
/// This is a zero-copy reference type which borrows from the input data.
13
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
14
pub struct OctetStringRef<'a> {
15
    /// Inner value
16
    inner: BytesRef<'a>,
17
}
18
19
impl<'a> OctetStringRef<'a> {
20
    /// Create a new ASN.1 `OCTET STRING` from a byte slice.
21
0
    pub fn new(slice: &'a [u8]) -> Result<Self> {
22
0
        BytesRef::new(slice)
23
0
            .map(|inner| Self { inner })
24
0
            .map_err(|_| ErrorKind::Length { tag: Self::TAG }.into())
25
0
    }
26
27
    /// Borrow the inner byte slice.
28
0
    pub fn as_bytes(&self) -> &'a [u8] {
29
0
        self.inner.as_slice()
30
0
    }
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn112octet_stringNtB2_14OctetStringRef8as_bytesB6_
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn112octet_stringNtB2_14OctetStringRef8as_bytesCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der4asn112octet_stringNtB2_14OctetStringRef8as_bytesCsj9qtwLkMHqH_4sec1
31
32
    /// Get the length of the inner byte slice.
33
0
    pub fn len(&self) -> Length {
34
0
        self.inner.len()
35
0
    }
36
37
    /// Is the inner byte slice empty?
38
0
    pub fn is_empty(&self) -> bool {
39
0
        self.inner.is_empty()
40
0
    }
41
42
    /// Parse `T` from this `OCTET STRING`'s contents.
43
0
    pub fn decode_into<T: Decode<'a>>(&self) -> Result<T> {
44
0
        Decode::from_der(self.as_bytes())
45
0
    }
46
}
47
48
impl_any_conversions!(OctetStringRef<'a>, 'a);
49
50
impl AsRef<[u8]> for OctetStringRef<'_> {
51
0
    fn as_ref(&self) -> &[u8] {
52
0
        self.as_bytes()
53
0
    }
54
}
55
56
impl<'a> DecodeValue<'a> for OctetStringRef<'a> {
57
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
58
0
        let inner = BytesRef::decode_value(reader, header)?;
59
0
        Ok(Self { inner })
60
0
    }
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn112octet_stringNtB6_14OctetStringRefNtNtBa_6decode11DecodeValue12decode_valueNtNtNtBa_6reader5slice11SliceReaderEBa_
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn112octet_stringNtB6_14OctetStringRefNtNtBa_6decode11DecodeValue12decode_valueINtNtNtBa_6reader6nested12NestedReaderNtNtB1Q_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn112octet_stringNtB6_14OctetStringRefNtNtBa_6decode11DecodeValue12decode_valueINtNtNtBa_6reader6nested12NestedReaderNtNtB1Q_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
61
}
62
63
impl EncodeValue for OctetStringRef<'_> {
64
0
    fn value_len(&self) -> Result<Length> {
65
0
        self.inner.value_len()
66
0
    }
Unexecuted instantiation: _RNvXs1_NtNtCscrZQdumITES_3der4asn112octet_stringNtB5_14OctetStringRefNtNtB9_6encode11EncodeValue9value_lenB9_
Unexecuted instantiation: _RNvXs1_NtNtCscrZQdumITES_3der4asn112octet_stringNtB5_14OctetStringRefNtNtB9_6encode11EncodeValue9value_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs1_NtNtCscrZQdumITES_3der4asn112octet_stringNtB5_14OctetStringRefNtNtB9_6encode11EncodeValue9value_lenCsj9qtwLkMHqH_4sec1
67
68
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
69
0
        self.inner.encode_value(writer)
70
0
    }
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn112octet_stringNtB6_14OctetStringRefNtNtBa_6encode11EncodeValue12encode_valuepEBa_
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn112octet_stringNtB6_14OctetStringRefNtNtBa_6encode11EncodeValue12encode_valueNtNtNtBa_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn112octet_stringNtB6_14OctetStringRefNtNtBa_6encode11EncodeValue12encode_valueNtNtNtBa_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
71
}
72
73
impl FixedTag for OctetStringRef<'_> {
74
    const TAG: Tag = Tag::OctetString;
75
}
76
77
impl OrdIsValueOrd for OctetStringRef<'_> {}
78
79
impl<'a> From<&OctetStringRef<'a>> for OctetStringRef<'a> {
80
0
    fn from(value: &OctetStringRef<'a>) -> OctetStringRef<'a> {
81
0
        *value
82
0
    }
83
}
84
85
impl<'a> From<OctetStringRef<'a>> for AnyRef<'a> {
86
0
    fn from(octet_string: OctetStringRef<'a>) -> AnyRef<'a> {
87
0
        AnyRef::from_tag_and_value(Tag::OctetString, octet_string.inner)
88
0
    }
89
}
90
91
impl<'a> From<OctetStringRef<'a>> for &'a [u8] {
92
0
    fn from(octet_string: OctetStringRef<'a>) -> &'a [u8] {
93
0
        octet_string.as_bytes()
94
0
    }
Unexecuted instantiation: _RNvXs6_NtNtCscrZQdumITES_3der4asn112octet_stringRShINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_14OctetStringRefE4fromB9_
Unexecuted instantiation: _RNvXs6_NtNtCscrZQdumITES_3der4asn112octet_stringRShINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_14OctetStringRefE4fromCssr1zNgi7Nt_5pkcs8
95
}
96
97
#[cfg(feature = "alloc")]
98
pub use self::allocating::OctetString;
99
100
#[cfg(feature = "alloc")]
101
mod allocating {
102
    use super::*;
103
    use crate::referenced::*;
104
    use alloc::vec::Vec;
105
106
    /// ASN.1 `OCTET STRING` type: owned form..
107
    ///
108
    /// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
109
    ///
110
    /// This type provides the same functionality as [`OctetStringRef`] but owns
111
    /// the backing data.
112
    #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
113
    pub struct OctetString {
114
        /// Bitstring represented as a slice of bytes.
115
        pub(super) inner: Vec<u8>,
116
    }
117
118
    impl OctetString {
119
        /// Create a new ASN.1 `OCTET STRING`.
120
0
        pub fn new(bytes: impl Into<Vec<u8>>) -> Result<Self> {
121
0
            let inner = bytes.into();
122
0
123
0
            // Ensure the bytes parse successfully as an `OctetStringRef`
124
0
            OctetStringRef::new(&inner)?;
125
126
0
            Ok(Self { inner })
127
0
        }
128
129
        /// Borrow the inner byte slice.
130
0
        pub fn as_bytes(&self) -> &[u8] {
131
0
            self.inner.as_slice()
132
0
        }
133
134
        /// Take ownership of the octet string.
135
0
        pub fn into_bytes(self) -> Vec<u8> {
136
0
            self.inner
137
0
        }
138
139
        /// Get the length of the inner byte slice.
140
0
        pub fn len(&self) -> Length {
141
0
            self.value_len().expect("invalid OCTET STRING length")
142
0
        }
143
144
        /// Is the inner byte slice empty?
145
0
        pub fn is_empty(&self) -> bool {
146
0
            self.inner.is_empty()
147
0
        }
148
    }
149
150
    impl_any_conversions!(OctetString);
151
152
    impl AsRef<[u8]> for OctetString {
153
0
        fn as_ref(&self) -> &[u8] {
154
0
            self.as_bytes()
155
0
        }
156
    }
157
158
    impl<'a> DecodeValue<'a> for OctetString {
159
0
        fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
160
0
            Self::new(reader.read_vec(header.length)?)
161
0
        }
162
    }
163
164
    impl EncodeValue for OctetString {
165
0
        fn value_len(&self) -> Result<Length> {
166
0
            self.inner.len().try_into()
167
0
        }
168
169
0
        fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
170
0
            writer.write(&self.inner)
171
0
        }
172
    }
173
174
    impl FixedTag for OctetString {
175
        const TAG: Tag = Tag::OctetString;
176
    }
177
178
    impl<'a> From<&'a OctetString> for OctetStringRef<'a> {
179
0
        fn from(octet_string: &'a OctetString) -> OctetStringRef<'a> {
180
0
            // Ensured to parse successfully in constructor
181
0
            OctetStringRef::new(&octet_string.inner).expect("invalid OCTET STRING")
182
0
        }
183
    }
184
185
    impl OrdIsValueOrd for OctetString {}
186
187
    impl<'a> RefToOwned<'a> for OctetStringRef<'a> {
188
        type Owned = OctetString;
189
0
        fn ref_to_owned(&self) -> Self::Owned {
190
0
            OctetString {
191
0
                inner: Vec::from(self.inner.as_slice()),
192
0
            }
193
0
        }
194
    }
195
196
    impl OwnedToRef for OctetString {
197
        type Borrowed<'a> = OctetStringRef<'a>;
198
0
        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
199
0
            self.into()
200
0
        }
201
    }
202
203
    // Implement by hand because the derive would create invalid values.
204
    // Use the constructor to create a valid value.
205
    #[cfg(feature = "arbitrary")]
206
    impl<'a> arbitrary::Arbitrary<'a> for OctetString {
207
        fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
208
            Self::new(Vec::arbitrary(u)?).map_err(|_| arbitrary::Error::IncorrectFormat)
209
        }
210
211
        fn size_hint(depth: usize) -> (usize, Option<usize>) {
212
            arbitrary::size_hint::and(u8::size_hint(depth), Vec::<u8>::size_hint(depth))
213
        }
214
    }
215
}
216
217
#[cfg(feature = "bytes")]
218
mod bytes {
219
    use super::OctetString;
220
    use crate::{DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Result, Tag, Writer};
221
    use bytes::Bytes;
222
223
    impl<'a> DecodeValue<'a> for Bytes {
224
        fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
225
            OctetString::decode_value(reader, header).map(|octet_string| octet_string.inner.into())
226
        }
227
    }
228
229
    impl EncodeValue for Bytes {
230
        fn value_len(&self) -> Result<Length> {
231
            self.len().try_into()
232
        }
233
234
        fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
235
            writer.write(self.as_ref())
236
        }
237
    }
238
239
    impl FixedTag for Bytes {
240
        const TAG: Tag = Tag::OctetString;
241
    }
242
}
243
244
#[cfg(test)]
245
mod tests {
246
    use crate::asn1::{OctetStringRef, PrintableStringRef};
247
248
    #[test]
249
    fn octet_string_decode_into() {
250
        // PrintableString "hi"
251
        let der = b"\x13\x02\x68\x69";
252
        let oct = OctetStringRef::new(der).unwrap();
253
254
        let res = oct.decode_into::<PrintableStringRef<'_>>().unwrap();
255
        assert_eq!(AsRef::<str>::as_ref(&res), "hi");
256
    }
257
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/oid.rs
Line
Count
Source
1
//! ASN.1 `OBJECT IDENTIFIER`
2
3
use crate::{
4
    asn1::AnyRef, ord::OrdIsValueOrd, DecodeValue, EncodeValue, Error, FixedTag, Header, Length,
5
    Reader, Result, Tag, Tagged, Writer,
6
};
7
use const_oid::ObjectIdentifier;
8
9
#[cfg(feature = "alloc")]
10
use super::Any;
11
12
impl<'a> DecodeValue<'a> for ObjectIdentifier {
13
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
14
0
        let mut buf = [0u8; ObjectIdentifier::MAX_SIZE];
15
0
        let slice = buf
16
0
            .get_mut(..header.length.try_into()?)
17
0
            .ok_or_else(|| Self::TAG.length_error())?;
Unexecuted instantiation: _RNCINvXNtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB9_6decode11DecodeValue12decode_valuepE0B9_
Unexecuted instantiation: _RNCINvXNtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB9_6decode11DecodeValue12decode_valueINtNtNtB9_6reader6nested12NestedReaderIB1Y_NtNtB22_5slice11SliceReaderEEE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvXNtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB9_6decode11DecodeValue12decode_valueINtNtNtB9_6reader6nested12NestedReaderIB1Y_NtNtB22_5slice11SliceReaderEEE0Csj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNCINvXNtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB9_6decode11DecodeValue12decode_valueINtNtNtB9_6reader6nested12NestedReaderNtNtB22_5slice11SliceReaderEE0Csj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNCINvXNtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB9_6decode11DecodeValue12decode_valueNtNtNtB9_6reader5slice11SliceReaderE0CskctcMqaO4X4_4spki
18
19
0
        let actual_len = reader.read_into(slice)?.len();
20
0
        debug_assert_eq!(actual_len, header.length.try_into()?);
21
0
        Ok(Self::from_bytes(slice)?)
22
0
    }
Unexecuted instantiation: _RINvXNtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB7_6decode11DecodeValue12decode_valuepEB7_
Unexecuted instantiation: _RINvXNtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB7_6decode11DecodeValue12decode_valueINtNtNtB7_6reader6nested12NestedReaderIB1W_NtNtB20_5slice11SliceReaderEEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB7_6decode11DecodeValue12decode_valueINtNtNtB7_6reader6nested12NestedReaderIB1W_NtNtB20_5slice11SliceReaderEEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXNtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB7_6decode11DecodeValue12decode_valueINtNtNtB7_6reader6nested12NestedReaderNtNtB20_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXNtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB7_6decode11DecodeValue12decode_valueNtNtNtB7_6reader5slice11SliceReaderECskctcMqaO4X4_4spki
23
}
24
25
impl EncodeValue for ObjectIdentifier {
26
0
    fn value_len(&self) -> Result<Length> {
27
0
        Length::try_from(self.as_bytes().len())
28
0
    }
29
30
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
31
0
        writer.write(self.as_bytes())
32
0
    }
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB9_6encode11EncodeValue12encode_valuepEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB9_6encode11EncodeValue12encode_valueNtNtNtB9_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der4asn13oidNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtB9_6encode11EncodeValue12encode_valueNtNtNtB9_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
33
}
34
35
impl FixedTag for ObjectIdentifier {
36
    const TAG: Tag = Tag::ObjectIdentifier;
37
}
38
39
impl OrdIsValueOrd for ObjectIdentifier {}
40
41
impl<'a> From<&'a ObjectIdentifier> for AnyRef<'a> {
42
0
    fn from(oid: &'a ObjectIdentifier) -> AnyRef<'a> {
43
0
        // Note: ensuring an infallible conversion is possible relies on the
44
0
        // invariant that `const_oid::MAX_LEN <= Length::max()`.
45
0
        //
46
0
        // The `length()` test below ensures this is the case.
47
0
        let value = oid
48
0
            .as_bytes()
49
0
            .try_into()
50
0
            .expect("OID length invariant violated");
51
0
52
0
        AnyRef::from_tag_and_value(Tag::ObjectIdentifier, value)
53
0
    }
54
}
55
56
#[cfg(feature = "alloc")]
57
impl From<ObjectIdentifier> for Any {
58
0
    fn from(oid: ObjectIdentifier) -> Any {
59
0
        AnyRef::from(&oid).into()
60
0
    }
61
}
62
63
impl TryFrom<AnyRef<'_>> for ObjectIdentifier {
64
    type Error = Error;
65
66
0
    fn try_from(any: AnyRef<'_>) -> Result<ObjectIdentifier> {
67
0
        any.tag().assert_eq(Tag::ObjectIdentifier)?;
68
0
        Ok(ObjectIdentifier::from_bytes(any.value())?)
69
0
    }
70
}
71
72
#[cfg(test)]
73
mod tests {
74
    use super::ObjectIdentifier;
75
    use crate::{Decode, Encode, Length};
76
77
    const EXAMPLE_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549");
78
    const EXAMPLE_OID_BYTES: &[u8; 8] = &[0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d];
79
80
    #[test]
81
    fn decode() {
82
        let oid = ObjectIdentifier::from_der(EXAMPLE_OID_BYTES).unwrap();
83
        assert_eq!(EXAMPLE_OID, oid);
84
    }
85
86
    #[test]
87
    fn encode() {
88
        let mut buffer = [0u8; 8];
89
        assert_eq!(
90
            EXAMPLE_OID_BYTES,
91
            EXAMPLE_OID.encode_to_slice(&mut buffer).unwrap()
92
        );
93
    }
94
95
    #[test]
96
    fn length() {
97
        // Ensure an infallible `From` conversion to `Any` will never panic
98
        assert!(ObjectIdentifier::MAX_SIZE <= Length::MAX.try_into().unwrap());
99
    }
100
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/optional.rs
Line
Count
Source
1
//! ASN.1 `OPTIONAL` as mapped to Rust's `Option` type
2
3
use crate::{Choice, Decode, DerOrd, Encode, Length, Reader, Result, Tag, Writer};
4
use core::cmp::Ordering;
5
6
impl<'a, T> Decode<'a> for Option<T>
7
where
8
    T: Choice<'a>, // NOTE: all `Decode + Tagged` types receive a blanket `Choice` impl
9
{
10
0
    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Option<T>> {
11
0
        if let Some(byte) = reader.peek_byte() {
12
0
            if T::can_decode(Tag::try_from(byte)?) {
13
0
                return T::decode(reader).map(Some);
14
0
            }
15
0
        }
16
17
0
        Ok(None)
18
0
    }
Unexecuted instantiation: _RINvXININtNtCscrZQdumITES_3der4asn18optional0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionpENtNtBa_6decode6Decode6decodepEBa_
Unexecuted instantiation: _RINvXNtNtCscrZQdumITES_3der4asn18optionalINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtB5_3any6AnyRefENtNtB7_6decode6Decode6decodeINtNtNtB7_6reader6nested12NestedReaderIB21_NtNtB25_5slice11SliceReaderEEECssr1zNgi7Nt_5pkcs8
19
}
20
21
impl<T> DerOrd for Option<T>
22
where
23
    T: DerOrd,
24
{
25
0
    fn der_cmp(&self, other: &Self) -> Result<Ordering> {
26
0
        match self {
27
0
            Some(a) => match other {
28
0
                Some(b) => a.der_cmp(b),
29
0
                None => Ok(Ordering::Greater),
30
            },
31
0
            None => Ok(Ordering::Less),
32
        }
33
0
    }
34
}
35
36
impl<T> Encode for Option<T>
37
where
38
    T: Encode,
39
{
40
0
    fn encoded_len(&self) -> Result<Length> {
41
0
        (&self).encoded_len()
42
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der4asn18optionals0_0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionpENtNtB9_6encode6Encode11encoded_lenB9_
Unexecuted instantiation: _RNvXs0_NtNtCscrZQdumITES_3der4asn18optionalINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtB7_3any6AnyRefENtNtB9_6encode6Encode11encoded_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs0_NtNtCscrZQdumITES_3der4asn18optionalINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB7_16context_specific15ContextSpecificNtNtB7_10bit_string12BitStringRefEENtNtB9_6encode6Encode11encoded_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs0_NtNtCscrZQdumITES_3der4asn18optionalINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB7_16context_specific18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersEENtNtB9_6encode6Encode11encoded_lenB25_
Unexecuted instantiation: _RNvXs0_NtNtCscrZQdumITES_3der4asn18optionalINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB7_16context_specific15ContextSpecificNtNtB7_10bit_string12BitStringRefEENtNtB9_6encode6Encode11encoded_lenCsj9qtwLkMHqH_4sec1
43
44
0
    fn encode(&self, writer: &mut impl Writer) -> Result<()> {
45
0
        (&self).encode(writer)
46
0
    }
Unexecuted instantiation: _RINvXININtNtCscrZQdumITES_3der4asn18optionals0_0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionpENtNtBa_6encode6Encode6encodepEBa_
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn18optionalINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtB8_3any6AnyRefENtNtBa_6encode6Encode6encodeNtNtNtBa_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn18optionalINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB8_16context_specific15ContextSpecificNtNtB8_10bit_string12BitStringRefEENtNtBa_6encode6Encode6encodeNtNtNtBa_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn18optionalINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB8_16context_specific18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersEENtNtBa_6encode6Encode6encodeNtNtNtBa_6writer5slice11SliceWriterEB26_
Unexecuted instantiation: _RINvXs0_NtNtCscrZQdumITES_3der4asn18optionalINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB8_16context_specific15ContextSpecificNtNtB8_10bit_string12BitStringRefEENtNtBa_6encode6Encode6encodeNtNtNtBa_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
47
}
48
49
impl<T> Encode for &Option<T>
50
where
51
    T: Encode,
52
{
53
0
    fn encoded_len(&self) -> Result<Length> {
54
0
        match self {
55
0
            Some(encodable) => encodable.encoded_len(),
56
0
            None => Ok(0u8.into()),
57
        }
58
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der4asn18optionals1_0pERINtNtCsbQ8arDwx5Xq_4core6option6OptionpENtNtB9_6encode6Encode11encoded_lenB9_
Unexecuted instantiation: _RNvXs1_NtNtCscrZQdumITES_3der4asn18optionalRINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtB7_3any6AnyRefENtNtB9_6encode6Encode11encoded_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs1_NtNtCscrZQdumITES_3der4asn18optionalRINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB7_16context_specific15ContextSpecificNtNtB7_10bit_string12BitStringRefEENtNtB9_6encode6Encode11encoded_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs1_NtNtCscrZQdumITES_3der4asn18optionalRINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB7_16context_specific18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersEENtNtB9_6encode6Encode11encoded_lenB26_
Unexecuted instantiation: _RNvXs1_NtNtCscrZQdumITES_3der4asn18optionalRINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB7_16context_specific15ContextSpecificNtNtB7_10bit_string12BitStringRefEENtNtB9_6encode6Encode11encoded_lenCsj9qtwLkMHqH_4sec1
59
60
0
    fn encode(&self, encoder: &mut impl Writer) -> Result<()> {
61
0
        match self {
62
0
            Some(encodable) => encodable.encode(encoder),
63
0
            None => Ok(()),
64
        }
65
0
    }
Unexecuted instantiation: _RINvXININtNtCscrZQdumITES_3der4asn18optionals1_0pERINtNtCsbQ8arDwx5Xq_4core6option6OptionpENtNtBa_6encode6Encode6encodepEBa_
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn18optionalRINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtB8_3any6AnyRefENtNtBa_6encode6Encode6encodeNtNtNtBa_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn18optionalRINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB8_16context_specific15ContextSpecificNtNtB8_10bit_string12BitStringRefEENtNtBa_6encode6Encode6encodeNtNtNtBa_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn18optionalRINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB8_16context_specific18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersEENtNtBa_6encode6Encode6encodeNtNtNtBa_6writer5slice11SliceWriterEB27_
Unexecuted instantiation: _RINvXs1_NtNtCscrZQdumITES_3der4asn18optionalRINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtB8_16context_specific15ContextSpecificNtNtB8_10bit_string12BitStringRefEENtNtBa_6encode6Encode6encodeNtNtNtBa_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
66
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/printable_string.rs
Line
Count
Source
1
//! ASN.1 `PrintableString` support.
2
3
use crate::{asn1::AnyRef, FixedTag, Result, StrRef, Tag};
4
use core::{fmt, ops::Deref};
5
6
macro_rules! impl_printable_string {
7
    ($type: ty) => {
8
        impl_printable_string!($type,);
9
    };
10
    ($type: ty, $($li: lifetime)?) => {
11
        impl_string_type!($type, $($li),*);
12
13
        impl<$($li),*> FixedTag for $type {
14
            const TAG: Tag = Tag::PrintableString;
15
        }
16
17
        impl<$($li),*> fmt::Debug for $type {
18
0
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19
0
                write!(f, "PrintableString({:?})", self.as_str())
20
0
            }
Unexecuted instantiation: _RNvXsa_NtNtCscrZQdumITES_3der4asn116printable_stringNtB5_18PrintableStringRefNtNtCsbQ8arDwx5Xq_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsc_NtNtNtCscrZQdumITES_3der4asn116printable_string10allocationNtB5_15PrintableStringNtNtCsbQ8arDwx5Xq_4core3fmt5Debug3fmt
21
        }
22
    };
23
}
24
25
/// ASN.1 `PrintableString` type.
26
///
27
/// Supports a subset the ASCII character set (described below).
28
///
29
/// For UTF-8, use [`Utf8StringRef`][`crate::asn1::Utf8StringRef`] instead.
30
/// For the full ASCII character set, use
31
/// [`Ia5StringRef`][`crate::asn1::Ia5StringRef`].
32
///
33
/// This is a zero-copy reference type which borrows from the input data.
34
///
35
/// # Supported characters
36
///
37
/// The following ASCII characters/ranges are supported:
38
///
39
/// - `A..Z`
40
/// - `a..z`
41
/// - `0..9`
42
/// - "` `" (i.e. space)
43
/// - `\`
44
/// - `(`
45
/// - `)`
46
/// - `+`
47
/// - `,`
48
/// - `-`
49
/// - `.`
50
/// - `/`
51
/// - `:`
52
/// - `=`
53
/// - `?`
54
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
55
pub struct PrintableStringRef<'a> {
56
    /// Inner value
57
    inner: StrRef<'a>,
58
}
59
60
impl<'a> PrintableStringRef<'a> {
61
    /// Create a new ASN.1 `PrintableString`.
62
0
    pub fn new<T>(input: &'a T) -> Result<Self>
63
0
    where
64
0
        T: AsRef<[u8]> + ?Sized,
65
0
    {
66
0
        let input = input.as_ref();
67
68
        // Validate all characters are within PrintableString's allowed set
69
0
        for &c in input.iter() {
70
0
            match c {
71
0
                b'A'..=b'Z'
72
0
                | b'a'..=b'z'
73
0
                | b'0'..=b'9'
74
                | b' '
75
                | b'\''
76
                | b'('
77
                | b')'
78
                | b'+'
79
                | b','
80
                | b'-'
81
                | b'.'
82
                | b'/'
83
                | b':'
84
                | b'='
85
0
                | b'?' => (),
86
0
                _ => return Err(Self::TAG.value_error()),
87
            }
88
        }
89
90
0
        StrRef::from_bytes(input)
91
0
            .map(|inner| Self { inner })
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116printable_stringNtB5_18PrintableStringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringE0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116printable_stringNtB5_18PrintableStringRef3newShE0B9_
92
0
            .map_err(|_| Self::TAG.value_error())
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116printable_stringNtB5_18PrintableStringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringEs_0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn116printable_stringNtB5_18PrintableStringRef3newShEs_0B9_
93
0
    }
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116printable_stringNtB3_18PrintableStringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn116printable_stringNtB3_18PrintableStringRef3newShEB7_
94
}
95
96
impl_printable_string!(PrintableStringRef<'a>, 'a);
97
98
impl<'a> Deref for PrintableStringRef<'a> {
99
    type Target = StrRef<'a>;
100
101
0
    fn deref(&self) -> &Self::Target {
102
0
        &self.inner
103
0
    }
104
}
105
impl<'a> From<&PrintableStringRef<'a>> for PrintableStringRef<'a> {
106
0
    fn from(value: &PrintableStringRef<'a>) -> PrintableStringRef<'a> {
107
0
        *value
108
0
    }
109
}
110
111
impl<'a> From<PrintableStringRef<'a>> for AnyRef<'a> {
112
0
    fn from(printable_string: PrintableStringRef<'a>) -> AnyRef<'a> {
113
0
        AnyRef::from_tag_and_value(Tag::PrintableString, printable_string.inner.into())
114
0
    }
115
}
116
117
#[cfg(feature = "alloc")]
118
pub use self::allocation::PrintableString;
119
120
#[cfg(feature = "alloc")]
121
mod allocation {
122
    use super::PrintableStringRef;
123
124
    use crate::{
125
        asn1::AnyRef,
126
        referenced::{OwnedToRef, RefToOwned},
127
        BytesRef, Error, FixedTag, Result, StrOwned, Tag,
128
    };
129
    use alloc::string::String;
130
    use core::{fmt, ops::Deref};
131
132
    /// ASN.1 `PrintableString` type.
133
    ///
134
    /// Supports a subset the ASCII character set (described below).
135
    ///
136
    /// For UTF-8, use [`Utf8StringRef`][`crate::asn1::Utf8StringRef`] instead.
137
    /// For the full ASCII character set, use
138
    /// [`Ia5StringRef`][`crate::asn1::Ia5StringRef`].
139
    ///
140
    /// # Supported characters
141
    ///
142
    /// The following ASCII characters/ranges are supported:
143
    ///
144
    /// - `A..Z`
145
    /// - `a..z`
146
    /// - `0..9`
147
    /// - "` `" (i.e. space)
148
    /// - `\`
149
    /// - `(`
150
    /// - `)`
151
    /// - `+`
152
    /// - `,`
153
    /// - `-`
154
    /// - `.`
155
    /// - `/`
156
    /// - `:`
157
    /// - `=`
158
    /// - `?`
159
    #[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
160
    pub struct PrintableString {
161
        /// Inner value
162
        inner: StrOwned,
163
    }
164
165
    impl PrintableString {
166
        /// Create a new ASN.1 `PrintableString`.
167
0
        pub fn new<T>(input: &T) -> Result<Self>
168
0
        where
169
0
            T: AsRef<[u8]> + ?Sized,
170
0
        {
171
0
            let input = input.as_ref();
172
0
            PrintableStringRef::new(input)?;
173
174
0
            StrOwned::from_bytes(input)
175
0
                .map(|inner| Self { inner })
176
0
                .map_err(|_| Self::TAG.value_error())
177
0
        }
178
    }
179
180
    impl_printable_string!(PrintableString);
181
182
    impl Deref for PrintableString {
183
        type Target = StrOwned;
184
185
0
        fn deref(&self) -> &Self::Target {
186
0
            &self.inner
187
0
        }
188
    }
189
190
    impl<'a> From<PrintableStringRef<'a>> for PrintableString {
191
0
        fn from(value: PrintableStringRef<'a>) -> PrintableString {
192
0
            let inner =
193
0
                StrOwned::from_bytes(value.inner.as_bytes()).expect("Invalid PrintableString");
194
0
            Self { inner }
195
0
        }
196
    }
197
198
    impl<'a> From<&'a PrintableString> for AnyRef<'a> {
199
0
        fn from(printable_string: &'a PrintableString) -> AnyRef<'a> {
200
0
            AnyRef::from_tag_and_value(
201
0
                Tag::PrintableString,
202
0
                BytesRef::new(printable_string.inner.as_bytes()).expect("Invalid PrintableString"),
203
0
            )
204
0
        }
205
    }
206
207
    impl<'a> RefToOwned<'a> for PrintableStringRef<'a> {
208
        type Owned = PrintableString;
209
0
        fn ref_to_owned(&self) -> Self::Owned {
210
0
            PrintableString {
211
0
                inner: self.inner.ref_to_owned(),
212
0
            }
213
0
        }
214
    }
215
216
    impl OwnedToRef for PrintableString {
217
        type Borrowed<'a> = PrintableStringRef<'a>;
218
0
        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
219
0
            PrintableStringRef {
220
0
                inner: self.inner.owned_to_ref(),
221
0
            }
222
0
        }
223
    }
224
225
    impl TryFrom<String> for PrintableString {
226
        type Error = Error;
227
228
0
        fn try_from(input: String) -> Result<Self> {
229
0
            PrintableStringRef::new(&input)?;
230
231
0
            StrOwned::new(input)
232
0
                .map(|inner| Self { inner })
233
0
                .map_err(|_| Self::TAG.value_error())
234
0
        }
235
    }
236
}
237
238
#[cfg(test)]
239
mod tests {
240
    use super::PrintableStringRef;
241
    use crate::Decode;
242
243
    #[test]
244
    fn parse_bytes() {
245
        let example_bytes = &[
246
            0x13, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x31,
247
        ];
248
249
        let printable_string = PrintableStringRef::from_der(example_bytes).unwrap();
250
        assert_eq!(printable_string.as_str(), "Test User 1");
251
    }
252
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/sequence.rs
Line
Count
Source
1
//! The [`Sequence`] trait simplifies writing decoders/encoders which map ASN.1
2
//! `SEQUENCE`s to Rust structs.
3
4
use crate::{
5
    BytesRef, DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Result, Tag, Writer,
6
};
7
8
#[cfg(feature = "alloc")]
9
use alloc::boxed::Box;
10
11
/// Marker trait for ASN.1 `SEQUENCE`s.
12
///
13
/// This is mainly used for custom derive.
14
pub trait Sequence<'a>: DecodeValue<'a> + EncodeValue {}
15
16
impl<'a, S> FixedTag for S
17
where
18
    S: Sequence<'a>,
19
{
20
    const TAG: Tag = Tag::Sequence;
21
}
22
23
#[cfg(feature = "alloc")]
24
impl<'a, T> Sequence<'a> for Box<T> where T: Sequence<'a> {}
25
26
/// The [`SequenceRef`] type provides raw access to the octets which comprise a
27
/// DER-encoded `SEQUENCE`.
28
///
29
/// This is a zero-copy reference type which borrows from the input data.
30
pub struct SequenceRef<'a> {
31
    /// Body of the `SEQUENCE`.
32
    body: BytesRef<'a>,
33
}
34
35
impl<'a> DecodeValue<'a> for SequenceRef<'a> {
36
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
37
0
        Ok(Self {
38
0
            body: BytesRef::decode_value(reader, header)?,
39
        })
40
0
    }
41
}
42
43
impl EncodeValue for SequenceRef<'_> {
44
0
    fn value_len(&self) -> Result<Length> {
45
0
        Ok(self.body.len())
46
0
    }
47
48
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
49
0
        self.body.encode_value(writer)
50
0
    }
51
}
52
53
impl<'a> Sequence<'a> for SequenceRef<'a> {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/sequence_of.rs
Line
Count
Source
1
//! ASN.1 `SEQUENCE OF` support.
2
3
use crate::{
4
    arrayvec, ord::iter_cmp, ArrayVec, Decode, DecodeValue, DerOrd, Encode, EncodeValue, FixedTag,
5
    Header, Length, Reader, Result, Tag, ValueOrd, Writer,
6
};
7
use core::cmp::Ordering;
8
9
#[cfg(feature = "alloc")]
10
use alloc::vec::Vec;
11
12
/// ASN.1 `SEQUENCE OF` backed by an array.
13
///
14
/// This type implements an append-only `SEQUENCE OF` type which is stack-based
15
/// and does not depend on `alloc` support.
16
// TODO(tarcieri): use `ArrayVec` when/if it's merged into `core`
17
// See: https://github.com/rust-lang/rfcs/pull/2990
18
#[derive(Clone, Debug, Eq, PartialEq)]
19
pub struct SequenceOf<T, const N: usize> {
20
    inner: ArrayVec<T, N>,
21
}
22
23
impl<T, const N: usize> SequenceOf<T, N> {
24
    /// Create a new [`SequenceOf`].
25
0
    pub fn new() -> Self {
26
0
        Self {
27
0
            inner: ArrayVec::new(),
28
0
        }
29
0
    }
30
31
    /// Add an element to this [`SequenceOf`].
32
0
    pub fn add(&mut self, element: T) -> Result<()> {
33
0
        self.inner.push(element)
34
0
    }
35
36
    /// Get an element of this [`SequenceOf`].
37
0
    pub fn get(&self, index: usize) -> Option<&T> {
38
0
        self.inner.get(index)
39
0
    }
40
41
    /// Iterate over the elements in this [`SequenceOf`].
42
0
    pub fn iter(&self) -> SequenceOfIter<'_, T> {
43
0
        SequenceOfIter {
44
0
            inner: self.inner.iter(),
45
0
        }
46
0
    }
47
48
    /// Is this [`SequenceOf`] empty?
49
0
    pub fn is_empty(&self) -> bool {
50
0
        self.inner.is_empty()
51
0
    }
52
53
    /// Number of elements in this [`SequenceOf`].
54
0
    pub fn len(&self) -> usize {
55
0
        self.inner.len()
56
0
    }
57
}
58
59
impl<T, const N: usize> Default for SequenceOf<T, N> {
60
0
    fn default() -> Self {
61
0
        Self::new()
62
0
    }
63
}
64
65
impl<'a, T, const N: usize> DecodeValue<'a> for SequenceOf<T, N>
66
where
67
    T: Decode<'a>,
68
{
69
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
70
0
        reader.read_nested(header.length, |reader| {
71
0
            let mut sequence_of = Self::new();
72
73
0
            while !reader.is_finished() {
74
0
                sequence_of.add(T::decode(reader)?)?;
75
            }
76
77
0
            Ok(sequence_of)
78
0
        })
79
0
    }
80
}
81
82
impl<T, const N: usize> EncodeValue for SequenceOf<T, N>
83
where
84
    T: Encode,
85
{
86
0
    fn value_len(&self) -> Result<Length> {
87
0
        self.iter()
88
0
            .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
89
0
    }
90
91
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
92
0
        for elem in self.iter() {
93
0
            elem.encode(writer)?;
94
        }
95
96
0
        Ok(())
97
0
    }
98
}
99
100
impl<T, const N: usize> FixedTag for SequenceOf<T, N> {
101
    const TAG: Tag = Tag::Sequence;
102
}
103
104
impl<T, const N: usize> ValueOrd for SequenceOf<T, N>
105
where
106
    T: DerOrd,
107
{
108
0
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
109
0
        iter_cmp(self.iter(), other.iter())
110
0
    }
111
}
112
113
/// Iterator over the elements of an [`SequenceOf`].
114
#[derive(Clone, Debug)]
115
pub struct SequenceOfIter<'a, T> {
116
    /// Inner iterator.
117
    inner: arrayvec::Iter<'a, T>,
118
}
119
120
impl<'a, T> Iterator for SequenceOfIter<'a, T> {
121
    type Item = &'a T;
122
123
0
    fn next(&mut self) -> Option<&'a T> {
124
0
        self.inner.next()
125
0
    }
126
}
127
128
impl<'a, T> ExactSizeIterator for SequenceOfIter<'a, T> {}
129
130
impl<'a, T, const N: usize> DecodeValue<'a> for [T; N]
131
where
132
    T: Decode<'a>,
133
{
134
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
135
0
        let sequence_of = SequenceOf::<T, N>::decode_value(reader, header)?;
136
137
        // TODO(tarcieri): use `[T; N]::try_map` instead of `expect` when stable
138
0
        if sequence_of.inner.len() == N {
139
0
            Ok(sequence_of
140
0
                .inner
141
0
                .into_array()
142
0
                .map(|elem| elem.expect("arrayvec length mismatch")))
143
        } else {
144
0
            Err(Self::TAG.length_error())
145
        }
146
0
    }
147
}
148
149
impl<T, const N: usize> EncodeValue for [T; N]
150
where
151
    T: Encode,
152
{
153
0
    fn value_len(&self) -> Result<Length> {
154
0
        self.iter()
155
0
            .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
156
0
    }
157
158
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
159
0
        for elem in self {
160
0
            elem.encode(writer)?;
161
        }
162
163
0
        Ok(())
164
0
    }
165
}
166
167
impl<T, const N: usize> FixedTag for [T; N] {
168
    const TAG: Tag = Tag::Sequence;
169
}
170
171
impl<T, const N: usize> ValueOrd for [T; N]
172
where
173
    T: DerOrd,
174
{
175
0
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
176
0
        iter_cmp(self.iter(), other.iter())
177
0
    }
178
}
179
180
#[cfg(feature = "alloc")]
181
impl<'a, T> DecodeValue<'a> for Vec<T>
182
where
183
    T: Decode<'a>,
184
{
185
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
186
0
        reader.read_nested(header.length, |reader| {
187
0
            let mut sequence_of = Self::new();
188
189
0
            while !reader.is_finished() {
190
0
                sequence_of.push(T::decode(reader)?);
191
            }
192
193
0
            Ok(sequence_of)
194
0
        })
195
0
    }
196
}
197
198
#[cfg(feature = "alloc")]
199
impl<T> EncodeValue for Vec<T>
200
where
201
    T: Encode,
202
{
203
0
    fn value_len(&self) -> Result<Length> {
204
0
        self.iter()
205
0
            .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
206
0
    }
207
208
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
209
0
        for elem in self {
210
0
            elem.encode(writer)?;
211
        }
212
213
0
        Ok(())
214
0
    }
215
}
216
217
#[cfg(feature = "alloc")]
218
impl<T> FixedTag for Vec<T> {
219
    const TAG: Tag = Tag::Sequence;
220
}
221
222
#[cfg(feature = "alloc")]
223
impl<T> ValueOrd for Vec<T>
224
where
225
    T: DerOrd,
226
{
227
0
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
228
0
        iter_cmp(self.iter(), other.iter())
229
0
    }
230
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/set_of.rs
Line
Count
Source
1
//! ASN.1 `SET OF` support.
2
//!
3
//! # Ordering Notes
4
//!
5
//! Some DER serializer implementations fail to properly sort elements of a
6
//! `SET OF`. This is technically non-canonical, but occurs frequently
7
//! enough that most DER decoders tolerate it. Unfortunately because
8
//! of that, we must also follow suit.
9
//!
10
//! However, all types in this module sort elements of a set at decode-time,
11
//! ensuring they'll be in the proper order if reserialized.
12
13
use crate::{
14
    arrayvec, ord::iter_cmp, ArrayVec, Decode, DecodeValue, DerOrd, Encode, EncodeValue, Error,
15
    ErrorKind, FixedTag, Header, Length, Reader, Result, Tag, ValueOrd, Writer,
16
};
17
use core::cmp::Ordering;
18
19
#[cfg(feature = "alloc")]
20
use {alloc::vec::Vec, core::slice};
21
22
/// ASN.1 `SET OF` backed by an array.
23
///
24
/// This type implements an append-only `SET OF` type which is stack-based
25
/// and does not depend on `alloc` support.
26
// TODO(tarcieri): use `ArrayVec` when/if it's merged into `core`
27
// See: https://github.com/rust-lang/rfcs/pull/2990
28
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
29
pub struct SetOf<T, const N: usize>
30
where
31
    T: DerOrd,
32
{
33
    inner: ArrayVec<T, N>,
34
}
35
36
impl<T, const N: usize> SetOf<T, N>
37
where
38
    T: DerOrd,
39
{
40
    /// Create a new [`SetOf`].
41
0
    pub fn new() -> Self {
42
0
        Self {
43
0
            inner: ArrayVec::default(),
44
0
        }
45
0
    }
46
47
    /// Add an item to this [`SetOf`].
48
    ///
49
    /// Items MUST be added in lexicographical order according to the
50
    /// [`DerOrd`] impl on `T`.
51
    #[deprecated(since = "0.7.6", note = "use `insert` or `insert_ordered` instead")]
52
0
    pub fn add(&mut self, new_elem: T) -> Result<()> {
53
0
        self.insert_ordered(new_elem)
54
0
    }
55
56
    /// Insert an item into this [`SetOf`].
57
0
    pub fn insert(&mut self, item: T) -> Result<()> {
58
0
        self.inner.push(item)?;
59
0
        der_sort(self.inner.as_mut())
60
0
    }
61
62
    /// Insert an item into this [`SetOf`].
63
    ///
64
    /// Items MUST be added in lexicographical order according to the
65
    /// [`DerOrd`] impl on `T`.
66
0
    pub fn insert_ordered(&mut self, item: T) -> Result<()> {
67
        // Ensure set elements are lexicographically ordered
68
0
        if let Some(last) = self.inner.last() {
69
0
            check_der_ordering(last, &item)?;
70
0
        }
71
72
0
        self.inner.push(item)
73
0
    }
74
75
    /// Get the nth element from this [`SetOf`].
76
0
    pub fn get(&self, index: usize) -> Option<&T> {
77
0
        self.inner.get(index)
78
0
    }
79
80
    /// Iterate over the elements of this [`SetOf`].
81
0
    pub fn iter(&self) -> SetOfIter<'_, T> {
82
0
        SetOfIter {
83
0
            inner: self.inner.iter(),
84
0
        }
85
0
    }
86
87
    /// Is this [`SetOf`] empty?
88
0
    pub fn is_empty(&self) -> bool {
89
0
        self.inner.is_empty()
90
0
    }
91
92
    /// Number of elements in this [`SetOf`].
93
0
    pub fn len(&self) -> usize {
94
0
        self.inner.len()
95
0
    }
96
}
97
98
impl<T, const N: usize> Default for SetOf<T, N>
99
where
100
    T: DerOrd,
101
{
102
0
    fn default() -> Self {
103
0
        Self::new()
104
0
    }
105
}
106
107
impl<'a, T, const N: usize> DecodeValue<'a> for SetOf<T, N>
108
where
109
    T: Decode<'a> + DerOrd,
110
{
111
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
112
0
        reader.read_nested(header.length, |reader| {
113
0
            let mut result = Self::new();
114
115
0
            while !reader.is_finished() {
116
0
                result.inner.push(T::decode(reader)?)?;
117
            }
118
119
0
            der_sort(result.inner.as_mut())?;
120
0
            validate(result.inner.as_ref())?;
121
0
            Ok(result)
122
0
        })
123
0
    }
124
}
125
126
impl<'a, T, const N: usize> EncodeValue for SetOf<T, N>
127
where
128
    T: 'a + Decode<'a> + Encode + DerOrd,
129
{
130
0
    fn value_len(&self) -> Result<Length> {
131
0
        self.iter()
132
0
            .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
133
0
    }
134
135
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
136
0
        for elem in self.iter() {
137
0
            elem.encode(writer)?;
138
        }
139
140
0
        Ok(())
141
0
    }
142
}
143
144
impl<'a, T, const N: usize> FixedTag for SetOf<T, N>
145
where
146
    T: Decode<'a> + DerOrd,
147
{
148
    const TAG: Tag = Tag::Set;
149
}
150
151
impl<T, const N: usize> TryFrom<[T; N]> for SetOf<T, N>
152
where
153
    T: DerOrd,
154
{
155
    type Error = Error;
156
157
0
    fn try_from(mut arr: [T; N]) -> Result<SetOf<T, N>> {
158
0
        der_sort(&mut arr)?;
159
160
0
        let mut result = SetOf::new();
161
162
0
        for elem in arr {
163
0
            result.insert_ordered(elem)?;
164
        }
165
166
0
        Ok(result)
167
0
    }
168
}
169
170
impl<T, const N: usize> ValueOrd for SetOf<T, N>
171
where
172
    T: DerOrd,
173
{
174
0
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
175
0
        iter_cmp(self.iter(), other.iter())
176
0
    }
177
}
178
179
/// Iterator over the elements of an [`SetOf`].
180
#[derive(Clone, Debug)]
181
pub struct SetOfIter<'a, T> {
182
    /// Inner iterator.
183
    inner: arrayvec::Iter<'a, T>,
184
}
185
186
impl<'a, T> Iterator for SetOfIter<'a, T> {
187
    type Item = &'a T;
188
189
0
    fn next(&mut self) -> Option<&'a T> {
190
0
        self.inner.next()
191
0
    }
192
}
193
194
impl<'a, T> ExactSizeIterator for SetOfIter<'a, T> {}
195
196
/// ASN.1 `SET OF` backed by a [`Vec`].
197
///
198
/// This type implements an append-only `SET OF` type which is heap-backed
199
/// and depends on `alloc` support.
200
#[cfg(feature = "alloc")]
201
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
202
pub struct SetOfVec<T>
203
where
204
    T: DerOrd,
205
{
206
    inner: Vec<T>,
207
}
208
209
#[cfg(feature = "alloc")]
210
impl<T: DerOrd> Default for SetOfVec<T> {
211
0
    fn default() -> Self {
212
0
        Self {
213
0
            inner: Default::default(),
214
0
        }
215
0
    }
216
}
217
218
#[cfg(feature = "alloc")]
219
impl<T> SetOfVec<T>
220
where
221
    T: DerOrd,
222
{
223
    /// Create a new [`SetOfVec`].
224
0
    pub fn new() -> Self {
225
0
        Self {
226
0
            inner: Vec::default(),
227
0
        }
228
0
    }
229
230
    /// Create a new [`SetOfVec`] from the given iterator.
231
    ///
232
    /// Note: this is an inherent method instead of an impl of the
233
    /// [`FromIterator`] trait in order to be fallible.
234
    #[allow(clippy::should_implement_trait)]
235
0
    pub fn from_iter<I>(iter: I) -> Result<Self>
236
0
    where
237
0
        I: IntoIterator<Item = T>,
238
0
    {
239
0
        Vec::from_iter(iter).try_into()
240
0
    }
241
242
    /// Add an element to this [`SetOfVec`].
243
    ///
244
    /// Items MUST be added in lexicographical order according to the
245
    /// [`DerOrd`] impl on `T`.
246
    #[deprecated(since = "0.7.6", note = "use `insert` or `insert_ordered` instead")]
247
0
    pub fn add(&mut self, item: T) -> Result<()> {
248
0
        self.insert_ordered(item)
249
0
    }
250
251
    /// Extend a [`SetOfVec`] using an iterator.
252
    ///
253
    /// Note: this is an inherent method instead of an impl of the
254
    /// [`Extend`] trait in order to be fallible.
255
0
    pub fn extend<I>(&mut self, iter: I) -> Result<()>
256
0
    where
257
0
        I: IntoIterator<Item = T>,
258
0
    {
259
0
        self.inner.extend(iter);
260
0
        der_sort(&mut self.inner)
261
0
    }
262
263
    /// Insert an item into this [`SetOfVec`]. Must be unique.
264
0
    pub fn insert(&mut self, item: T) -> Result<()> {
265
0
        self.inner.push(item);
266
0
        der_sort(&mut self.inner)
267
0
    }
268
269
    /// Insert an item into this [`SetOfVec`]. Must be unique.
270
    ///
271
    /// Items MUST be added in lexicographical order according to the
272
    /// [`DerOrd`] impl on `T`.
273
0
    pub fn insert_ordered(&mut self, item: T) -> Result<()> {
274
        // Ensure set elements are lexicographically ordered
275
0
        if let Some(last) = self.inner.last() {
276
0
            check_der_ordering(last, &item)?;
277
0
        }
278
279
0
        self.inner.push(item);
280
0
        Ok(())
281
0
    }
282
283
    /// Borrow the elements of this [`SetOfVec`] as a slice.
284
0
    pub fn as_slice(&self) -> &[T] {
285
0
        self.inner.as_slice()
286
0
    }
287
288
    /// Get the nth element from this [`SetOfVec`].
289
0
    pub fn get(&self, index: usize) -> Option<&T> {
290
0
        self.inner.get(index)
291
0
    }
292
293
    /// Convert this [`SetOfVec`] into the inner [`Vec`].
294
0
    pub fn into_vec(self) -> Vec<T> {
295
0
        self.inner
296
0
    }
297
298
    /// Iterate over the elements of this [`SetOfVec`].
299
0
    pub fn iter(&self) -> slice::Iter<'_, T> {
300
0
        self.inner.iter()
301
0
    }
302
303
    /// Is this [`SetOfVec`] empty?
304
0
    pub fn is_empty(&self) -> bool {
305
0
        self.inner.is_empty()
306
0
    }
307
308
    /// Number of elements in this [`SetOfVec`].
309
0
    pub fn len(&self) -> usize {
310
0
        self.inner.len()
311
0
    }
312
}
313
314
#[cfg(feature = "alloc")]
315
impl<T> AsRef<[T]> for SetOfVec<T>
316
where
317
    T: DerOrd,
318
{
319
0
    fn as_ref(&self) -> &[T] {
320
0
        self.as_slice()
321
0
    }
322
}
323
324
#[cfg(feature = "alloc")]
325
impl<'a, T> DecodeValue<'a> for SetOfVec<T>
326
where
327
    T: Decode<'a> + DerOrd,
328
{
329
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
330
0
        reader.read_nested(header.length, |reader| {
331
0
            let mut inner = Vec::new();
332
333
0
            while !reader.is_finished() {
334
0
                inner.push(T::decode(reader)?);
335
            }
336
337
0
            der_sort(inner.as_mut())?;
338
0
            validate(inner.as_ref())?;
339
0
            Ok(Self { inner })
340
0
        })
341
0
    }
342
}
343
344
#[cfg(feature = "alloc")]
345
impl<'a, T> EncodeValue for SetOfVec<T>
346
where
347
    T: 'a + Decode<'a> + Encode + DerOrd,
348
{
349
0
    fn value_len(&self) -> Result<Length> {
350
0
        self.iter()
351
0
            .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
352
0
    }
353
354
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
355
0
        for elem in self.iter() {
356
0
            elem.encode(writer)?;
357
        }
358
359
0
        Ok(())
360
0
    }
361
}
362
363
#[cfg(feature = "alloc")]
364
impl<T> FixedTag for SetOfVec<T>
365
where
366
    T: DerOrd,
367
{
368
    const TAG: Tag = Tag::Set;
369
}
370
371
#[cfg(feature = "alloc")]
372
impl<T> From<SetOfVec<T>> for Vec<T>
373
where
374
    T: DerOrd,
375
{
376
0
    fn from(set: SetOfVec<T>) -> Vec<T> {
377
0
        set.into_vec()
378
0
    }
379
}
380
381
#[cfg(feature = "alloc")]
382
impl<T> TryFrom<Vec<T>> for SetOfVec<T>
383
where
384
    T: DerOrd,
385
{
386
    type Error = Error;
387
388
0
    fn try_from(mut vec: Vec<T>) -> Result<SetOfVec<T>> {
389
0
        der_sort(vec.as_mut_slice())?;
390
0
        Ok(SetOfVec { inner: vec })
391
0
    }
392
}
393
394
#[cfg(feature = "alloc")]
395
impl<T, const N: usize> TryFrom<[T; N]> for SetOfVec<T>
396
where
397
    T: DerOrd,
398
{
399
    type Error = Error;
400
401
0
    fn try_from(arr: [T; N]) -> Result<SetOfVec<T>> {
402
0
        Vec::from(arr).try_into()
403
0
    }
404
}
405
406
#[cfg(feature = "alloc")]
407
impl<T> ValueOrd for SetOfVec<T>
408
where
409
    T: DerOrd,
410
{
411
0
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
412
0
        iter_cmp(self.iter(), other.iter())
413
0
    }
414
}
415
416
// Implement by hand because the derive would create invalid values.
417
// Use the conversion from Vec to create a valid value.
418
#[cfg(feature = "arbitrary")]
419
impl<'a, T> arbitrary::Arbitrary<'a> for SetOfVec<T>
420
where
421
    T: DerOrd + arbitrary::Arbitrary<'a>,
422
{
423
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
424
        Self::try_from(
425
            u.arbitrary_iter()?
426
                .collect::<std::result::Result<Vec<_>, _>>()?,
427
        )
428
        .map_err(|_| arbitrary::Error::IncorrectFormat)
429
    }
430
431
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
432
        (0, None)
433
    }
434
}
435
436
/// Ensure set elements are lexicographically ordered using [`DerOrd`].
437
0
fn check_der_ordering<T: DerOrd>(a: &T, b: &T) -> Result<()> {
438
0
    match a.der_cmp(b)? {
439
0
        Ordering::Less => Ok(()),
440
0
        Ordering::Equal => Err(ErrorKind::SetDuplicate.into()),
441
0
        Ordering::Greater => Err(ErrorKind::SetOrdering.into()),
442
    }
443
0
}
444
445
/// Sort a mut slice according to its [`DerOrd`], returning any errors which
446
/// might occur during the comparison.
447
///
448
/// The algorithm is insertion sort, which should perform well when the input
449
/// is mostly sorted to begin with.
450
///
451
/// This function is used rather than Rust's built-in `[T]::sort_by` in order
452
/// to support heapless `no_std` targets as well as to enable bubbling up
453
/// sorting errors.
454
#[allow(clippy::integer_arithmetic)]
455
0
fn der_sort<T: DerOrd>(slice: &mut [T]) -> Result<()> {
456
0
    for i in 0..slice.len() {
457
0
        let mut j = i;
458
459
0
        while j > 0 {
460
0
            match slice[j - 1].der_cmp(&slice[j])? {
461
0
                Ordering::Less => break,
462
0
                Ordering::Equal => return Err(ErrorKind::SetDuplicate.into()),
463
0
                Ordering::Greater => {
464
0
                    slice.swap(j - 1, j);
465
0
                    j -= 1;
466
0
                }
467
            }
468
        }
469
    }
470
471
0
    Ok(())
472
0
}
473
474
/// Validate the elements of a `SET OF`, ensuring that they are all in order
475
/// and that there are no duplicates.
476
0
fn validate<T: DerOrd>(slice: &[T]) -> Result<()> {
477
0
    if let Some(len) = slice.len().checked_sub(1) {
478
0
        for i in 0..len {
479
0
            let j = i.checked_add(1).ok_or(ErrorKind::Overflow)?;
480
481
0
            match slice.get(i..=j) {
482
0
                Some([a, b]) => {
483
0
                    if a.der_cmp(b)? != Ordering::Less {
484
0
                        return Err(ErrorKind::SetOrdering.into());
485
0
                    }
486
                }
487
0
                _ => return Err(Tag::Set.value_error()),
488
            }
489
        }
490
0
    }
491
492
0
    Ok(())
493
0
}
494
495
#[cfg(test)]
496
mod tests {
497
    use super::SetOf;
498
    #[cfg(feature = "alloc")]
499
    use super::SetOfVec;
500
    use crate::ErrorKind;
501
502
    #[test]
503
    fn setof_tryfrom_array() {
504
        let arr = [3u16, 2, 1, 65535, 0];
505
        let set = SetOf::try_from(arr).unwrap();
506
        assert!(set.iter().copied().eq([0, 1, 2, 3, 65535]));
507
    }
508
509
    #[test]
510
    fn setof_tryfrom_array_reject_duplicates() {
511
        let arr = [1u16, 1];
512
        let err = SetOf::try_from(arr).err().unwrap();
513
        assert_eq!(err.kind(), ErrorKind::SetDuplicate);
514
    }
515
516
    #[cfg(feature = "alloc")]
517
    #[test]
518
    fn setofvec_tryfrom_array() {
519
        let arr = [3u16, 2, 1, 65535, 0];
520
        let set = SetOfVec::try_from(arr).unwrap();
521
        assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
522
    }
523
524
    #[cfg(feature = "alloc")]
525
    #[test]
526
    fn setofvec_tryfrom_vec() {
527
        let vec = vec![3u16, 2, 1, 65535, 0];
528
        let set = SetOfVec::try_from(vec).unwrap();
529
        assert_eq!(set.as_ref(), &[0, 1, 2, 3, 65535]);
530
    }
531
532
    #[cfg(feature = "alloc")]
533
    #[test]
534
    fn setofvec_tryfrom_vec_reject_duplicates() {
535
        let vec = vec![1u16, 1];
536
        let err = SetOfVec::try_from(vec).err().unwrap();
537
        assert_eq!(err.kind(), ErrorKind::SetDuplicate);
538
    }
539
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/teletex_string.rs
Line
Count
Source
1
//! ASN.1 `TeletexString` support.
2
//!
3
use crate::{asn1::AnyRef, FixedTag, Result, StrRef, Tag};
4
use core::{fmt, ops::Deref};
5
6
macro_rules! impl_teletex_string {
7
    ($type: ty) => {
8
        impl_teletex_string!($type,);
9
    };
10
    ($type: ty, $($li: lifetime)?) => {
11
        impl_string_type!($type, $($li),*);
12
13
        impl<$($li),*> FixedTag for $type {
14
            const TAG: Tag = Tag::TeletexString;
15
        }
16
17
        impl<$($li),*> fmt::Debug for $type {
18
0
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19
0
                write!(f, "TeletexString({:?})", self.as_str())
20
0
            }
Unexecuted instantiation: _RNvXsa_NtNtCscrZQdumITES_3der4asn114teletex_stringNtB5_16TeletexStringRefNtNtCsbQ8arDwx5Xq_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsc_NtNtNtCscrZQdumITES_3der4asn114teletex_string10allocationNtB5_13TeletexStringNtNtCsbQ8arDwx5Xq_4core3fmt5Debug3fmt
21
        }
22
    };
23
}
24
25
/// ASN.1 `TeletexString` type.
26
///
27
/// Supports a subset the ASCII character set (described below).
28
///
29
/// For UTF-8, use [`Utf8StringRef`][`crate::asn1::Utf8StringRef`] instead.
30
/// For the full ASCII character set, use
31
/// [`Ia5StringRef`][`crate::asn1::Ia5StringRef`].
32
///
33
/// This is a zero-copy reference type which borrows from the input data.
34
///
35
/// # Supported characters
36
///
37
/// The standard defines a complex character set allowed in this type. However, quoting the ASN.1
38
/// mailing list, "a sizable volume of software in the world treats TeletexString (T61String) as a
39
/// simple 8-bit string with mostly Windows Latin 1 (superset of iso-8859-1) encoding".
40
///
41
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
42
pub struct TeletexStringRef<'a> {
43
    /// Inner value
44
    inner: StrRef<'a>,
45
}
46
47
impl<'a> TeletexStringRef<'a> {
48
    /// Create a new ASN.1 `TeletexString`.
49
0
    pub fn new<T>(input: &'a T) -> Result<Self>
50
0
    where
51
0
        T: AsRef<[u8]> + ?Sized,
52
0
    {
53
0
        let input = input.as_ref();
54
0
55
0
        // FIXME: support higher part of the charset
56
0
        if input.iter().any(|&c| c > 0x7F) {
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn114teletex_stringNtB5_16TeletexStringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringE0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn114teletex_stringNtB5_16TeletexStringRef3newShE0B9_
57
0
            return Err(Self::TAG.value_error());
58
0
        }
59
0
60
0
        StrRef::from_bytes(input)
61
0
            .map(|inner| Self { inner })
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn114teletex_stringNtB5_16TeletexStringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringEs_0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn114teletex_stringNtB5_16TeletexStringRef3newShEs_0B9_
62
0
            .map_err(|_| Self::TAG.value_error())
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn114teletex_stringNtB5_16TeletexStringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringEs0_0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn114teletex_stringNtB5_16TeletexStringRef3newShEs0_0B9_
63
0
    }
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn114teletex_stringNtB3_16TeletexStringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn114teletex_stringNtB3_16TeletexStringRef3newShEB7_
64
}
65
66
impl_teletex_string!(TeletexStringRef<'a>, 'a);
67
68
impl<'a> Deref for TeletexStringRef<'a> {
69
    type Target = StrRef<'a>;
70
71
0
    fn deref(&self) -> &Self::Target {
72
0
        &self.inner
73
0
    }
74
}
75
76
impl<'a> From<&TeletexStringRef<'a>> for TeletexStringRef<'a> {
77
0
    fn from(value: &TeletexStringRef<'a>) -> TeletexStringRef<'a> {
78
0
        *value
79
0
    }
80
}
81
82
impl<'a> From<TeletexStringRef<'a>> for AnyRef<'a> {
83
0
    fn from(teletex_string: TeletexStringRef<'a>) -> AnyRef<'a> {
84
0
        AnyRef::from_tag_and_value(Tag::TeletexString, teletex_string.inner.into())
85
0
    }
86
}
87
88
#[cfg(feature = "alloc")]
89
pub use self::allocation::TeletexString;
90
91
#[cfg(feature = "alloc")]
92
mod allocation {
93
    use super::TeletexStringRef;
94
95
    use crate::{
96
        asn1::AnyRef,
97
        referenced::{OwnedToRef, RefToOwned},
98
        BytesRef, Error, FixedTag, Result, StrOwned, Tag,
99
    };
100
    use alloc::string::String;
101
    use core::{fmt, ops::Deref};
102
103
    /// ASN.1 `TeletexString` type.
104
    ///
105
    /// Supports a subset the ASCII character set (described below).
106
    ///
107
    /// For UTF-8, use [`Utf8StringRef`][`crate::asn1::Utf8StringRef`] instead.
108
    /// For the full ASCII character set, use
109
    /// [`Ia5StringRef`][`crate::asn1::Ia5StringRef`].
110
    ///
111
    /// # Supported characters
112
    ///
113
    /// The standard defines a complex character set allowed in this type. However, quoting the ASN.1
114
    /// mailing list, "a sizable volume of software in the world treats TeletexString (T61String) as a
115
    /// simple 8-bit string with mostly Windows Latin 1 (superset of iso-8859-1) encoding".
116
    ///
117
    #[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
118
    pub struct TeletexString {
119
        /// Inner value
120
        inner: StrOwned,
121
    }
122
123
    impl TeletexString {
124
        /// Create a new ASN.1 `TeletexString`.
125
0
        pub fn new<T>(input: &T) -> Result<Self>
126
0
        where
127
0
            T: AsRef<[u8]> + ?Sized,
128
0
        {
129
0
            let input = input.as_ref();
130
0
131
0
            TeletexStringRef::new(input)?;
132
133
0
            StrOwned::from_bytes(input)
134
0
                .map(|inner| Self { inner })
135
0
                .map_err(|_| Self::TAG.value_error())
136
0
        }
137
    }
138
139
    impl_teletex_string!(TeletexString);
140
141
    impl Deref for TeletexString {
142
        type Target = StrOwned;
143
144
0
        fn deref(&self) -> &Self::Target {
145
0
            &self.inner
146
0
        }
147
    }
148
149
    impl<'a> From<TeletexStringRef<'a>> for TeletexString {
150
0
        fn from(value: TeletexStringRef<'a>) -> TeletexString {
151
0
            let inner =
152
0
                StrOwned::from_bytes(value.inner.as_bytes()).expect("Invalid TeletexString");
153
0
            Self { inner }
154
0
        }
155
    }
156
157
    impl<'a> From<&'a TeletexString> for AnyRef<'a> {
158
0
        fn from(teletex_string: &'a TeletexString) -> AnyRef<'a> {
159
0
            AnyRef::from_tag_and_value(
160
0
                Tag::TeletexString,
161
0
                BytesRef::new(teletex_string.inner.as_bytes()).expect("Invalid TeletexString"),
162
0
            )
163
0
        }
164
    }
165
166
    impl<'a> RefToOwned<'a> for TeletexStringRef<'a> {
167
        type Owned = TeletexString;
168
0
        fn ref_to_owned(&self) -> Self::Owned {
169
0
            TeletexString {
170
0
                inner: self.inner.ref_to_owned(),
171
0
            }
172
0
        }
173
    }
174
175
    impl OwnedToRef for TeletexString {
176
        type Borrowed<'a> = TeletexStringRef<'a>;
177
0
        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
178
0
            TeletexStringRef {
179
0
                inner: self.inner.owned_to_ref(),
180
0
            }
181
0
        }
182
    }
183
184
    impl TryFrom<String> for TeletexString {
185
        type Error = Error;
186
187
0
        fn try_from(input: String) -> Result<Self> {
188
0
            TeletexStringRef::new(&input)?;
189
190
0
            StrOwned::new(input)
191
0
                .map(|inner| Self { inner })
192
0
                .map_err(|_| Self::TAG.value_error())
193
0
        }
194
    }
195
}
196
197
#[cfg(test)]
198
mod tests {
199
    use super::TeletexStringRef;
200
    use crate::Decode;
201
    use crate::SliceWriter;
202
203
    #[test]
204
    fn parse_bytes() {
205
        let example_bytes = &[
206
            0x14, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x31,
207
        ];
208
209
        let teletex_string = TeletexStringRef::from_der(example_bytes).unwrap();
210
        assert_eq!(teletex_string.as_str(), "Test User 1");
211
        let mut out = [0_u8; 30];
212
        let mut writer = SliceWriter::new(&mut out);
213
        writer.encode(&teletex_string).unwrap();
214
        let encoded = writer.finish().unwrap();
215
        assert_eq!(encoded, example_bytes);
216
    }
217
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/utc_time.rs
Line
Count
Source
1
//! ASN.1 `UTCTime` support.
2
3
use crate::{
4
    datetime::{self, DateTime},
5
    ord::OrdIsValueOrd,
6
    DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader, Result, Tag,
7
    Writer,
8
};
9
use core::time::Duration;
10
11
#[cfg(feature = "std")]
12
use std::time::SystemTime;
13
14
/// ASN.1 `UTCTime` type.
15
///
16
/// This type implements the validity requirements specified in
17
/// [RFC 5280 Section 4.1.2.5.1][1], namely:
18
///
19
/// > For the purposes of this profile, UTCTime values MUST be expressed in
20
/// > Greenwich Mean Time (Zulu) and MUST include seconds (i.e., times are
21
/// > `YYMMDDHHMMSSZ`), even where the number of seconds is zero.  Conforming
22
/// > systems MUST interpret the year field (`YY`) as follows:
23
/// >
24
/// > - Where `YY` is greater than or equal to 50, the year SHALL be
25
/// >   interpreted as `19YY`; and
26
/// > - Where `YY` is less than 50, the year SHALL be interpreted as `20YY`.
27
///
28
/// Note: Due to common operations working on `UNIX_EPOCH` [`UtcTime`]s are
29
/// only supported for the years 1970-2049.
30
///
31
/// [1]: https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
32
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
33
pub struct UtcTime(DateTime);
34
35
impl UtcTime {
36
    /// Length of an RFC 5280-flavored ASN.1 DER-encoded [`UtcTime`].
37
    pub const LENGTH: usize = 13;
38
39
    /// Maximum year that can be represented as a `UTCTime`.
40
    pub const MAX_YEAR: u16 = 2049;
41
42
    /// Create a [`UtcTime`] from a [`DateTime`].
43
0
    pub fn from_date_time(datetime: DateTime) -> Result<Self> {
44
0
        if datetime.year() <= UtcTime::MAX_YEAR {
45
0
            Ok(Self(datetime))
46
        } else {
47
0
            Err(Self::TAG.value_error())
48
        }
49
0
    }
50
51
    /// Convert this [`UtcTime`] into a [`DateTime`].
52
0
    pub fn to_date_time(&self) -> DateTime {
53
0
        self.0
54
0
    }
55
56
    /// Create a new [`UtcTime`] given a [`Duration`] since `UNIX_EPOCH`
57
    /// (a.k.a. "Unix time")
58
0
    pub fn from_unix_duration(unix_duration: Duration) -> Result<Self> {
59
0
        DateTime::from_unix_duration(unix_duration)?.try_into()
60
0
    }
61
62
    /// Get the duration of this timestamp since `UNIX_EPOCH`.
63
0
    pub fn to_unix_duration(&self) -> Duration {
64
0
        self.0.unix_duration()
65
0
    }
66
67
    /// Instantiate from [`SystemTime`].
68
    #[cfg(feature = "std")]
69
0
    pub fn from_system_time(time: SystemTime) -> Result<Self> {
70
0
        DateTime::try_from(time)
71
0
            .map_err(|_| Self::TAG.value_error())?
72
0
            .try_into()
73
0
    }
74
75
    /// Convert to [`SystemTime`].
76
    #[cfg(feature = "std")]
77
0
    pub fn to_system_time(&self) -> SystemTime {
78
0
        self.0.to_system_time()
79
0
    }
80
}
81
82
impl_any_conversions!(UtcTime);
83
84
impl<'a> DecodeValue<'a> for UtcTime {
85
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
86
0
        if Self::LENGTH != usize::try_from(header.length)? {
87
0
            return Err(Self::TAG.value_error());
88
0
        }
89
0
90
0
        let mut bytes = [0u8; Self::LENGTH];
91
0
        reader.read_into(&mut bytes)?;
92
93
0
        match bytes {
94
            // RFC 5280 requires mandatory seconds and Z-normalized time zone
95
0
            [year1, year2, mon1, mon2, day1, day2, hour1, hour2, min1, min2, sec1, sec2, b'Z'] => {
96
0
                let year = u16::from(datetime::decode_decimal(Self::TAG, year1, year2)?);
97
0
                let month = datetime::decode_decimal(Self::TAG, mon1, mon2)?;
98
0
                let day = datetime::decode_decimal(Self::TAG, day1, day2)?;
99
0
                let hour = datetime::decode_decimal(Self::TAG, hour1, hour2)?;
100
0
                let minute = datetime::decode_decimal(Self::TAG, min1, min2)?;
101
0
                let second = datetime::decode_decimal(Self::TAG, sec1, sec2)?;
102
103
                // RFC 5280 rules for interpreting the year
104
0
                let year = if year >= 50 {
105
0
                    year.checked_add(1900)
106
                } else {
107
0
                    year.checked_add(2000)
108
                }
109
0
                .ok_or(ErrorKind::DateTime)?;
110
111
0
                DateTime::new(year, month, day, hour, minute, second)
112
0
                    .map_err(|_| Self::TAG.value_error())
113
0
                    .and_then(|dt| Self::from_unix_duration(dt.unix_duration()))
114
            }
115
0
            _ => Err(Self::TAG.value_error()),
116
        }
117
0
    }
118
}
119
120
impl EncodeValue for UtcTime {
121
0
    fn value_len(&self) -> Result<Length> {
122
0
        Self::LENGTH.try_into()
123
0
    }
124
125
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
126
0
        let year = match self.0.year() {
127
0
            y @ 1950..=1999 => y.checked_sub(1900),
128
0
            y @ 2000..=2049 => y.checked_sub(2000),
129
0
            _ => return Err(Self::TAG.value_error()),
130
        }
131
0
        .and_then(|y| u8::try_from(y).ok())
132
0
        .ok_or(ErrorKind::DateTime)?;
133
134
0
        datetime::encode_decimal(writer, Self::TAG, year)?;
135
0
        datetime::encode_decimal(writer, Self::TAG, self.0.month())?;
136
0
        datetime::encode_decimal(writer, Self::TAG, self.0.day())?;
137
0
        datetime::encode_decimal(writer, Self::TAG, self.0.hour())?;
138
0
        datetime::encode_decimal(writer, Self::TAG, self.0.minutes())?;
139
0
        datetime::encode_decimal(writer, Self::TAG, self.0.seconds())?;
140
0
        writer.write_byte(b'Z')
141
0
    }
142
}
143
144
impl FixedTag for UtcTime {
145
    const TAG: Tag = Tag::UtcTime;
146
}
147
148
impl OrdIsValueOrd for UtcTime {}
149
150
impl From<&UtcTime> for UtcTime {
151
0
    fn from(value: &UtcTime) -> UtcTime {
152
0
        *value
153
0
    }
154
}
155
156
impl From<UtcTime> for DateTime {
157
0
    fn from(utc_time: UtcTime) -> DateTime {
158
0
        utc_time.0
159
0
    }
160
}
161
162
impl From<&UtcTime> for DateTime {
163
0
    fn from(utc_time: &UtcTime) -> DateTime {
164
0
        utc_time.0
165
0
    }
166
}
167
168
impl TryFrom<DateTime> for UtcTime {
169
    type Error = Error;
170
171
0
    fn try_from(datetime: DateTime) -> Result<Self> {
172
0
        Self::from_date_time(datetime)
173
0
    }
174
}
175
176
impl TryFrom<&DateTime> for UtcTime {
177
    type Error = Error;
178
179
0
    fn try_from(datetime: &DateTime) -> Result<Self> {
180
0
        Self::from_date_time(*datetime)
181
0
    }
182
}
183
184
#[cfg(feature = "std")]
185
impl From<UtcTime> for SystemTime {
186
0
    fn from(utc_time: UtcTime) -> SystemTime {
187
0
        utc_time.to_system_time()
188
0
    }
189
}
190
191
// Implement by hand because the derive would create invalid values.
192
// Use the conversion from DateTime to create a valid value.
193
// The DateTime type has a way bigger range of valid years than UtcTime,
194
// so the DateTime year is mapped into a valid range to throw away less inputs.
195
#[cfg(feature = "arbitrary")]
196
impl<'a> arbitrary::Arbitrary<'a> for UtcTime {
197
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
198
        const MIN_YEAR: u16 = 1970;
199
        const VALID_YEAR_COUNT: u16 = UtcTime::MAX_YEAR - MIN_YEAR + 1;
200
        const AVERAGE_SECONDS_IN_YEAR: u64 = 31_556_952;
201
202
        let datetime = DateTime::arbitrary(u)?;
203
        let year = datetime.year();
204
        let duration = datetime.unix_duration();
205
206
        // Clamp the year into a valid range to not throw away too much input
207
        let valid_year = (year.saturating_sub(MIN_YEAR))
208
            .rem_euclid(VALID_YEAR_COUNT)
209
            .saturating_add(MIN_YEAR);
210
        let year_to_remove = year.saturating_sub(valid_year);
211
        let valid_duration = duration
212
            - Duration::from_secs(
213
                u64::from(year_to_remove).saturating_mul(AVERAGE_SECONDS_IN_YEAR),
214
            );
215
216
        Self::from_date_time(DateTime::from_unix_duration(valid_duration).expect("supported range"))
217
            .map_err(|_| arbitrary::Error::IncorrectFormat)
218
    }
219
220
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
221
        DateTime::size_hint(depth)
222
    }
223
}
224
225
#[cfg(test)]
226
mod tests {
227
    use super::UtcTime;
228
    use crate::{Decode, Encode, SliceWriter};
229
    use hex_literal::hex;
230
231
    #[test]
232
    fn round_trip_vector() {
233
        let example_bytes = hex!("17 0d 39 31 30 35 30 36 32 33 34 35 34 30 5a");
234
        let utc_time = UtcTime::from_der(&example_bytes).unwrap();
235
        assert_eq!(utc_time.to_unix_duration().as_secs(), 673573540);
236
237
        let mut buf = [0u8; 128];
238
        let mut encoder = SliceWriter::new(&mut buf);
239
        utc_time.encode(&mut encoder).unwrap();
240
        assert_eq!(example_bytes, encoder.finish().unwrap());
241
    }
242
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/utf8_string.rs
Line
Count
Source
1
//! ASN.1 `UTF8String` support.
2
3
use crate::{
4
    asn1::AnyRef, ord::OrdIsValueOrd, EncodeValue, Error, FixedTag, Length, Result, StrRef, Tag,
5
    Writer,
6
};
7
use core::{fmt, ops::Deref, str};
8
9
#[cfg(feature = "alloc")]
10
use {
11
    crate::{DecodeValue, Header, Reader},
12
    alloc::{borrow::ToOwned, string::String},
13
};
14
15
/// ASN.1 `UTF8String` type.
16
///
17
/// Supports the full UTF-8 encoding.
18
///
19
/// Note that the [`Decode`][`crate::Decode`] and [`Encode`][`crate::Encode`]
20
/// traits are impl'd for Rust's [`str`][`prim@str`] primitive, which
21
/// decodes/encodes as a [`Utf8StringRef`].
22
///
23
/// You are free to use [`str`][`prim@str`] instead of this type, however it's
24
/// still provided for explicitness in cases where it might be ambiguous with
25
/// other ASN.1 string encodings such as
26
/// [`PrintableStringRef`][`crate::asn1::PrintableStringRef`].
27
///
28
/// This is a zero-copy reference type which borrows from the input data.
29
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
30
pub struct Utf8StringRef<'a> {
31
    /// Inner value
32
    inner: StrRef<'a>,
33
}
34
35
impl<'a> Utf8StringRef<'a> {
36
    /// Create a new ASN.1 `UTF8String`.
37
0
    pub fn new<T>(input: &'a T) -> Result<Self>
38
0
    where
39
0
        T: AsRef<[u8]> + ?Sized,
40
0
    {
41
0
        StrRef::from_bytes(input.as_ref()).map(|inner| Self { inner })
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn111utf8_stringNtB5_13Utf8StringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringE0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn111utf8_stringNtB5_13Utf8StringRef3newShE0B9_
Unexecuted instantiation: _RNCINvMNtNtCscrZQdumITES_3der4asn111utf8_stringNtB5_13Utf8StringRef3neweE0B9_
42
0
    }
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn111utf8_stringNtB3_13Utf8StringRef3newNtNtCsiBl6Lc3cFal_5alloc6string6StringEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn111utf8_stringNtB3_13Utf8StringRef3newShEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der4asn111utf8_stringNtB3_13Utf8StringRef3neweEB7_
43
}
44
45
impl_string_type!(Utf8StringRef<'a>, 'a);
46
47
impl<'a> Deref for Utf8StringRef<'a> {
48
    type Target = StrRef<'a>;
49
50
0
    fn deref(&self) -> &Self::Target {
51
0
        &self.inner
52
0
    }
53
}
54
55
impl FixedTag for Utf8StringRef<'_> {
56
    const TAG: Tag = Tag::Utf8String;
57
}
58
59
impl<'a> From<&Utf8StringRef<'a>> for Utf8StringRef<'a> {
60
0
    fn from(value: &Utf8StringRef<'a>) -> Utf8StringRef<'a> {
61
0
        *value
62
0
    }
63
}
64
65
impl<'a> From<Utf8StringRef<'a>> for AnyRef<'a> {
66
0
    fn from(utf_string: Utf8StringRef<'a>) -> AnyRef<'a> {
67
0
        AnyRef::from_tag_and_value(Tag::Utf8String, utf_string.inner.into())
68
0
    }
69
}
70
71
impl<'a> fmt::Debug for Utf8StringRef<'a> {
72
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73
0
        write!(f, "Utf8String({:?})", self.as_str())
74
0
    }
75
}
76
77
impl<'a> TryFrom<AnyRef<'a>> for &'a str {
78
    type Error = Error;
79
80
0
    fn try_from(any: AnyRef<'a>) -> Result<&'a str> {
81
0
        Utf8StringRef::try_from(any).map(|s| s.as_str())
82
0
    }
83
}
84
85
impl EncodeValue for str {
86
0
    fn value_len(&self) -> Result<Length> {
87
0
        Utf8StringRef::new(self)?.value_len()
88
0
    }
89
90
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
91
0
        Utf8StringRef::new(self)?.encode_value(writer)
92
0
    }
93
}
94
95
impl FixedTag for str {
96
    const TAG: Tag = Tag::Utf8String;
97
}
98
99
impl OrdIsValueOrd for str {}
100
101
#[cfg(feature = "alloc")]
102
impl<'a> From<Utf8StringRef<'a>> for String {
103
0
    fn from(s: Utf8StringRef<'a>) -> String {
104
0
        s.as_str().to_owned()
105
0
    }
106
}
107
108
#[cfg(feature = "alloc")]
109
impl<'a> TryFrom<AnyRef<'a>> for String {
110
    type Error = Error;
111
112
0
    fn try_from(any: AnyRef<'a>) -> Result<String> {
113
0
        Utf8StringRef::try_from(any).map(|s| s.as_str().to_owned())
114
0
    }
115
}
116
117
#[cfg(feature = "alloc")]
118
impl<'a> DecodeValue<'a> for String {
119
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
120
0
        Ok(String::from_utf8(reader.read_vec(header.length)?)?)
121
0
    }
122
}
123
124
#[cfg(feature = "alloc")]
125
impl EncodeValue for String {
126
0
    fn value_len(&self) -> Result<Length> {
127
0
        Utf8StringRef::new(self)?.value_len()
128
0
    }
129
130
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
131
0
        Utf8StringRef::new(self)?.encode_value(writer)
132
0
    }
133
}
134
135
#[cfg(feature = "alloc")]
136
impl FixedTag for String {
137
    const TAG: Tag = Tag::Utf8String;
138
}
139
140
#[cfg(feature = "alloc")]
141
impl OrdIsValueOrd for String {}
142
143
#[cfg(test)]
144
mod tests {
145
    use super::Utf8StringRef;
146
    use crate::Decode;
147
148
    #[test]
149
    fn parse_ascii_bytes() {
150
        let example_bytes = &[
151
            0x0c, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x31,
152
        ];
153
154
        let utf8_string = Utf8StringRef::from_der(example_bytes).unwrap();
155
        assert_eq!(utf8_string.as_str(), "Test User 1");
156
    }
157
158
    #[test]
159
    fn parse_utf8_bytes() {
160
        let example_bytes = &[0x0c, 0x06, 0x48, 0x65, 0x6c, 0x6c, 0xc3, 0xb3];
161
        let utf8_string = Utf8StringRef::from_der(example_bytes).unwrap();
162
        assert_eq!(utf8_string.as_str(), "Helló");
163
    }
164
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/videotex_string.rs
Line
Count
Source
1
//! ASN.1 `VideotexString` support.
2
3
use crate::{asn1::AnyRef, FixedTag, Result, StrRef, Tag};
4
use core::{fmt, ops::Deref};
5
6
/// ASN.1 `VideotexString` type.
7
///
8
/// Supports a subset the ASCII character set (described below).
9
///
10
/// For UTF-8, use [`Utf8StringRef`][`crate::asn1::Utf8StringRef`] instead.
11
/// For the full ASCII character set, use
12
/// [`Ia5StringRef`][`crate::asn1::Ia5StringRef`].
13
///
14
/// This is a zero-copy reference type which borrows from the input data.
15
///
16
/// # Supported characters
17
///
18
/// For the practical purposes VideotexString is treated as IA5string, disallowing non-ASCII chars.
19
///
20
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
21
pub struct VideotexStringRef<'a> {
22
    /// Inner value
23
    inner: StrRef<'a>,
24
}
25
26
impl<'a> VideotexStringRef<'a> {
27
    /// Create a new ASN.1 `VideotexString`.
28
0
    pub fn new<T>(input: &'a T) -> Result<Self>
29
0
    where
30
0
        T: AsRef<[u8]> + ?Sized,
31
0
    {
32
0
        let input = input.as_ref();
33
0
34
0
        // Validate all characters are within VideotexString's allowed set
35
0
        // FIXME: treat as if it were IA5String
36
0
        if input.iter().any(|&c| c > 0x7F) {
37
0
            return Err(Self::TAG.value_error());
38
0
        }
39
0
40
0
        StrRef::from_bytes(input)
41
0
            .map(|inner| Self { inner })
42
0
            .map_err(|_| Self::TAG.value_error())
43
0
    }
44
}
45
46
impl_string_type!(VideotexStringRef<'a>, 'a);
47
48
impl<'a> Deref for VideotexStringRef<'a> {
49
    type Target = StrRef<'a>;
50
51
0
    fn deref(&self) -> &Self::Target {
52
0
        &self.inner
53
0
    }
54
}
55
56
impl FixedTag for VideotexStringRef<'_> {
57
    const TAG: Tag = Tag::VideotexString;
58
}
59
60
impl<'a> From<&VideotexStringRef<'a>> for VideotexStringRef<'a> {
61
0
    fn from(value: &VideotexStringRef<'a>) -> VideotexStringRef<'a> {
62
0
        *value
63
0
    }
64
}
65
66
impl<'a> From<VideotexStringRef<'a>> for AnyRef<'a> {
67
0
    fn from(printable_string: VideotexStringRef<'a>) -> AnyRef<'a> {
68
0
        AnyRef::from_tag_and_value(Tag::VideotexString, printable_string.inner.into())
69
0
    }
70
}
71
72
impl<'a> From<VideotexStringRef<'a>> for &'a [u8] {
73
0
    fn from(printable_string: VideotexStringRef<'a>) -> &'a [u8] {
74
0
        printable_string.as_bytes()
75
0
    }
76
}
77
78
impl<'a> fmt::Debug for VideotexStringRef<'a> {
79
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80
0
        write!(f, "VideotexString({:?})", self.as_str())
81
0
    }
82
}
83
84
#[cfg(test)]
85
mod tests {
86
    use super::VideotexStringRef;
87
    use crate::Decode;
88
89
    #[test]
90
    fn parse_bytes() {
91
        let example_bytes = &[
92
            0x15, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x31,
93
        ];
94
95
        let printable_string = VideotexStringRef::from_der(example_bytes).unwrap();
96
        assert_eq!(printable_string.as_str(), "Test User 1");
97
    }
98
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/bytes_owned.rs
Line
Count
Source
1
//! Common handling for types backed by byte allocation with enforcement of a
2
//! library-level length limitation i.e. `Length::max()`.
3
4
use crate::{
5
    referenced::OwnedToRef, BytesRef, DecodeValue, DerOrd, EncodeValue, Error, Header, Length,
6
    Reader, Result, StrRef, Writer,
7
};
8
use alloc::{boxed::Box, vec::Vec};
9
use core::cmp::Ordering;
10
11
/// Byte slice newtype which respects the `Length::max()` limit.
12
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
13
pub(crate) struct BytesOwned {
14
    /// Precomputed `Length` (avoids possible panicking conversions)
15
    length: Length,
16
17
    /// Inner value
18
    inner: Box<[u8]>,
19
}
20
21
impl BytesOwned {
22
    /// Create a new [`BytesOwned`], ensuring that the provided `slice` value
23
    /// is shorter than `Length::max()`.
24
0
    pub fn new(data: impl Into<Box<[u8]>>) -> Result<Self> {
25
0
        let inner: Box<[u8]> = data.into();
26
0
27
0
        Ok(Self {
28
0
            length: Length::try_from(inner.len())?,
29
0
            inner,
30
        })
31
0
    }
Unexecuted instantiation: _RINvMNtCscrZQdumITES_3der11bytes_ownedNtB3_10BytesOwned3newINtNtCsiBl6Lc3cFal_5alloc3vec3VechEEB5_
Unexecuted instantiation: _RINvMNtCscrZQdumITES_3der11bytes_ownedNtB3_10BytesOwned3newINtNtCsiBl6Lc3cFal_5alloc5boxed3BoxShEEB5_
Unexecuted instantiation: _RINvMNtCscrZQdumITES_3der11bytes_ownedNtB3_10BytesOwned3newRShEB5_
32
33
    /// Borrow the inner byte slice
34
0
    pub fn as_slice(&self) -> &[u8] {
35
0
        &self.inner
36
0
    }
37
38
    /// Get the [`Length`] of this [`BytesRef`]
39
0
    pub fn len(&self) -> Length {
40
0
        self.length
41
0
    }
42
43
    /// Is this [`BytesOwned`] empty?
44
0
    pub fn is_empty(&self) -> bool {
45
0
        self.len() == Length::ZERO
46
0
    }
47
}
48
49
impl AsRef<[u8]> for BytesOwned {
50
0
    fn as_ref(&self) -> &[u8] {
51
0
        self.as_slice()
52
0
    }
53
}
54
55
impl<'a> DecodeValue<'a> for BytesOwned {
56
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
57
0
        reader.read_vec(header.length).and_then(Self::new)
58
0
    }
59
}
60
61
impl EncodeValue for BytesOwned {
62
0
    fn value_len(&self) -> Result<Length> {
63
0
        Ok(self.length)
64
0
    }
65
66
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
67
0
        writer.write(self.as_ref())
68
0
    }
69
}
70
71
impl Default for BytesOwned {
72
0
    fn default() -> Self {
73
0
        Self {
74
0
            length: Length::ZERO,
75
0
            inner: Box::new([]),
76
0
        }
77
0
    }
78
}
79
80
impl DerOrd for BytesOwned {
81
0
    fn der_cmp(&self, other: &Self) -> Result<Ordering> {
82
0
        Ok(self.as_slice().cmp(other.as_slice()))
83
0
    }
84
}
85
86
impl From<BytesOwned> for Box<[u8]> {
87
0
    fn from(bytes: BytesOwned) -> Box<[u8]> {
88
0
        bytes.inner
89
0
    }
90
}
91
92
impl From<StrRef<'_>> for BytesOwned {
93
0
    fn from(s: StrRef<'_>) -> BytesOwned {
94
0
        let bytes = s.as_bytes();
95
0
        debug_assert_eq!(bytes.len(), usize::try_from(s.length).expect("overflow"));
96
97
0
        BytesOwned {
98
0
            inner: Box::from(bytes),
99
0
            length: s.length,
100
0
        }
101
0
    }
102
}
103
104
impl OwnedToRef for BytesOwned {
105
    type Borrowed<'a> = BytesRef<'a>;
106
0
    fn owned_to_ref(&self) -> Self::Borrowed<'_> {
107
0
        BytesRef {
108
0
            length: self.length,
109
0
            inner: self.inner.as_ref(),
110
0
        }
111
0
    }
112
}
113
114
impl From<BytesRef<'_>> for BytesOwned {
115
0
    fn from(s: BytesRef<'_>) -> BytesOwned {
116
0
        BytesOwned {
117
0
            length: s.length,
118
0
            inner: Box::from(s.inner),
119
0
        }
120
0
    }
121
}
122
123
impl TryFrom<&[u8]> for BytesOwned {
124
    type Error = Error;
125
126
0
    fn try_from(bytes: &[u8]) -> Result<Self> {
127
0
        Self::new(bytes)
128
0
    }
129
}
130
131
impl TryFrom<Box<[u8]>> for BytesOwned {
132
    type Error = Error;
133
134
0
    fn try_from(bytes: Box<[u8]>) -> Result<Self> {
135
0
        Self::new(bytes)
136
0
    }
137
}
138
139
impl TryFrom<Vec<u8>> for BytesOwned {
140
    type Error = Error;
141
142
0
    fn try_from(bytes: Vec<u8>) -> Result<Self> {
143
0
        Self::new(bytes)
144
0
    }
145
}
146
147
// Implement by hand because the derive would create invalid values.
148
// Make sure the length and the inner.len matches.
149
#[cfg(feature = "arbitrary")]
150
impl<'a> arbitrary::Arbitrary<'a> for BytesOwned {
151
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
152
        let length = u.arbitrary()?;
153
        Ok(Self {
154
            length,
155
            inner: Box::from(u.bytes(u32::from(length) as usize)?),
156
        })
157
    }
158
159
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
160
        arbitrary::size_hint::and(Length::size_hint(depth), (0, None))
161
    }
162
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/bytes_ref.rs
Line
Count
Source
1
//! Common handling for types backed by byte slices with enforcement of a
2
//! library-level length limitation i.e. `Length::max()`.
3
4
use crate::{
5
    DecodeValue, DerOrd, EncodeValue, Error, Header, Length, Reader, Result, StrRef, Writer,
6
};
7
use core::cmp::Ordering;
8
9
#[cfg(feature = "alloc")]
10
use crate::StrOwned;
11
12
/// Byte slice newtype which respects the `Length::max()` limit.
13
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
14
pub(crate) struct BytesRef<'a> {
15
    /// Precomputed `Length` (avoids possible panicking conversions)
16
    pub length: Length,
17
18
    /// Inner value
19
    pub inner: &'a [u8],
20
}
21
22
impl<'a> BytesRef<'a> {
23
    /// Constant value representing an empty byte slice.
24
    pub const EMPTY: Self = Self {
25
        length: Length::ZERO,
26
        inner: &[],
27
    };
28
29
    /// Create a new [`BytesRef`], ensuring that the provided `slice` value
30
    /// is shorter than `Length::max()`.
31
0
    pub fn new(slice: &'a [u8]) -> Result<Self> {
32
0
        Ok(Self {
33
0
            length: Length::try_from(slice.len())?,
34
0
            inner: slice,
35
        })
36
0
    }
37
38
    /// Borrow the inner byte slice
39
0
    pub fn as_slice(&self) -> &'a [u8] {
40
0
        self.inner
41
0
    }
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der9bytes_refNtB2_8BytesRef8as_sliceB4_
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der9bytes_refNtB2_8BytesRef8as_sliceCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der9bytes_refNtB2_8BytesRef8as_sliceCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der9bytes_refNtB2_8BytesRef8as_sliceCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der9bytes_refNtB2_8BytesRef8as_sliceCskctcMqaO4X4_4spki
42
43
    /// Get the [`Length`] of this [`BytesRef`]
44
0
    pub fn len(self) -> Length {
45
0
        self.length
46
0
    }
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der9bytes_refNtB2_8BytesRef3lenB4_
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der9bytes_refNtB2_8BytesRef3lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der9bytes_refNtB2_8BytesRef3lenCskctcMqaO4X4_4spki
47
48
    /// Is this [`BytesRef`] empty?
49
0
    pub fn is_empty(self) -> bool {
50
0
        self.len() == Length::ZERO
51
0
    }
52
}
53
54
impl AsRef<[u8]> for BytesRef<'_> {
55
0
    fn as_ref(&self) -> &[u8] {
56
0
        self.as_slice()
57
0
    }
Unexecuted instantiation: _RNvXs_NtCscrZQdumITES_3der9bytes_refNtB4_8BytesRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_refB6_
Unexecuted instantiation: _RNvXs_NtCscrZQdumITES_3der9bytes_refNtB4_8BytesRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_refCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtCscrZQdumITES_3der9bytes_refNtB4_8BytesRefINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_refCsj9qtwLkMHqH_4sec1
58
}
59
60
impl<'a> DecodeValue<'a> for BytesRef<'a> {
61
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
62
0
        reader.read_slice(header.length).and_then(Self::new)
63
0
    }
Unexecuted instantiation: _RINvXs0_NtCscrZQdumITES_3der9bytes_refNtB6_8BytesRefNtNtB8_6decode11DecodeValue12decode_valueNtNtNtB8_6reader5slice11SliceReaderEB8_
Unexecuted instantiation: _RINvXs0_NtCscrZQdumITES_3der9bytes_refNtB6_8BytesRefNtNtB8_6decode11DecodeValue12decode_valueINtNtNtB8_6reader6nested12NestedReaderNtNtB1y_5slice11SliceReaderEECs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RINvXs0_NtCscrZQdumITES_3der9bytes_refNtB6_8BytesRefNtNtB8_6decode11DecodeValue12decode_valueINtNtNtB8_6reader6nested12NestedReaderIB1u_NtNtB1y_5slice11SliceReaderEEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs0_NtCscrZQdumITES_3der9bytes_refNtB6_8BytesRefNtNtB8_6decode11DecodeValue12decode_valueINtNtNtB8_6reader6nested12NestedReaderNtNtB1y_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs0_NtCscrZQdumITES_3der9bytes_refNtB6_8BytesRefNtNtB8_6decode11DecodeValue12decode_valueINtNtNtB8_6reader6nested12NestedReaderIB1u_NtNtB1y_5slice11SliceReaderEEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXs0_NtCscrZQdumITES_3der9bytes_refNtB6_8BytesRefNtNtB8_6decode11DecodeValue12decode_valueINtNtNtB8_6reader6nested12NestedReaderNtNtB1y_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
64
}
65
66
impl EncodeValue for BytesRef<'_> {
67
0
    fn value_len(&self) -> Result<Length> {
68
0
        Ok(self.length)
69
0
    }
Unexecuted instantiation: _RNvXs1_NtCscrZQdumITES_3der9bytes_refNtB5_8BytesRefNtNtB7_6encode11EncodeValue9value_lenB7_
Unexecuted instantiation: _RNvXs1_NtCscrZQdumITES_3der9bytes_refNtB5_8BytesRefNtNtB7_6encode11EncodeValue9value_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs1_NtCscrZQdumITES_3der9bytes_refNtB5_8BytesRefNtNtB7_6encode11EncodeValue9value_lenCsj9qtwLkMHqH_4sec1
70
71
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
72
0
        writer.write(self.as_ref())
73
0
    }
Unexecuted instantiation: _RINvXs1_NtCscrZQdumITES_3der9bytes_refNtB6_8BytesRefNtNtB8_6encode11EncodeValue12encode_valuepEB8_
Unexecuted instantiation: _RINvXs1_NtCscrZQdumITES_3der9bytes_refNtB6_8BytesRefNtNtB8_6encode11EncodeValue12encode_valueNtNtNtB8_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs1_NtCscrZQdumITES_3der9bytes_refNtB6_8BytesRefNtNtB8_6encode11EncodeValue12encode_valueNtNtNtB8_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
74
}
75
76
impl Default for BytesRef<'_> {
77
0
    fn default() -> Self {
78
0
        Self {
79
0
            length: Length::ZERO,
80
0
            inner: &[],
81
0
        }
82
0
    }
83
}
84
85
impl DerOrd for BytesRef<'_> {
86
0
    fn der_cmp(&self, other: &Self) -> Result<Ordering> {
87
0
        Ok(self.as_slice().cmp(other.as_slice()))
88
0
    }
89
}
90
91
impl<'a> From<StrRef<'a>> for BytesRef<'a> {
92
0
    fn from(s: StrRef<'a>) -> BytesRef<'a> {
93
0
        let bytes = s.as_bytes();
94
0
        debug_assert_eq!(bytes.len(), usize::try_from(s.length).expect("overflow"));
95
96
0
        BytesRef {
97
0
            inner: bytes,
98
0
            length: s.length,
99
0
        }
100
0
    }
101
}
102
103
#[cfg(feature = "alloc")]
104
impl<'a> From<&'a StrOwned> for BytesRef<'a> {
105
0
    fn from(s: &'a StrOwned) -> BytesRef<'a> {
106
0
        let bytes = s.as_bytes();
107
0
        debug_assert_eq!(bytes.len(), usize::try_from(s.length).expect("overflow"));
108
109
0
        BytesRef {
110
0
            inner: bytes,
111
0
            length: s.length,
112
0
        }
113
0
    }
114
}
115
116
impl<'a> TryFrom<&'a [u8]> for BytesRef<'a> {
117
    type Error = Error;
118
119
0
    fn try_from(slice: &'a [u8]) -> Result<Self> {
120
0
        Self::new(slice)
121
0
    }
122
}
123
124
// Implement by hand because the derive would create invalid values.
125
// Make sure the length and the inner.len matches.
126
#[cfg(feature = "arbitrary")]
127
impl<'a> arbitrary::Arbitrary<'a> for BytesRef<'a> {
128
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
129
        let length = u.arbitrary()?;
130
        Ok(Self {
131
            length,
132
            inner: u.bytes(u32::from(length) as usize)?,
133
        })
134
    }
135
136
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
137
        arbitrary::size_hint::and(Length::size_hint(depth), (0, None))
138
    }
139
}
140
141
#[cfg(feature = "alloc")]
142
mod allocating {
143
    use super::BytesRef;
144
    use crate::{referenced::RefToOwned, BytesOwned};
145
146
    impl<'a> RefToOwned<'a> for BytesRef<'a> {
147
        type Owned = BytesOwned;
148
0
        fn ref_to_owned(&self) -> Self::Owned {
149
0
            BytesOwned::from(*self)
150
0
        }
151
    }
152
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/datetime.rs
Line
Count
Source
1
//! Date and time functionality shared between various ASN.1 types
2
//! (e.g. `GeneralizedTime`, `UTCTime`)
3
4
// Adapted from the `humantime` crate.
5
// Copyright (c) 2016 The humantime Developers
6
// Released under the MIT OR Apache 2.0 licenses
7
8
use crate::{Error, ErrorKind, Result, Tag, Writer};
9
use core::{fmt, str::FromStr, time::Duration};
10
11
#[cfg(feature = "std")]
12
use std::time::{SystemTime, UNIX_EPOCH};
13
14
#[cfg(feature = "time")]
15
use time::PrimitiveDateTime;
16
17
/// Minimum year allowed in [`DateTime`] values.
18
const MIN_YEAR: u16 = 1970;
19
20
/// Maximum duration since `UNIX_EPOCH` which can be represented as a
21
/// [`DateTime`] (non-inclusive).
22
///
23
/// This corresponds to: 9999-12-31T23:59:59Z
24
const MAX_UNIX_DURATION: Duration = Duration::from_secs(253_402_300_799);
25
26
/// Date-and-time type shared by multiple ASN.1 types
27
/// (e.g. `GeneralizedTime`, `UTCTime`).
28
///
29
/// Following conventions from RFC 5280, this type is always Z-normalized
30
/// (i.e. represents a UTC time). However, it isn't named "UTC time" in order
31
/// to prevent confusion with ASN.1 `UTCTime`.
32
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
33
pub struct DateTime {
34
    /// Full year (e.g. 2000).
35
    ///
36
    /// Must be >=1970 to permit positive conversions to Unix time.
37
    year: u16,
38
39
    /// Month (1-12)
40
    month: u8,
41
42
    /// Day of the month (1-31)
43
    day: u8,
44
45
    /// Hour (0-23)
46
    hour: u8,
47
48
    /// Minutes (0-59)
49
    minutes: u8,
50
51
    /// Seconds (0-59)
52
    seconds: u8,
53
54
    /// [`Duration`] since the Unix epoch.
55
    unix_duration: Duration,
56
}
57
58
impl DateTime {
59
    /// This is the maximum date represented by the [`DateTime`]
60
    /// This corresponds to: 9999-12-31T23:59:59Z
61
    pub const INFINITY: DateTime = DateTime {
62
        year: 9999,
63
        month: 12,
64
        day: 31,
65
        hour: 23,
66
        minutes: 59,
67
        seconds: 59,
68
        unix_duration: MAX_UNIX_DURATION,
69
    };
70
71
    /// Create a new [`DateTime`] from the given UTC time components.
72
    // TODO(tarcieri): checked arithmetic
73
    #[allow(clippy::integer_arithmetic)]
74
0
    pub fn new(year: u16, month: u8, day: u8, hour: u8, minutes: u8, seconds: u8) -> Result<Self> {
75
0
        // Basic validation of the components.
76
0
        if year < MIN_YEAR
77
0
            || !(1..=12).contains(&month)
78
0
            || !(1..=31).contains(&day)
79
0
            || !(0..=23).contains(&hour)
80
0
            || !(0..=59).contains(&minutes)
81
0
            || !(0..=59).contains(&seconds)
82
        {
83
0
            return Err(ErrorKind::DateTime.into());
84
0
        }
85
0
86
0
        let leap_years =
87
0
            ((year - 1) - 1968) / 4 - ((year - 1) - 1900) / 100 + ((year - 1) - 1600) / 400;
88
89
0
        let is_leap_year = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
90
91
0
        let (mut ydays, mdays): (u16, u8) = match month {
92
0
            1 => (0, 31),
93
0
            2 if is_leap_year => (31, 29),
94
0
            2 => (31, 28),
95
0
            3 => (59, 31),
96
0
            4 => (90, 30),
97
0
            5 => (120, 31),
98
0
            6 => (151, 30),
99
0
            7 => (181, 31),
100
0
            8 => (212, 31),
101
0
            9 => (243, 30),
102
0
            10 => (273, 31),
103
0
            11 => (304, 30),
104
0
            12 => (334, 31),
105
0
            _ => return Err(ErrorKind::DateTime.into()),
106
        };
107
108
0
        if day > mdays || day == 0 {
109
0
            return Err(ErrorKind::DateTime.into());
110
0
        }
111
0
112
0
        ydays += u16::from(day) - 1;
113
0
114
0
        if is_leap_year && month > 2 {
115
0
            ydays += 1;
116
0
        }
117
118
0
        let days = u64::from(year - 1970) * 365 + u64::from(leap_years) + u64::from(ydays);
119
0
        let time = u64::from(seconds) + (u64::from(minutes) * 60) + (u64::from(hour) * 3600);
120
0
        let unix_duration = Duration::from_secs(time + days * 86400);
121
0
122
0
        if unix_duration > MAX_UNIX_DURATION {
123
0
            return Err(ErrorKind::DateTime.into());
124
0
        }
125
0
126
0
        Ok(Self {
127
0
            year,
128
0
            month,
129
0
            day,
130
0
            hour,
131
0
            minutes,
132
0
            seconds,
133
0
            unix_duration,
134
0
        })
135
0
    }
136
137
    /// Compute a [`DateTime`] from the given [`Duration`] since the `UNIX_EPOCH`.
138
    ///
139
    /// Returns `None` if the value is outside the supported date range.
140
    // TODO(tarcieri): checked arithmetic
141
    #[allow(clippy::integer_arithmetic)]
142
0
    pub fn from_unix_duration(unix_duration: Duration) -> Result<Self> {
143
0
        if unix_duration > MAX_UNIX_DURATION {
144
0
            return Err(ErrorKind::DateTime.into());
145
0
        }
146
0
147
0
        let secs_since_epoch = unix_duration.as_secs();
148
149
        /// 2000-03-01 (mod 400 year, immediately after Feb 29)
150
        const LEAPOCH: i64 = 11017;
151
        const DAYS_PER_400Y: i64 = 365 * 400 + 97;
152
        const DAYS_PER_100Y: i64 = 365 * 100 + 24;
153
        const DAYS_PER_4Y: i64 = 365 * 4 + 1;
154
155
0
        let days = i64::try_from(secs_since_epoch / 86400)? - LEAPOCH;
156
0
        let secs_of_day = secs_since_epoch % 86400;
157
0
158
0
        let mut qc_cycles = days / DAYS_PER_400Y;
159
0
        let mut remdays = days % DAYS_PER_400Y;
160
0
161
0
        if remdays < 0 {
162
0
            remdays += DAYS_PER_400Y;
163
0
            qc_cycles -= 1;
164
0
        }
165
166
0
        let mut c_cycles = remdays / DAYS_PER_100Y;
167
0
        if c_cycles == 4 {
168
0
            c_cycles -= 1;
169
0
        }
170
0
        remdays -= c_cycles * DAYS_PER_100Y;
171
0
172
0
        let mut q_cycles = remdays / DAYS_PER_4Y;
173
0
        if q_cycles == 25 {
174
0
            q_cycles -= 1;
175
0
        }
176
0
        remdays -= q_cycles * DAYS_PER_4Y;
177
0
178
0
        let mut remyears = remdays / 365;
179
0
        if remyears == 4 {
180
0
            remyears -= 1;
181
0
        }
182
0
        remdays -= remyears * 365;
183
0
184
0
        let mut year = 2000 + remyears + 4 * q_cycles + 100 * c_cycles + 400 * qc_cycles;
185
0
186
0
        let months = [31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29];
187
0
        let mut mon = 0;
188
0
        for mon_len in months.iter() {
189
0
            mon += 1;
190
0
            if remdays < *mon_len {
191
0
                break;
192
0
            }
193
0
            remdays -= *mon_len;
194
        }
195
0
        let mday = remdays + 1;
196
0
        let mon = if mon + 2 > 12 {
197
0
            year += 1;
198
0
            mon - 10
199
        } else {
200
0
            mon + 2
201
        };
202
203
0
        let second = secs_of_day % 60;
204
0
        let mins_of_day = secs_of_day / 60;
205
0
        let minute = mins_of_day % 60;
206
0
        let hour = mins_of_day / 60;
207
0
208
0
        Self::new(
209
0
            year.try_into()?,
210
0
            mon,
211
0
            mday.try_into()?,
212
0
            hour.try_into()?,
213
0
            minute.try_into()?,
214
0
            second.try_into()?,
215
        )
216
0
    }
217
218
    /// Get the year.
219
0
    pub fn year(&self) -> u16 {
220
0
        self.year
221
0
    }
222
223
    /// Get the month.
224
0
    pub fn month(&self) -> u8 {
225
0
        self.month
226
0
    }
227
228
    /// Get the day.
229
0
    pub fn day(&self) -> u8 {
230
0
        self.day
231
0
    }
232
233
    /// Get the hour.
234
0
    pub fn hour(&self) -> u8 {
235
0
        self.hour
236
0
    }
237
238
    /// Get the minutes.
239
0
    pub fn minutes(&self) -> u8 {
240
0
        self.minutes
241
0
    }
242
243
    /// Get the seconds.
244
0
    pub fn seconds(&self) -> u8 {
245
0
        self.seconds
246
0
    }
247
248
    /// Compute [`Duration`] since `UNIX_EPOCH` from the given calendar date.
249
0
    pub fn unix_duration(&self) -> Duration {
250
0
        self.unix_duration
251
0
    }
252
253
    /// Instantiate from [`SystemTime`].
254
    #[cfg(feature = "std")]
255
0
    pub fn from_system_time(time: SystemTime) -> Result<Self> {
256
0
        time.duration_since(UNIX_EPOCH)
257
0
            .map_err(|_| ErrorKind::DateTime.into())
258
0
            .and_then(Self::from_unix_duration)
259
0
    }
260
261
    /// Convert to [`SystemTime`].
262
    #[cfg(feature = "std")]
263
0
    pub fn to_system_time(&self) -> SystemTime {
264
0
        UNIX_EPOCH + self.unix_duration()
265
0
    }
266
}
267
268
impl FromStr for DateTime {
269
    type Err = Error;
270
271
0
    fn from_str(s: &str) -> Result<Self> {
272
0
        match *s.as_bytes() {
273
0
            [year1, year2, year3, year4, b'-', month1, month2, b'-', day1, day2, b'T', hour1, hour2, b':', min1, min2, b':', sec1, sec2, b'Z'] =>
274
0
            {
275
0
                let tag = Tag::GeneralizedTime;
276
0
                let year = decode_year(&[year1, year2, year3, year4])?;
277
0
                let month = decode_decimal(tag, month1, month2).map_err(|_| ErrorKind::DateTime)?;
278
0
                let day = decode_decimal(tag, day1, day2).map_err(|_| ErrorKind::DateTime)?;
279
0
                let hour = decode_decimal(tag, hour1, hour2).map_err(|_| ErrorKind::DateTime)?;
280
0
                let minutes = decode_decimal(tag, min1, min2).map_err(|_| ErrorKind::DateTime)?;
281
0
                let seconds = decode_decimal(tag, sec1, sec2).map_err(|_| ErrorKind::DateTime)?;
282
0
                Self::new(year, month, day, hour, minutes, seconds)
283
            }
284
0
            _ => Err(ErrorKind::DateTime.into()),
285
        }
286
0
    }
287
}
288
289
impl fmt::Display for DateTime {
290
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
291
0
        write!(
292
0
            f,
293
0
            "{:02}-{:02}-{:02}T{:02}:{:02}:{:02}Z",
294
0
            self.year, self.month, self.day, self.hour, self.minutes, self.seconds
295
0
        )
296
0
    }
297
}
298
299
#[cfg(feature = "std")]
300
impl From<DateTime> for SystemTime {
301
0
    fn from(time: DateTime) -> SystemTime {
302
0
        time.to_system_time()
303
0
    }
304
}
305
306
#[cfg(feature = "std")]
307
impl From<&DateTime> for SystemTime {
308
0
    fn from(time: &DateTime) -> SystemTime {
309
0
        time.to_system_time()
310
0
    }
311
}
312
313
#[cfg(feature = "std")]
314
impl TryFrom<SystemTime> for DateTime {
315
    type Error = Error;
316
317
0
    fn try_from(time: SystemTime) -> Result<DateTime> {
318
0
        DateTime::from_system_time(time)
319
0
    }
320
}
321
322
#[cfg(feature = "std")]
323
impl TryFrom<&SystemTime> for DateTime {
324
    type Error = Error;
325
326
0
    fn try_from(time: &SystemTime) -> Result<DateTime> {
327
0
        DateTime::from_system_time(*time)
328
0
    }
329
}
330
331
#[cfg(feature = "time")]
332
impl TryFrom<DateTime> for PrimitiveDateTime {
333
    type Error = Error;
334
335
    fn try_from(time: DateTime) -> Result<PrimitiveDateTime> {
336
        let month = time.month().try_into()?;
337
        let date = time::Date::from_calendar_date(i32::from(time.year()), month, time.day())?;
338
        let time = time::Time::from_hms(time.hour(), time.minutes(), time.seconds())?;
339
340
        Ok(PrimitiveDateTime::new(date, time))
341
    }
342
}
343
344
#[cfg(feature = "time")]
345
impl TryFrom<PrimitiveDateTime> for DateTime {
346
    type Error = Error;
347
348
    fn try_from(time: PrimitiveDateTime) -> Result<DateTime> {
349
        DateTime::new(
350
            time.year().try_into().map_err(|_| ErrorKind::DateTime)?,
351
            time.month().into(),
352
            time.day(),
353
            time.hour(),
354
            time.minute(),
355
            time.second(),
356
        )
357
    }
358
}
359
360
// Implement by hand because the derive would create invalid values.
361
// Use the conversion from Duration to create a valid value.
362
#[cfg(feature = "arbitrary")]
363
impl<'a> arbitrary::Arbitrary<'a> for DateTime {
364
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
365
        Self::from_unix_duration(Duration::new(
366
            u.int_in_range(0..=MAX_UNIX_DURATION.as_secs().saturating_sub(1))?,
367
            u.int_in_range(0..=999_999_999)?,
368
        ))
369
        .map_err(|_| arbitrary::Error::IncorrectFormat)
370
    }
371
372
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
373
        arbitrary::size_hint::and(u64::size_hint(depth), u32::size_hint(depth))
374
    }
375
}
376
377
/// Decode 2-digit decimal value
378
// TODO(tarcieri): checked arithmetic
379
#[allow(clippy::integer_arithmetic)]
380
0
pub(crate) fn decode_decimal(tag: Tag, hi: u8, lo: u8) -> Result<u8> {
381
0
    if hi.is_ascii_digit() && lo.is_ascii_digit() {
382
0
        Ok((hi - b'0') * 10 + (lo - b'0'))
383
    } else {
384
0
        Err(tag.value_error())
385
    }
386
0
}
387
388
/// Encode 2-digit decimal value
389
0
pub(crate) fn encode_decimal<W>(writer: &mut W, tag: Tag, value: u8) -> Result<()>
390
0
where
391
0
    W: Writer + ?Sized,
392
0
{
393
0
    let hi_val = value / 10;
394
0
395
0
    if hi_val >= 10 {
396
0
        return Err(tag.value_error());
397
0
    }
398
0
399
0
    writer.write_byte(b'0'.checked_add(hi_val).ok_or(ErrorKind::Overflow)?)?;
400
0
    writer.write_byte(b'0'.checked_add(value % 10).ok_or(ErrorKind::Overflow)?)
401
0
}
402
403
/// Decode 4-digit year.
404
// TODO(tarcieri): checked arithmetic
405
#[allow(clippy::integer_arithmetic)]
406
0
fn decode_year(year: &[u8; 4]) -> Result<u16> {
407
0
    let tag = Tag::GeneralizedTime;
408
0
    let hi = decode_decimal(tag, year[0], year[1]).map_err(|_| ErrorKind::DateTime)?;
409
0
    let lo = decode_decimal(tag, year[2], year[3]).map_err(|_| ErrorKind::DateTime)?;
410
0
    Ok(u16::from(hi) * 100 + u16::from(lo))
411
0
}
412
413
#[cfg(test)]
414
mod tests {
415
    use super::DateTime;
416
417
    /// Ensure a day is OK
418
    fn is_date_valid(year: u16, month: u8, day: u8, hour: u8, minute: u8, second: u8) -> bool {
419
        DateTime::new(year, month, day, hour, minute, second).is_ok()
420
    }
421
422
    #[test]
423
    fn feb_leap_year_handling() {
424
        assert!(is_date_valid(2000, 2, 29, 0, 0, 0));
425
        assert!(!is_date_valid(2001, 2, 29, 0, 0, 0));
426
        assert!(!is_date_valid(2100, 2, 29, 0, 0, 0));
427
    }
428
429
    #[test]
430
    fn from_str() {
431
        let datetime = "2001-01-02T12:13:14Z".parse::<DateTime>().unwrap();
432
        assert_eq!(datetime.year(), 2001);
433
        assert_eq!(datetime.month(), 1);
434
        assert_eq!(datetime.day(), 2);
435
        assert_eq!(datetime.hour(), 12);
436
        assert_eq!(datetime.minutes(), 13);
437
        assert_eq!(datetime.seconds(), 14);
438
    }
439
440
    #[cfg(feature = "alloc")]
441
    #[test]
442
    fn display() {
443
        use alloc::string::ToString;
444
        let datetime = DateTime::new(2001, 01, 02, 12, 13, 14).unwrap();
445
        assert_eq!(&datetime.to_string(), "2001-01-02T12:13:14Z");
446
    }
447
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/decode.rs
Line
Count
Source
1
//! Trait definition for [`Decode`].
2
3
use crate::{FixedTag, Header, Reader, Result, SliceReader};
4
use core::marker::PhantomData;
5
6
#[cfg(feature = "pem")]
7
use crate::{pem::PemLabel, PemReader};
8
9
#[cfg(doc)]
10
use crate::{Length, Tag};
11
12
#[cfg(feature = "alloc")]
13
use alloc::boxed::Box;
14
15
/// Decoding trait.
16
///
17
/// This trait provides the core abstraction upon which all decoding operations
18
/// are based.
19
pub trait Decode<'a>: Sized {
20
    /// Attempt to decode this message using the provided decoder.
21
    fn decode<R: Reader<'a>>(decoder: &mut R) -> Result<Self>;
22
23
    /// Parse `Self` from the provided DER-encoded byte slice.
24
0
    fn from_der(bytes: &'a [u8]) -> Result<Self> {
25
0
        let mut reader = SliceReader::new(bytes)?;
26
0
        let result = Self::decode(&mut reader)?;
27
0
        reader.finish(result)
28
0
    }
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der3tag3TagNtNtB6_6decode6Decode8from_derB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6header6HeaderNtNtB6_6decode6Decode8from_derB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6length16IndefiniteLengthNtNtB6_6decode6Decode8from_derB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6length6LengthNtNtB6_6decode6Decode8from_derB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der8document8DocumentNtNtB6_6decode6Decode8from_derB6_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn13any6AnyRefNtNtB8_6decode6Decode8from_derB8_
Unexecuted instantiation: _RNvYNtNtNtNtCscrZQdumITES_3der4asn13any10allocating3AnyNtNtBa_6decode6Decode8from_derBa_
Unexecuted instantiation: _RNvYNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoNtNtCscrZQdumITES_3der6decode6Decode8from_derB6_
Unexecuted instantiation: _RNvYNtNtCssr1zNgi7Nt_5pkcs87version7VersionNtNtCscrZQdumITES_3der6decode6Decode8from_derB6_
Unexecuted instantiation: _RNvYNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyNtNtCscrZQdumITES_3der6decode6Decode8from_derB6_
29
}
30
31
impl<'a, T> Decode<'a> for T
32
where
33
    T: DecodeValue<'a> + FixedTag,
34
{
35
0
    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<T> {
36
0
        let header = Header::decode(reader)?;
37
0
        header.tag.assert_eq(T::TAG)?;
38
0
        T::decode_value(reader, header)
39
0
    }
Unexecuted instantiation: _RINvXININtCscrZQdumITES_3der6decode0pEpNtB6_6Decode6decodepEB8_
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodeNtNtNtNtB5_4asn17integer4uint7UintRefNtB3_6Decode6decodeINtNtNtB5_6reader6nested12NestedReaderNtNtB1t_5slice11SliceReaderEECs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodeINtNtCskctcMqaO4X4_4spki9algorithm19AlgorithmIdentifierNtNtNtB5_4asn13any6AnyRefENtB3_6Decode6decodeINtNtNtB5_6reader6nested12NestedReaderNtNtB2b_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodeNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtB3_6Decode6decodeINtNtNtB5_6reader6nested12NestedReaderIB1w_NtNtB1A_5slice11SliceReaderEEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodeNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoNtB3_6Decode6decodeNtNtNtB5_6reader5slice11SliceReaderEBy_
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodeNtNtNtB5_4asn110bit_string12BitStringRefNtB3_6Decode6decodeINtNtNtB5_6reader6nested12NestedReaderIB1s_NtNtB1w_5slice11SliceReaderEEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodeNtNtNtB5_4asn112octet_string14OctetStringRefNtB3_6Decode6decodeINtNtNtB5_6reader6nested12NestedReaderNtNtB1A_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodehNtB3_6Decode6decodeINtNtNtB5_6reader6nested12NestedReaderNtNtBT_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodehNtB3_6Decode6decodeNtNtNtB5_6reader5slice11SliceReaderECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodeNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersNtB3_6Decode6decodeINtNtNtB5_6reader6nested12NestedReaderIB1B_NtNtB1F_5slice11SliceReaderEEEBy_
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodeNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyNtB3_6Decode6decodeNtNtNtB5_6reader5slice11SliceReaderEBy_
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodeNtNtNtB5_4asn110bit_string12BitStringRefNtB3_6Decode6decodeINtNtNtB5_6reader6nested12NestedReaderIB1s_NtNtB1w_5slice11SliceReaderEEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodeNtNtNtB5_4asn112octet_string14OctetStringRefNtB3_6Decode6decodeINtNtNtB5_6reader6nested12NestedReaderNtNtB1A_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6decodehNtB3_6Decode6decodeINtNtNtB5_6reader6nested12NestedReaderNtNtBT_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
40
}
41
42
/// Dummy implementation for [`PhantomData`] which allows deriving
43
/// implementations on structs with phantom fields.
44
impl<'a, T> Decode<'a> for PhantomData<T>
45
where
46
    T: ?Sized,
47
{
48
0
    fn decode<R: Reader<'a>>(_reader: &mut R) -> Result<PhantomData<T>> {
49
0
        Ok(PhantomData)
50
0
    }
51
}
52
53
/// Marker trait for data structures that can be decoded from DER without
54
/// borrowing any data from the decoder.
55
///
56
/// This is primarily useful for trait bounds on functions which require that
57
/// no data is borrowed from the decoder, for example a PEM decoder which needs
58
/// to first decode data from Base64.
59
///
60
/// This trait is inspired by the [`DeserializeOwned` trait from `serde`](https://docs.rs/serde/latest/serde/de/trait.DeserializeOwned.html).
61
pub trait DecodeOwned: for<'a> Decode<'a> {}
62
63
impl<T> DecodeOwned for T where T: for<'a> Decode<'a> {}
64
65
/// PEM decoding trait.
66
///
67
/// This trait is automatically impl'd for any type which impls both
68
/// [`DecodeOwned`] and [`PemLabel`].
69
#[cfg(feature = "pem")]
70
pub trait DecodePem: DecodeOwned + PemLabel {
71
    /// Try to decode this type from PEM.
72
    fn from_pem(pem: impl AsRef<[u8]>) -> Result<Self>;
73
}
74
75
#[cfg(feature = "pem")]
76
impl<T: DecodeOwned + PemLabel> DecodePem for T {
77
0
    fn from_pem(pem: impl AsRef<[u8]>) -> Result<Self> {
78
0
        let mut reader = PemReader::new(pem.as_ref())?;
79
0
        Self::validate_pem_label(reader.type_label())?;
80
0
        T::decode(&mut reader)
81
0
    }
82
}
83
84
/// Decode the value part of a Tag-Length-Value encoded field, sans the [`Tag`]
85
/// and [`Length`].
86
pub trait DecodeValue<'a>: Sized {
87
    /// Attempt to decode this message using the provided [`Reader`].
88
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>;
89
}
90
91
#[cfg(feature = "alloc")]
92
impl<'a, T> DecodeValue<'a> for Box<T>
93
where
94
    T: DecodeValue<'a>,
95
{
96
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
97
0
        Ok(Box::new(T::decode_value(reader, header)?))
98
0
    }
99
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/document.rs
Line
Count
Source
1
//! ASN.1 DER-encoded documents stored on the heap.
2
3
use crate::{Decode, Encode, Error, FixedTag, Length, Reader, Result, SliceReader, Tag, Writer};
4
use alloc::vec::Vec;
5
use core::fmt::{self, Debug};
6
7
#[cfg(feature = "pem")]
8
use {crate::pem, alloc::string::String};
9
10
#[cfg(feature = "std")]
11
use std::{fs, path::Path};
12
13
#[cfg(all(feature = "pem", feature = "std"))]
14
use alloc::borrow::ToOwned;
15
16
#[cfg(feature = "zeroize")]
17
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
18
19
/// ASN.1 DER-encoded document.
20
///
21
/// This type wraps an encoded ASN.1 DER message. The document checked to
22
/// ensure it contains a valid DER-encoded `SEQUENCE`.
23
///
24
/// It implements common functionality related to encoding/decoding such
25
/// documents, such as PEM encapsulation as well as reading/writing documents
26
/// from/to the filesystem.
27
///
28
/// The [`SecretDocument`] provides a wrapper for this type with additional
29
/// hardening applied.
30
#[derive(Clone, Eq, PartialEq)]
31
pub struct Document {
32
    /// ASN.1 DER encoded bytes.
33
    der_bytes: Vec<u8>,
34
35
    /// Length of this document.
36
    length: Length,
37
}
38
39
impl Document {
40
    /// Get the ASN.1 DER-encoded bytes of this document.
41
0
    pub fn as_bytes(&self) -> &[u8] {
42
0
        self.der_bytes.as_slice()
43
0
    }
44
45
    /// Convert to a [`SecretDocument`].
46
    #[cfg(feature = "zeroize")]
47
0
    pub fn into_secret(self) -> SecretDocument {
48
0
        SecretDocument(self)
49
0
    }
50
51
    /// Convert to an ASN.1 DER-encoded byte vector.
52
0
    pub fn into_vec(self) -> Vec<u8> {
53
0
        self.der_bytes
54
0
    }
55
56
    /// Return an ASN.1 DER-encoded byte vector.
57
0
    pub fn to_vec(&self) -> Vec<u8> {
58
0
        self.der_bytes.clone()
59
0
    }
60
61
    /// Get the length of the encoded ASN.1 DER in bytes.
62
0
    pub fn len(&self) -> Length {
63
0
        self.length
64
0
    }
65
66
    /// Try to decode the inner ASN.1 DER message contained in this
67
    /// [`Document`] as the given type.
68
0
    pub fn decode_msg<'a, T: Decode<'a>>(&'a self) -> Result<T> {
69
0
        T::from_der(self.as_bytes())
70
0
    }
71
72
    /// Encode the provided type as ASN.1 DER, storing the resulting encoded DER
73
    /// as a [`Document`].
74
0
    pub fn encode_msg<T: Encode>(msg: &T) -> Result<Self> {
75
0
        msg.to_der()?.try_into()
76
0
    }
Unexecuted instantiation: _RINvMNtCscrZQdumITES_3der8documentNtB3_8Document10encode_msgpEB5_
Unexecuted instantiation: _RINvMNtCscrZQdumITES_3der8documentNtB3_8Document10encode_msgNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoEB10_
Unexecuted instantiation: _RINvMNtCscrZQdumITES_3der8documentNtB3_8Document10encode_msgNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyEB10_
77
78
    /// Decode ASN.1 DER document from PEM.
79
    ///
80
    /// Returns the PEM label and decoded [`Document`] on success.
81
    #[cfg(feature = "pem")]
82
0
    pub fn from_pem(pem: &str) -> Result<(&str, Self)> {
83
0
        let (label, der_bytes) = pem::decode_vec(pem.as_bytes())?;
84
0
        Ok((label, der_bytes.try_into()?))
85
0
    }
86
87
    /// Encode ASN.1 DER document as a PEM string with encapsulation boundaries
88
    /// containing the provided PEM type `label` (e.g. `CERTIFICATE`).
89
    #[cfg(feature = "pem")]
90
0
    pub fn to_pem(&self, label: &'static str, line_ending: pem::LineEnding) -> Result<String> {
91
0
        Ok(pem::encode_string(label, line_ending, self.as_bytes())?)
92
0
    }
93
94
    /// Read ASN.1 DER document from a file.
95
    #[cfg(feature = "std")]
96
0
    pub fn read_der_file(path: impl AsRef<Path>) -> Result<Self> {
97
0
        fs::read(path)?.try_into()
98
0
    }
99
100
    /// Write ASN.1 DER document to a file.
101
    #[cfg(feature = "std")]
102
0
    pub fn write_der_file(&self, path: impl AsRef<Path>) -> Result<()> {
103
0
        Ok(fs::write(path, self.as_bytes())?)
104
0
    }
105
106
    /// Read PEM-encoded ASN.1 DER document from a file.
107
    #[cfg(all(feature = "pem", feature = "std"))]
108
0
    pub fn read_pem_file(path: impl AsRef<Path>) -> Result<(String, Self)> {
109
0
        Self::from_pem(&fs::read_to_string(path)?).map(|(label, doc)| (label.to_owned(), doc))
110
0
    }
111
112
    /// Write PEM-encoded ASN.1 DER document to a file.
113
    #[cfg(all(feature = "pem", feature = "std"))]
114
0
    pub fn write_pem_file(
115
0
        &self,
116
0
        path: impl AsRef<Path>,
117
0
        label: &'static str,
118
0
        line_ending: pem::LineEnding,
119
0
    ) -> Result<()> {
120
0
        let pem = self.to_pem(label, line_ending)?;
121
0
        Ok(fs::write(path, pem.as_bytes())?)
122
0
    }
123
}
124
125
impl AsRef<[u8]> for Document {
126
0
    fn as_ref(&self) -> &[u8] {
127
0
        self.as_bytes()
128
0
    }
129
}
130
131
impl Debug for Document {
132
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133
0
        f.write_str("Document(")?;
134
135
0
        for byte in self.as_bytes() {
136
0
            write!(f, "{:02X}", byte)?;
137
        }
138
139
0
        f.write_str(")")
140
0
    }
141
}
142
143
impl<'a> Decode<'a> for Document {
144
0
    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Document> {
145
0
        let header = reader.peek_header()?;
146
0
        let length = (header.encoded_len()? + header.length)?;
147
0
        let bytes = reader.read_slice(length)?;
148
149
0
        Ok(Self {
150
0
            der_bytes: bytes.into(),
151
0
            length,
152
0
        })
153
0
    }
154
}
155
156
impl Encode for Document {
157
0
    fn encoded_len(&self) -> Result<Length> {
158
0
        Ok(self.len())
159
0
    }
160
161
0
    fn encode(&self, writer: &mut impl Writer) -> Result<()> {
162
0
        writer.write(self.as_bytes())
163
0
    }
164
}
165
166
impl FixedTag for Document {
167
    const TAG: Tag = Tag::Sequence;
168
}
169
170
impl TryFrom<&[u8]> for Document {
171
    type Error = Error;
172
173
0
    fn try_from(der_bytes: &[u8]) -> Result<Self> {
174
0
        Self::from_der(der_bytes)
175
0
    }
176
}
177
178
impl TryFrom<Vec<u8>> for Document {
179
    type Error = Error;
180
181
0
    fn try_from(der_bytes: Vec<u8>) -> Result<Self> {
182
0
        let mut decoder = SliceReader::new(&der_bytes)?;
183
0
        decode_sequence(&mut decoder)?;
184
0
        decoder.finish(())?;
185
186
0
        let length = der_bytes.len().try_into()?;
187
0
        Ok(Self { der_bytes, length })
188
0
    }
189
}
190
191
/// Secret [`Document`] type.
192
///
193
/// Useful for formats which represent potentially secret data, such as
194
/// cryptographic keys.
195
///
196
/// This type provides additional hardening such as ensuring that the contents
197
/// are zeroized-on-drop, and also using more restrictive file permissions when
198
/// writing files to disk.
199
#[cfg(feature = "zeroize")]
200
#[derive(Clone)]
201
pub struct SecretDocument(Document);
202
203
#[cfg(feature = "zeroize")]
204
impl SecretDocument {
205
    /// Borrow the inner serialized bytes of this document.
206
0
    pub fn as_bytes(&self) -> &[u8] {
207
0
        self.0.as_bytes()
208
0
    }
209
210
    /// Return an allocated ASN.1 DER serialization as a byte vector.
211
0
    pub fn to_bytes(&self) -> Zeroizing<Vec<u8>> {
212
0
        Zeroizing::new(self.0.to_vec())
213
0
    }
214
215
    /// Get the length of the encoded ASN.1 DER in bytes.
216
0
    pub fn len(&self) -> Length {
217
0
        self.0.len()
218
0
    }
219
220
    /// Try to decode the inner ASN.1 DER message as the given type.
221
0
    pub fn decode_msg<'a, T: Decode<'a>>(&'a self) -> Result<T> {
222
0
        self.0.decode_msg()
223
0
    }
224
225
    /// Encode the provided type as ASN.1 DER.
226
0
    pub fn encode_msg<T: Encode>(msg: &T) -> Result<Self> {
227
0
        Document::encode_msg(msg).map(Self)
228
0
    }
Unexecuted instantiation: _RINvMs6_NtCscrZQdumITES_3der8documentNtB6_14SecretDocument10encode_msgpEB8_
Unexecuted instantiation: _RINvMs6_NtCscrZQdumITES_3der8documentNtB6_14SecretDocument10encode_msgNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoEB1a_
Unexecuted instantiation: _RINvMs6_NtCscrZQdumITES_3der8documentNtB6_14SecretDocument10encode_msgNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyEB1a_
229
230
    /// Decode ASN.1 DER document from PEM.
231
    #[cfg(feature = "pem")]
232
0
    pub fn from_pem(pem: &str) -> Result<(&str, Self)> {
233
0
        Document::from_pem(pem).map(|(label, doc)| (label, Self(doc)))
234
0
    }
235
236
    /// Encode ASN.1 DER document as a PEM string.
237
    #[cfg(feature = "pem")]
238
0
    pub fn to_pem(
239
0
        &self,
240
0
        label: &'static str,
241
0
        line_ending: pem::LineEnding,
242
0
    ) -> Result<Zeroizing<String>> {
243
0
        self.0.to_pem(label, line_ending).map(Zeroizing::new)
244
0
    }
245
246
    /// Read ASN.1 DER document from a file.
247
    #[cfg(feature = "std")]
248
0
    pub fn read_der_file(path: impl AsRef<Path>) -> Result<Self> {
249
0
        Document::read_der_file(path).map(Self)
250
0
    }
251
252
    /// Write ASN.1 DER document to a file.
253
    #[cfg(feature = "std")]
254
0
    pub fn write_der_file(&self, path: impl AsRef<Path>) -> Result<()> {
255
0
        write_secret_file(path, self.as_bytes())
256
0
    }
257
258
    /// Read PEM-encoded ASN.1 DER document from a file.
259
    #[cfg(all(feature = "pem", feature = "std"))]
260
0
    pub fn read_pem_file(path: impl AsRef<Path>) -> Result<(String, Self)> {
261
0
        Document::read_pem_file(path).map(|(label, doc)| (label, Self(doc)))
262
0
    }
263
264
    /// Write PEM-encoded ASN.1 DER document to a file.
265
    #[cfg(all(feature = "pem", feature = "std"))]
266
0
    pub fn write_pem_file(
267
0
        &self,
268
0
        path: impl AsRef<Path>,
269
0
        label: &'static str,
270
0
        line_ending: pem::LineEnding,
271
0
    ) -> Result<()> {
272
0
        write_secret_file(path, self.to_pem(label, line_ending)?.as_bytes())
273
0
    }
274
}
275
#[cfg(feature = "zeroize")]
276
impl Debug for SecretDocument {
277
0
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
278
0
        fmt.debug_struct("SecretDocument").finish_non_exhaustive()
279
0
    }
280
}
281
282
#[cfg(feature = "zeroize")]
283
impl Drop for SecretDocument {
284
0
    fn drop(&mut self) {
285
0
        self.0.der_bytes.zeroize();
286
0
    }
287
}
288
289
#[cfg(feature = "zeroize")]
290
impl From<Document> for SecretDocument {
291
0
    fn from(doc: Document) -> SecretDocument {
292
0
        SecretDocument(doc)
293
0
    }
294
}
295
296
#[cfg(feature = "zeroize")]
297
impl TryFrom<&[u8]> for SecretDocument {
298
    type Error = Error;
299
300
0
    fn try_from(der_bytes: &[u8]) -> Result<Self> {
301
0
        Document::try_from(der_bytes).map(Self)
302
0
    }
303
}
304
305
#[cfg(feature = "zeroize")]
306
impl TryFrom<Vec<u8>> for SecretDocument {
307
    type Error = Error;
308
309
0
    fn try_from(der_bytes: Vec<u8>) -> Result<Self> {
310
0
        Document::try_from(der_bytes).map(Self)
311
0
    }
312
}
313
314
#[cfg(feature = "zeroize")]
315
impl ZeroizeOnDrop for SecretDocument {}
316
317
/// Attempt to decode a ASN.1 `SEQUENCE` from the given decoder, returning the
318
/// entire sequence including the header.
319
0
fn decode_sequence<'a>(decoder: &mut SliceReader<'a>) -> Result<&'a [u8]> {
320
0
    let header = decoder.peek_header()?;
321
0
    header.tag.assert_eq(Tag::Sequence)?;
322
323
0
    let len = (header.encoded_len()? + header.length)?;
324
0
    decoder.read_slice(len)
325
0
}
326
327
/// Write a file containing secret data to the filesystem, restricting the
328
/// file permissions so it's only readable by the owner
329
#[cfg(all(unix, feature = "std", feature = "zeroize"))]
330
0
fn write_secret_file(path: impl AsRef<Path>, data: &[u8]) -> Result<()> {
331
    use std::{io::Write, os::unix::fs::OpenOptionsExt};
332
333
    /// File permissions for secret data
334
    #[cfg(unix)]
335
    const SECRET_FILE_PERMS: u32 = 0o600;
336
337
0
    fs::OpenOptions::new()
338
0
        .create(true)
339
0
        .write(true)
340
0
        .truncate(true)
341
0
        .mode(SECRET_FILE_PERMS)
342
0
        .open(path)
343
0
        .and_then(|mut file| file.write_all(data))?;
344
345
0
    Ok(())
346
0
}
347
348
/// Write a file containing secret data to the filesystem
349
// TODO(tarcieri): permissions hardening on Windows
350
#[cfg(all(not(unix), feature = "std", feature = "zeroize"))]
351
fn write_secret_file(path: impl AsRef<Path>, data: &[u8]) -> Result<()> {
352
    fs::write(path, data)?;
353
    Ok(())
354
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/encode.rs
Line
Count
Source
1
//! Trait definition for [`Encode`].
2
3
use crate::{Header, Length, Result, SliceWriter, Tagged, Writer};
4
use core::marker::PhantomData;
5
6
#[cfg(feature = "alloc")]
7
use {alloc::boxed::Box, alloc::vec::Vec, core::iter};
8
9
#[cfg(feature = "pem")]
10
use {
11
    crate::PemWriter,
12
    alloc::string::String,
13
    pem_rfc7468::{self as pem, LineEnding, PemLabel},
14
};
15
16
#[cfg(any(feature = "alloc", feature = "pem"))]
17
use crate::ErrorKind;
18
19
#[cfg(doc)]
20
use crate::Tag;
21
22
/// Encoding trait.
23
pub trait Encode {
24
    /// Compute the length of this value in bytes when encoded as ASN.1 DER.
25
    fn encoded_len(&self) -> Result<Length>;
26
27
    /// Encode this value as ASN.1 DER using the provided [`Writer`].
28
    fn encode(&self, encoder: &mut impl Writer) -> Result<()>;
29
30
    /// Encode this value to the provided byte slice, returning a sub-slice
31
    /// containing the encoded message.
32
0
    fn encode_to_slice<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8]> {
33
0
        let mut writer = SliceWriter::new(buf);
34
0
        self.encode(&mut writer)?;
35
0
        writer.finish()
36
0
    }
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der3tag3TagNtNtB6_6encode6Encode15encode_to_sliceB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6header6HeaderNtNtB6_6encode6Encode15encode_to_sliceB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6length16IndefiniteLengthNtNtB6_6encode6Encode15encode_to_sliceB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6length6LengthNtNtB6_6encode6Encode15encode_to_sliceB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der8document8DocumentNtNtB6_6encode6Encode15encode_to_sliceB6_
Unexecuted instantiation: _RNvYNtNtCssr1zNgi7Nt_5pkcs87version7VersionNtNtCscrZQdumITES_3der6encode6Encode15encode_to_sliceB6_
37
38
    /// Encode this message as ASN.1 DER, appending it to the provided
39
    /// byte vector.
40
    #[cfg(feature = "alloc")]
41
0
    fn encode_to_vec(&self, buf: &mut Vec<u8>) -> Result<Length> {
42
0
        let expected_len = usize::try_from(self.encoded_len()?)?;
43
0
        buf.reserve(expected_len);
44
0
        buf.extend(iter::repeat(0).take(expected_len));
45
0
46
0
        let mut writer = SliceWriter::new(buf);
47
0
        self.encode(&mut writer)?;
48
0
        let actual_len = writer.finish()?.len();
49
0
50
0
        if expected_len != actual_len {
51
            return Err(ErrorKind::Incomplete {
52
0
                expected_len: expected_len.try_into()?,
53
0
                actual_len: actual_len.try_into()?,
54
            }
55
0
            .into());
56
0
        }
57
0
58
0
        actual_len.try_into()
59
0
    }
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der3tag3TagNtNtB6_6encode6Encode13encode_to_vecB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6header6HeaderNtNtB6_6encode6Encode13encode_to_vecB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6length16IndefiniteLengthNtNtB6_6encode6Encode13encode_to_vecB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6length6LengthNtNtB6_6encode6Encode13encode_to_vecB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der8document8DocumentNtNtB6_6encode6Encode13encode_to_vecB6_
Unexecuted instantiation: _RNvYNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoNtNtCscrZQdumITES_3der6encode6Encode13encode_to_vecB6_
Unexecuted instantiation: _RNvYNtNtCssr1zNgi7Nt_5pkcs87version7VersionNtNtCscrZQdumITES_3der6encode6Encode13encode_to_vecB6_
Unexecuted instantiation: _RNvYNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyNtNtCscrZQdumITES_3der6encode6Encode13encode_to_vecB6_
60
61
    /// Encode this type as DER, returning a byte vector.
62
    #[cfg(feature = "alloc")]
63
0
    fn to_der(&self) -> Result<Vec<u8>> {
64
0
        let mut buf = Vec::new();
65
0
        self.encode_to_vec(&mut buf)?;
66
0
        Ok(buf)
67
0
    }
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der3tag3TagNtNtB6_6encode6Encode6to_derB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6header6HeaderNtNtB6_6encode6Encode6to_derB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6length16IndefiniteLengthNtNtB6_6encode6Encode6to_derB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der6length6LengthNtNtB6_6encode6Encode6to_derB6_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der8document8DocumentNtNtB6_6encode6Encode6to_derB6_
Unexecuted instantiation: _RNvYNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoNtNtCscrZQdumITES_3der6encode6Encode6to_derB6_
Unexecuted instantiation: _RNvYNtNtCssr1zNgi7Nt_5pkcs87version7VersionNtNtCscrZQdumITES_3der6encode6Encode6to_derB6_
Unexecuted instantiation: _RNvYNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyNtNtCscrZQdumITES_3der6encode6Encode6to_derB6_
68
}
69
70
impl<T> Encode for T
71
where
72
    T: EncodeValue + Tagged,
73
{
74
    /// Compute the length of this value in bytes when encoded as ASN.1 DER.
75
0
    fn encoded_len(&self) -> Result<Length> {
76
0
        self.value_len().and_then(|len| len.for_tlv())
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodehNtB4_6Encode11encoded_len0B6_
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeINtNtCskctcMqaO4X4_4spki9algorithm19AlgorithmIdentifierNtNtNtB6_4asn13any6AnyRefENtB4_6Encode11encoded_len0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeINtNtNtB6_4asn116context_specific15ContextSpecificNtNtBA_10bit_string12BitStringRefENtB4_6Encode11encoded_len0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtB4_6Encode11encoded_len0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoNtB4_6Encode11encoded_len0Bz_
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeNtNtNtB6_4asn110bit_string12BitStringRefNtB4_6Encode11encoded_len0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeNtNtNtB6_4asn112octet_string14OctetStringRefNtB4_6Encode11encoded_len0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeNtNtNtB6_4asn13any6AnyRefNtB4_6Encode11encoded_len0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeINtNtB6_10encode_ref14EncodeValueRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtB4_6Encode11encoded_len0B19_
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeINtNtNtB6_4asn116context_specific15ContextSpecificNtNtBA_10bit_string12BitStringRefENtB4_6Encode11encoded_len0Csj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeINtNtNtB6_4asn116context_specific18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtB4_6Encode11encoded_len0B1q_
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyNtB4_6Encode11encoded_len0Bz_
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeNtNtNtB6_4asn110bit_string12BitStringRefNtB4_6Encode11encoded_len0Csj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodeNtNtNtB6_4asn112octet_string14OctetStringRefNtB4_6Encode11encoded_len0Csj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der6encodehNtB4_6Encode11encoded_len0Csj9qtwLkMHqH_4sec1
77
0
    }
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodehNtB2_6Encode11encoded_lenB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeINtNtCskctcMqaO4X4_4spki9algorithm19AlgorithmIdentifierNtNtNtB4_4asn13any6AnyRefENtB2_6Encode11encoded_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeINtNtNtB4_4asn116context_specific15ContextSpecificNtNtBy_10bit_string12BitStringRefENtB2_6Encode11encoded_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtB2_6Encode11encoded_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoNtB2_6Encode11encoded_lenBx_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeNtNtNtB4_4asn110bit_string12BitStringRefNtB2_6Encode11encoded_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeNtNtNtB4_4asn112octet_string14OctetStringRefNtB2_6Encode11encoded_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeNtNtNtB4_4asn13any6AnyRefNtB2_6Encode11encoded_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeINtNtB4_10encode_ref14EncodeValueRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtB2_6Encode11encoded_lenB17_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeINtNtNtB4_4asn116context_specific15ContextSpecificNtNtBy_10bit_string12BitStringRefENtB2_6Encode11encoded_lenCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeINtNtNtB4_4asn116context_specific18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtB2_6Encode11encoded_lenB1o_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyNtB2_6Encode11encoded_lenBx_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeNtNtNtB4_4asn110bit_string12BitStringRefNtB2_6Encode11encoded_lenCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodeNtNtNtB4_4asn112octet_string14OctetStringRefNtB2_6Encode11encoded_lenCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der6encodehNtB2_6Encode11encoded_lenCsj9qtwLkMHqH_4sec1
78
79
    /// Encode this value as ASN.1 DER using the provided [`Writer`].
80
0
    fn encode(&self, writer: &mut impl Writer) -> Result<()> {
81
0
        self.header()?.encode(writer)?;
82
0
        self.encode_value(writer)
83
0
    }
Unexecuted instantiation: _RINvXININtCscrZQdumITES_3der6encode0pEpNtB6_6Encode6encodepEB8_
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeINtNtCskctcMqaO4X4_4spki9algorithm19AlgorithmIdentifierNtNtNtB5_4asn13any6AnyRefENtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeINtNtNtB5_4asn116context_specific15ContextSpecificNtNtBz_10bit_string12BitStringRefENtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoNtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterEBy_
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeNtNtNtB5_4asn110bit_string12BitStringRefNtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeNtNtNtB5_4asn112octet_string14OctetStringRefNtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeNtNtNtB5_4asn13any6AnyRefNtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodehNtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeINtNtB5_10encode_ref14EncodeValueRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterEB18_
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeINtNtNtB5_4asn116context_specific15ContextSpecificNtNtBz_10bit_string12BitStringRefENtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeINtNtNtB5_4asn116context_specific18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterEB1p_
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyNtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterEBy_
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeNtNtNtB5_4asn110bit_string12BitStringRefNtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodeNtNtNtB5_4asn112octet_string14OctetStringRefNtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXNtCscrZQdumITES_3der6encodehNtB3_6Encode6encodeNtNtNtB5_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
84
}
85
86
/// Dummy implementation for [`PhantomData`] which allows deriving
87
/// implementations on structs with phantom fields.
88
impl<T> Encode for PhantomData<T>
89
where
90
    T: ?Sized,
91
{
92
0
    fn encoded_len(&self) -> Result<Length> {
93
0
        Ok(Length::ZERO)
94
0
    }
95
96
0
    fn encode(&self, _writer: &mut impl Writer) -> Result<()> {
97
0
        Ok(())
98
0
    }
99
}
100
101
/// PEM encoding trait.
102
///
103
/// This trait is automatically impl'd for any type which impls both
104
/// [`Encode`] and [`PemLabel`].
105
#[cfg(feature = "pem")]
106
pub trait EncodePem: Encode + PemLabel {
107
    /// Try to encode this type as PEM.
108
    fn to_pem(&self, line_ending: LineEnding) -> Result<String>;
109
}
110
111
#[cfg(feature = "pem")]
112
impl<T: Encode + PemLabel> EncodePem for T {
113
0
    fn to_pem(&self, line_ending: LineEnding) -> Result<String> {
114
0
        let der_len = usize::try_from(self.encoded_len()?)?;
115
0
        let pem_len = pem::encapsulated_len(Self::PEM_LABEL, line_ending, der_len)?;
116
117
0
        let mut buf = vec![0u8; pem_len];
118
0
        let mut writer = PemWriter::new(Self::PEM_LABEL, line_ending, &mut buf)?;
119
0
        self.encode(&mut writer)?;
120
121
0
        let actual_len = writer.finish()?;
122
0
        buf.truncate(actual_len);
123
0
        Ok(String::from_utf8(buf)?)
124
0
    }
125
}
126
127
/// Encode the value part of a Tag-Length-Value encoded field, sans the [`Tag`]
128
/// and [`Length`].
129
pub trait EncodeValue {
130
    /// Get the [`Header`] used to encode this value.
131
0
    fn header(&self) -> Result<Header>
132
0
    where
133
0
        Self: Tagged,
134
0
    {
135
0
        Header::new(self.tag(), self.value_len()?)
136
0
    }
Unexecuted instantiation: _RNvYINtNtCsiBl6Lc3cFal_5alloc3vec3VechENtNtCscrZQdumITES_3der6encode11EncodeValue6headerBF_
Unexecuted instantiation: _RNvYNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtCscrZQdumITES_3der6encode11EncodeValue6headerBO_
Unexecuted instantiation: _RNvYNtNtCsVNp5ty2IzJ_3std4time10SystemTimeNtNtCscrZQdumITES_3der6encode11EncodeValue6headerBI_
Unexecuted instantiation: _RNvYNtNtCscrZQdumITES_3der8datetime8DateTimeNtNtB6_6encode11EncodeValue6headerB6_
Unexecuted instantiation: _RNvYNtNtCsiBl6Lc3cFal_5alloc6string6StringNtNtCscrZQdumITES_3der6encode11EncodeValue6headerBI_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn110bit_string12BitStringRefNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn110bmp_string9BmpStringNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn110ia5_string12Ia5StringRefNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn111utf8_string13Utf8StringRefNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn112octet_string14OctetStringRefNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn114teletex_string16TeletexStringRefNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn115videotex_string17VideotexStringRefNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn116generalized_time15GeneralizedTimeNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn116printable_string18PrintableStringRefNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn13any6AnyRefNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn14null4NullNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn18sequence11SequenceRefNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn18utc_time7UtcTimeNtNtB8_6encode11EncodeValue6headerB8_
Unexecuted instantiation: _RNvYNtNtNtNtCscrZQdumITES_3der4asn110bit_string10allocating9BitStringNtNtBa_6encode11EncodeValue6headerBa_
Unexecuted instantiation: _RNvYNtNtNtNtCscrZQdumITES_3der4asn110ia5_string10allocation9Ia5StringNtNtBa_6encode11EncodeValue6headerBa_
Unexecuted instantiation: _RNvYNtNtNtNtCscrZQdumITES_3der4asn112octet_string10allocating11OctetStringNtNtBa_6encode11EncodeValue6headerBa_
Unexecuted instantiation: _RNvYNtNtNtNtCscrZQdumITES_3der4asn114teletex_string10allocation13TeletexStringNtNtBa_6encode11EncodeValue6headerBa_
Unexecuted instantiation: _RNvYNtNtNtNtCscrZQdumITES_3der4asn116printable_string10allocation15PrintableStringNtNtBa_6encode11EncodeValue6headerBa_
Unexecuted instantiation: _RNvYNtNtNtNtCscrZQdumITES_3der4asn13any10allocating3AnyNtNtBa_6encode11EncodeValue6headerBa_
Unexecuted instantiation: _RNvYNtNtNtNtCscrZQdumITES_3der4asn17integer3int6IntRefNtNtBa_6encode11EncodeValue6headerBa_
Unexecuted instantiation: _RNvYNtNtNtNtCscrZQdumITES_3der4asn17integer4uint7UintRefNtNtBa_6encode11EncodeValue6headerBa_
Unexecuted instantiation: _RNvYNtNtNtNtNtCscrZQdumITES_3der4asn17integer3int10allocating3IntNtNtBc_6encode11EncodeValue6headerBc_
Unexecuted instantiation: _RNvYNtNtNtNtNtCscrZQdumITES_3der4asn17integer4uint10allocating4UintNtNtBc_6encode11EncodeValue6headerBc_
Unexecuted instantiation: _RNvYaNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYbNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYhNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYlNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYmNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYnNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYoNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYsNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYtNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYuNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYxNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYyNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB7_
Unexecuted instantiation: _RNvYINtNtCskctcMqaO4X4_4spki9algorithm19AlgorithmIdentifierNtNtNtCscrZQdumITES_3der4asn13any6AnyRefENtNtB11_6encode11EncodeValue6headerCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der4asn116context_specific15ContextSpecificNtNtB7_10bit_string12BitStringRefENtNtB9_6encode11EncodeValue6headerCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtNtCscrZQdumITES_3der6encode11EncodeValue6headerCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB6_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn110bit_string12BitStringRefNtNtB8_6encode11EncodeValue6headerCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn112octet_string14OctetStringRefNtNtB8_6encode11EncodeValue6headerCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn13any6AnyRefNtNtB8_6encode11EncodeValue6headerCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYhNtNtCscrZQdumITES_3der6encode11EncodeValue6headerCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYINtNtCscrZQdumITES_3der10encode_ref14EncodeValueRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtNtB7_6encode11EncodeValue6headerBV_
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der4asn116context_specific15ContextSpecificNtNtB7_10bit_string12BitStringRefENtNtB9_6encode11EncodeValue6headerCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der4asn116context_specific18ContextSpecificRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtNtB9_6encode11EncodeValue6headerB1c_
Unexecuted instantiation: _RNvYNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB6_
Unexecuted instantiation: _RNvYNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyNtNtCscrZQdumITES_3der6encode11EncodeValue6headerB6_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn110bit_string12BitStringRefNtNtB8_6encode11EncodeValue6headerCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der4asn112octet_string14OctetStringRefNtNtB8_6encode11EncodeValue6headerCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvYhNtNtCscrZQdumITES_3der6encode11EncodeValue6headerCsj9qtwLkMHqH_4sec1
137
138
    /// Compute the length of this value (sans [`Tag`]+[`Length`] header) when
139
    /// encoded as ASN.1 DER.
140
    fn value_len(&self) -> Result<Length>;
141
142
    /// Encode value (sans [`Tag`]+[`Length`] header) as ASN.1 DER using the
143
    /// provided [`Writer`].
144
    fn encode_value(&self, encoder: &mut impl Writer) -> Result<()>;
145
}
146
147
#[cfg(feature = "alloc")]
148
impl<T> EncodeValue for Box<T>
149
where
150
    T: EncodeValue,
151
{
152
0
    fn value_len(&self) -> Result<Length> {
153
0
        T::value_len(self)
154
0
    }
155
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
156
0
        T::encode_value(self, writer)
157
0
    }
158
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/encode_ref.rs
Line
Count
Source
1
//! Wrapper object for encoding reference types.
2
// TODO(tarcieri): replace with blanket impls of `Encode(Value)` for reference types?
3
4
use crate::{Encode, EncodeValue, Length, Result, Tag, Tagged, ValueOrd, Writer};
5
use core::cmp::Ordering;
6
7
/// Reference encoder: wrapper type which impls `Encode` for any reference to a
8
/// type which impls the same.
9
pub struct EncodeRef<'a, T>(pub &'a T);
10
11
impl<'a, T> AsRef<T> for EncodeRef<'a, T> {
12
0
    fn as_ref(&self) -> &T {
13
0
        self.0
14
0
    }
15
}
16
17
impl<'a, T> Encode for EncodeRef<'a, T>
18
where
19
    T: Encode,
20
{
21
0
    fn encoded_len(&self) -> Result<Length> {
22
0
        self.0.encoded_len()
23
0
    }
24
25
0
    fn encode(&self, writer: &mut impl Writer) -> Result<()> {
26
0
        self.0.encode(writer)
27
0
    }
28
}
29
30
/// Reference value encoder: wrapper type which impls `EncodeValue` and `Tagged`
31
/// for any reference type which impls the same.
32
///
33
/// By virtue of the blanket impl, this type also impls `Encode`.
34
pub struct EncodeValueRef<'a, T>(pub &'a T);
35
36
impl<'a, T> AsRef<T> for EncodeValueRef<'a, T> {
37
0
    fn as_ref(&self) -> &T {
38
0
        self.0
39
0
    }
40
}
41
42
impl<'a, T> EncodeValue for EncodeValueRef<'a, T>
43
where
44
    T: EncodeValue,
45
{
46
0
    fn value_len(&self) -> Result<Length> {
47
0
        self.0.value_len()
48
0
    }
Unexecuted instantiation: _RNvXININtCscrZQdumITES_3der10encode_refs1_0pEINtB5_14EncodeValueRefpENtNtB7_6encode11EncodeValue9value_lenB7_
Unexecuted instantiation: _RNvXs1_NtCscrZQdumITES_3der10encode_refINtB5_14EncodeValueRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtNtB7_6encode11EncodeValue9value_lenB11_
49
50
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
51
0
        self.0.encode_value(writer)
52
0
    }
Unexecuted instantiation: _RINvXININtCscrZQdumITES_3der10encode_refs1_0pEINtB6_14EncodeValueRefpENtNtB8_6encode11EncodeValue12encode_valuepEB8_
Unexecuted instantiation: _RINvXs1_NtCscrZQdumITES_3der10encode_refINtB6_14EncodeValueRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtNtB8_6encode11EncodeValue12encode_valueNtNtNtB8_6writer5slice11SliceWriterEB12_
53
}
54
55
impl<'a, T> Tagged for EncodeValueRef<'a, T>
56
where
57
    T: Tagged,
58
{
59
0
    fn tag(&self) -> Tag {
60
0
        self.0.tag()
61
0
    }
Unexecuted instantiation: _RNvXININtCscrZQdumITES_3der10encode_refs2_0pEINtB5_14EncodeValueRefpENtNtB7_3tag6Tagged3tagB7_
Unexecuted instantiation: _RNvXs2_NtCscrZQdumITES_3der10encode_refINtB5_14EncodeValueRefNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersENtNtB7_3tag6Tagged3tagB11_
62
}
63
64
impl<'a, T> ValueOrd for EncodeValueRef<'a, T>
65
where
66
    T: ValueOrd,
67
{
68
0
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
69
0
        self.0.value_cmp(other.0)
70
0
    }
71
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/error.rs
Line
Count
Source
1
//! Error types.
2
3
pub use core::str::Utf8Error;
4
5
use crate::{Length, Tag};
6
use core::{convert::Infallible, fmt, num::TryFromIntError};
7
8
#[cfg(feature = "oid")]
9
use crate::asn1::ObjectIdentifier;
10
11
#[cfg(feature = "pem")]
12
use crate::pem;
13
14
/// Result type.
15
pub type Result<T> = core::result::Result<T, Error>;
16
17
/// Error type.
18
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
19
pub struct Error {
20
    /// Kind of error.
21
    kind: ErrorKind,
22
23
    /// Position inside of message where error occurred.
24
    position: Option<Length>,
25
}
26
27
impl Error {
28
    /// Create a new [`Error`].
29
0
    pub fn new(kind: ErrorKind, position: Length) -> Error {
30
0
        Error {
31
0
            kind,
32
0
            position: Some(position),
33
0
        }
34
0
    }
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der5errorNtB2_5Error3newB4_
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der5errorNtB2_5Error3newCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der5errorNtB2_5Error3newCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der5errorNtB2_5Error3newCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der5errorNtB2_5Error3newCskctcMqaO4X4_4spki
35
36
    /// Create a new [`ErrorKind::Incomplete`] for the given length.
37
    ///
38
    /// Computes the expected len as being one greater than `actual_len`.
39
0
    pub fn incomplete(actual_len: Length) -> Self {
40
0
        match actual_len + Length::ONE {
41
0
            Ok(expected_len) => ErrorKind::Incomplete {
42
0
                expected_len,
43
0
                actual_len,
44
0
            }
45
0
            .at(actual_len),
46
0
            Err(err) => err.kind().at(actual_len),
47
        }
48
0
    }
49
50
    /// Get the [`ErrorKind`] which occurred.
51
0
    pub fn kind(self) -> ErrorKind {
52
0
        self.kind
53
0
    }
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der5errorNtB2_5Error4kindB4_
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der5errorNtB2_5Error4kindCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der5errorNtB2_5Error4kindCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der5errorNtB2_5Error4kindCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der5errorNtB2_5Error4kindCskctcMqaO4X4_4spki
54
55
    /// Get the position inside of the message where the error occurred.
56
0
    pub fn position(self) -> Option<Length> {
57
0
        self.position
58
0
    }
59
60
    /// For errors occurring inside of a nested message, extend the position
61
    /// count by the location where the nested message occurs.
62
0
    pub(crate) fn nested(self, nested_position: Length) -> Self {
63
0
        // TODO(tarcieri): better handle length overflows occurring in this calculation?
64
0
        let position = (nested_position + self.position.unwrap_or_default()).ok();
65
0
66
0
        Self {
67
0
            kind: self.kind,
68
0
            position,
69
0
        }
70
0
    }
71
}
72
73
#[cfg(feature = "std")]
74
impl std::error::Error for Error {}
75
76
impl fmt::Display for Error {
77
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78
0
        write!(f, "{}", self.kind)?;
79
80
0
        if let Some(pos) = self.position {
81
0
            write!(f, " at DER byte {}", pos)?;
82
0
        }
83
84
0
        Ok(())
85
0
    }
86
}
87
88
impl From<ErrorKind> for Error {
89
0
    fn from(kind: ErrorKind) -> Error {
90
0
        Error {
91
0
            kind,
92
0
            position: None,
93
0
        }
94
0
    }
Unexecuted instantiation: _RNvXs1_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_9ErrorKindE4fromB7_
Unexecuted instantiation: _RNvXs1_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_9ErrorKindE4fromCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvXs1_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_9ErrorKindE4fromCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs1_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_9ErrorKindE4fromCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXs1_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_9ErrorKindE4fromCskctcMqaO4X4_4spki
95
}
96
97
impl From<Infallible> for Error {
98
0
    fn from(_: Infallible) -> Error {
99
0
        unreachable!()
100
    }
101
}
102
103
impl From<TryFromIntError> for Error {
104
0
    fn from(_: TryFromIntError) -> Error {
105
0
        Error {
106
0
            kind: ErrorKind::Overflow,
107
0
            position: None,
108
0
        }
109
0
    }
110
}
111
112
impl From<Utf8Error> for Error {
113
0
    fn from(err: Utf8Error) -> Error {
114
0
        Error {
115
0
            kind: ErrorKind::Utf8(err),
116
0
            position: None,
117
0
        }
118
0
    }
119
}
120
121
#[cfg(feature = "alloc")]
122
impl From<alloc::string::FromUtf8Error> for Error {
123
0
    fn from(err: alloc::string::FromUtf8Error) -> Error {
124
0
        ErrorKind::Utf8(err.utf8_error()).into()
125
0
    }
126
}
127
128
#[cfg(feature = "oid")]
129
impl From<const_oid::Error> for Error {
130
0
    fn from(_: const_oid::Error) -> Error {
131
0
        ErrorKind::OidMalformed.into()
132
0
    }
Unexecuted instantiation: _RNvXs6_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtCs7FMNkqQAJBl_9const_oid5error5ErrorE4fromB7_
Unexecuted instantiation: _RNvXs6_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtCs7FMNkqQAJBl_9const_oid5error5ErrorE4fromCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs6_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtCs7FMNkqQAJBl_9const_oid5error5ErrorE4fromCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXs6_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtCs7FMNkqQAJBl_9const_oid5error5ErrorE4fromCskctcMqaO4X4_4spki
133
}
134
135
#[cfg(feature = "pem")]
136
impl From<pem::Error> for Error {
137
0
    fn from(err: pem::Error) -> Error {
138
0
        ErrorKind::Pem(err).into()
139
0
    }
Unexecuted instantiation: _RNvXs7_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtCs7ONNNQjtL1v_11pem_rfc74685error5ErrorE4fromB7_
Unexecuted instantiation: _RNvXs7_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtCs7ONNNQjtL1v_11pem_rfc74685error5ErrorE4fromCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs7_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtCs7ONNNQjtL1v_11pem_rfc74685error5ErrorE4fromCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXs7_NtCscrZQdumITES_3der5errorNtB5_5ErrorINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtCs7ONNNQjtL1v_11pem_rfc74685error5ErrorE4fromCskctcMqaO4X4_4spki
140
}
141
142
#[cfg(feature = "std")]
143
impl From<std::io::Error> for Error {
144
0
    fn from(err: std::io::Error) -> Error {
145
0
        match err.kind() {
146
0
            std::io::ErrorKind::NotFound => ErrorKind::FileNotFound,
147
0
            std::io::ErrorKind::PermissionDenied => ErrorKind::PermissionDenied,
148
0
            other => ErrorKind::Io(other),
149
        }
150
0
        .into()
151
0
    }
152
}
153
154
#[cfg(feature = "time")]
155
impl From<time::error::ComponentRange> for Error {
156
    fn from(_: time::error::ComponentRange) -> Error {
157
        ErrorKind::DateTime.into()
158
    }
159
}
160
161
/// Error type.
162
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
163
#[non_exhaustive]
164
pub enum ErrorKind {
165
    /// Date-and-time related errors.
166
    DateTime,
167
168
    /// This error indicates a previous DER parsing operation resulted in
169
    /// an error and tainted the state of a `Decoder` or `Encoder`.
170
    ///
171
    /// Once this occurs, the overall operation has failed and cannot be
172
    /// subsequently resumed.
173
    Failed,
174
175
    /// File not found error.
176
    #[cfg(feature = "std")]
177
    FileNotFound,
178
179
    /// Message is incomplete and does not contain all of the expected data.
180
    Incomplete {
181
        /// Expected message length.
182
        ///
183
        /// Note that this length represents a *minimum* lower bound on how
184
        /// much additional data is needed to continue parsing the message.
185
        ///
186
        /// It's possible upon subsequent message parsing that the parser will
187
        /// discover even more data is needed.
188
        expected_len: Length,
189
190
        /// Actual length of the message buffer currently being processed.
191
        actual_len: Length,
192
    },
193
194
    /// I/O errors.
195
    #[cfg(feature = "std")]
196
    Io(std::io::ErrorKind),
197
198
    /// Indefinite length disallowed.
199
    IndefiniteLength,
200
201
    /// Incorrect length for a given field.
202
    Length {
203
        /// Tag of the value being decoded.
204
        tag: Tag,
205
    },
206
207
    /// Message is not canonically encoded.
208
    Noncanonical {
209
        /// Tag of the value which is not canonically encoded.
210
        tag: Tag,
211
    },
212
213
    /// OID is improperly encoded.
214
    OidMalformed,
215
216
    /// Unknown OID.
217
    ///
218
    /// This error is intended to be used by libraries which parse DER-based
219
    /// formats which encounter unknown or unsupported OID libraries.
220
    ///
221
    /// It enables passing back the OID value to the caller, which allows them
222
    /// to determine which OID(s) are causing the error (and then potentially
223
    /// contribute upstream support for algorithms they care about).
224
    #[cfg(feature = "oid")]
225
    OidUnknown {
226
        /// OID value that was unrecognized by a parser for a DER-based format.
227
        oid: ObjectIdentifier,
228
    },
229
230
    /// `SET` cannot contain duplicates.
231
    SetDuplicate,
232
233
    /// `SET` ordering error: items not in canonical order.
234
    SetOrdering,
235
236
    /// Integer overflow occurred (library bug!).
237
    Overflow,
238
239
    /// Message is longer than this library's internal limits support.
240
    Overlength,
241
242
    /// PEM encoding errors.
243
    #[cfg(feature = "pem")]
244
    Pem(pem::Error),
245
246
    /// Permission denied reading file.
247
    #[cfg(feature = "std")]
248
    PermissionDenied,
249
250
    /// Reader does not support the requested operation.
251
    Reader,
252
253
    /// Unknown tag mode.
254
    TagModeUnknown,
255
256
    /// Invalid tag number.
257
    ///
258
    /// The "tag number" is the lower 5-bits of a tag's octet.
259
    /// This error occurs in the case that all 5-bits are set to `1`,
260
    /// which indicates a multi-byte tag which is unsupported by this library.
261
    TagNumberInvalid,
262
263
    /// Unexpected tag.
264
    TagUnexpected {
265
        /// Tag the decoder was expecting (if there is a single such tag).
266
        ///
267
        /// `None` if multiple tags are expected/allowed, but the `actual` tag
268
        /// does not match any of them.
269
        expected: Option<Tag>,
270
271
        /// Actual tag encountered in the message.
272
        actual: Tag,
273
    },
274
275
    /// Unknown/unsupported tag.
276
    TagUnknown {
277
        /// Raw byte value of the tag.
278
        byte: u8,
279
    },
280
281
    /// Undecoded trailing data at end of message.
282
    TrailingData {
283
        /// Length of the decoded data.
284
        decoded: Length,
285
286
        /// Total length of the remaining data left in the buffer.
287
        remaining: Length,
288
    },
289
290
    /// UTF-8 errors.
291
    Utf8(Utf8Error),
292
293
    /// Unexpected value.
294
    Value {
295
        /// Tag of the unexpected value.
296
        tag: Tag,
297
    },
298
}
299
300
impl ErrorKind {
301
    /// Annotate an [`ErrorKind`] with context about where it occurred,
302
    /// returning an error.
303
0
    pub fn at(self, position: Length) -> Error {
304
0
        Error::new(self, position)
305
0
    }
Unexecuted instantiation: _RNvMs9_NtCscrZQdumITES_3der5errorNtB5_9ErrorKind2atB7_
Unexecuted instantiation: _RNvMs9_NtCscrZQdumITES_3der5errorNtB5_9ErrorKind2atCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvMs9_NtCscrZQdumITES_3der5errorNtB5_9ErrorKind2atCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMs9_NtCscrZQdumITES_3der5errorNtB5_9ErrorKind2atCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvMs9_NtCscrZQdumITES_3der5errorNtB5_9ErrorKind2atCskctcMqaO4X4_4spki
306
}
307
308
impl fmt::Display for ErrorKind {
309
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310
0
        match self {
311
0
            ErrorKind::DateTime => write!(f, "date/time error"),
312
0
            ErrorKind::Failed => write!(f, "operation failed"),
313
            #[cfg(feature = "std")]
314
0
            ErrorKind::FileNotFound => write!(f, "file not found"),
315
            ErrorKind::Incomplete {
316
0
                expected_len,
317
0
                actual_len,
318
0
            } => write!(
319
0
                f,
320
0
                "ASN.1 DER message is incomplete: expected {}, actual {}",
321
0
                expected_len, actual_len
322
0
            ),
323
            #[cfg(feature = "std")]
324
0
            ErrorKind::Io(err) => write!(f, "I/O error: {:?}", err),
325
0
            ErrorKind::IndefiniteLength => write!(f, "indefinite length disallowed"),
326
0
            ErrorKind::Length { tag } => write!(f, "incorrect length for {}", tag),
327
0
            ErrorKind::Noncanonical { tag } => {
328
0
                write!(f, "ASN.1 {} not canonically encoded as DER", tag)
329
            }
330
0
            ErrorKind::OidMalformed => write!(f, "malformed OID"),
331
            #[cfg(feature = "oid")]
332
0
            ErrorKind::OidUnknown { oid } => {
333
0
                write!(f, "unknown/unsupported OID: {}", oid)
334
            }
335
0
            ErrorKind::SetDuplicate => write!(f, "SET OF contains duplicate"),
336
0
            ErrorKind::SetOrdering => write!(f, "SET OF ordering error"),
337
0
            ErrorKind::Overflow => write!(f, "integer overflow"),
338
0
            ErrorKind::Overlength => write!(f, "ASN.1 DER message is too long"),
339
            #[cfg(feature = "pem")]
340
0
            ErrorKind::Pem(e) => write!(f, "PEM error: {}", e),
341
            #[cfg(feature = "std")]
342
0
            ErrorKind::PermissionDenied => write!(f, "permission denied"),
343
0
            ErrorKind::Reader => write!(f, "reader does not support the requested operation"),
344
0
            ErrorKind::TagModeUnknown => write!(f, "unknown tag mode"),
345
0
            ErrorKind::TagNumberInvalid => write!(f, "invalid tag number"),
346
0
            ErrorKind::TagUnexpected { expected, actual } => {
347
0
                write!(f, "unexpected ASN.1 DER tag: ")?;
348
349
0
                if let Some(tag) = expected {
350
0
                    write!(f, "expected {}, ", tag)?;
351
0
                }
352
353
0
                write!(f, "got {}", actual)
354
            }
355
0
            ErrorKind::TagUnknown { byte } => {
356
0
                write!(f, "unknown/unsupported ASN.1 DER tag: 0x{:02x}", byte)
357
            }
358
0
            ErrorKind::TrailingData { decoded, remaining } => {
359
0
                write!(
360
0
                    f,
361
0
                    "trailing data at end of DER message: decoded {} bytes, {} bytes remaining",
362
0
                    decoded, remaining
363
0
                )
364
            }
365
0
            ErrorKind::Utf8(e) => write!(f, "{}", e),
366
0
            ErrorKind::Value { tag } => write!(f, "malformed ASN.1 DER value for {}", tag),
367
        }
368
0
    }
369
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/header.rs
Line
Count
Source
1
//! ASN.1 DER headers.
2
3
use crate::{Decode, DerOrd, Encode, ErrorKind, Length, Reader, Result, Tag, Writer};
4
use core::cmp::Ordering;
5
6
/// ASN.1 DER headers: tag + length component of TLV-encoded values
7
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
8
pub struct Header {
9
    /// Tag representing the type of the encoded value
10
    pub tag: Tag,
11
12
    /// Length of the encoded value
13
    pub length: Length,
14
}
15
16
impl Header {
17
    /// Create a new [`Header`] from a [`Tag`] and a specified length.
18
    ///
19
    /// Returns an error if the length exceeds the limits of [`Length`].
20
0
    pub fn new(tag: Tag, length: impl TryInto<Length>) -> Result<Self> {
21
0
        let length = length.try_into().map_err(|_| ErrorKind::Overflow)?;
Unexecuted instantiation: _RNCINvMNtCscrZQdumITES_3der6headerNtB5_6Header3newNtNtB7_6length6LengthE0B7_
Unexecuted instantiation: _RNCINvMNtCscrZQdumITES_3der6headerNtB5_6Header3newNtNtB7_6length6LengthE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvMNtCscrZQdumITES_3der6headerNtB5_6Header3newNtNtB7_6length6LengthE0Csj9qtwLkMHqH_4sec1
22
0
        Ok(Self { tag, length })
23
0
    }
Unexecuted instantiation: _RINvMNtCscrZQdumITES_3der6headerNtB3_6Header3newNtNtB5_6length6LengthEB5_
Unexecuted instantiation: _RINvMNtCscrZQdumITES_3der6headerNtB3_6Header3newNtNtB5_6length6LengthECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvMNtCscrZQdumITES_3der6headerNtB3_6Header3newNtNtB5_6length6LengthECsj9qtwLkMHqH_4sec1
24
}
25
26
impl<'a> Decode<'a> for Header {
27
0
    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Header> {
28
0
        let tag = Tag::decode(reader)?;
29
30
0
        let length = Length::decode(reader).map_err(|e| {
31
0
            if e.kind() == ErrorKind::Overlength {
32
0
                ErrorKind::Length { tag }.into()
33
            } else {
34
0
                e
35
            }
36
0
        })?;
Unexecuted instantiation: _RNCINvXs_NtCscrZQdumITES_3der6headerNtB7_6HeaderNtNtB9_6decode6Decode6decodeNtNtNtB9_6reader3pem9PemReaderE0B9_
Unexecuted instantiation: _RNCINvXs_NtCscrZQdumITES_3der6headerNtB7_6HeaderNtNtB9_6decode6Decode6decodeNtNtNtB9_6reader5slice11SliceReaderE0B9_
Unexecuted instantiation: _RNCINvXs_NtCscrZQdumITES_3der6headerNtB7_6HeaderNtNtB9_6decode6Decode6decodeINtNtNtB9_6reader6nested12NestedReaderNtNtB1h_5slice11SliceReaderEE0Cs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNCINvXs_NtCscrZQdumITES_3der6headerNtB7_6HeaderNtNtB9_6decode6Decode6decodeNtNtNtB9_6reader5slice11SliceReaderE0Cs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNCINvXs_NtCscrZQdumITES_3der6headerNtB7_6HeaderNtNtB9_6decode6Decode6decodeINtNtNtB9_6reader6nested12NestedReaderIB1d_NtNtB1h_5slice11SliceReaderEEE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvXs_NtCscrZQdumITES_3der6headerNtB7_6HeaderNtNtB9_6decode6Decode6decodeINtNtNtB9_6reader6nested12NestedReaderNtNtB1h_5slice11SliceReaderEE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvXs_NtCscrZQdumITES_3der6headerNtB7_6HeaderNtNtB9_6decode6Decode6decodeNtNtNtB9_6reader5slice11SliceReaderE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvXs_NtCscrZQdumITES_3der6headerNtB7_6HeaderNtNtB9_6decode6Decode6decodeINtNtNtB9_6reader6nested12NestedReaderIB1d_NtNtB1h_5slice11SliceReaderEEE0Csj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNCINvXs_NtCscrZQdumITES_3der6headerNtB7_6HeaderNtNtB9_6decode6Decode6decodeINtNtNtB9_6reader6nested12NestedReaderNtNtB1h_5slice11SliceReaderEE0Csj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNCINvXs_NtCscrZQdumITES_3der6headerNtB7_6HeaderNtNtB9_6decode6Decode6decodeNtNtNtB9_6reader5slice11SliceReaderE0Csj9qtwLkMHqH_4sec1
37
38
0
        Ok(Self { tag, length })
39
0
    }
Unexecuted instantiation: _RINvXs_NtCscrZQdumITES_3der6headerNtB5_6HeaderNtNtB7_6decode6Decode6decodeNtNtNtB7_6reader3pem9PemReaderEB7_
Unexecuted instantiation: _RINvXs_NtCscrZQdumITES_3der6headerNtB5_6HeaderNtNtB7_6decode6Decode6decodeNtNtNtB7_6reader5slice11SliceReaderEB7_
Unexecuted instantiation: _RINvXs_NtCscrZQdumITES_3der6headerNtB5_6HeaderNtNtB7_6decode6Decode6decodeINtNtNtB7_6reader6nested12NestedReaderNtNtB1f_5slice11SliceReaderEECs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RINvXs_NtCscrZQdumITES_3der6headerNtB5_6HeaderNtNtB7_6decode6Decode6decodeNtNtNtB7_6reader5slice11SliceReaderECs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RINvXs_NtCscrZQdumITES_3der6headerNtB5_6HeaderNtNtB7_6decode6Decode6decodeINtNtNtB7_6reader6nested12NestedReaderIB1b_NtNtB1f_5slice11SliceReaderEEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs_NtCscrZQdumITES_3der6headerNtB5_6HeaderNtNtB7_6decode6Decode6decodeINtNtNtB7_6reader6nested12NestedReaderNtNtB1f_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs_NtCscrZQdumITES_3der6headerNtB5_6HeaderNtNtB7_6decode6Decode6decodeNtNtNtB7_6reader5slice11SliceReaderECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs_NtCscrZQdumITES_3der6headerNtB5_6HeaderNtNtB7_6decode6Decode6decodeINtNtNtB7_6reader6nested12NestedReaderIB1b_NtNtB1f_5slice11SliceReaderEEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXs_NtCscrZQdumITES_3der6headerNtB5_6HeaderNtNtB7_6decode6Decode6decodeINtNtNtB7_6reader6nested12NestedReaderNtNtB1f_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXs_NtCscrZQdumITES_3der6headerNtB5_6HeaderNtNtB7_6decode6Decode6decodeNtNtNtB7_6reader5slice11SliceReaderECsj9qtwLkMHqH_4sec1
40
}
41
42
impl Encode for Header {
43
0
    fn encoded_len(&self) -> Result<Length> {
44
0
        self.tag.encoded_len()? + self.length.encoded_len()?
45
0
    }
46
47
0
    fn encode(&self, writer: &mut impl Writer) -> Result<()> {
48
0
        self.tag.encode(writer)?;
49
0
        self.length.encode(writer)
50
0
    }
Unexecuted instantiation: _RINvXs0_NtCscrZQdumITES_3der6headerNtB6_6HeaderNtNtB8_6encode6Encode6encodeNtNtNtB8_6writer5slice11SliceWriterEB8_
Unexecuted instantiation: _RINvXs0_NtCscrZQdumITES_3der6headerNtB6_6HeaderNtNtB8_6encode6Encode6encodeNtNtNtB8_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs0_NtCscrZQdumITES_3der6headerNtB6_6HeaderNtNtB8_6encode6Encode6encodeNtNtNtB8_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
51
}
52
53
impl DerOrd for Header {
54
0
    fn der_cmp(&self, other: &Self) -> Result<Ordering> {
55
0
        match self.tag.der_cmp(&other.tag)? {
56
0
            Ordering::Equal => self.length.der_cmp(&other.length),
57
0
            ordering => Ok(ordering),
58
        }
59
0
    }
60
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/length.rs
Line
Count
Source
1
//! Length calculations for encoded ASN.1 DER values
2
3
use crate::{Decode, DerOrd, Encode, Error, ErrorKind, Reader, Result, SliceWriter, Writer};
4
use core::{
5
    cmp::Ordering,
6
    fmt,
7
    ops::{Add, Sub},
8
};
9
10
/// Maximum number of octets in a DER encoding of a [`Length`] using the
11
/// rules implemented by this crate.
12
const MAX_DER_OCTETS: usize = 5;
13
14
/// Maximum length as a `u32` (256 MiB).
15
const MAX_U32: u32 = 0xfff_ffff;
16
17
/// Octet identifying an indefinite length as described in X.690 Section
18
/// 8.1.3.6.1:
19
///
20
/// > The single octet shall have bit 8 set to one, and bits 7 to
21
/// > 1 set to zero.
22
const INDEFINITE_LENGTH_OCTET: u8 = 0b10000000; // 0x80
23
24
/// ASN.1-encoded length.
25
///
26
/// Maximum length is defined by the [`Length::MAX`] constant (256 MiB).
27
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
28
pub struct Length(u32);
29
30
impl Length {
31
    /// Length of `0`
32
    pub const ZERO: Self = Self(0);
33
34
    /// Length of `1`
35
    pub const ONE: Self = Self(1);
36
37
    /// Maximum length currently supported: 256 MiB
38
    pub const MAX: Self = Self(MAX_U32);
39
40
    /// Create a new [`Length`] for any value which fits inside of a [`u16`].
41
    ///
42
    /// This function is const-safe and therefore useful for [`Length`] constants.
43
0
    pub const fn new(value: u16) -> Self {
44
0
        Self(value as u32)
45
0
    }
46
47
    /// Is this length equal to zero?
48
0
    pub fn is_zero(self) -> bool {
49
0
        self == Self::ZERO
50
0
    }
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der6lengthNtB2_6Length7is_zeroB4_
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der6lengthNtB2_6Length7is_zeroCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der6lengthNtB2_6Length7is_zeroCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der6lengthNtB2_6Length7is_zeroCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der6lengthNtB2_6Length7is_zeroCskctcMqaO4X4_4spki
51
52
    /// Get the length of DER Tag-Length-Value (TLV) encoded data if `self`
53
    /// is the length of the inner "value" portion of the message.
54
0
    pub fn for_tlv(self) -> Result<Self> {
55
0
        Self::ONE + self.encoded_len()? + self
56
0
    }
57
58
    /// Perform saturating addition of two lengths.
59
0
    pub fn saturating_add(self, rhs: Self) -> Self {
60
0
        Self(self.0.saturating_add(rhs.0))
61
0
    }
62
63
    /// Perform saturating subtraction of two lengths.
64
0
    pub fn saturating_sub(self, rhs: Self) -> Self {
65
0
        Self(self.0.saturating_sub(rhs.0))
66
0
    }
67
68
    /// Get initial octet of the encoded length (if one is required).
69
    ///
70
    /// From X.690 Section 8.1.3.5:
71
    /// > In the long form, the length octets shall consist of an initial octet
72
    /// > and one or more subsequent octets. The initial octet shall be encoded
73
    /// > as follows:
74
    /// >
75
    /// > a) bit 8 shall be one;
76
    /// > b) bits 7 to 1 shall encode the number of subsequent octets in the
77
    /// >    length octets, as an unsigned binary integer with bit 7 as the
78
    /// >    most significant bit;
79
    /// > c) the value 11111111₂ shall not be used.
80
0
    fn initial_octet(self) -> Option<u8> {
81
0
        match self.0 {
82
0
            0x80..=0xFF => Some(0x81),
83
0
            0x100..=0xFFFF => Some(0x82),
84
0
            0x10000..=0xFFFFFF => Some(0x83),
85
0
            0x1000000..=MAX_U32 => Some(0x84),
86
0
            _ => None,
87
        }
88
0
    }
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der6lengthNtB2_6Length13initial_octetB4_
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der6lengthNtB2_6Length13initial_octetCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der6lengthNtB2_6Length13initial_octetCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtCscrZQdumITES_3der6lengthNtB2_6Length13initial_octetCsj9qtwLkMHqH_4sec1
89
}
90
91
impl Add for Length {
92
    type Output = Result<Self>;
93
94
0
    fn add(self, other: Self) -> Result<Self> {
95
0
        self.0
96
0
            .checked_add(other.0)
97
0
            .ok_or_else(|| ErrorKind::Overflow.into())
98
0
            .and_then(TryInto::try_into)
99
0
    }
100
}
101
102
impl Add<u8> for Length {
103
    type Output = Result<Self>;
104
105
0
    fn add(self, other: u8) -> Result<Self> {
106
0
        self + Length::from(other)
107
0
    }
108
}
109
110
impl Add<u16> for Length {
111
    type Output = Result<Self>;
112
113
0
    fn add(self, other: u16) -> Result<Self> {
114
0
        self + Length::from(other)
115
0
    }
116
}
117
118
impl Add<u32> for Length {
119
    type Output = Result<Self>;
120
121
0
    fn add(self, other: u32) -> Result<Self> {
122
0
        self + Length::try_from(other)?
123
0
    }
124
}
125
126
impl Add<usize> for Length {
127
    type Output = Result<Self>;
128
129
0
    fn add(self, other: usize) -> Result<Self> {
130
0
        self + Length::try_from(other)?
131
0
    }
132
}
133
134
impl Add<Length> for Result<Length> {
135
    type Output = Self;
136
137
0
    fn add(self, other: Length) -> Self {
138
0
        self? + other
139
0
    }
140
}
141
142
impl Sub for Length {
143
    type Output = Result<Self>;
144
145
0
    fn sub(self, other: Length) -> Result<Self> {
146
0
        self.0
147
0
            .checked_sub(other.0)
148
0
            .ok_or_else(|| ErrorKind::Overflow.into())
149
0
            .and_then(TryInto::try_into)
150
0
    }
151
}
152
153
impl Sub<Length> for Result<Length> {
154
    type Output = Self;
155
156
0
    fn sub(self, other: Length) -> Self {
157
0
        self? - other
158
0
    }
159
}
160
161
impl From<u8> for Length {
162
0
    fn from(len: u8) -> Length {
163
0
        Length(len.into())
164
0
    }
Unexecuted instantiation: _RNvXs7_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert4FromhE4fromB7_
Unexecuted instantiation: _RNvXs7_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert4FromhE4fromCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvXs7_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert4FromhE4fromCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs7_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert4FromhE4fromCsj9qtwLkMHqH_4sec1
165
}
166
167
impl From<u16> for Length {
168
0
    fn from(len: u16) -> Length {
169
0
        Length(len.into())
170
0
    }
171
}
172
173
impl From<Length> for u32 {
174
0
    fn from(length: Length) -> u32 {
175
0
        length.0
176
0
    }
Unexecuted instantiation: _RNvXs9_NtCscrZQdumITES_3der6lengthmINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_6LengthE4fromB7_
Unexecuted instantiation: _RNvXs9_NtCscrZQdumITES_3der6lengthmINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_6LengthE4fromCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs9_NtCscrZQdumITES_3der6lengthmINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_6LengthE4fromCsj9qtwLkMHqH_4sec1
177
}
178
179
impl TryFrom<u32> for Length {
180
    type Error = Error;
181
182
0
    fn try_from(len: u32) -> Result<Length> {
183
0
        if len <= Self::MAX.0 {
184
0
            Ok(Length(len))
185
        } else {
186
0
            Err(ErrorKind::Overflow.into())
187
        }
188
0
    }
Unexecuted instantiation: _RNvXsa_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFrommE8try_fromB7_
Unexecuted instantiation: _RNvXsa_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFrommE8try_fromCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvXsa_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFrommE8try_fromCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXsa_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFrommE8try_fromCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXsa_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFrommE8try_fromCskctcMqaO4X4_4spki
189
}
190
191
impl TryFrom<usize> for Length {
192
    type Error = Error;
193
194
0
    fn try_from(len: usize) -> Result<Length> {
195
0
        u32::try_from(len)
196
0
            .map_err(|_| ErrorKind::Overflow)?
Unexecuted instantiation: _RNCNvXsb_NtCscrZQdumITES_3der6lengthNtB7_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromjE8try_from0B9_
Unexecuted instantiation: _RNCNvXsb_NtCscrZQdumITES_3der6lengthNtB7_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromjE8try_from0Cs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNCNvXsb_NtCscrZQdumITES_3der6lengthNtB7_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromjE8try_from0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCNvXsb_NtCscrZQdumITES_3der6lengthNtB7_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromjE8try_from0Csj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNCNvXsb_NtCscrZQdumITES_3der6lengthNtB7_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromjE8try_from0CskctcMqaO4X4_4spki
197
0
            .try_into()
198
0
    }
Unexecuted instantiation: _RNvXsb_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromjE8try_fromB7_
Unexecuted instantiation: _RNvXsb_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromjE8try_fromCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvXsb_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromjE8try_fromCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXsb_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromjE8try_fromCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXsb_NtCscrZQdumITES_3der6lengthNtB5_6LengthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromjE8try_fromCskctcMqaO4X4_4spki
199
}
200
201
impl TryFrom<Length> for usize {
202
    type Error = Error;
203
204
0
    fn try_from(len: Length) -> Result<usize> {
205
0
        len.0.try_into().map_err(|_| ErrorKind::Overflow.into())
206
0
    }
Unexecuted instantiation: _RNvXsc_NtCscrZQdumITES_3der6lengthjINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB5_6LengthE8try_fromB7_
Unexecuted instantiation: _RNvXsc_NtCscrZQdumITES_3der6lengthjINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB5_6LengthE8try_fromCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXsc_NtCscrZQdumITES_3der6lengthjINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB5_6LengthE8try_fromCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXsc_NtCscrZQdumITES_3der6lengthjINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB5_6LengthE8try_fromCskctcMqaO4X4_4spki
207
}
208
209
impl<'a> Decode<'a> for Length {
210
0
    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Length> {
211
0
        match reader.read_byte()? {
212
            // Note: per X.690 Section 8.1.3.6.1 the byte 0x80 encodes indefinite
213
            // lengths, which are not allowed in DER, so disallow that byte.
214
0
            len if len < INDEFINITE_LENGTH_OCTET => Ok(len.into()),
215
0
            INDEFINITE_LENGTH_OCTET => Err(ErrorKind::IndefiniteLength.into()),
216
            // 1-4 byte variable-sized length prefix
217
0
            tag @ 0x81..=0x84 => {
218
0
                let nbytes = tag.checked_sub(0x80).ok_or(ErrorKind::Overlength)? as usize;
219
0
                debug_assert!(nbytes <= 4);
220
221
0
                let mut decoded_len = 0u32;
222
0
                for _ in 0..nbytes {
223
0
                    decoded_len = decoded_len.checked_shl(8).ok_or(ErrorKind::Overflow)?
224
0
                        | u32::from(reader.read_byte()?);
225
                }
226
227
0
                let length = Length::try_from(decoded_len)?;
228
229
                // X.690 Section 10.1: DER lengths must be encoded with a minimum
230
                // number of octets
231
0
                if length.initial_octet() == Some(tag) {
232
0
                    Ok(length)
233
                } else {
234
0
                    Err(ErrorKind::Overlength.into())
235
                }
236
            }
237
            _ => {
238
                // We specialize to a maximum 4-byte length (including initial octet)
239
0
                Err(ErrorKind::Overlength.into())
240
            }
241
        }
242
0
    }
Unexecuted instantiation: _RINvXsd_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6decode6Decode6decodeNtNtNtB8_6reader3pem9PemReaderEB8_
Unexecuted instantiation: _RINvXsd_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6decode6Decode6decodeNtNtNtB8_6reader5slice11SliceReaderEB8_
Unexecuted instantiation: _RINvXsd_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6decode6Decode6decodeINtNtNtB8_6reader6nested12NestedReaderNtNtB1g_5slice11SliceReaderEECs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RINvXsd_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6decode6Decode6decodeNtNtNtB8_6reader5slice11SliceReaderECs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RINvXsd_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6decode6Decode6decodeINtNtNtB8_6reader6nested12NestedReaderIB1c_NtNtB1g_5slice11SliceReaderEEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXsd_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6decode6Decode6decodeINtNtNtB8_6reader6nested12NestedReaderNtNtB1g_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXsd_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6decode6Decode6decodeNtNtNtB8_6reader5slice11SliceReaderECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXsd_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6decode6Decode6decodeINtNtNtB8_6reader6nested12NestedReaderIB1c_NtNtB1g_5slice11SliceReaderEEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXsd_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6decode6Decode6decodeINtNtNtB8_6reader6nested12NestedReaderNtNtB1g_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXsd_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6decode6Decode6decodeNtNtNtB8_6reader5slice11SliceReaderECsj9qtwLkMHqH_4sec1
243
}
244
245
impl Encode for Length {
246
0
    fn encoded_len(&self) -> Result<Length> {
247
0
        match self.0 {
248
0
            0..=0x7F => Ok(Length(1)),
249
0
            0x80..=0xFF => Ok(Length(2)),
250
0
            0x100..=0xFFFF => Ok(Length(3)),
251
0
            0x10000..=0xFFFFFF => Ok(Length(4)),
252
0
            0x1000000..=MAX_U32 => Ok(Length(5)),
253
0
            _ => Err(ErrorKind::Overflow.into()),
254
        }
255
0
    }
256
257
0
    fn encode(&self, writer: &mut impl Writer) -> Result<()> {
258
0
        match self.initial_octet() {
259
0
            Some(tag_byte) => {
260
0
                writer.write_byte(tag_byte)?;
261
262
                // Strip leading zeroes
263
0
                match self.0.to_be_bytes() {
264
0
                    [0, 0, 0, byte] => writer.write_byte(byte),
265
0
                    [0, 0, bytes @ ..] => writer.write(&bytes),
266
0
                    [0, bytes @ ..] => writer.write(&bytes),
267
0
                    bytes => writer.write(&bytes),
268
                }
269
            }
270
            #[allow(clippy::cast_possible_truncation)]
271
0
            None => writer.write_byte(self.0 as u8),
272
        }
273
0
    }
Unexecuted instantiation: _RINvXse_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6encode6Encode6encodeNtNtNtB8_6writer5slice11SliceWriterEB8_
Unexecuted instantiation: _RINvXse_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6encode6Encode6encodeNtNtNtB8_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXse_NtCscrZQdumITES_3der6lengthNtB6_6LengthNtNtB8_6encode6Encode6encodeNtNtNtB8_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
274
}
275
276
impl DerOrd for Length {
277
0
    fn der_cmp(&self, other: &Self) -> Result<Ordering> {
278
0
        let mut buf1 = [0u8; MAX_DER_OCTETS];
279
0
        let mut buf2 = [0u8; MAX_DER_OCTETS];
280
0
281
0
        let mut encoder1 = SliceWriter::new(&mut buf1);
282
0
        encoder1.encode(self)?;
283
284
0
        let mut encoder2 = SliceWriter::new(&mut buf2);
285
0
        encoder2.encode(other)?;
286
287
0
        Ok(encoder1.finish()?.cmp(encoder2.finish()?))
288
0
    }
289
}
290
291
impl fmt::Display for Length {
292
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
293
0
        self.0.fmt(f)
294
0
    }
295
}
296
297
// Implement by hand because the derive would create invalid values.
298
// Generate a u32 with a valid range.
299
#[cfg(feature = "arbitrary")]
300
impl<'a> arbitrary::Arbitrary<'a> for Length {
301
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
302
        Ok(Self(u.int_in_range(0..=MAX_U32)?))
303
    }
304
305
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
306
        u32::size_hint(depth)
307
    }
308
}
309
310
/// Length type with support for indefinite lengths as used by ASN.1 BER,
311
/// as described in X.690 Section 8.1.3.6:
312
///
313
/// > 8.1.3.6 For the indefinite form, the length octets indicate that the
314
/// > contents octets are terminated by end-of-contents
315
/// > octets (see 8.1.5), and shall consist of a single octet.
316
/// >
317
/// > 8.1.3.6.1 The single octet shall have bit 8 set to one, and bits 7 to
318
/// > 1 set to zero.
319
/// >
320
/// > 8.1.3.6.2 If this form of length is used, then end-of-contents octets
321
/// > (see 8.1.5) shall be present in the encoding following the contents
322
/// > octets.
323
///
324
/// Indefinite lengths are non-canonical and therefore invalid DER, however
325
/// there are interoperability corner cases where we have little choice but to
326
/// tolerate some BER productions where this is helpful.
327
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
328
pub struct IndefiniteLength(Option<Length>);
329
330
impl IndefiniteLength {
331
    /// Length of `0`.
332
    pub const ZERO: Self = Self(Some(Length::ZERO));
333
334
    /// Length of `1`.
335
    pub const ONE: Self = Self(Some(Length::ONE));
336
337
    /// Indefinite length.
338
    pub const INDEFINITE: Self = Self(None);
339
}
340
341
impl IndefiniteLength {
342
    /// Create a definite length from a type which can be converted into a
343
    /// `Length`.
344
0
    pub fn new(length: impl Into<Length>) -> Self {
345
0
        Self(Some(length.into()))
346
0
    }
347
348
    /// Is this length definite?
349
0
    pub fn is_definite(self) -> bool {
350
0
        self.0.is_some()
351
0
    }
352
    /// Is this length indefinite?
353
0
    pub fn is_indefinite(self) -> bool {
354
0
        self.0.is_none()
355
0
    }
356
}
357
358
impl<'a> Decode<'a> for IndefiniteLength {
359
0
    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<IndefiniteLength> {
360
0
        if reader.peek_byte() == Some(INDEFINITE_LENGTH_OCTET) {
361
            // Consume the byte we already peeked at.
362
0
            let byte = reader.read_byte()?;
363
0
            debug_assert_eq!(byte, INDEFINITE_LENGTH_OCTET);
364
365
0
            Ok(Self::INDEFINITE)
366
        } else {
367
0
            Length::decode(reader).map(Into::into)
368
        }
369
0
    }
370
}
371
372
impl Encode for IndefiniteLength {
373
0
    fn encoded_len(&self) -> Result<Length> {
374
0
        match self.0 {
375
0
            Some(length) => length.encoded_len(),
376
0
            None => Ok(Length::ONE),
377
        }
378
0
    }
379
380
0
    fn encode(&self, writer: &mut impl Writer) -> Result<()> {
381
0
        match self.0 {
382
0
            Some(length) => length.encode(writer),
383
0
            None => writer.write_byte(INDEFINITE_LENGTH_OCTET),
384
        }
385
0
    }
386
}
387
388
impl From<Length> for IndefiniteLength {
389
0
    fn from(length: Length) -> IndefiniteLength {
390
0
        Self(Some(length))
391
0
    }
392
}
393
394
impl From<Option<Length>> for IndefiniteLength {
395
0
    fn from(length: Option<Length>) -> IndefiniteLength {
396
0
        IndefiniteLength(length)
397
0
    }
398
}
399
400
impl From<IndefiniteLength> for Option<Length> {
401
0
    fn from(length: IndefiniteLength) -> Option<Length> {
402
0
        length.0
403
0
    }
404
}
405
406
impl TryFrom<IndefiniteLength> for Length {
407
    type Error = Error;
408
409
0
    fn try_from(length: IndefiniteLength) -> Result<Length> {
410
0
        length.0.ok_or_else(|| ErrorKind::IndefiniteLength.into())
411
0
    }
412
}
413
414
#[cfg(test)]
415
mod tests {
416
    use super::{IndefiniteLength, Length};
417
    use crate::{Decode, DerOrd, Encode, ErrorKind};
418
    use core::cmp::Ordering;
419
420
    #[test]
421
    fn decode() {
422
        assert_eq!(Length::ZERO, Length::from_der(&[0x00]).unwrap());
423
424
        assert_eq!(Length::from(0x7Fu8), Length::from_der(&[0x7F]).unwrap());
425
426
        assert_eq!(
427
            Length::from(0x80u8),
428
            Length::from_der(&[0x81, 0x80]).unwrap()
429
        );
430
431
        assert_eq!(
432
            Length::from(0xFFu8),
433
            Length::from_der(&[0x81, 0xFF]).unwrap()
434
        );
435
436
        assert_eq!(
437
            Length::from(0x100u16),
438
            Length::from_der(&[0x82, 0x01, 0x00]).unwrap()
439
        );
440
441
        assert_eq!(
442
            Length::try_from(0x10000u32).unwrap(),
443
            Length::from_der(&[0x83, 0x01, 0x00, 0x00]).unwrap()
444
        );
445
    }
446
447
    #[test]
448
    fn encode() {
449
        let mut buffer = [0u8; 4];
450
451
        assert_eq!(&[0x00], Length::ZERO.encode_to_slice(&mut buffer).unwrap());
452
453
        assert_eq!(
454
            &[0x7F],
455
            Length::from(0x7Fu8).encode_to_slice(&mut buffer).unwrap()
456
        );
457
458
        assert_eq!(
459
            &[0x81, 0x80],
460
            Length::from(0x80u8).encode_to_slice(&mut buffer).unwrap()
461
        );
462
463
        assert_eq!(
464
            &[0x81, 0xFF],
465
            Length::from(0xFFu8).encode_to_slice(&mut buffer).unwrap()
466
        );
467
468
        assert_eq!(
469
            &[0x82, 0x01, 0x00],
470
            Length::from(0x100u16).encode_to_slice(&mut buffer).unwrap()
471
        );
472
473
        assert_eq!(
474
            &[0x83, 0x01, 0x00, 0x00],
475
            Length::try_from(0x10000u32)
476
                .unwrap()
477
                .encode_to_slice(&mut buffer)
478
                .unwrap()
479
        );
480
    }
481
482
    #[test]
483
    fn indefinite_lengths() {
484
        // DER disallows indefinite lengths
485
        assert!(Length::from_der(&[0x80]).is_err());
486
487
        // The `IndefiniteLength` type supports them
488
        let indefinite_length = IndefiniteLength::from_der(&[0x80]).unwrap();
489
        assert!(indefinite_length.is_indefinite());
490
        assert_eq!(indefinite_length, IndefiniteLength::INDEFINITE);
491
492
        // It also supports definite lengths.
493
        let length = IndefiniteLength::from_der(&[0x83, 0x01, 0x00, 0x00]).unwrap();
494
        assert!(length.is_definite());
495
        assert_eq!(
496
            Length::try_from(0x10000u32).unwrap(),
497
            length.try_into().unwrap()
498
        );
499
    }
500
501
    #[test]
502
    fn add_overflows_when_max_length_exceeded() {
503
        let result = Length::MAX + Length::ONE;
504
        assert_eq!(
505
            result.err().map(|err| err.kind()),
506
            Some(ErrorKind::Overflow)
507
        );
508
    }
509
510
    #[test]
511
    fn der_ord() {
512
        assert_eq!(Length::ONE.der_cmp(&Length::MAX).unwrap(), Ordering::Less);
513
    }
514
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/ord.rs
Line
Count
Source
1
//! Ordering trait.
2
3
use crate::{EncodeValue, Result, Tagged};
4
use core::{cmp::Ordering, marker::PhantomData};
5
6
/// DER ordering trait.
7
///
8
/// Compares the ordering of two values based on their ASN.1 DER
9
/// serializations.
10
///
11
/// This is used by the DER encoding for `SET OF` in order to establish an
12
/// ordering for the elements of sets.
13
pub trait DerOrd {
14
    /// Return an [`Ordering`] between `self` and `other` when serialized as
15
    /// ASN.1 DER.
16
    fn der_cmp(&self, other: &Self) -> Result<Ordering>;
17
}
18
19
/// DER value ordering trait.
20
///
21
/// Compares the ordering of the value portion of TLV-encoded DER productions.
22
pub trait ValueOrd {
23
    /// Return an [`Ordering`] between value portion of TLV-encoded `self` and
24
    /// `other` when serialized as ASN.1 DER.
25
    fn value_cmp(&self, other: &Self) -> Result<Ordering>;
26
}
27
28
impl<T> DerOrd for T
29
where
30
    T: EncodeValue + ValueOrd + Tagged,
31
{
32
0
    fn der_cmp(&self, other: &Self) -> Result<Ordering> {
33
0
        match self.header()?.der_cmp(&other.header()?)? {
34
0
            Ordering::Equal => self.value_cmp(other),
35
0
            ordering => Ok(ordering),
36
        }
37
0
    }
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3ordINtNtCsiBl6Lc3cFal_5alloc3vec3VechENtB2_6DerOrd7der_cmpB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3ordhNtB2_6DerOrd7der_cmpB4_
38
}
39
40
/// Marker trait for types whose `Ord` impl can be used as `ValueOrd`.
41
///
42
/// This means the `Ord` impl will sort values in the same order as their DER
43
/// encodings.
44
pub trait OrdIsValueOrd: Ord {}
45
46
impl<T> ValueOrd for T
47
where
48
    T: OrdIsValueOrd,
49
{
50
0
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
51
0
        Ok(self.cmp(other))
52
0
    }
53
}
54
55
/// Compare the order of two iterators using [`DerCmp`] on the values.
56
0
pub(crate) fn iter_cmp<'a, I, T: 'a>(a: I, b: I) -> Result<Ordering>
57
0
where
58
0
    I: Iterator<Item = &'a T> + ExactSizeIterator,
59
0
    T: DerOrd,
60
0
{
61
0
    let length_ord = a.len().cmp(&b.len());
62
63
0
    for (value1, value2) in a.zip(b) {
64
0
        match value1.der_cmp(value2)? {
65
0
            Ordering::Equal => (),
66
0
            other => return Ok(other),
67
        }
68
    }
69
70
0
    Ok(length_ord)
71
0
}
72
73
/// Provide a no-op implementation for PhantomData
74
impl<T> ValueOrd for PhantomData<T> {
75
0
    fn value_cmp(&self, _other: &Self) -> Result<Ordering> {
76
0
        Ok(Ordering::Equal)
77
0
    }
78
}
79
80
/// Provide a no-op implementation for PhantomData
81
impl<T> DerOrd for PhantomData<T> {
82
0
    fn der_cmp(&self, _other: &Self) -> Result<Ordering> {
83
0
        Ok(Ordering::Equal)
84
0
    }
85
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/reader.rs
Line
Count
Source
1
//! Reader trait.
2
3
pub(crate) mod nested;
4
#[cfg(feature = "pem")]
5
pub(crate) mod pem;
6
pub(crate) mod slice;
7
8
pub(crate) use nested::NestedReader;
9
10
use crate::{
11
    asn1::ContextSpecific, Decode, DecodeValue, Encode, Error, ErrorKind, FixedTag, Header, Length,
12
    Result, Tag, TagMode, TagNumber,
13
};
14
15
#[cfg(feature = "alloc")]
16
use alloc::vec::Vec;
17
18
/// Reader trait which reads DER-encoded input.
19
pub trait Reader<'r>: Sized {
20
    /// Get the length of the input.
21
    fn input_len(&self) -> Length;
22
23
    /// Peek at the next byte of input without modifying the cursor.
24
    fn peek_byte(&self) -> Option<u8>;
25
26
    /// Peek forward in the input data, attempting to decode a [`Header`] from
27
    /// the data at the current position in the decoder.
28
    ///
29
    /// Does not modify the decoder's state.
30
    fn peek_header(&self) -> Result<Header>;
31
32
    /// Get the position within the buffer.
33
    fn position(&self) -> Length;
34
35
    /// Attempt to read data borrowed directly from the input as a slice,
36
    /// updating the internal cursor position.
37
    ///
38
    /// # Returns
39
    /// - `Ok(slice)` on success
40
    /// - `Err(ErrorKind::Incomplete)` if there is not enough data
41
    /// - `Err(ErrorKind::Reader)` if the reader can't borrow from the input
42
    fn read_slice(&mut self, len: Length) -> Result<&'r [u8]>;
43
44
    /// Attempt to decode an ASN.1 `CONTEXT-SPECIFIC` field with the
45
    /// provided [`TagNumber`].
46
0
    fn context_specific<T>(&mut self, tag_number: TagNumber, tag_mode: TagMode) -> Result<Option<T>>
47
0
    where
48
0
        T: DecodeValue<'r> + FixedTag,
49
0
    {
50
0
        Ok(match tag_mode {
51
0
            TagMode::Explicit => ContextSpecific::<T>::decode_explicit(self, tag_number)?,
52
0
            TagMode::Implicit => ContextSpecific::<T>::decode_implicit(self, tag_number)?,
53
        }
54
0
        .map(|field| field.value))
Unexecuted instantiation: _RNCINvYpNtNtCscrZQdumITES_3der6reader6Reader16context_specificpE0Ba_
Unexecuted instantiation: _RNCINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtBa_5slice11SliceReaderENtBa_6Reader16context_specificNtNtNtBc_4asn110bit_string12BitStringRefE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtBa_5slice11SliceReaderENtBa_6Reader16context_specificNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersE0B1V_
Unexecuted instantiation: _RNCINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtBa_5slice11SliceReaderENtBa_6Reader16context_specificNtNtNtBc_4asn110bit_string12BitStringRefE0Csj9qtwLkMHqH_4sec1
55
0
    }
Unexecuted instantiation: _RINvYpNtNtCscrZQdumITES_3der6reader6Reader16context_specificpEB8_
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader16context_specificNtNtNtBa_4asn110bit_string12BitStringRefECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader16context_specificNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersEB1T_
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader16context_specificNtNtNtBa_4asn110bit_string12BitStringRefECsj9qtwLkMHqH_4sec1
56
57
    /// Decode a value which impls the [`Decode`] trait.
58
0
    fn decode<T: Decode<'r>>(&mut self) -> Result<T> {
59
0
        T::decode(self).map_err(|e| e.nested(self.position()))
Unexecuted instantiation: _RNCINvYpNtNtCscrZQdumITES_3der6reader6Reader6decodepE0Ba_
Unexecuted instantiation: _RNCINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB6_NtNtBa_5slice11SliceReaderEENtBa_6Reader6decodeINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtNtBc_4asn13any6AnyRefEE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB6_NtNtBa_5slice11SliceReaderEENtBa_6Reader6decodeNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtBa_5slice11SliceReaderENtBa_6Reader6decodeINtNtCskctcMqaO4X4_4spki9algorithm19AlgorithmIdentifierNtNtNtBc_4asn13any6AnyRefEE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtBa_5slice11SliceReaderENtBa_6Reader6decodeINtNtNtBc_4asn116context_specific15ContextSpecificNtNtB1L_3any6AnyRefEE0Cssr1zNgi7Nt_5pkcs8
60
0
    }
Unexecuted instantiation: _RINvYpNtNtCscrZQdumITES_3der6reader6Reader6decodepEB8_
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB4_NtNtB8_5slice11SliceReaderEENtB8_6Reader6decodeINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtNtBa_4asn13any6AnyRefEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB4_NtNtB8_5slice11SliceReaderEENtB8_6Reader6decodeNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader6decodeINtNtCskctcMqaO4X4_4spki9algorithm19AlgorithmIdentifierNtNtNtBa_4asn13any6AnyRefEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader6decodeINtNtNtBa_4asn116context_specific15ContextSpecificNtNtB1J_3any6AnyRefEECssr1zNgi7Nt_5pkcs8
61
62
    /// Return an error with the given [`ErrorKind`], annotating it with
63
    /// context about where the error occurred.
64
0
    fn error(&mut self, kind: ErrorKind) -> Error {
65
0
        kind.at(self.position())
66
0
    }
67
68
    /// Finish decoding, returning the given value if there is no
69
    /// remaining data, or an error otherwise
70
0
    fn finish<T>(self, value: T) -> Result<T> {
71
0
        if !self.is_finished() {
72
0
            Err(ErrorKind::TrailingData {
73
0
                decoded: self.position(),
74
0
                remaining: self.remaining_len(),
75
0
            }
76
0
            .at(self.position()))
77
        } else {
78
0
            Ok(value)
79
        }
80
0
    }
Unexecuted instantiation: _RINvYpNtNtCscrZQdumITES_3der6reader6Reader6finishpEB8_
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader6finishTNtNtNtNtBa_4asn17integer4uint7UintRefB1F_EECs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB4_NtNtB8_5slice11SliceReaderEENtB8_6Reader6finishINtNtCskctcMqaO4X4_4spki9algorithm19AlgorithmIdentifierNtNtNtBa_4asn13any6AnyRefEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB4_NtNtB8_5slice11SliceReaderEENtB8_6Reader6finishNtNtNtBa_4asn110bit_string12BitStringRefECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB4_NtNtB8_5slice11SliceReaderEENtB8_6Reader6finishNtNtNtBa_4asn13any6AnyRefECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader6finishNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoEB1I_
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB4_NtNtB8_5slice11SliceReaderEENtB8_6Reader6finishNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersEB1N_
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB4_NtNtB8_5slice11SliceReaderEENtB8_6Reader6finishNtNtNtBa_4asn110bit_string12BitStringRefECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader6finishNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyEB1I_
81
82
    /// Have we read all of the input data?
83
0
    fn is_finished(&self) -> bool {
84
0
        self.remaining_len().is_zero()
85
0
    }
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader3pem9PemReaderNtB6_6Reader11is_finishedB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader11is_finishedB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader11is_finishedCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB7_5slice11SliceReaderENtB7_6Reader11is_finishedCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader11is_finishedCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB3_NtNtB7_5slice11SliceReaderEENtB7_6Reader11is_finishedCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB7_5slice11SliceReaderENtB7_6Reader11is_finishedCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader11is_finishedCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB7_5slice11SliceReaderENtB7_6Reader11is_finishedCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB3_NtNtB7_5slice11SliceReaderEENtB7_6Reader11is_finishedCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader11is_finishedCskctcMqaO4X4_4spki
86
87
    /// Offset within the original input stream.
88
    ///
89
    /// This is used for error reporting, and doesn't need to be overridden
90
    /// by any reader implementations (except for the built-in `NestedReader`,
91
    /// which consumes nested input messages)
92
0
    fn offset(&self) -> Length {
93
0
        self.position()
94
0
    }
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader3pem9PemReaderNtB6_6Reader6offsetB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader6offsetB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader6offsetCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader6offsetCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader6offsetCsj9qtwLkMHqH_4sec1
95
96
    /// Peek at the next byte in the decoder and attempt to decode it as a
97
    /// [`Tag`] value.
98
    ///
99
    /// Does not modify the decoder's state.
100
0
    fn peek_tag(&self) -> Result<Tag> {
101
0
        match self.peek_byte() {
102
0
            Some(byte) => byte.try_into(),
103
0
            None => Err(Error::incomplete(self.input_len())),
104
        }
105
0
    }
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader3pem9PemReaderNtB6_6Reader8peek_tagB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader8peek_tagB8_
106
107
    /// Read a single byte.
108
0
    fn read_byte(&mut self) -> Result<u8> {
109
0
        let mut buf = [0];
110
0
        self.read_into(&mut buf)?;
111
0
        Ok(buf[0])
112
0
    }
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader3pem9PemReaderNtB6_6Reader9read_byteB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader9read_byteB8_
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB7_5slice11SliceReaderENtB7_6Reader9read_byteCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader9read_byteCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB3_NtNtB7_5slice11SliceReaderEENtB7_6Reader9read_byteCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB7_5slice11SliceReaderENtB7_6Reader9read_byteCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader9read_byteCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB3_NtNtB7_5slice11SliceReaderEENtB7_6Reader9read_byteCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB7_5slice11SliceReaderENtB7_6Reader9read_byteCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader9read_byteCsj9qtwLkMHqH_4sec1
113
114
    /// Attempt to read input data, writing it into the provided buffer, and
115
    /// returning a slice on success.
116
    ///
117
    /// # Returns
118
    /// - `Ok(slice)` if there is sufficient data
119
    /// - `Err(ErrorKind::Incomplete)` if there is not enough data
120
0
    fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> {
121
0
        let input = self.read_slice(buf.len().try_into()?)?;
122
0
        buf.copy_from_slice(input);
123
0
        Ok(buf)
124
0
    }
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader9read_intoB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader9read_intoCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader9read_intoCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader9read_intoCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader9read_intoCskctcMqaO4X4_4spki
125
126
    /// Read nested data of the given length.
127
0
    fn read_nested<'n, T, F>(&'n mut self, len: Length, f: F) -> Result<T>
128
0
    where
129
0
        F: FnOnce(&mut NestedReader<'n, Self>) -> Result<T>,
130
0
    {
131
0
        let mut reader = NestedReader::new(self, len)?;
132
0
        let ret = f(&mut reader)?;
133
0
        reader.finish(ret)
134
0
    }
Unexecuted instantiation: _RINvYpNtNtCscrZQdumITES_3der6reader6Reader11read_nestedppEB8_
Unexecuted instantiation: _RINvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB7_6Reader11read_nestedTNtNtNtNtB9_4asn17integer4uint7UintRefB1h_ENCNvNtCs56dDIOPvtI3_5ecdsa3der10decode_der0EB23_
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader11read_nestedINtNtCskctcMqaO4X4_4spki9algorithm19AlgorithmIdentifierNtNtNtBa_4asn13any6AnyRefENCINvXB1N_B1K_NtNtBa_6decode11DecodeValue12decode_valueB3_E0ECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader11read_nestedNtNtNtBa_4asn110bit_string12BitStringRefNCINvXs0_NtB1O_16context_specificINtB2x_15ContextSpecificB1K_ENtNtBa_6decode6Decode6decodeB3_E0ECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader11read_nestedNtNtNtBa_4asn13any6AnyRefNCINvXs0_NtB1O_16context_specificINtB2i_15ContextSpecificB1K_ENtNtBa_6decode6Decode6decodeB3_E0ECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB7_6Reader11read_nestedNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoNCINvXs_B1i_B1g_NtNtB9_6decode11DecodeValue12decode_valueB3_E0EB1k_
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader11read_nestedNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersNCINvXs0_NtNtBa_4asn116context_specificINtB2G_15ContextSpecificB1K_ENtNtBa_6decode6Decode6decodeB3_E0EB1O_
Unexecuted instantiation: _RINvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB8_5slice11SliceReaderENtB8_6Reader11read_nestedNtNtNtBa_4asn110bit_string12BitStringRefNCINvXs0_NtB1O_16context_specificINtB2x_15ContextSpecificB1K_ENtNtBa_6decode6Decode6decodeB3_E0ECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB7_6Reader11read_nestedNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyNCINvXs_B1i_B1g_NtNtB9_6decode11DecodeValue12decode_valueB3_E0EB1k_
135
136
    /// Read a byte vector of the given length.
137
    #[cfg(feature = "alloc")]
138
0
    fn read_vec(&mut self, len: Length) -> Result<Vec<u8>> {
139
0
        let mut bytes = vec![0u8; usize::try_from(len)?];
140
0
        self.read_into(&mut bytes)?;
141
0
        Ok(bytes)
142
0
    }
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader3pem9PemReaderNtB6_6Reader8read_vecB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader8read_vecB8_
143
144
    /// Get the number of bytes still remaining in the buffer.
145
0
    fn remaining_len(&self) -> Length {
146
0
        debug_assert!(self.position() <= self.input_len());
147
0
        self.input_len().saturating_sub(self.position())
148
0
    }
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader3pem9PemReaderNtB6_6Reader13remaining_lenB8_
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB7_5slice11SliceReaderENtB7_6Reader13remaining_lenCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB3_NtNtB7_5slice11SliceReaderEENtB7_6Reader13remaining_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB7_5slice11SliceReaderENtB7_6Reader13remaining_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderIB3_NtNtB7_5slice11SliceReaderEENtB7_6Reader13remaining_lenCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvYINtNtNtCscrZQdumITES_3der6reader6nested12NestedReaderNtNtB7_5slice11SliceReaderENtB7_6Reader13remaining_lenCsj9qtwLkMHqH_4sec1
149
150
    /// Read an ASN.1 `SEQUENCE`, creating a nested [`Reader`] for the body and
151
    /// calling the provided closure with it.
152
0
    fn sequence<'n, F, T>(&'n mut self, f: F) -> Result<T>
153
0
    where
154
0
        F: FnOnce(&mut NestedReader<'n, Self>) -> Result<T>,
155
0
    {
156
0
        let header = Header::decode(self)?;
157
0
        header.tag.assert_eq(Tag::Sequence)?;
158
0
        self.read_nested(header.length, f)
159
0
    }
160
161
    /// Obtain a slice of bytes contain a complete TLV production suitable for parsing later.
162
0
    fn tlv_bytes(&mut self) -> Result<&'r [u8]> {
163
0
        let header = self.peek_header()?;
164
0
        let header_len = header.encoded_len()?;
165
0
        self.read_slice((header_len + header.length)?)
166
0
    }
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader3pem9PemReaderNtB6_6Reader9tlv_bytesB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6reader5slice11SliceReaderNtB6_6Reader9tlv_bytesB8_
167
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/reader/nested.rs
Line
Count
Source
1
//! Reader type for consuming nested TLV records within a DER document.
2
3
use crate::{reader::Reader, Error, ErrorKind, Header, Length, Result};
4
5
/// Reader type used by [`Reader::read_nested`].
6
pub struct NestedReader<'i, R> {
7
    /// Inner reader type.
8
    inner: &'i mut R,
9
10
    /// Nested input length.
11
    input_len: Length,
12
13
    /// Position within the nested input.
14
    position: Length,
15
}
16
17
impl<'i, 'r, R: Reader<'r>> NestedReader<'i, R> {
18
    /// Create a new nested reader which can read the given [`Length`].
19
0
    pub(crate) fn new(inner: &'i mut R, len: Length) -> Result<Self> {
20
0
        if len <= inner.remaining_len() {
21
0
            Ok(Self {
22
0
                inner,
23
0
                input_len: len,
24
0
                position: Length::ZERO,
25
0
            })
26
        } else {
27
            Err(ErrorKind::Incomplete {
28
0
                expected_len: (inner.offset() + len)?,
29
0
                actual_len: (inner.offset() + inner.remaining_len())?,
30
            }
31
0
            .at(inner.offset()))
32
        }
33
0
    }
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderpE3newB6_
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderNtNtB4_5slice11SliceReaderE3newCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderIBD_NtNtB4_5slice11SliceReaderEE3newCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderNtNtB4_5slice11SliceReaderE3newCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderIBD_NtNtB4_5slice11SliceReaderEE3newCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderNtNtB4_5slice11SliceReaderE3newCsj9qtwLkMHqH_4sec1
34
35
    /// Move the position cursor the given length, returning an error if there
36
    /// isn't enough remaining data in the nested input.
37
0
    fn advance_position(&mut self, len: Length) -> Result<()> {
38
0
        let new_position = (self.position + len)?;
39
40
0
        if new_position <= self.input_len {
41
0
            self.position = new_position;
42
0
            Ok(())
43
        } else {
44
            Err(ErrorKind::Incomplete {
45
0
                expected_len: (self.inner.offset() + len)?,
46
0
                actual_len: (self.inner.offset() + self.remaining_len())?,
47
            }
48
0
            .at(self.inner.offset()))
49
        }
50
0
    }
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderpE16advance_positionB6_
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderNtNtB4_5slice11SliceReaderE16advance_positionCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderIBD_NtNtB4_5slice11SliceReaderEE16advance_positionCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderNtNtB4_5slice11SliceReaderE16advance_positionCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderIBD_NtNtB4_5slice11SliceReaderEE16advance_positionCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader6nestedINtB2_12NestedReaderNtNtB4_5slice11SliceReaderE16advance_positionCsj9qtwLkMHqH_4sec1
51
}
52
53
impl<'i, 'r, R: Reader<'r>> Reader<'r> for NestedReader<'i, R> {
54
0
    fn input_len(&self) -> Length {
55
0
        self.input_len
56
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der6reader6nesteds_0pEINtB5_12NestedReaderpENtB7_6Reader9input_lenB9_
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader9input_lenCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderIBF_NtNtB6_5slice11SliceReaderEENtB6_6Reader9input_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader9input_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderIBF_NtNtB6_5slice11SliceReaderEENtB6_6Reader9input_lenCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader9input_lenCsj9qtwLkMHqH_4sec1
57
58
0
    fn peek_byte(&self) -> Option<u8> {
59
0
        if self.is_finished() {
60
0
            None
61
        } else {
62
0
            self.inner.peek_byte()
63
        }
64
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der6reader6nesteds_0pEINtB5_12NestedReaderpENtB7_6Reader9peek_byteB9_
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderIBF_NtNtB6_5slice11SliceReaderEENtB6_6Reader9peek_byteCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader9peek_byteCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader9peek_byteCsj9qtwLkMHqH_4sec1
65
66
0
    fn peek_header(&self) -> Result<Header> {
67
0
        if self.is_finished() {
68
0
            Err(Error::incomplete(self.offset()))
69
        } else {
70
            // TODO(tarcieri): handle peeking past nested length
71
0
            self.inner.peek_header()
72
        }
73
0
    }
74
75
0
    fn position(&self) -> Length {
76
0
        self.position
77
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der6reader6nesteds_0pEINtB5_12NestedReaderpENtB7_6Reader8positionB9_
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader8positionCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderIBF_NtNtB6_5slice11SliceReaderEENtB6_6Reader8positionCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader8positionCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderIBF_NtNtB6_5slice11SliceReaderEENtB6_6Reader8positionCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader8positionCsj9qtwLkMHqH_4sec1
78
79
0
    fn read_slice(&mut self, len: Length) -> Result<&'r [u8]> {
80
0
        self.advance_position(len)?;
81
0
        self.inner.read_slice(len)
82
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der6reader6nesteds_0pEINtB5_12NestedReaderpENtB7_6Reader10read_sliceB9_
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader10read_sliceCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderIBF_NtNtB6_5slice11SliceReaderEENtB6_6Reader10read_sliceCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader10read_sliceCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderIBF_NtNtB6_5slice11SliceReaderEENtB6_6Reader10read_sliceCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader10read_sliceCsj9qtwLkMHqH_4sec1
83
84
0
    fn error(&mut self, kind: ErrorKind) -> Error {
85
0
        self.inner.error(kind)
86
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der6reader6nesteds_0pEINtB5_12NestedReaderpENtB7_6Reader5errorB9_
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader5errorCssr1zNgi7Nt_5pkcs8
87
88
0
    fn offset(&self) -> Length {
89
0
        self.inner.offset()
90
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der6reader6nesteds_0pEINtB5_12NestedReaderpENtB7_6Reader6offsetB9_
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader6offsetCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader6offsetCsj9qtwLkMHqH_4sec1
91
92
0
    fn read_into<'o>(&mut self, out: &'o mut [u8]) -> Result<&'o [u8]> {
93
0
        self.advance_position(Length::try_from(out.len())?)?;
94
0
        self.inner.read_into(out)
95
0
    }
Unexecuted instantiation: _RNvXININtNtCscrZQdumITES_3der6reader6nesteds_0pEINtB5_12NestedReaderpENtB7_6Reader9read_intoB9_
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader9read_intoCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderIBF_NtNtB6_5slice11SliceReaderEENtB6_6Reader9read_intoCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader9read_intoCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderIBF_NtNtB6_5slice11SliceReaderEENtB6_6Reader9read_intoCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader6nestedINtB4_12NestedReaderNtNtB6_5slice11SliceReaderENtB6_6Reader9read_intoCsj9qtwLkMHqH_4sec1
96
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/reader/pem.rs
Line
Count
Source
1
//! Streaming PEM reader.
2
3
use super::Reader;
4
use crate::{Decode, Error, ErrorKind, Header, Length, Result};
5
use core::cell::RefCell;
6
7
#[allow(clippy::integer_arithmetic)]
8
mod utils {
9
    use crate::{Error, Length, Result};
10
    use pem_rfc7468::Decoder;
11
12
    #[derive(Clone)]
13
    pub(super) struct BufReader<'i> {
14
        /// Inner PEM decoder.
15
        decoder: Decoder<'i>,
16
17
        /// Remaining after base64 decoding
18
        remaining: usize,
19
20
        /// Read buffer
21
        buf: [u8; BufReader::CAPACITY],
22
23
        /// Position of the head in the buffer,
24
        pos: usize,
25
26
        /// Position of the tail in the buffer,
27
        cap: usize,
28
    }
29
30
    impl<'i> BufReader<'i> {
31
        const CAPACITY: usize = 256;
32
33
0
        pub fn new(pem: &'i [u8]) -> Result<Self> {
34
0
            let decoder = Decoder::new(pem)?;
35
0
            let remaining = decoder.remaining_len();
36
0
37
0
            Ok(Self {
38
0
                decoder,
39
0
                remaining,
40
0
                buf: [0u8; 256],
41
0
                pos: 0,
42
0
                cap: 0,
43
0
            })
44
0
        }
45
46
0
        pub fn remaining_len(&self) -> usize {
47
0
            self.decoder.remaining_len() + self.cap - self.pos
48
0
        }
49
50
0
        fn fill_buffer(&mut self) -> Result<()> {
51
0
            debug_assert!(self.pos <= self.cap);
52
53
0
            if self.is_empty() {
54
0
                self.pos = 0;
55
0
                self.cap = 0;
56
0
            }
57
58
0
            let end = (self.cap + self.remaining).min(Self::CAPACITY);
59
0
            let writable_slice = &mut self.buf[self.cap..end];
60
0
            if writable_slice.is_empty() {
61
0
                return Ok(());
62
0
            }
63
64
0
            let wrote = self.decoder.decode(writable_slice)?.len();
65
0
            if wrote == 0 {
66
0
                return Err(Error::incomplete(Length::try_from(self.pos)?));
67
0
            }
68
0
69
0
            self.cap += wrote;
70
0
            self.remaining -= wrote;
71
0
            debug_assert!(self.cap <= Self::CAPACITY);
72
73
0
            Ok(())
74
0
        }
75
76
        /// Get the PEM label which will be used in the encapsulation boundaries
77
        /// for this document.
78
0
        pub fn type_label(&self) -> &'i str {
79
0
            self.decoder.type_label()
80
0
        }
81
82
0
        fn is_empty(&self) -> bool {
83
0
            self.pos == self.cap
84
0
        }
85
86
0
        fn as_slice(&self) -> &[u8] {
87
0
            &self.buf[self.pos..self.cap]
88
0
        }
89
    }
90
91
    impl<'i> BufReader<'i> {
92
0
        pub fn peek_byte(&self) -> Option<u8> {
93
0
            let s = self.as_slice();
94
0
            s.first().copied()
95
0
        }
96
97
0
        pub fn copy_to_slice<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> {
98
0
            let mut output_pos = 0;
99
100
0
            while output_pos < buf.len() {
101
0
                if self.is_empty() {
102
0
                    self.fill_buffer()?;
103
0
                }
104
105
0
                let available = &self.buf[self.pos..self.cap];
106
0
                let window_len = (buf.len() - output_pos).min(available.len());
107
0
                let window = &mut buf[output_pos..output_pos + window_len];
108
0
109
0
                window.copy_from_slice(&available[..window_len]);
110
0
                self.pos += window_len;
111
0
                output_pos += window_len;
112
            }
113
114
            // Don't leave the read buffer empty for peek_byte()
115
0
            if self.is_empty() && self.decoder.remaining_len() != 0 {
116
0
                self.fill_buffer()?
117
0
            }
118
119
0
            debug_assert_eq!(output_pos, buf.len());
120
121
0
            Ok(buf)
122
0
        }
123
    }
124
}
125
126
/// `Reader` type which decodes PEM on-the-fly.
127
#[cfg(feature = "pem")]
128
#[derive(Clone)]
129
pub struct PemReader<'i> {
130
    /// Inner PEM decoder wrapped in a BufReader.
131
    reader: RefCell<utils::BufReader<'i>>,
132
133
    /// Input length (in bytes after Base64 decoding).
134
    input_len: Length,
135
136
    /// Position in the input buffer (in bytes after Base64 decoding).
137
    position: Length,
138
}
139
140
#[cfg(feature = "pem")]
141
impl<'i> PemReader<'i> {
142
    /// Create a new PEM reader which decodes data on-the-fly.
143
    ///
144
    /// Uses the default 64-character line wrapping.
145
0
    pub fn new(pem: &'i [u8]) -> Result<Self> {
146
0
        let reader = utils::BufReader::new(pem)?;
147
0
        let input_len = Length::try_from(reader.remaining_len())?;
148
149
0
        Ok(Self {
150
0
            reader: RefCell::new(reader),
151
0
            input_len,
152
0
            position: Length::ZERO,
153
0
        })
154
0
    }
155
156
    /// Get the PEM label which will be used in the encapsulation boundaries
157
    /// for this document.
158
0
    pub fn type_label(&self) -> &'i str {
159
0
        self.reader.borrow().type_label()
160
0
    }
161
}
162
163
#[cfg(feature = "pem")]
164
impl<'i> Reader<'i> for PemReader<'i> {
165
0
    fn input_len(&self) -> Length {
166
0
        self.input_len
167
0
    }
168
169
0
    fn peek_byte(&self) -> Option<u8> {
170
0
        if self.is_finished() {
171
0
            None
172
        } else {
173
0
            self.reader.borrow().peek_byte()
174
        }
175
0
    }
176
177
0
    fn peek_header(&self) -> Result<Header> {
178
0
        if self.is_finished() {
179
0
            Err(Error::incomplete(self.offset()))
180
        } else {
181
0
            Header::decode(&mut self.clone())
182
        }
183
0
    }
184
185
0
    fn position(&self) -> Length {
186
0
        self.position
187
0
    }
188
189
0
    fn read_slice(&mut self, _len: Length) -> Result<&'i [u8]> {
190
0
        // Can't borrow from PEM because it requires decoding
191
0
        Err(ErrorKind::Reader.into())
192
0
    }
193
194
0
    fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> {
195
0
        let bytes = self.reader.borrow_mut().copy_to_slice(buf)?;
196
197
0
        self.position = (self.position + bytes.len())?;
198
199
0
        debug_assert_eq!(
200
            self.position,
201
0
            (self.input_len - Length::try_from(self.reader.borrow().remaining_len())?)?
202
        );
203
204
0
        Ok(bytes)
205
0
    }
206
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/reader/slice.rs
Line
Count
Source
1
//! Slice reader.
2
3
use crate::{BytesRef, Decode, Error, ErrorKind, Header, Length, Reader, Result, Tag};
4
5
/// [`Reader`] which consumes an input byte slice.
6
#[derive(Clone, Debug)]
7
pub struct SliceReader<'a> {
8
    /// Byte slice being decoded.
9
    bytes: BytesRef<'a>,
10
11
    /// Did the decoding operation fail?
12
    failed: bool,
13
14
    /// Position within the decoded slice.
15
    position: Length,
16
}
17
18
impl<'a> SliceReader<'a> {
19
    /// Create a new slice reader for the given byte slice.
20
0
    pub fn new(bytes: &'a [u8]) -> Result<Self> {
21
0
        Ok(Self {
22
0
            bytes: BytesRef::new(bytes)?,
23
            failed: false,
24
            position: Length::ZERO,
25
        })
26
0
    }
27
28
    /// Return an error with the given [`ErrorKind`], annotating it with
29
    /// context about where the error occurred.
30
0
    pub fn error(&mut self, kind: ErrorKind) -> Error {
31
0
        self.failed = true;
32
0
        kind.at(self.position)
33
0
    }
34
35
    /// Return an error for an invalid value with the given tag.
36
0
    pub fn value_error(&mut self, tag: Tag) -> Error {
37
0
        self.error(tag.value_error().kind())
38
0
    }
39
40
    /// Did the decoding operation fail due to an error?
41
0
    pub fn is_failed(&self) -> bool {
42
0
        self.failed
43
0
    }
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader5sliceNtB2_11SliceReader9is_failedB6_
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader5sliceNtB2_11SliceReader9is_failedCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader5sliceNtB2_11SliceReader9is_failedCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader5sliceNtB2_11SliceReader9is_failedCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6reader5sliceNtB2_11SliceReader9is_failedCskctcMqaO4X4_4spki
44
45
    /// Obtain the remaining bytes in this slice reader from the current cursor
46
    /// position.
47
0
    fn remaining(&self) -> Result<&'a [u8]> {
48
0
        if self.is_failed() {
49
0
            Err(ErrorKind::Failed.at(self.position))
50
        } else {
51
0
            self.bytes
52
0
                .as_slice()
53
0
                .get(self.position.try_into()?..)
54
0
                .ok_or_else(|| Error::incomplete(self.input_len()))
55
        }
56
0
    }
57
}
58
59
impl<'a> Reader<'a> for SliceReader<'a> {
60
0
    fn input_len(&self) -> Length {
61
0
        self.bytes.len()
62
0
    }
63
64
0
    fn peek_byte(&self) -> Option<u8> {
65
0
        self.remaining()
66
0
            .ok()
67
0
            .and_then(|bytes| bytes.first().cloned())
68
0
    }
69
70
0
    fn peek_header(&self) -> Result<Header> {
71
0
        Header::decode(&mut self.clone())
72
0
    }
73
74
0
    fn position(&self) -> Length {
75
0
        self.position
76
0
    }
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB4_11SliceReaderNtB6_6Reader8positionB8_
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB4_11SliceReaderNtB6_6Reader8positionCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB4_11SliceReaderNtB6_6Reader8positionCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB4_11SliceReaderNtB6_6Reader8positionCsj9qtwLkMHqH_4sec1
77
78
0
    fn read_slice(&mut self, len: Length) -> Result<&'a [u8]> {
79
0
        if self.is_failed() {
80
0
            return Err(self.error(ErrorKind::Failed));
81
0
        }
82
0
83
0
        match self.remaining()?.get(..len.try_into()?) {
84
0
            Some(result) => {
85
0
                self.position = (self.position + len)?;
86
0
                Ok(result)
87
            }
88
0
            None => Err(self.error(ErrorKind::Incomplete {
89
0
                expected_len: (self.position + len)?,
90
0
                actual_len: self.input_len(),
91
            })),
92
        }
93
0
    }
94
95
0
    fn decode<T: Decode<'a>>(&mut self) -> Result<T> {
96
0
        if self.is_failed() {
97
0
            return Err(self.error(ErrorKind::Failed));
98
0
        }
99
0
100
0
        T::decode(self).map_err(|e| {
101
0
            self.failed = true;
102
0
            e.nested(self.position)
103
0
        })
104
0
    }
105
106
0
    fn error(&mut self, kind: ErrorKind) -> Error {
107
0
        self.failed = true;
108
0
        kind.at(self.position)
109
0
    }
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB4_11SliceReaderNtB6_6Reader5errorB8_
Unexecuted instantiation: _RNvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB4_11SliceReaderNtB6_6Reader5errorCssr1zNgi7Nt_5pkcs8
110
111
0
    fn finish<T>(self, value: T) -> Result<T> {
112
0
        if self.is_failed() {
113
0
            Err(ErrorKind::Failed.at(self.position))
114
0
        } else if !self.is_finished() {
115
0
            Err(ErrorKind::TrailingData {
116
0
                decoded: self.position,
117
0
                remaining: self.remaining_len(),
118
0
            }
119
0
            .at(self.position))
120
        } else {
121
0
            Ok(value)
122
        }
123
0
    }
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtB9_3tag3TagEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtB9_6header6HeaderEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtB9_6length16IndefiniteLengthEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtB9_6length6LengthEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtB9_8document8DocumentEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtB9_4asn110bit_string12BitStringRefEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtB9_4asn110ia5_string12Ia5StringRefEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtB9_4asn111utf8_string13Utf8StringRefEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtB9_4asn112octet_string14OctetStringRefEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtB9_4asn114teletex_string16TeletexStringRefEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtB9_4asn115videotex_string17VideotexStringRefEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtB9_4asn116generalized_time15GeneralizedTimeEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtB9_4asn116printable_string18PrintableStringRefEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtB9_4asn13any6AnyRefEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtB9_4asn14null4NullEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtB9_4asn18utc_time7UtcTimeEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtNtB9_4asn110bit_string10allocating9BitStringEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtNtB9_4asn110ia5_string10allocation9Ia5StringEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtNtB9_4asn112octet_string10allocating11OctetStringEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtNtB9_4asn114teletex_string10allocation13TeletexStringEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtNtB9_4asn116printable_string10allocation15PrintableStringEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtNtB9_4asn13any10allocating3AnyEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtNtB9_4asn17integer3int6IntRefEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtNtB9_4asn17integer4uint7UintRefEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtNtNtB9_4asn17integer3int10allocating3IntEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtNtNtNtB9_4asn17integer4uint10allocating4UintEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishaEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishhEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishlEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishmEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishnEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishoEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishsEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishtEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishuEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishxEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishyEB9_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishTNtNtNtNtB9_4asn17integer4uint7UintRefB1g_EECs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoEB1j_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtCssr1zNgi7Nt_5pkcs87version7VersionEB1j_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyEB1j_
Unexecuted instantiation: _RINvXs_NtNtCscrZQdumITES_3der6reader5sliceNtB5_11SliceReaderNtB7_6Reader6finishNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierECskctcMqaO4X4_4spki
124
125
0
    fn remaining_len(&self) -> Length {
126
0
        debug_assert!(self.position <= self.input_len());
127
0
        self.input_len().saturating_sub(self.position)
128
0
    }
129
}
130
131
#[cfg(test)]
132
mod tests {
133
    use super::SliceReader;
134
    use crate::{Decode, ErrorKind, Length, Reader, Tag};
135
    use hex_literal::hex;
136
137
    // INTEGER: 42
138
    const EXAMPLE_MSG: &[u8] = &hex!("02012A00");
139
140
    #[test]
141
    fn empty_message() {
142
        let mut reader = SliceReader::new(&[]).unwrap();
143
        let err = bool::decode(&mut reader).err().unwrap();
144
        assert_eq!(Some(Length::ZERO), err.position());
145
146
        match err.kind() {
147
            ErrorKind::Incomplete {
148
                expected_len,
149
                actual_len,
150
            } => {
151
                assert_eq!(actual_len, 0u8.into());
152
                assert_eq!(expected_len, 1u8.into());
153
            }
154
            other => panic!("unexpected error kind: {:?}", other),
155
        }
156
    }
157
158
    #[test]
159
    fn invalid_field_length() {
160
        const MSG_LEN: usize = 2;
161
162
        let mut reader = SliceReader::new(&EXAMPLE_MSG[..MSG_LEN]).unwrap();
163
        let err = i8::decode(&mut reader).err().unwrap();
164
        assert_eq!(Some(Length::from(2u8)), err.position());
165
166
        match err.kind() {
167
            ErrorKind::Incomplete {
168
                expected_len,
169
                actual_len,
170
            } => {
171
                assert_eq!(actual_len, MSG_LEN.try_into().unwrap());
172
                assert_eq!(expected_len, (MSG_LEN + 1).try_into().unwrap());
173
            }
174
            other => panic!("unexpected error kind: {:?}", other),
175
        }
176
    }
177
178
    #[test]
179
    fn trailing_data() {
180
        let mut reader = SliceReader::new(EXAMPLE_MSG).unwrap();
181
        let x = i8::decode(&mut reader).unwrap();
182
        assert_eq!(42i8, x);
183
184
        let err = reader.finish(x).err().unwrap();
185
        assert_eq!(Some(Length::from(3u8)), err.position());
186
187
        assert_eq!(
188
            ErrorKind::TrailingData {
189
                decoded: 3u8.into(),
190
                remaining: 1u8.into()
191
            },
192
            err.kind()
193
        );
194
    }
195
196
    #[test]
197
    fn peek_tag() {
198
        let reader = SliceReader::new(EXAMPLE_MSG).unwrap();
199
        assert_eq!(reader.position(), Length::ZERO);
200
        assert_eq!(reader.peek_tag().unwrap(), Tag::Integer);
201
        assert_eq!(reader.position(), Length::ZERO); // Position unchanged
202
    }
203
204
    #[test]
205
    fn peek_header() {
206
        let reader = SliceReader::new(EXAMPLE_MSG).unwrap();
207
        assert_eq!(reader.position(), Length::ZERO);
208
209
        let header = reader.peek_header().unwrap();
210
        assert_eq!(header.tag, Tag::Integer);
211
        assert_eq!(header.length, Length::ONE);
212
        assert_eq!(reader.position(), Length::ZERO); // Position unchanged
213
    }
214
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/referenced.rs
Line
Count
Source
1
//! A module for working with referenced data.
2
3
/// A trait for borrowing data from an owned struct
4
pub trait OwnedToRef {
5
    /// The resulting type referencing back to Self
6
    type Borrowed<'a>
7
    where
8
        Self: 'a;
9
10
    /// Creates a new object referencing back to the self for storage
11
    fn owned_to_ref(&self) -> Self::Borrowed<'_>;
12
}
13
14
/// A trait for cloning a referenced structure and getting owned objects
15
///
16
/// This is the pendant to [`OwnedToRef`]
17
pub trait RefToOwned<'a> {
18
    /// The resulting type after obtaining ownership.
19
    type Owned: OwnedToRef<Borrowed<'a> = Self>
20
    where
21
        Self: 'a;
22
23
    /// Creates a new object taking ownership of the data
24
    fn ref_to_owned(&self) -> Self::Owned;
25
}
26
27
impl<T> OwnedToRef for Option<T>
28
where
29
    T: OwnedToRef,
30
{
31
    type Borrowed<'a> = Option<T::Borrowed<'a>> where T: 'a;
32
33
0
    fn owned_to_ref(&self) -> Self::Borrowed<'_> {
34
0
        self.as_ref().map(|o| o.owned_to_ref())
Unexecuted instantiation: _RNCNvXININtCscrZQdumITES_3der10referenced0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionpENtB7_10OwnedToRef12owned_to_ref0B9_
Unexecuted instantiation: _RNCNvXNtCscrZQdumITES_3der10referencedINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtNtNtB6_4asn13any10allocating3AnyENtB4_10OwnedToRef12owned_to_ref0CskctcMqaO4X4_4spki
35
0
    }
Unexecuted instantiation: _RNvXININtCscrZQdumITES_3der10referenced0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionpENtB5_10OwnedToRef12owned_to_refB7_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der10referencedINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtNtNtB4_4asn13any10allocating3AnyENtB2_10OwnedToRef12owned_to_refCskctcMqaO4X4_4spki
36
}
37
38
impl<'a, T> RefToOwned<'a> for Option<T>
39
where
40
    T: RefToOwned<'a> + 'a,
41
    T::Owned: OwnedToRef,
42
{
43
    type Owned = Option<T::Owned>;
44
0
    fn ref_to_owned(&self) -> Self::Owned {
45
0
        self.as_ref().map(|o| o.ref_to_owned())
Unexecuted instantiation: _RNCNvXININtCscrZQdumITES_3der10referenceds_0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionpENtB7_10RefToOwned12ref_to_owned0B9_
Unexecuted instantiation: _RNCNvXs_NtCscrZQdumITES_3der10referencedINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtNtB8_4asn13any6AnyRefENtB6_10RefToOwned12ref_to_owned0CskctcMqaO4X4_4spki
46
0
    }
Unexecuted instantiation: _RNvXININtCscrZQdumITES_3der10referenceds_0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionpENtB5_10RefToOwned12ref_to_ownedB7_
Unexecuted instantiation: _RNvXs_NtCscrZQdumITES_3der10referencedINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtNtB6_4asn13any6AnyRefENtB4_10RefToOwned12ref_to_ownedCskctcMqaO4X4_4spki
47
}
48
49
#[cfg(feature = "alloc")]
50
mod allocating {
51
    use super::{OwnedToRef, RefToOwned};
52
    use alloc::boxed::Box;
53
54
    impl<'a> RefToOwned<'a> for &'a [u8] {
55
        type Owned = Box<[u8]>;
56
57
0
        fn ref_to_owned(&self) -> Self::Owned {
58
0
            Box::from(*self)
59
0
        }
60
    }
61
62
    impl OwnedToRef for Box<[u8]> {
63
        type Borrowed<'a> = &'a [u8];
64
65
0
        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
66
0
            self.as_ref()
67
0
        }
68
    }
69
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/str_owned.rs
Line
Count
Source
1
//! Common handling for types backed by `String` with enforcement of a
2
//! library-level length limitation i.e. `Length::max()`.
3
4
use crate::{
5
    referenced::OwnedToRef, BytesRef, DecodeValue, EncodeValue, Header, Length, Reader, Result,
6
    StrRef, Writer,
7
};
8
use alloc::string::String;
9
use core::str;
10
11
/// String newtype which respects the [`Length::max`] limit.
12
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
13
pub struct StrOwned {
14
    /// Inner value
15
    pub(crate) inner: String,
16
17
    /// Precomputed `Length` (avoids possible panicking conversions)
18
    pub(crate) length: Length,
19
}
20
21
impl StrOwned {
22
    /// Create a new [`StrOwned`], ensuring that the byte representation of
23
    /// the provided `str` value is shorter than `Length::max()`.
24
0
    pub fn new(s: String) -> Result<Self> {
25
0
        let length = Length::try_from(s.as_bytes().len())?;
26
27
0
        Ok(Self { inner: s, length })
28
0
    }
29
30
    /// Parse a [`String`] from UTF-8 encoded bytes.
31
0
    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
32
0
        Ok(Self {
33
0
            inner: String::from_utf8(bytes.to_vec())?,
34
0
            length: Length::try_from(bytes.len())?,
35
        })
36
0
    }
37
38
    /// Borrow the inner `str`
39
0
    pub fn as_str(&self) -> &str {
40
0
        &self.inner
41
0
    }
42
43
    /// Borrow the inner byte slice
44
0
    pub fn as_bytes(&self) -> &[u8] {
45
0
        self.inner.as_bytes()
46
0
    }
47
48
    /// Get the [`Length`] of this [`StrOwned`]
49
0
    pub fn len(&self) -> Length {
50
0
        self.length
51
0
    }
52
53
    /// Is this [`StrOwned`] empty?
54
0
    pub fn is_empty(&self) -> bool {
55
0
        self.len() == Length::ZERO
56
0
    }
57
}
58
59
impl AsRef<str> for StrOwned {
60
0
    fn as_ref(&self) -> &str {
61
0
        self.as_str()
62
0
    }
63
}
64
65
impl AsRef<[u8]> for StrOwned {
66
0
    fn as_ref(&self) -> &[u8] {
67
0
        self.as_bytes()
68
0
    }
69
}
70
71
impl<'a> DecodeValue<'a> for StrOwned {
72
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
73
0
        Self::from_bytes(BytesRef::decode_value(reader, header)?.as_slice())
74
0
    }
75
}
76
77
impl EncodeValue for StrOwned {
78
0
    fn value_len(&self) -> Result<Length> {
79
0
        Ok(self.length)
80
0
    }
81
82
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
83
0
        writer.write(self.as_ref())
84
0
    }
85
}
86
87
impl From<StrRef<'_>> for StrOwned {
88
0
    fn from(s: StrRef<'_>) -> StrOwned {
89
0
        Self {
90
0
            inner: String::from(s.inner),
91
0
            length: s.length,
92
0
        }
93
0
    }
94
}
95
96
impl OwnedToRef for StrOwned {
97
    type Borrowed<'a> = StrRef<'a>;
98
0
    fn owned_to_ref(&self) -> Self::Borrowed<'_> {
99
0
        StrRef {
100
0
            length: self.length,
101
0
            inner: self.inner.as_ref(),
102
0
        }
103
0
    }
104
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/str_ref.rs
Line
Count
Source
1
//! Common handling for types backed by `str` slices with enforcement of a
2
//! library-level length limitation i.e. `Length::max()`.
3
4
use crate::{BytesRef, DecodeValue, EncodeValue, Header, Length, Reader, Result, Writer};
5
use core::str;
6
7
/// String slice newtype which respects the [`Length::max`] limit.
8
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
9
pub struct StrRef<'a> {
10
    /// Inner value
11
    pub(crate) inner: &'a str,
12
13
    /// Precomputed `Length` (avoids possible panicking conversions)
14
    pub(crate) length: Length,
15
}
16
17
impl<'a> StrRef<'a> {
18
    /// Create a new [`StrRef`], ensuring that the byte representation of
19
    /// the provided `str` value is shorter than `Length::max()`.
20
0
    pub fn new(s: &'a str) -> Result<Self> {
21
0
        Ok(Self {
22
0
            inner: s,
23
0
            length: Length::try_from(s.as_bytes().len())?,
24
        })
25
0
    }
26
27
    /// Parse a [`StrRef`] from UTF-8 encoded bytes.
28
0
    pub fn from_bytes(bytes: &'a [u8]) -> Result<Self> {
29
0
        Self::new(str::from_utf8(bytes)?)
30
0
    }
31
32
    /// Borrow the inner `str`
33
0
    pub fn as_str(&self) -> &'a str {
34
0
        self.inner
35
0
    }
36
37
    /// Borrow the inner byte slice
38
0
    pub fn as_bytes(&self) -> &'a [u8] {
39
0
        self.inner.as_bytes()
40
0
    }
41
42
    /// Get the [`Length`] of this [`StrRef`]
43
0
    pub fn len(self) -> Length {
44
0
        self.length
45
0
    }
46
47
    /// Is this [`StrRef`] empty?
48
0
    pub fn is_empty(self) -> bool {
49
0
        self.len() == Length::ZERO
50
0
    }
51
}
52
53
impl AsRef<str> for StrRef<'_> {
54
0
    fn as_ref(&self) -> &str {
55
0
        self.as_str()
56
0
    }
57
}
58
59
impl AsRef<[u8]> for StrRef<'_> {
60
0
    fn as_ref(&self) -> &[u8] {
61
0
        self.as_bytes()
62
0
    }
63
}
64
65
impl<'a> DecodeValue<'a> for StrRef<'a> {
66
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
67
0
        Self::from_bytes(BytesRef::decode_value(reader, header)?.as_slice())
68
0
    }
69
}
70
71
impl<'a> EncodeValue for StrRef<'a> {
72
0
    fn value_len(&self) -> Result<Length> {
73
0
        Ok(self.length)
74
0
    }
75
76
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
77
0
        writer.write(self.as_ref())
78
0
    }
79
}
80
81
#[cfg(feature = "alloc")]
82
mod allocating {
83
    use super::StrRef;
84
    use crate::{referenced::RefToOwned, StrOwned};
85
86
    impl<'a> RefToOwned<'a> for StrRef<'a> {
87
        type Owned = StrOwned;
88
0
        fn ref_to_owned(&self) -> Self::Owned {
89
0
            StrOwned::from(*self)
90
0
        }
91
    }
92
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/tag.rs
Line
Count
Source
1
//! ASN.1 tags.
2
#![cfg_attr(feature = "arbitrary", allow(clippy::integer_arithmetic))]
3
4
mod class;
5
mod mode;
6
mod number;
7
8
pub use self::{class::Class, mode::TagMode, number::TagNumber};
9
10
use crate::{Decode, DerOrd, Encode, Error, ErrorKind, Length, Reader, Result, Writer};
11
use core::{cmp::Ordering, fmt};
12
13
/// Indicator bit for constructed form encoding (i.e. vs primitive form)
14
const CONSTRUCTED_FLAG: u8 = 0b100000;
15
16
/// Types which have a constant ASN.1 [`Tag`].
17
pub trait FixedTag {
18
    /// ASN.1 tag
19
    const TAG: Tag;
20
}
21
22
/// Types which have an ASN.1 [`Tag`].
23
pub trait Tagged {
24
    /// Get the ASN.1 tag that this type is encoded with.
25
    fn tag(&self) -> Tag;
26
}
27
28
/// Types which are [`FixedTag`] always have a known [`Tag`] type.
29
impl<T: FixedTag> Tagged for T {
30
0
    fn tag(&self) -> Tag {
31
0
        T::TAG
32
0
    }
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagINtNtCsiBl6Lc3cFal_5alloc3vec3VechENtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtB4_8datetime8DateTimeNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtCsVNp5ty2IzJ_3std4time10SystemTimeNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtCsiBl6Lc3cFal_5alloc6string6StringNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn110bit_string12BitStringRefNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn110bmp_string9BmpStringNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn110ia5_string12Ia5StringRefNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn111utf8_string13Utf8StringRefNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn112octet_string14OctetStringRefNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn114teletex_string16TeletexStringRefNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn115videotex_string17VideotexStringRefNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn116generalized_time15GeneralizedTimeNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn116printable_string18PrintableStringRefNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn14null4NullNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn18sequence11SequenceRefNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn18utc_time7UtcTimeNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtNtB4_4asn110bit_string10allocating9BitStringNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtNtB4_4asn110ia5_string10allocation9Ia5StringNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtNtB4_4asn112octet_string10allocating11OctetStringNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtNtB4_4asn114teletex_string10allocation13TeletexStringNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtNtB4_4asn116printable_string10allocation15PrintableStringNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtNtB4_4asn17integer3int6IntRefNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtNtB4_4asn17integer4uint7UintRefNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtNtNtB4_4asn17integer3int10allocating3IntNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtNtNtB4_4asn17integer4uint10allocating4UintNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagaNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagbNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3taghNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3taglNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagmNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagnNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagoNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagsNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagtNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3taguNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagxNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagyNtB2_6Tagged3tagB4_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagINtNtCskctcMqaO4X4_4spki9algorithm19AlgorithmIdentifierNtNtNtB4_4asn13any6AnyRefENtB2_6Tagged3tagCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtCs7FMNkqQAJBl_9const_oid16ObjectIdentifierNtB2_6Tagged3tagCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoNtB2_6Tagged3tagBu_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn110bit_string12BitStringRefNtB2_6Tagged3tagCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn112octet_string14OctetStringRefNtB2_6Tagged3tagCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3taghNtB2_6Tagged3tagCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtCsj9qtwLkMHqH_4sec110parameters12EcParametersNtB2_6Tagged3tagBu_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyNtB2_6Tagged3tagBu_
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn110bit_string12BitStringRefNtB2_6Tagged3tagCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3tagNtNtNtB4_4asn112octet_string14OctetStringRefNtB2_6Tagged3tagCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvXNtCscrZQdumITES_3der3taghNtB2_6Tagged3tagCsj9qtwLkMHqH_4sec1
33
}
34
35
/// ASN.1 tags.
36
///
37
/// Tags are the leading identifier octet of the Tag-Length-Value encoding
38
/// used by ASN.1 DER and identify the type of the subsequent value.
39
///
40
/// They are described in X.690 Section 8.1.2: Identifier octets, and
41
/// structured as follows:
42
///
43
/// ```text
44
/// | Class | P/C | Tag Number |
45
/// ```
46
///
47
/// - Bits 8/7: [`Class`]
48
/// - Bit 6: primitive (0) or constructed (1)
49
/// - Bits 5-1: tag number
50
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
51
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
52
#[non_exhaustive]
53
pub enum Tag {
54
    /// `BOOLEAN` tag: `1`.
55
    Boolean,
56
57
    /// `INTEGER` tag: `2`.
58
    Integer,
59
60
    /// `BIT STRING` tag: `3`.
61
    BitString,
62
63
    /// `OCTET STRING` tag: `4`.
64
    OctetString,
65
66
    /// `NULL` tag: `5`.
67
    Null,
68
69
    /// `OBJECT IDENTIFIER` tag: `6`.
70
    ObjectIdentifier,
71
72
    /// `REAL` tag: `9`.
73
    Real,
74
75
    /// `ENUMERATED` tag: `10`.
76
    Enumerated,
77
78
    /// `UTF8String` tag: `12`.
79
    Utf8String,
80
81
    /// `SEQUENCE` tag: `16`.
82
    Sequence,
83
84
    /// `SET` and `SET OF` tag: `17`.
85
    Set,
86
87
    /// `NumericString` tag: `18`.
88
    NumericString,
89
90
    /// `PrintableString` tag: `19`.
91
    PrintableString,
92
93
    /// `TeletexString` tag: `20`.
94
    TeletexString,
95
96
    /// `VideotexString` tag: `21`.
97
    VideotexString,
98
99
    /// `IA5String` tag: `22`.
100
    Ia5String,
101
102
    /// `UTCTime` tag: `23`.
103
    UtcTime,
104
105
    /// `GeneralizedTime` tag: `24`.
106
    GeneralizedTime,
107
108
    /// `VisibleString` tag: `26`.
109
    VisibleString,
110
111
    /// `BMPString` tag: `30`.
112
    BmpString,
113
114
    /// Application tag.
115
    Application {
116
        /// Is this tag constructed? (vs primitive).
117
        constructed: bool,
118
119
        /// Tag number.
120
        number: TagNumber,
121
    },
122
123
    /// Context-specific tag.
124
    ContextSpecific {
125
        /// Is this tag constructed? (vs primitive).
126
        constructed: bool,
127
128
        /// Tag number.
129
        number: TagNumber,
130
    },
131
132
    /// Private tag number.
133
    Private {
134
        /// Is this tag constructed? (vs primitive).
135
        constructed: bool,
136
137
        /// Tag number.
138
        number: TagNumber,
139
    },
140
}
141
142
impl Tag {
143
    /// Assert that this [`Tag`] matches the provided expected tag.
144
    ///
145
    /// On mismatch, returns an [`Error`] with [`ErrorKind::TagUnexpected`].
146
0
    pub fn assert_eq(self, expected: Tag) -> Result<Tag> {
147
0
        if self == expected {
148
0
            Ok(self)
149
        } else {
150
0
            Err(self.unexpected_error(Some(expected)))
151
        }
152
0
    }
153
154
    /// Get the [`Class`] that corresponds to this [`Tag`].
155
0
    pub fn class(self) -> Class {
156
0
        match self {
157
0
            Tag::Application { .. } => Class::Application,
158
0
            Tag::ContextSpecific { .. } => Class::ContextSpecific,
159
0
            Tag::Private { .. } => Class::Private,
160
0
            _ => Class::Universal,
161
        }
162
0
    }
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag5classB6_
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag5classCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag5classCsj9qtwLkMHqH_4sec1
163
164
    /// Get the [`TagNumber`] (lower 6-bits) for this tag.
165
0
    pub fn number(self) -> TagNumber {
166
0
        TagNumber(self.octet() & TagNumber::MASK)
167
0
    }
168
169
    /// Does this tag represent a constructed (as opposed to primitive) field?
170
0
    pub fn is_constructed(self) -> bool {
171
0
        self.octet() & CONSTRUCTED_FLAG != 0
172
0
    }
173
174
    /// Is this an application tag?
175
0
    pub fn is_application(self) -> bool {
176
0
        self.class() == Class::Application
177
0
    }
178
179
    /// Is this a context-specific tag?
180
0
    pub fn is_context_specific(self) -> bool {
181
0
        self.class() == Class::ContextSpecific
182
0
    }
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag19is_context_specificB6_
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag19is_context_specificCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag19is_context_specificCsj9qtwLkMHqH_4sec1
183
184
    /// Is this a private tag?
185
0
    pub fn is_private(self) -> bool {
186
0
        self.class() == Class::Private
187
0
    }
188
189
    /// Is this a universal tag?
190
0
    pub fn is_universal(self) -> bool {
191
0
        self.class() == Class::Universal
192
0
    }
193
194
    /// Get the octet encoding for this [`Tag`].
195
0
    pub fn octet(self) -> u8 {
196
0
        match self {
197
0
            Tag::Boolean => 0x01,
198
0
            Tag::Integer => 0x02,
199
0
            Tag::BitString => 0x03,
200
0
            Tag::OctetString => 0x04,
201
0
            Tag::Null => 0x05,
202
0
            Tag::ObjectIdentifier => 0x06,
203
0
            Tag::Real => 0x09,
204
0
            Tag::Enumerated => 0x0A,
205
0
            Tag::Utf8String => 0x0C,
206
0
            Tag::Sequence => 0x10 | CONSTRUCTED_FLAG,
207
0
            Tag::Set => 0x11 | CONSTRUCTED_FLAG,
208
0
            Tag::NumericString => 0x12,
209
0
            Tag::PrintableString => 0x13,
210
0
            Tag::TeletexString => 0x14,
211
0
            Tag::VideotexString => 0x15,
212
0
            Tag::Ia5String => 0x16,
213
0
            Tag::UtcTime => 0x17,
214
0
            Tag::GeneralizedTime => 0x18,
215
0
            Tag::VisibleString => 0x1A,
216
0
            Tag::BmpString => 0x1E,
217
            Tag::Application {
218
0
                constructed,
219
0
                number,
220
            }
221
            | Tag::ContextSpecific {
222
0
                constructed,
223
0
                number,
224
            }
225
            | Tag::Private {
226
0
                constructed,
227
0
                number,
228
0
            } => self.class().octet(constructed, number),
229
        }
230
0
    }
231
232
    /// Create an [`Error`] for an invalid [`Length`].
233
0
    pub fn length_error(self) -> Error {
234
0
        ErrorKind::Length { tag: self }.into()
235
0
    }
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag12length_errorB6_
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag12length_errorCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag12length_errorCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag12length_errorCskctcMqaO4X4_4spki
236
237
    /// Create an [`Error`] for an non-canonical value with the ASN.1 type
238
    /// identified by this tag.
239
0
    pub fn non_canonical_error(self) -> Error {
240
0
        ErrorKind::Noncanonical { tag: self }.into()
241
0
    }
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag19non_canonical_errorB6_
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag19non_canonical_errorCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag19non_canonical_errorCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag19non_canonical_errorCsj9qtwLkMHqH_4sec1
242
243
    /// Create an [`Error`] because the current tag was unexpected, with an
244
    /// optional expected tag.
245
0
    pub fn unexpected_error(self, expected: Option<Self>) -> Error {
246
0
        ErrorKind::TagUnexpected {
247
0
            expected,
248
0
            actual: self,
249
0
        }
250
0
        .into()
251
0
    }
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag16unexpected_errorB6_
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag16unexpected_errorCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag16unexpected_errorCsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag16unexpected_errorCskctcMqaO4X4_4spki
252
253
    /// Create an [`Error`] for an invalid value with the ASN.1 type identified
254
    /// by this tag.
255
0
    pub fn value_error(self) -> Error {
256
0
        ErrorKind::Value { tag: self }.into()
257
0
    }
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag11value_errorB6_
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag11value_errorCs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag11value_errorCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMs_NtCscrZQdumITES_3der3tagNtB4_3Tag11value_errorCsj9qtwLkMHqH_4sec1
258
}
259
260
impl TryFrom<u8> for Tag {
261
    type Error = Error;
262
263
0
    fn try_from(byte: u8) -> Result<Tag> {
264
0
        let constructed = byte & CONSTRUCTED_FLAG != 0;
265
0
        let number = TagNumber::try_from(byte & TagNumber::MASK)?;
266
267
0
        match byte {
268
0
            0x01 => Ok(Tag::Boolean),
269
0
            0x02 => Ok(Tag::Integer),
270
0
            0x03 => Ok(Tag::BitString),
271
0
            0x04 => Ok(Tag::OctetString),
272
0
            0x05 => Ok(Tag::Null),
273
0
            0x06 => Ok(Tag::ObjectIdentifier),
274
0
            0x09 => Ok(Tag::Real),
275
0
            0x0A => Ok(Tag::Enumerated),
276
0
            0x0C => Ok(Tag::Utf8String),
277
0
            0x12 => Ok(Tag::NumericString),
278
0
            0x13 => Ok(Tag::PrintableString),
279
0
            0x14 => Ok(Tag::TeletexString),
280
0
            0x15 => Ok(Tag::VideotexString),
281
0
            0x16 => Ok(Tag::Ia5String),
282
0
            0x17 => Ok(Tag::UtcTime),
283
0
            0x18 => Ok(Tag::GeneralizedTime),
284
0
            0x1A => Ok(Tag::VisibleString),
285
0
            0x1E => Ok(Tag::BmpString),
286
0
            0x30 => Ok(Tag::Sequence), // constructed
287
0
            0x31 => Ok(Tag::Set),      // constructed
288
0
            0x40..=0x7E => Ok(Tag::Application {
289
0
                constructed,
290
0
                number,
291
0
            }),
292
0
            0x80..=0xBE => Ok(Tag::ContextSpecific {
293
0
                constructed,
294
0
                number,
295
0
            }),
296
0
            0xC0..=0xFE => Ok(Tag::Private {
297
0
                constructed,
298
0
                number,
299
0
            }),
300
0
            _ => Err(ErrorKind::TagUnknown { byte }.into()),
301
        }
302
0
    }
303
}
304
305
impl From<Tag> for u8 {
306
0
    fn from(tag: Tag) -> u8 {
307
0
        tag.octet()
308
0
    }
309
}
310
311
impl From<&Tag> for u8 {
312
0
    fn from(tag: &Tag) -> u8 {
313
0
        u8::from(*tag)
314
0
    }
315
}
316
317
impl<'a> Decode<'a> for Tag {
318
0
    fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Self> {
319
0
        reader.read_byte().and_then(Self::try_from)
320
0
    }
Unexecuted instantiation: _RINvXs3_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6decode6Decode6decodeNtNtNtB8_6reader3pem9PemReaderEB8_
Unexecuted instantiation: _RINvXs3_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6decode6Decode6decodeNtNtNtB8_6reader5slice11SliceReaderEB8_
Unexecuted instantiation: _RINvXs3_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6decode6Decode6decodeINtNtNtB8_6reader6nested12NestedReaderNtNtB1a_5slice11SliceReaderEECs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RINvXs3_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6decode6Decode6decodeNtNtNtB8_6reader5slice11SliceReaderECs56dDIOPvtI3_5ecdsa
Unexecuted instantiation: _RINvXs3_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6decode6Decode6decodeINtNtNtB8_6reader6nested12NestedReaderIB16_NtNtB1a_5slice11SliceReaderEEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs3_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6decode6Decode6decodeINtNtNtB8_6reader6nested12NestedReaderNtNtB1a_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs3_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6decode6Decode6decodeNtNtNtB8_6reader5slice11SliceReaderECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs3_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6decode6Decode6decodeINtNtNtB8_6reader6nested12NestedReaderIB16_NtNtB1a_5slice11SliceReaderEEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXs3_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6decode6Decode6decodeINtNtNtB8_6reader6nested12NestedReaderNtNtB1a_5slice11SliceReaderEECsj9qtwLkMHqH_4sec1
Unexecuted instantiation: _RINvXs3_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6decode6Decode6decodeNtNtNtB8_6reader5slice11SliceReaderECsj9qtwLkMHqH_4sec1
321
}
322
323
impl Encode for Tag {
324
0
    fn encoded_len(&self) -> Result<Length> {
325
0
        Ok(Length::ONE)
326
0
    }
327
328
0
    fn encode(&self, writer: &mut impl Writer) -> Result<()> {
329
0
        writer.write_byte(self.into())
330
0
    }
Unexecuted instantiation: _RINvXs4_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6encode6Encode6encodeNtNtNtB8_6writer5slice11SliceWriterEB8_
Unexecuted instantiation: _RINvXs4_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6encode6Encode6encodeNtNtNtB8_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXs4_NtCscrZQdumITES_3der3tagNtB6_3TagNtNtB8_6encode6Encode6encodeNtNtNtB8_6writer5slice11SliceWriterECsj9qtwLkMHqH_4sec1
331
}
332
333
impl DerOrd for Tag {
334
0
    fn der_cmp(&self, other: &Self) -> Result<Ordering> {
335
0
        Ok(self.octet().cmp(&other.octet()))
336
0
    }
337
}
338
339
impl fmt::Display for Tag {
340
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
341
        const FIELD_TYPE: [&str; 2] = ["primitive", "constructed"];
342
343
0
        match *self {
344
0
            Tag::Boolean => f.write_str("BOOLEAN"),
345
0
            Tag::Integer => f.write_str("INTEGER"),
346
0
            Tag::BitString => f.write_str("BIT STRING"),
347
0
            Tag::OctetString => f.write_str("OCTET STRING"),
348
0
            Tag::Null => f.write_str("NULL"),
349
0
            Tag::ObjectIdentifier => f.write_str("OBJECT IDENTIFIER"),
350
0
            Tag::Real => f.write_str("REAL"),
351
0
            Tag::Enumerated => f.write_str("ENUMERATED"),
352
0
            Tag::Utf8String => f.write_str("UTF8String"),
353
0
            Tag::Set => f.write_str("SET"),
354
0
            Tag::NumericString => f.write_str("NumericString"),
355
0
            Tag::PrintableString => f.write_str("PrintableString"),
356
0
            Tag::TeletexString => f.write_str("TeletexString"),
357
0
            Tag::VideotexString => f.write_str("VideotexString"),
358
0
            Tag::Ia5String => f.write_str("IA5String"),
359
0
            Tag::UtcTime => f.write_str("UTCTime"),
360
0
            Tag::GeneralizedTime => f.write_str("GeneralizedTime"),
361
0
            Tag::VisibleString => f.write_str("VisibleString"),
362
0
            Tag::BmpString => f.write_str("BMPString"),
363
0
            Tag::Sequence => f.write_str("SEQUENCE"),
364
            Tag::Application {
365
0
                constructed,
366
0
                number,
367
0
            } => write!(
368
0
                f,
369
0
                "APPLICATION [{}] ({})",
370
0
                number,
371
0
                FIELD_TYPE[usize::from(constructed)]
372
0
            ),
373
            Tag::ContextSpecific {
374
0
                constructed,
375
0
                number,
376
0
            } => write!(
377
0
                f,
378
0
                "CONTEXT-SPECIFIC [{}] ({})",
379
0
                number,
380
0
                FIELD_TYPE[usize::from(constructed)]
381
0
            ),
382
            Tag::Private {
383
0
                constructed,
384
0
                number,
385
0
            } => write!(
386
0
                f,
387
0
                "PRIVATE [{}] ({})",
388
0
                number,
389
0
                FIELD_TYPE[usize::from(constructed)]
390
0
            ),
391
        }
392
0
    }
393
}
394
395
impl fmt::Debug for Tag {
396
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
397
0
        write!(f, "Tag(0x{:02x}: {})", u8::from(*self), self)
398
0
    }
399
}
400
401
#[cfg(test)]
402
mod tests {
403
    use super::TagNumber;
404
    use super::{Class, Tag};
405
406
    #[test]
407
    fn tag_class() {
408
        assert_eq!(Tag::Boolean.class(), Class::Universal);
409
        assert_eq!(Tag::Integer.class(), Class::Universal);
410
        assert_eq!(Tag::BitString.class(), Class::Universal);
411
        assert_eq!(Tag::OctetString.class(), Class::Universal);
412
        assert_eq!(Tag::Null.class(), Class::Universal);
413
        assert_eq!(Tag::ObjectIdentifier.class(), Class::Universal);
414
        assert_eq!(Tag::Real.class(), Class::Universal);
415
        assert_eq!(Tag::Enumerated.class(), Class::Universal);
416
        assert_eq!(Tag::Utf8String.class(), Class::Universal);
417
        assert_eq!(Tag::Set.class(), Class::Universal);
418
        assert_eq!(Tag::NumericString.class(), Class::Universal);
419
        assert_eq!(Tag::PrintableString.class(), Class::Universal);
420
        assert_eq!(Tag::TeletexString.class(), Class::Universal);
421
        assert_eq!(Tag::VideotexString.class(), Class::Universal);
422
        assert_eq!(Tag::Ia5String.class(), Class::Universal);
423
        assert_eq!(Tag::UtcTime.class(), Class::Universal);
424
        assert_eq!(Tag::GeneralizedTime.class(), Class::Universal);
425
        assert_eq!(Tag::Sequence.class(), Class::Universal);
426
427
        for num in 0..=30 {
428
            for &constructed in &[false, true] {
429
                let number = TagNumber::new(num);
430
431
                assert_eq!(
432
                    Tag::Application {
433
                        constructed,
434
                        number
435
                    }
436
                    .class(),
437
                    Class::Application
438
                );
439
440
                assert_eq!(
441
                    Tag::ContextSpecific {
442
                        constructed,
443
                        number
444
                    }
445
                    .class(),
446
                    Class::ContextSpecific
447
                );
448
449
                assert_eq!(
450
                    Tag::Private {
451
                        constructed,
452
                        number
453
                    }
454
                    .class(),
455
                    Class::Private
456
                );
457
            }
458
        }
459
    }
460
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/tag/class.rs
Line
Count
Source
1
//! Class of an ASN.1 tag.
2
3
use super::{TagNumber, CONSTRUCTED_FLAG};
4
use core::fmt;
5
6
/// Class of an ASN.1 tag.
7
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
8
#[repr(u8)]
9
pub enum Class {
10
    /// `UNIVERSAL`: built-in types whose meaning is the same in all
11
    /// applications.
12
    Universal = 0b00000000,
13
14
    /// `APPLICATION`: types whose meaning is specific to an application,
15
    ///
16
    /// Types in two different applications may have the same
17
    /// application-specific tag and different meanings.
18
    Application = 0b01000000,
19
20
    /// `CONTEXT-SPECIFIC`: types whose meaning is specific to a given
21
    /// structured type.
22
    ///
23
    /// Context-specific tags are used to distinguish between component types
24
    /// with the same underlying tag within the context of a given structured
25
    /// type, and component types in two different structured types may have
26
    /// the same tag and different meanings.
27
    ContextSpecific = 0b10000000,
28
29
    /// `PRIVATE`: types whose meaning is specific to a given enterprise.
30
    Private = 0b11000000,
31
}
32
33
impl Class {
34
    /// Compute the identifier octet for a tag number of this class.
35
    #[allow(clippy::integer_arithmetic)]
36
0
    pub(super) fn octet(self, constructed: bool, number: TagNumber) -> u8 {
37
0
        self as u8 | number.value() | (u8::from(constructed) * CONSTRUCTED_FLAG)
38
0
    }
39
}
40
41
impl fmt::Display for Class {
42
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43
0
        f.write_str(match self {
44
0
            Class::Universal => "UNIVERSAL",
45
0
            Class::Application => "APPLICATION",
46
0
            Class::ContextSpecific => "CONTEXT-SPECIFIC",
47
0
            Class::Private => "PRIVATE",
48
        })
49
0
    }
50
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/tag/mode.rs
Line
Count
Source
1
//! Tag modes.
2
3
use crate::{Error, ErrorKind, Result};
4
use core::{fmt, str::FromStr};
5
6
/// Tagging modes: `EXPLICIT` versus `IMPLICIT`.
7
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
8
pub enum TagMode {
9
    /// `EXPLICIT` tagging.
10
    ///
11
    /// Tag is added in addition to the inner tag of the type.
12
    #[default]
13
    Explicit,
14
15
    /// `IMPLICIT` tagging.
16
    ///
17
    /// Tag replaces the existing tag of the inner type.
18
    Implicit,
19
}
20
21
impl FromStr for TagMode {
22
    type Err = Error;
23
24
0
    fn from_str(s: &str) -> Result<Self> {
25
0
        match s {
26
0
            "EXPLICIT" | "explicit" => Ok(TagMode::Explicit),
27
0
            "IMPLICIT" | "implicit" => Ok(TagMode::Implicit),
28
0
            _ => Err(ErrorKind::TagModeUnknown.into()),
29
        }
30
0
    }
31
}
32
33
impl fmt::Display for TagMode {
34
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35
0
        match self {
36
0
            TagMode::Explicit => f.write_str("EXPLICIT"),
37
0
            TagMode::Implicit => f.write_str("IMPLICIT"),
38
        }
39
0
    }
40
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/tag/number.rs
Line
Count
Source
1
//! ASN.1 tag numbers
2
3
use super::Tag;
4
use crate::{Error, ErrorKind, Result};
5
use core::fmt;
6
7
/// ASN.1 tag numbers (i.e. lower 5 bits of a [`Tag`]).
8
///
9
/// From X.690 Section 8.1.2.2:
10
///
11
/// > bits 5 to 1 shall encode the number of the tag as a binary integer with
12
/// > bit 5 as the most significant bit.
13
///
14
/// This library supports tag numbers ranging from zero to 30 (inclusive),
15
/// which can be represented as a single identifier octet.
16
///
17
/// Section 8.1.2.4 describes how to support multi-byte tag numbers, which are
18
/// encoded by using a leading tag number of 31 (`0b11111`). This library
19
/// deliberately does not support this: tag numbers greater than 30 are
20
/// disallowed.
21
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
22
pub struct TagNumber(pub(super) u8);
23
24
impl TagNumber {
25
    /// Tag number `0`
26
    pub const N0: Self = Self(0);
27
28
    /// Tag number `1`
29
    pub const N1: Self = Self(1);
30
31
    /// Tag number `2`
32
    pub const N2: Self = Self(2);
33
34
    /// Tag number `3`
35
    pub const N3: Self = Self(3);
36
37
    /// Tag number `4`
38
    pub const N4: Self = Self(4);
39
40
    /// Tag number `5`
41
    pub const N5: Self = Self(5);
42
43
    /// Tag number `6`
44
    pub const N6: Self = Self(6);
45
46
    /// Tag number `7`
47
    pub const N7: Self = Self(7);
48
49
    /// Tag number `8`
50
    pub const N8: Self = Self(8);
51
52
    /// Tag number `9`
53
    pub const N9: Self = Self(9);
54
55
    /// Tag number `10`
56
    pub const N10: Self = Self(10);
57
58
    /// Tag number `11`
59
    pub const N11: Self = Self(11);
60
61
    /// Tag number `12`
62
    pub const N12: Self = Self(12);
63
64
    /// Tag number `13`
65
    pub const N13: Self = Self(13);
66
67
    /// Tag number `14`
68
    pub const N14: Self = Self(14);
69
70
    /// Tag number `15`
71
    pub const N15: Self = Self(15);
72
73
    /// Tag number `16`
74
    pub const N16: Self = Self(16);
75
76
    /// Tag number `17`
77
    pub const N17: Self = Self(17);
78
79
    /// Tag number `18`
80
    pub const N18: Self = Self(18);
81
82
    /// Tag number `19`
83
    pub const N19: Self = Self(19);
84
85
    /// Tag number `20`
86
    pub const N20: Self = Self(20);
87
88
    /// Tag number `21`
89
    pub const N21: Self = Self(21);
90
91
    /// Tag number `22`
92
    pub const N22: Self = Self(22);
93
94
    /// Tag number `23`
95
    pub const N23: Self = Self(23);
96
97
    /// Tag number `24`
98
    pub const N24: Self = Self(24);
99
100
    /// Tag number `25`
101
    pub const N25: Self = Self(25);
102
103
    /// Tag number `26`
104
    pub const N26: Self = Self(26);
105
106
    /// Tag number `27`
107
    pub const N27: Self = Self(27);
108
109
    /// Tag number `28`
110
    pub const N28: Self = Self(28);
111
112
    /// Tag number `29`
113
    pub const N29: Self = Self(29);
114
115
    /// Tag number `30`
116
    pub const N30: Self = Self(30);
117
118
    /// Mask value used to obtain the tag number from a tag octet.
119
    pub(super) const MASK: u8 = 0b11111;
120
121
    /// Maximum tag number supported (inclusive).
122
    const MAX: u8 = 30;
123
124
    /// Create a new tag number (const-friendly).
125
    ///
126
    /// Panics if the tag number is greater than `30`.
127
    /// For a fallible conversion, use [`TryFrom`] instead.
128
0
    pub const fn new(byte: u8) -> Self {
129
0
        #[allow(clippy::panic)]
130
0
        if byte > Self::MAX {
131
0
            panic!("tag number out of range");
132
0
        }
133
0
134
0
        Self(byte)
135
0
    }
136
137
    /// Create an `APPLICATION` tag with this tag number.
138
0
    pub fn application(self, constructed: bool) -> Tag {
139
0
        Tag::Application {
140
0
            constructed,
141
0
            number: self,
142
0
        }
143
0
    }
144
145
    /// Create a `CONTEXT-SPECIFIC` tag with this tag number.
146
0
    pub fn context_specific(self, constructed: bool) -> Tag {
147
0
        Tag::ContextSpecific {
148
0
            constructed,
149
0
            number: self,
150
0
        }
151
0
    }
152
153
    /// Create a `PRIVATE` tag with this tag number.
154
0
    pub fn private(self, constructed: bool) -> Tag {
155
0
        Tag::Private {
156
0
            constructed,
157
0
            number: self,
158
0
        }
159
0
    }
160
161
    /// Get the inner value.
162
0
    pub fn value(self) -> u8 {
163
0
        self.0
164
0
    }
165
}
166
167
impl TryFrom<u8> for TagNumber {
168
    type Error = Error;
169
170
0
    fn try_from(byte: u8) -> Result<Self> {
171
0
        match byte {
172
0
            0..=Self::MAX => Ok(Self(byte)),
173
0
            _ => Err(ErrorKind::TagNumberInvalid.into()),
174
        }
175
0
    }
176
}
177
178
impl From<TagNumber> for u8 {
179
0
    fn from(tag_number: TagNumber) -> u8 {
180
0
        tag_number.0
181
0
    }
182
}
183
184
impl fmt::Display for TagNumber {
185
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186
0
        write!(f, "{}", self.0)
187
0
    }
188
}
189
190
// Implement by hand because the derive would create invalid values.
191
// Use the constructor to create a valid value.
192
#[cfg(feature = "arbitrary")]
193
impl<'a> arbitrary::Arbitrary<'a> for TagNumber {
194
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
195
        Ok(Self::new(u.int_in_range(0..=Self::MAX)?))
196
    }
197
198
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
199
        u8::size_hint(depth)
200
    }
201
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/writer.rs
Line
Count
Source
1
//! Writer trait.
2
3
#[cfg(feature = "pem")]
4
pub(crate) mod pem;
5
pub(crate) mod slice;
6
7
use crate::Result;
8
9
#[cfg(feature = "std")]
10
use std::io;
11
12
/// Writer trait which outputs encoded DER.
13
pub trait Writer {
14
    /// Write the given DER-encoded bytes as output.
15
    fn write(&mut self, slice: &[u8]) -> Result<()>;
16
17
    /// Write a single byte.
18
0
    fn write_byte(&mut self, byte: u8) -> Result<()> {
19
0
        self.write(&[byte])
20
0
    }
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6writer3pem9PemWriterNtB6_6Writer10write_byteB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6writer5slice11SliceWriterNtB6_6Writer10write_byteB8_
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6writer5slice11SliceWriterNtB6_6Writer10write_byteCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvYNtNtNtCscrZQdumITES_3der6writer5slice11SliceWriterNtB6_6Writer10write_byteCsj9qtwLkMHqH_4sec1
21
}
22
23
#[cfg(feature = "std")]
24
impl<W: io::Write> Writer for W {
25
0
    fn write(&mut self, slice: &[u8]) -> Result<()> {
26
0
        <Self as io::Write>::write(self, slice)?;
27
0
        Ok(())
28
0
    }
29
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/writer/pem.rs
Line
Count
Source
1
//! Streaming PEM writer.
2
3
use super::Writer;
4
use crate::Result;
5
use pem_rfc7468::{Encoder, LineEnding};
6
7
/// `Writer` type which outputs PEM-encoded data.
8
pub struct PemWriter<'w>(Encoder<'static, 'w>);
9
10
impl<'w> PemWriter<'w> {
11
    /// Create a new PEM writer which outputs into the provided buffer.
12
    ///
13
    /// Uses the default 64-character line wrapping.
14
0
    pub fn new(
15
0
        type_label: &'static str,
16
0
        line_ending: LineEnding,
17
0
        out: &'w mut [u8],
18
0
    ) -> Result<Self> {
19
0
        Ok(Self(Encoder::new(type_label, line_ending, out)?))
20
0
    }
21
22
    /// Get the PEM label which will be used in the encapsulation boundaries
23
    /// for this document.
24
0
    pub fn type_label(&self) -> &'static str {
25
0
        self.0.type_label()
26
0
    }
27
28
    /// Finish encoding PEM, writing the post-encapsulation boundary.
29
    ///
30
    /// On success, returns the total number of bytes written to the output buffer.
31
0
    pub fn finish(self) -> Result<usize> {
32
0
        Ok(self.0.finish()?)
33
0
    }
34
}
35
36
impl Writer for PemWriter<'_> {
37
0
    fn write(&mut self, slice: &[u8]) -> Result<()> {
38
0
        self.0.encode(slice)?;
39
0
        Ok(())
40
0
    }
41
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/writer/slice.rs
Line
Count
Source
1
//! Slice writer.
2
3
use crate::{
4
    asn1::*, Encode, EncodeValue, ErrorKind, Header, Length, Result, Tag, TagMode, TagNumber,
5
    Tagged, Writer,
6
};
7
8
/// [`Writer`] which encodes DER into a mutable output byte slice.
9
#[derive(Debug)]
10
pub struct SliceWriter<'a> {
11
    /// Buffer into which DER-encoded message is written
12
    bytes: &'a mut [u8],
13
14
    /// Has the encoding operation failed?
15
    failed: bool,
16
17
    /// Total number of bytes written to buffer so far
18
    position: Length,
19
}
20
21
impl<'a> SliceWriter<'a> {
22
    /// Create a new encoder with the given byte slice as a backing buffer.
23
0
    pub fn new(bytes: &'a mut [u8]) -> Self {
24
0
        Self {
25
0
            bytes,
26
0
            failed: false,
27
0
            position: Length::ZERO,
28
0
        }
29
0
    }
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6writer5sliceNtB2_11SliceWriter3newB6_
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6writer5sliceNtB2_11SliceWriter3newCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6writer5sliceNtB2_11SliceWriter3newCsj9qtwLkMHqH_4sec1
30
31
    /// Encode a value which impls the [`Encode`] trait.
32
0
    pub fn encode<T: Encode>(&mut self, encodable: &T) -> Result<()> {
33
0
        if self.is_failed() {
34
0
            self.error(ErrorKind::Failed)?
35
0
        }
36
37
0
        encodable.encode(self).map_err(|e| {
38
0
            self.failed = true;
39
0
            e.nested(self.position)
40
0
        })
41
0
    }
42
43
    /// Return an error with the given [`ErrorKind`], annotating it with
44
    /// context about where the error occurred.
45
0
    pub fn error<T>(&mut self, kind: ErrorKind) -> Result<T> {
46
0
        self.failed = true;
47
0
        Err(kind.at(self.position))
48
0
    }
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der6writer5sliceNtB3_11SliceWriter5erroruEB7_
Unexecuted instantiation: _RINvMNtNtCscrZQdumITES_3der6writer5sliceNtB3_11SliceWriter5errorNtNtB7_6length6LengthEB7_
49
50
    /// Did the decoding operation fail due to an error?
51
0
    pub fn is_failed(&self) -> bool {
52
0
        self.failed
53
0
    }
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6writer5sliceNtB2_11SliceWriter9is_failedB6_
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6writer5sliceNtB2_11SliceWriter9is_failedCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6writer5sliceNtB2_11SliceWriter9is_failedCsj9qtwLkMHqH_4sec1
54
55
    /// Finish encoding to the buffer, returning a slice containing the data
56
    /// written to the buffer.
57
0
    pub fn finish(self) -> Result<&'a [u8]> {
58
0
        let position = self.position;
59
0
60
0
        if self.is_failed() {
61
0
            return Err(ErrorKind::Failed.at(position));
62
0
        }
63
0
64
0
        self.bytes
65
0
            .get(..usize::try_from(position)?)
66
0
            .ok_or_else(|| ErrorKind::Overlength.at(position))
Unexecuted instantiation: _RNCNvMNtNtCscrZQdumITES_3der6writer5sliceNtB4_11SliceWriter6finish0B8_
Unexecuted instantiation: _RNCNvMNtNtCscrZQdumITES_3der6writer5sliceNtB4_11SliceWriter6finish0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCNvMNtNtCscrZQdumITES_3der6writer5sliceNtB4_11SliceWriter6finish0Csj9qtwLkMHqH_4sec1
67
0
    }
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6writer5sliceNtB2_11SliceWriter6finishB6_
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6writer5sliceNtB2_11SliceWriter6finishCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvMNtNtCscrZQdumITES_3der6writer5sliceNtB2_11SliceWriter6finishCsj9qtwLkMHqH_4sec1
68
69
    /// Encode a `CONTEXT-SPECIFIC` field with the provided tag number and mode.
70
0
    pub fn context_specific<T>(
71
0
        &mut self,
72
0
        tag_number: TagNumber,
73
0
        tag_mode: TagMode,
74
0
        value: &T,
75
0
    ) -> Result<()>
76
0
    where
77
0
        T: EncodeValue + Tagged,
78
0
    {
79
0
        ContextSpecificRef {
80
0
            tag_number,
81
0
            tag_mode,
82
0
            value,
83
0
        }
84
0
        .encode(self)
85
0
    }
86
87
    /// Encode an ASN.1 `SEQUENCE` of the given length.
88
    ///
89
    /// Spawns a nested slice writer which is expected to be exactly the
90
    /// specified length upon completion.
91
0
    pub fn sequence<F>(&mut self, length: Length, f: F) -> Result<()>
92
0
    where
93
0
        F: FnOnce(&mut SliceWriter<'_>) -> Result<()>,
94
0
    {
95
0
        Header::new(Tag::Sequence, length).and_then(|header| header.encode(self))?;
96
97
0
        let mut nested_encoder = SliceWriter::new(self.reserve(length)?);
98
0
        f(&mut nested_encoder)?;
99
100
0
        if nested_encoder.finish()?.len() == usize::try_from(length)? {
101
0
            Ok(())
102
        } else {
103
0
            self.error(ErrorKind::Length { tag: Tag::Sequence })
104
        }
105
0
    }
106
107
    /// Reserve a portion of the internal buffer, updating the internal cursor
108
    /// position and returning a mutable slice.
109
0
    fn reserve(&mut self, len: impl TryInto<Length>) -> Result<&mut [u8]> {
110
0
        if self.is_failed() {
111
0
            return Err(ErrorKind::Failed.at(self.position));
112
0
        }
113
114
0
        let len = len
115
0
            .try_into()
116
0
            .or_else(|_| self.error(ErrorKind::Overflow))?;
117
118
0
        let end = (self.position + len).or_else(|e| self.error(e.kind()))?;
119
0
        let slice = self
120
0
            .bytes
121
0
            .get_mut(self.position.try_into()?..end.try_into()?)
122
0
            .ok_or_else(|| ErrorKind::Overlength.at(end))?;
123
124
0
        self.position = end;
125
0
        Ok(slice)
126
0
    }
127
}
128
129
impl<'a> Writer for SliceWriter<'a> {
130
0
    fn write(&mut self, slice: &[u8]) -> Result<()> {
131
0
        self.reserve(slice.len())?.copy_from_slice(slice);
132
0
        Ok(())
133
0
    }
134
}
135
136
#[cfg(test)]
137
mod tests {
138
    use super::SliceWriter;
139
    use crate::{Encode, ErrorKind, Length};
140
141
    #[test]
142
    fn overlength_message() {
143
        let mut buffer = [];
144
        let mut writer = SliceWriter::new(&mut buffer);
145
        let err = false.encode(&mut writer).err().unwrap();
146
        assert_eq!(err.kind(), ErrorKind::Overlength);
147
        assert_eq!(err.position(), Some(Length::ONE));
148
    }
149
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/digest-0.10.7/src/core_api/ct_variable.rs
Line
Count
Source
1
use super::{
2
    AlgorithmName, Buffer, BufferKindUser, FixedOutputCore, Reset, TruncSide, UpdateCore,
3
    VariableOutputCore,
4
};
5
use crate::HashMarker;
6
#[cfg(feature = "mac")]
7
use crate::MacMarker;
8
#[cfg(feature = "oid")]
9
use const_oid::{AssociatedOid, ObjectIdentifier};
10
use core::{fmt, marker::PhantomData};
11
use crypto_common::{
12
    generic_array::{ArrayLength, GenericArray},
13
    typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, U256},
14
    Block, BlockSizeUser, OutputSizeUser,
15
};
16
17
/// Dummy type used with [`CtVariableCoreWrapper`] in cases when
18
/// resulting hash does not have a known OID.
19
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
20
pub struct NoOid;
21
22
/// Wrapper around [`VariableOutputCore`] which selects output size
23
/// at compile time.
24
#[derive(Clone)]
25
pub struct CtVariableCoreWrapper<T, OutSize, O = NoOid>
26
where
27
    T: VariableOutputCore,
28
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
29
    LeEq<OutSize, T::OutputSize>: NonZero,
30
    T::BlockSize: IsLess<U256>,
31
    Le<T::BlockSize, U256>: NonZero,
32
{
33
    inner: T,
34
    _out: PhantomData<(OutSize, O)>,
35
}
36
37
impl<T, OutSize, O> HashMarker for CtVariableCoreWrapper<T, OutSize, O>
38
where
39
    T: VariableOutputCore + HashMarker,
40
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
41
    LeEq<OutSize, T::OutputSize>: NonZero,
42
    T::BlockSize: IsLess<U256>,
43
    Le<T::BlockSize, U256>: NonZero,
44
{
45
}
46
47
#[cfg(feature = "mac")]
48
impl<T, OutSize, O> MacMarker for CtVariableCoreWrapper<T, OutSize, O>
49
where
50
    T: VariableOutputCore + MacMarker,
51
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
52
    LeEq<OutSize, T::OutputSize>: NonZero,
53
    T::BlockSize: IsLess<U256>,
54
    Le<T::BlockSize, U256>: NonZero,
55
{
56
}
57
58
impl<T, OutSize, O> BlockSizeUser for CtVariableCoreWrapper<T, OutSize, O>
59
where
60
    T: VariableOutputCore,
61
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
62
    LeEq<OutSize, T::OutputSize>: NonZero,
63
    T::BlockSize: IsLess<U256>,
64
    Le<T::BlockSize, U256>: NonZero,
65
{
66
    type BlockSize = T::BlockSize;
67
}
68
69
impl<T, OutSize, O> UpdateCore for CtVariableCoreWrapper<T, OutSize, O>
70
where
71
    T: VariableOutputCore,
72
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
73
    LeEq<OutSize, T::OutputSize>: NonZero,
74
    T::BlockSize: IsLess<U256>,
75
    Le<T::BlockSize, U256>: NonZero,
76
{
77
    #[inline]
78
10.2k
    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
79
10.2k
        self.inner.update_blocks(blocks);
80
10.2k
    }
Unexecuted instantiation: _RNvXs1_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtB7_10UpdateCore13update_blocksCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs1_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtB7_10UpdateCore13update_blocksCs2IvCg5PL8uK_11chia_traits
_RNvXs1_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtB7_10UpdateCore13update_blocksCs4RkbDk9WRL5_5clvmr
Line
Count
Source
78
10.2k
    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
79
10.2k
        self.inner.update_blocks(blocks);
80
10.2k
    }
Unexecuted instantiation: _RNvXININtNtCsfSiVvAzsu9K_6digest8core_api11ct_variables1_0pppEINtB5_21CtVariableCoreWrapperpppENtB7_10UpdateCore13update_blocksB9_
Unexecuted instantiation: _RNvXs1_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtB7_10UpdateCore13update_blocksCsjewTDwKBbyD_4k256
81
}
82
83
impl<T, OutSize, O> OutputSizeUser for CtVariableCoreWrapper<T, OutSize, O>
84
where
85
    T: VariableOutputCore,
86
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize> + 'static,
87
    LeEq<OutSize, T::OutputSize>: NonZero,
88
    T::BlockSize: IsLess<U256>,
89
    Le<T::BlockSize, U256>: NonZero,
90
{
91
    type OutputSize = OutSize;
92
}
93
94
impl<T, OutSize, O> BufferKindUser for CtVariableCoreWrapper<T, OutSize, O>
95
where
96
    T: VariableOutputCore,
97
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
98
    LeEq<OutSize, T::OutputSize>: NonZero,
99
    T::BlockSize: IsLess<U256>,
100
    Le<T::BlockSize, U256>: NonZero,
101
{
102
    type BufferKind = T::BufferKind;
103
}
104
105
impl<T, OutSize, O> FixedOutputCore for CtVariableCoreWrapper<T, OutSize, O>
106
where
107
    T: VariableOutputCore,
108
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize> + 'static,
109
    LeEq<OutSize, T::OutputSize>: NonZero,
110
    T::BlockSize: IsLess<U256>,
111
    Le<T::BlockSize, U256>: NonZero,
112
{
113
    #[inline]
114
9.60k
    fn finalize_fixed_core(
115
9.60k
        &mut self,
116
9.60k
        buffer: &mut Buffer<Self>,
117
9.60k
        out: &mut GenericArray<u8, Self::OutputSize>,
118
9.60k
    ) {
119
9.60k
        let mut full_res = Default::default();
120
9.60k
        self.inner.finalize_variable_core(buffer, &mut full_res);
121
9.60k
        let n = out.len();
122
9.60k
        let m = full_res.len() - n;
123
9.60k
        match T::TRUNC_SIDE {
124
9.60k
            TruncSide::Left => out.copy_from_slice(&full_res[..n]),
125
0
            TruncSide::Right => out.copy_from_slice(&full_res[m..]),
126
        }
127
9.60k
    }
Unexecuted instantiation: _RNvXs4_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtB7_15FixedOutputCore19finalize_fixed_coreCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs4_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtB7_15FixedOutputCore19finalize_fixed_coreCs2IvCg5PL8uK_11chia_traits
_RNvXs4_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtB7_15FixedOutputCore19finalize_fixed_coreCs4RkbDk9WRL5_5clvmr
Line
Count
Source
114
9.60k
    fn finalize_fixed_core(
115
9.60k
        &mut self,
116
9.60k
        buffer: &mut Buffer<Self>,
117
9.60k
        out: &mut GenericArray<u8, Self::OutputSize>,
118
9.60k
    ) {
119
9.60k
        let mut full_res = Default::default();
120
9.60k
        self.inner.finalize_variable_core(buffer, &mut full_res);
121
9.60k
        let n = out.len();
122
9.60k
        let m = full_res.len() - n;
123
9.60k
        match T::TRUNC_SIDE {
124
9.60k
            TruncSide::Left => out.copy_from_slice(&full_res[..n]),
125
0
            TruncSide::Right => out.copy_from_slice(&full_res[m..]),
126
        }
127
9.60k
    }
Unexecuted instantiation: _RNvXININtNtCsfSiVvAzsu9K_6digest8core_api11ct_variables4_0pppEINtB5_21CtVariableCoreWrapperpppENtB7_15FixedOutputCore19finalize_fixed_coreB9_
Unexecuted instantiation: _RNvXs4_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtB7_15FixedOutputCore19finalize_fixed_coreCsjewTDwKBbyD_4k256
128
}
129
130
impl<T, OutSize, O> Default for CtVariableCoreWrapper<T, OutSize, O>
131
where
132
    T: VariableOutputCore,
133
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
134
    LeEq<OutSize, T::OutputSize>: NonZero,
135
    T::BlockSize: IsLess<U256>,
136
    Le<T::BlockSize, U256>: NonZero,
137
{
138
    #[inline]
139
9.63k
    fn default() -> Self {
140
9.63k
        Self {
141
9.63k
            inner: T::new(OutSize::USIZE).unwrap(),
142
9.63k
            _out: PhantomData,
143
9.63k
        }
144
9.63k
    }
Unexecuted instantiation: _RNvXs5_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs5_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs2IvCg5PL8uK_11chia_traits
_RNvXs5_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs4RkbDk9WRL5_5clvmr
Line
Count
Source
139
9.63k
    fn default() -> Self {
140
9.63k
        Self {
141
9.63k
            inner: T::new(OutSize::USIZE).unwrap(),
142
9.63k
            _out: PhantomData,
143
9.63k
        }
144
9.63k
    }
Unexecuted instantiation: _RNvXININtNtCsfSiVvAzsu9K_6digest8core_api11ct_variables5_0pppEINtB5_21CtVariableCoreWrapperpppENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultB9_
Unexecuted instantiation: _RNvXs5_NtNtCsfSiVvAzsu9K_6digest8core_api11ct_variableINtB5_21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB25_IB25_IB25_IB25_IB25_NtB27_5UTermNtNtB29_3bit2B1ENtB3i_2B0EB3w_EB3w_EB3w_EB3w_ENtB1n_9OidSha256ENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCsjewTDwKBbyD_4k256
145
}
146
147
impl<T, OutSize, O> Reset for CtVariableCoreWrapper<T, OutSize, O>
148
where
149
    T: VariableOutputCore,
150
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
151
    LeEq<OutSize, T::OutputSize>: NonZero,
152
    T::BlockSize: IsLess<U256>,
153
    Le<T::BlockSize, U256>: NonZero,
154
{
155
    #[inline]
156
0
    fn reset(&mut self) {
157
0
        *self = Default::default();
158
0
    }
159
}
160
161
impl<T, OutSize, O> AlgorithmName for CtVariableCoreWrapper<T, OutSize, O>
162
where
163
    T: VariableOutputCore + AlgorithmName,
164
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
165
    LeEq<OutSize, T::OutputSize>: NonZero,
166
    T::BlockSize: IsLess<U256>,
167
    Le<T::BlockSize, U256>: NonZero,
168
{
169
0
    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
170
0
        T::write_alg_name(f)?;
171
0
        f.write_str("_")?;
172
0
        write!(f, "{}", OutSize::USIZE)
173
0
    }
174
}
175
176
#[cfg(feature = "oid")]
177
#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
178
impl<T, OutSize, O> AssociatedOid for CtVariableCoreWrapper<T, OutSize, O>
179
where
180
    T: VariableOutputCore,
181
    O: AssociatedOid,
182
    OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
183
    LeEq<OutSize, T::OutputSize>: NonZero,
184
    T::BlockSize: IsLess<U256>,
185
    Le<T::BlockSize, U256>: NonZero,
186
{
187
    const OID: ObjectIdentifier = O::OID;
188
}
189
190
/// Implement dummy type with hidden docs which is used to "carry" hasher
191
/// OID for [`CtVariableCoreWrapper`].
192
#[macro_export]
193
macro_rules! impl_oid_carrier {
194
    ($name:ident, $oid:literal) => {
195
        #[doc(hidden)]
196
        #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
197
        pub struct $name;
198
199
        #[cfg(feature = "oid")]
200
        impl AssociatedOid for $name {
201
            const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap($oid);
202
        }
203
    };
204
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/digest-0.10.7/src/core_api/rt_variable.rs
Line
Count
Source
1
use super::{AlgorithmName, TruncSide, UpdateCore, VariableOutputCore};
2
#[cfg(feature = "mac")]
3
use crate::MacMarker;
4
use crate::{HashMarker, InvalidBufferSize};
5
use crate::{InvalidOutputSize, Reset, Update, VariableOutput, VariableOutputReset};
6
use block_buffer::BlockBuffer;
7
use core::fmt;
8
use crypto_common::typenum::{IsLess, Le, NonZero, Unsigned, U256};
9
10
/// Wrapper around [`VariableOutputCore`] which selects output size
11
/// at run time.
12
#[derive(Clone)]
13
pub struct RtVariableCoreWrapper<T>
14
where
15
    T: VariableOutputCore + UpdateCore,
16
    T::BlockSize: IsLess<U256>,
17
    Le<T::BlockSize, U256>: NonZero,
18
{
19
    core: T,
20
    buffer: BlockBuffer<T::BlockSize, T::BufferKind>,
21
    output_size: usize,
22
}
23
24
impl<T> RtVariableCoreWrapper<T>
25
where
26
    T: VariableOutputCore,
27
    T::BlockSize: IsLess<U256>,
28
    Le<T::BlockSize, U256>: NonZero,
29
{
30
    #[inline]
31
0
    fn finalize_dirty(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> {
32
0
        let Self {
33
0
            core,
34
0
            buffer,
35
0
            output_size,
36
0
        } = self;
37
0
        if out.len() != *output_size || out.len() > Self::MAX_OUTPUT_SIZE {
38
0
            return Err(InvalidBufferSize);
39
0
        }
40
0
        let mut full_res = Default::default();
41
0
        core.finalize_variable_core(buffer, &mut full_res);
42
0
        let n = out.len();
43
0
        let m = full_res.len() - n;
44
0
        match T::TRUNC_SIDE {
45
0
            TruncSide::Left => out.copy_from_slice(&full_res[..n]),
46
0
            TruncSide::Right => out.copy_from_slice(&full_res[m..]),
47
        }
48
0
        Ok(())
49
0
    }
50
}
51
52
impl<T> HashMarker for RtVariableCoreWrapper<T>
53
where
54
    T: VariableOutputCore + HashMarker,
55
    T::BlockSize: IsLess<U256>,
56
    Le<T::BlockSize, U256>: NonZero,
57
{
58
}
59
60
#[cfg(feature = "mac")]
61
#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
62
impl<T> MacMarker for RtVariableCoreWrapper<T>
63
where
64
    T: VariableOutputCore + MacMarker,
65
    T::BlockSize: IsLess<U256>,
66
    Le<T::BlockSize, U256>: NonZero,
67
{
68
}
69
70
impl<T> Reset for RtVariableCoreWrapper<T>
71
where
72
    T: VariableOutputCore + UpdateCore + Reset,
73
    T::BlockSize: IsLess<U256>,
74
    Le<T::BlockSize, U256>: NonZero,
75
{
76
    #[inline]
77
0
    fn reset(&mut self) {
78
0
        self.buffer.reset();
79
0
        self.core.reset();
80
0
    }
81
}
82
83
impl<T> Update for RtVariableCoreWrapper<T>
84
where
85
    T: VariableOutputCore + UpdateCore,
86
    T::BlockSize: IsLess<U256>,
87
    Le<T::BlockSize, U256>: NonZero,
88
{
89
    #[inline]
90
0
    fn update(&mut self, input: &[u8]) {
91
0
        let Self { core, buffer, .. } = self;
92
0
        buffer.digest_blocks(input, |blocks| core.update_blocks(blocks));
93
0
    }
94
}
95
96
impl<T> VariableOutput for RtVariableCoreWrapper<T>
97
where
98
    T: VariableOutputCore + UpdateCore,
99
    T::BlockSize: IsLess<U256>,
100
    Le<T::BlockSize, U256>: NonZero,
101
{
102
    const MAX_OUTPUT_SIZE: usize = T::OutputSize::USIZE;
103
104
0
    fn new(output_size: usize) -> Result<Self, InvalidOutputSize> {
105
0
        let buffer = Default::default();
106
0
        T::new(output_size).map(|core| Self {
107
0
            core,
108
0
            buffer,
109
0
            output_size,
110
0
        })
111
0
    }
112
113
0
    fn output_size(&self) -> usize {
114
0
        self.output_size
115
0
    }
116
117
0
    fn finalize_variable(mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> {
118
0
        self.finalize_dirty(out)
119
0
    }
120
}
121
122
impl<T> VariableOutputReset for RtVariableCoreWrapper<T>
123
where
124
    T: VariableOutputCore + UpdateCore + Reset,
125
    T::BlockSize: IsLess<U256>,
126
    Le<T::BlockSize, U256>: NonZero,
127
{
128
0
    fn finalize_variable_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> {
129
0
        self.finalize_dirty(out)?;
130
0
        self.core.reset();
131
0
        self.buffer.reset();
132
0
        Ok(())
133
0
    }
134
}
135
136
impl<T> fmt::Debug for RtVariableCoreWrapper<T>
137
where
138
    T: VariableOutputCore + UpdateCore + AlgorithmName,
139
    T::BlockSize: IsLess<U256>,
140
    Le<T::BlockSize, U256>: NonZero,
141
{
142
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
143
0
        T::write_alg_name(f)?;
144
0
        f.write_str(" { .. }")
145
0
    }
146
}
147
148
#[cfg(feature = "std")]
149
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
150
impl<T> std::io::Write for RtVariableCoreWrapper<T>
151
where
152
    T: VariableOutputCore + UpdateCore,
153
    T::BlockSize: IsLess<U256>,
154
    Le<T::BlockSize, U256>: NonZero,
155
{
156
    #[inline]
157
0
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
158
0
        Update::update(self, buf);
159
0
        Ok(buf.len())
160
0
    }
161
162
    #[inline]
163
0
    fn flush(&mut self) -> std::io::Result<()> {
164
0
        Ok(())
165
0
    }
166
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/digest-0.10.7/src/core_api/wrapper.rs
Line
Count
Source
1
use super::{
2
    AlgorithmName, Buffer, BufferKindUser, ExtendableOutputCore, FixedOutputCore, OutputSizeUser,
3
    Reset, UpdateCore, XofReaderCoreWrapper,
4
};
5
use crate::{
6
    ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset, HashMarker, Update,
7
};
8
use block_buffer::BlockBuffer;
9
use core::fmt;
10
use crypto_common::{
11
    typenum::{IsLess, Le, NonZero, U256},
12
    BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output,
13
};
14
15
#[cfg(feature = "mac")]
16
use crate::MacMarker;
17
#[cfg(feature = "oid")]
18
use const_oid::{AssociatedOid, ObjectIdentifier};
19
20
/// Wrapper around [`BufferKindUser`].
21
///
22
/// It handles data buffering and implements the slice-based traits.
23
#[derive(Clone, Default)]
24
pub struct CoreWrapper<T>
25
where
26
    T: BufferKindUser,
27
    T::BlockSize: IsLess<U256>,
28
    Le<T::BlockSize, U256>: NonZero,
29
{
30
    core: T,
31
    buffer: BlockBuffer<T::BlockSize, T::BufferKind>,
32
}
33
34
impl<T> HashMarker for CoreWrapper<T>
35
where
36
    T: BufferKindUser + HashMarker,
37
    T::BlockSize: IsLess<U256>,
38
    Le<T::BlockSize, U256>: NonZero,
39
{
40
}
41
42
#[cfg(feature = "mac")]
43
#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
44
impl<T> MacMarker for CoreWrapper<T>
45
where
46
    T: BufferKindUser + MacMarker,
47
    T::BlockSize: IsLess<U256>,
48
    Le<T::BlockSize, U256>: NonZero,
49
{
50
}
51
52
// this blanket impl is needed for HMAC
53
impl<T> BlockSizeUser for CoreWrapper<T>
54
where
55
    T: BufferKindUser + HashMarker,
56
    T::BlockSize: IsLess<U256>,
57
    Le<T::BlockSize, U256>: NonZero,
58
{
59
    type BlockSize = T::BlockSize;
60
}
61
62
impl<T> CoreWrapper<T>
63
where
64
    T: BufferKindUser,
65
    T::BlockSize: IsLess<U256>,
66
    Le<T::BlockSize, U256>: NonZero,
67
{
68
    /// Create new wrapper from `core`.
69
    #[inline]
70
0
    pub fn from_core(core: T) -> Self {
71
0
        let buffer = Default::default();
72
0
        Self { core, buffer }
73
0
    }
Unexecuted instantiation: _RNvMs1_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIBM_INtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3f_IB3f_IB3f_IB3f_IB3f_NtB3h_5UTermNtNtB3j_3bit2B1ENtB4s_2B0EB4G_EB4G_EB4G_EB4G_ENtB2x_9OidSha256EEEE9from_coreCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs1_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperpE9from_coreB9_
74
75
    /// Decompose wrapper into inner parts.
76
    #[inline]
77
0
    pub fn decompose(self) -> (T, Buffer<T>) {
78
0
        let Self { core, buffer } = self;
79
0
        (core, buffer)
80
0
    }
81
}
82
83
impl<T> KeySizeUser for CoreWrapper<T>
84
where
85
    T: BufferKindUser + KeySizeUser,
86
    T::BlockSize: IsLess<U256>,
87
    Le<T::BlockSize, U256>: NonZero,
88
{
89
    type KeySize = T::KeySize;
90
}
91
92
impl<T> KeyInit for CoreWrapper<T>
93
where
94
    T: BufferKindUser + KeyInit,
95
    T::BlockSize: IsLess<U256>,
96
    Le<T::BlockSize, U256>: NonZero,
97
{
98
    #[inline]
99
0
    fn new(key: &Key<Self>) -> Self {
100
0
        Self {
101
0
            core: T::new(key),
102
0
            buffer: Default::default(),
103
0
        }
104
0
    }
105
106
    #[inline]
107
0
    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
108
0
        Ok(Self {
109
0
            core: T::new_from_slice(key)?,
110
0
            buffer: Default::default(),
111
        })
112
0
    }
Unexecuted instantiation: _RNvXs3_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIBM_INtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3f_IB3f_IB3f_IB3f_IB3f_NtB3h_5UTermNtNtB3j_3bit2B1ENtB4s_2B0EB4G_EB4G_EB4G_EB4G_ENtB2x_9OidSha256EEEENtCslUxhuGmkrsg_13crypto_common7KeyInit14new_from_sliceCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtNtCsfSiVvAzsu9K_6digest8core_api7wrappers3_0pEINtB5_11CoreWrapperpENtCslUxhuGmkrsg_13crypto_common7KeyInit14new_from_sliceB9_
113
}
114
115
impl<T> fmt::Debug for CoreWrapper<T>
116
where
117
    T: BufferKindUser + AlgorithmName,
118
    T::BlockSize: IsLess<U256>,
119
    Le<T::BlockSize, U256>: NonZero,
120
{
121
    #[inline]
122
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
123
0
        T::write_alg_name(f)?;
124
0
        f.write_str(" { .. }")
125
0
    }
126
}
127
128
impl<T> Reset for CoreWrapper<T>
129
where
130
    T: BufferKindUser + Reset,
131
    T::BlockSize: IsLess<U256>,
132
    Le<T::BlockSize, U256>: NonZero,
133
{
134
    #[inline]
135
0
    fn reset(&mut self) {
136
0
        self.core.reset();
137
0
        self.buffer.reset();
138
0
    }
139
}
140
141
impl<T> Update for CoreWrapper<T>
142
where
143
    T: BufferKindUser + UpdateCore,
144
    T::BlockSize: IsLess<U256>,
145
    Le<T::BlockSize, U256>: NonZero,
146
{
147
    #[inline]
148
29.0k
    fn update(&mut self, input: &[u8]) {
149
29.0k
        let Self { core, buffer } = self;
150
29.0k
        buffer.digest_blocks(input, |blocks| core.update_blocks(blocks));
Unexecuted instantiation: _RNCNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB7_11CoreWrapperINtNtB9_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2A_IB2A_IB2A_IB2A_IB2A_NtB2C_5UTermNtNtB2E_3bit2B1ENtB3N_2B0EB41_EB41_EB41_EB41_ENtB1S_9OidSha256EENtBb_6Update6update0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB7_11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIBO_INtNtB9_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3h_IB3h_IB3h_IB3h_IB3h_NtB3j_5UTermNtNtB3l_3bit2B1ENtB4u_2B0EB4I_EB4I_EB4I_EB4I_ENtB2z_9OidSha256EEEENtBb_6Update6update0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB7_11CoreWrapperINtNtB9_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2A_IB2A_IB2A_IB2A_IB2A_NtB2C_5UTermNtNtB2E_3bit2B1ENtB3N_2B0EB41_EB41_EB41_EB41_ENtB1S_9OidSha256EENtBb_6Update6update0Cs2IvCg5PL8uK_11chia_traits
_RNCNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB7_11CoreWrapperINtNtB9_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2A_IB2A_IB2A_IB2A_IB2A_NtB2C_5UTermNtNtB2E_3bit2B1ENtB3N_2B0EB41_EB41_EB41_EB41_ENtB1S_9OidSha256EENtBb_6Update6update0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
150
10.2k
        buffer.digest_blocks(input, |blocks| core.update_blocks(blocks));
Unexecuted instantiation: _RNCNvXININtNtCsfSiVvAzsu9K_6digest8core_api7wrappers6_0pEINtB7_11CoreWrapperpENtBb_6Update6update0Bb_
Unexecuted instantiation: _RNCNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB7_11CoreWrapperINtNtB9_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2A_IB2A_IB2A_IB2A_IB2A_NtB2C_5UTermNtNtB2E_3bit2B1ENtB3N_2B0EB41_EB41_EB41_EB41_ENtB1S_9OidSha256EENtBb_6Update6update0CsjewTDwKBbyD_4k256
151
29.0k
    }
Unexecuted instantiation: _RNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIBM_INtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3f_IB3f_IB3f_IB3f_IB3f_NtB3h_5UTermNtNtB3j_3bit2B1ENtB4s_2B0EB4G_EB4G_EB4G_EB4G_ENtB2x_9OidSha256EEEENtB9_6Update6updateCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2y_IB2y_IB2y_IB2y_IB2y_NtB2A_5UTermNtNtB2C_3bit2B1ENtB3L_2B0EB3Z_EB3Z_EB3Z_EB3Z_ENtB1Q_9OidSha256EENtB9_6Update6updateCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2y_IB2y_IB2y_IB2y_IB2y_NtB2A_5UTermNtNtB2C_3bit2B1ENtB3L_2B0EB3Z_EB3Z_EB3Z_EB3Z_ENtB1Q_9OidSha256EENtB9_6Update6updateCs2IvCg5PL8uK_11chia_traits
_RNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2y_IB2y_IB2y_IB2y_IB2y_NtB2A_5UTermNtNtB2C_3bit2B1ENtB3L_2B0EB3Z_EB3Z_EB3Z_EB3Z_ENtB1Q_9OidSha256EENtB9_6Update6updateCs4RkbDk9WRL5_5clvmr
Line
Count
Source
148
29.0k
    fn update(&mut self, input: &[u8]) {
149
29.0k
        let Self { core, buffer } = self;
150
29.0k
        buffer.digest_blocks(input, |blocks| core.update_blocks(blocks));
151
29.0k
    }
Unexecuted instantiation: _RNvXININtNtCsfSiVvAzsu9K_6digest8core_api7wrappers6_0pEINtB5_11CoreWrapperpENtB9_6Update6updateB9_
Unexecuted instantiation: _RNvXs6_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2y_IB2y_IB2y_IB2y_IB2y_NtB2A_5UTermNtNtB2C_3bit2B1ENtB3L_2B0EB3Z_EB3Z_EB3Z_EB3Z_ENtB1Q_9OidSha256EENtB9_6Update6updateCsjewTDwKBbyD_4k256
152
}
153
154
impl<T> OutputSizeUser for CoreWrapper<T>
155
where
156
    T: BufferKindUser + OutputSizeUser,
157
    T::BlockSize: IsLess<U256>,
158
    Le<T::BlockSize, U256>: NonZero,
159
{
160
    type OutputSize = T::OutputSize;
161
}
162
163
impl<T> FixedOutput for CoreWrapper<T>
164
where
165
    T: FixedOutputCore,
166
    T::BlockSize: IsLess<U256>,
167
    Le<T::BlockSize, U256>: NonZero,
168
{
169
    #[inline]
170
9.60k
    fn finalize_into(mut self, out: &mut Output<Self>) {
171
9.60k
        let Self { core, buffer } = &mut self;
172
9.60k
        core.finalize_fixed_core(buffer, out);
173
9.60k
    }
Unexecuted instantiation: _RNvXs8_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2y_IB2y_IB2y_IB2y_IB2y_NtB2A_5UTermNtNtB2C_3bit2B1ENtB3L_2B0EB3Z_EB3Z_EB3Z_EB3Z_ENtB1Q_9OidSha256EENtB9_11FixedOutput13finalize_intoCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs8_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIBM_INtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3f_IB3f_IB3f_IB3f_IB3f_NtB3h_5UTermNtNtB3j_3bit2B1ENtB4s_2B0EB4G_EB4G_EB4G_EB4G_ENtB2x_9OidSha256EEEENtB9_11FixedOutput13finalize_intoCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs8_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2y_IB2y_IB2y_IB2y_IB2y_NtB2A_5UTermNtNtB2C_3bit2B1ENtB3L_2B0EB3Z_EB3Z_EB3Z_EB3Z_ENtB1Q_9OidSha256EENtB9_11FixedOutput13finalize_intoCs2IvCg5PL8uK_11chia_traits
_RNvXs8_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2y_IB2y_IB2y_IB2y_IB2y_NtB2A_5UTermNtNtB2C_3bit2B1ENtB3L_2B0EB3Z_EB3Z_EB3Z_EB3Z_ENtB1Q_9OidSha256EENtB9_11FixedOutput13finalize_intoCs4RkbDk9WRL5_5clvmr
Line
Count
Source
170
9.60k
    fn finalize_into(mut self, out: &mut Output<Self>) {
171
9.60k
        let Self { core, buffer } = &mut self;
172
9.60k
        core.finalize_fixed_core(buffer, out);
173
9.60k
    }
Unexecuted instantiation: _RNvXININtNtCsfSiVvAzsu9K_6digest8core_api7wrappers8_0pEINtB5_11CoreWrapperpENtB9_11FixedOutput13finalize_intoB9_
Unexecuted instantiation: _RNvXs8_NtNtCsfSiVvAzsu9K_6digest8core_api7wrapperINtB5_11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2y_IB2y_IB2y_IB2y_IB2y_NtB2A_5UTermNtNtB2C_3bit2B1ENtB3L_2B0EB3Z_EB3Z_EB3Z_EB3Z_ENtB1Q_9OidSha256EENtB9_11FixedOutput13finalize_intoCsjewTDwKBbyD_4k256
174
}
175
176
impl<T> FixedOutputReset for CoreWrapper<T>
177
where
178
    T: FixedOutputCore + Reset,
179
    T::BlockSize: IsLess<U256>,
180
    Le<T::BlockSize, U256>: NonZero,
181
{
182
    #[inline]
183
0
    fn finalize_into_reset(&mut self, out: &mut Output<Self>) {
184
0
        let Self { core, buffer } = self;
185
0
        core.finalize_fixed_core(buffer, out);
186
0
        core.reset();
187
0
        buffer.reset();
188
0
    }
189
}
190
191
impl<T> ExtendableOutput for CoreWrapper<T>
192
where
193
    T: ExtendableOutputCore,
194
    T::BlockSize: IsLess<U256>,
195
    Le<T::BlockSize, U256>: NonZero,
196
    <T::ReaderCore as BlockSizeUser>::BlockSize: IsLess<U256>,
197
    Le<<T::ReaderCore as BlockSizeUser>::BlockSize, U256>: NonZero,
198
{
199
    type Reader = XofReaderCoreWrapper<T::ReaderCore>;
200
201
    #[inline]
202
0
    fn finalize_xof(self) -> Self::Reader {
203
0
        let (mut core, mut buffer) = self.decompose();
204
0
        let core = core.finalize_xof_core(&mut buffer);
205
0
        let buffer = Default::default();
206
0
        Self::Reader { core, buffer }
207
0
    }
208
}
209
210
impl<T> ExtendableOutputReset for CoreWrapper<T>
211
where
212
    T: ExtendableOutputCore + Reset,
213
    T::BlockSize: IsLess<U256>,
214
    Le<T::BlockSize, U256>: NonZero,
215
    <T::ReaderCore as BlockSizeUser>::BlockSize: IsLess<U256>,
216
    Le<<T::ReaderCore as BlockSizeUser>::BlockSize, U256>: NonZero,
217
{
218
    #[inline]
219
0
    fn finalize_xof_reset(&mut self) -> Self::Reader {
220
0
        let Self { core, buffer } = self;
221
0
        let reader_core = core.finalize_xof_core(buffer);
222
0
        core.reset();
223
0
        buffer.reset();
224
0
        let buffer = Default::default();
225
0
        Self::Reader {
226
0
            core: reader_core,
227
0
            buffer,
228
0
        }
229
0
    }
230
}
231
232
#[cfg(feature = "oid")]
233
#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
234
impl<T> AssociatedOid for CoreWrapper<T>
235
where
236
    T: BufferKindUser + AssociatedOid,
237
    T::BlockSize: IsLess<U256>,
238
    Le<T::BlockSize, U256>: NonZero,
239
{
240
    const OID: ObjectIdentifier = T::OID;
241
}
242
243
#[cfg(feature = "std")]
244
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
245
impl<T> std::io::Write for CoreWrapper<T>
246
where
247
    T: BufferKindUser + UpdateCore,
248
    T::BlockSize: IsLess<U256>,
249
    Le<T::BlockSize, U256>: NonZero,
250
{
251
    #[inline]
252
0
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
253
0
        Update::update(self, buf);
254
0
        Ok(buf.len())
255
0
    }
256
257
    #[inline]
258
0
    fn flush(&mut self) -> std::io::Result<()> {
259
0
        Ok(())
260
0
    }
261
}
262
263
/// A proxy trait to a core type implemented by [`CoreWrapper`]
264
// TODO: replace with an inherent associated type on stabilization:
265
// https://github.com/rust-lang/rust/issues/8995
266
pub trait CoreProxy: sealed::Sealed {
267
    /// Type wrapped by [`CoreWrapper`].
268
    type Core;
269
}
270
271
mod sealed {
272
    pub trait Sealed {}
273
}
274
275
impl<T> sealed::Sealed for CoreWrapper<T>
276
where
277
    T: BufferKindUser,
278
    T::BlockSize: IsLess<U256>,
279
    Le<T::BlockSize, U256>: NonZero,
280
{
281
}
282
283
impl<T> CoreProxy for CoreWrapper<T>
284
where
285
    T: BufferKindUser,
286
    T::BlockSize: IsLess<U256>,
287
    Le<T::BlockSize, U256>: NonZero,
288
{
289
    type Core = T;
290
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/digest-0.10.7/src/core_api/xof_reader.rs
Line
Count
Source
1
use super::{AlgorithmName, XofReaderCore};
2
use crate::XofReader;
3
use block_buffer::EagerBuffer;
4
use core::fmt;
5
use crypto_common::typenum::{IsLess, Le, NonZero, U256};
6
7
/// Wrapper around [`XofReaderCore`] implementations.
8
///
9
/// It handles data buffering and implements the mid-level traits.
10
#[derive(Clone, Default)]
11
pub struct XofReaderCoreWrapper<T>
12
where
13
    T: XofReaderCore,
14
    T::BlockSize: IsLess<U256>,
15
    Le<T::BlockSize, U256>: NonZero,
16
{
17
    pub(super) core: T,
18
    pub(super) buffer: EagerBuffer<T::BlockSize>,
19
}
20
21
impl<T> fmt::Debug for XofReaderCoreWrapper<T>
22
where
23
    T: XofReaderCore + AlgorithmName,
24
    T::BlockSize: IsLess<U256>,
25
    Le<T::BlockSize, U256>: NonZero,
26
{
27
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
28
0
        T::write_alg_name(f)?;
29
0
        f.write_str(" { .. }")
30
0
    }
31
}
32
33
impl<T> XofReader for XofReaderCoreWrapper<T>
34
where
35
    T: XofReaderCore,
36
    T::BlockSize: IsLess<U256>,
37
    Le<T::BlockSize, U256>: NonZero,
38
{
39
    #[inline]
40
0
    fn read(&mut self, buffer: &mut [u8]) {
41
0
        let Self { core, buffer: buf } = self;
42
0
        buf.set_data(buffer, |blocks| {
43
0
            for block in blocks {
44
0
                *block = core.read_block();
45
0
            }
46
0
        });
47
0
    }
48
}
49
50
#[cfg(feature = "std")]
51
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
52
impl<T> std::io::Read for XofReaderCoreWrapper<T>
53
where
54
    T: XofReaderCore,
55
    T::BlockSize: IsLess<U256>,
56
    Le<T::BlockSize, U256>: NonZero,
57
{
58
    #[inline]
59
0
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
60
0
        XofReader::read(self, buf);
61
0
        Ok(buf.len())
62
0
    }
63
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/digest-0.10.7/src/digest.rs
Line
Count
Source
1
use super::{FixedOutput, FixedOutputReset, InvalidBufferSize, Reset, Update};
2
use crypto_common::{typenum::Unsigned, Output, OutputSizeUser};
3
4
#[cfg(feature = "alloc")]
5
use alloc::boxed::Box;
6
7
/// Marker trait for cryptographic hash functions.
8
pub trait HashMarker {}
9
10
/// Convenience wrapper trait covering functionality of cryptographic hash
11
/// functions with fixed output size.
12
///
13
/// This trait wraps [`Update`], [`FixedOutput`], [`Default`], and
14
/// [`HashMarker`] traits and provides additional convenience methods.
15
pub trait Digest: OutputSizeUser {
16
    /// Create new hasher instance.
17
    fn new() -> Self;
18
19
    /// Create new hasher instance which has processed the provided data.
20
    fn new_with_prefix(data: impl AsRef<[u8]>) -> Self;
21
22
    /// Process data, updating the internal state.
23
    fn update(&mut self, data: impl AsRef<[u8]>);
24
25
    /// Process input data in a chained manner.
26
    #[must_use]
27
    fn chain_update(self, data: impl AsRef<[u8]>) -> Self;
28
29
    /// Retrieve result and consume hasher instance.
30
    fn finalize(self) -> Output<Self>;
31
32
    /// Write result into provided array and consume the hasher instance.
33
    fn finalize_into(self, out: &mut Output<Self>);
34
35
    /// Retrieve result and reset hasher instance.
36
    fn finalize_reset(&mut self) -> Output<Self>
37
    where
38
        Self: FixedOutputReset;
39
40
    /// Write result into provided array and reset the hasher instance.
41
    fn finalize_into_reset(&mut self, out: &mut Output<Self>)
42
    where
43
        Self: FixedOutputReset;
44
45
    /// Reset hasher instance to its initial state.
46
    fn reset(&mut self)
47
    where
48
        Self: Reset;
49
50
    /// Get output size of the hasher
51
    fn output_size() -> usize;
52
53
    /// Compute hash of `data`.
54
    fn digest(data: impl AsRef<[u8]>) -> Output<Self>;
55
}
56
57
impl<D: FixedOutput + Default + Update + HashMarker> Digest for D {
58
    #[inline]
59
0
    fn new() -> Self {
60
0
        Self::default()
61
0
    }
Unexecuted instantiation: _RNvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB4_8core_api7wrapper11CoreWrapperINtNtBB_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2E_IB2E_IB2E_IB2E_IB2E_NtB2G_5UTermNtNtB2I_3bit2B1ENtB3R_2B0EB45_EB45_EB45_EB45_ENtB1W_9OidSha256EENtB2_6Digest3newCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB4_8core_api7wrapper11CoreWrapperINtNtBB_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2E_IB2E_IB2E_IB2E_IB2E_NtB2G_5UTermNtNtB2I_3bit2B1ENtB3R_2B0EB45_EB45_EB45_EB45_ENtB1W_9OidSha256EENtB2_6Digest3newCs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RNvXININtCsfSiVvAzsu9K_6digest6digest0pEpNtB5_6Digest3newB7_
Unexecuted instantiation: _RNvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB4_8core_api7wrapper11CoreWrapperINtNtBB_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2E_IB2E_IB2E_IB2E_IB2E_NtB2G_5UTermNtNtB2I_3bit2B1ENtB3R_2B0EB45_EB45_EB45_EB45_ENtB1W_9OidSha256EENtB2_6Digest3newCsjewTDwKBbyD_4k256
62
63
    #[inline]
64
0
    fn new_with_prefix(data: impl AsRef<[u8]>) -> Self
65
0
    where
66
0
        Self: Default + Sized,
67
0
    {
68
0
        let mut h = Self::default();
69
0
        h.update(data.as_ref());
70
0
        h
71
0
    }
Unexecuted instantiation: _RINvXININtCsfSiVvAzsu9K_6digest6digest0pEpNtB6_6Digest15new_with_prefixpEB8_
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest15new_with_prefixRShECsjewTDwKBbyD_4k256
72
73
    #[inline]
74
29.0k
    fn update(&mut self, data: impl AsRef<[u8]>) {
75
29.0k
        Update::update(self, data.as_ref());
76
29.0k
    }
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateAhj1fe0_ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateAhj20_ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateAhj240_ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateAhj30_ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateAhj4_ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateAhj60_ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateRShECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateAhj1_ECs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateRAhj10_ECs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateRAhj1_ECs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateRAhj2_ECs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateRAhj4_ECs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateRAhj8_ECs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateRShECs2IvCg5PL8uK_11chia_traits
_RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateRShECs4RkbDk9WRL5_5clvmr
Line
Count
Source
74
29.0k
    fn update(&mut self, data: impl AsRef<[u8]>) {
75
29.0k
        Update::update(self, data.as_ref());
76
29.0k
    }
Unexecuted instantiation: _RINvXININtCsfSiVvAzsu9K_6digest6digest0pEpNtB6_6Digest6updatepEB8_
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6updateINtCskVr04X3DebC_13generic_array12GenericArrayhB2E_EECsjewTDwKBbyD_4k256
77
78
    #[inline]
79
0
    fn chain_update(mut self, data: impl AsRef<[u8]>) -> Self {
80
0
        Update::update(&mut self, data.as_ref());
81
0
        self
82
0
    }
Unexecuted instantiation: _RINvXININtCsfSiVvAzsu9K_6digest6digest0pEpNtB6_6Digest12chain_updatepEB8_
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest12chain_updateAhj20_ECsjewTDwKBbyD_4k256
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest12chain_updateINtCskVr04X3DebC_13generic_array12GenericArrayhB2E_EECsjewTDwKBbyD_4k256
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest12chain_updateRAhj20_ECsjewTDwKBbyD_4k256
83
84
    #[inline]
85
9.60k
    fn finalize(self) -> Output<Self> {
86
9.60k
        FixedOutput::finalize_fixed(self)
87
9.60k
    }
Unexecuted instantiation: _RNvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB4_8core_api7wrapper11CoreWrapperINtNtBB_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2E_IB2E_IB2E_IB2E_IB2E_NtB2G_5UTermNtNtB2I_3bit2B1ENtB3R_2B0EB45_EB45_EB45_EB45_ENtB1W_9OidSha256EENtB2_6Digest8finalizeCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB4_8core_api7wrapper11CoreWrapperINtNtBB_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2E_IB2E_IB2E_IB2E_IB2E_NtB2G_5UTermNtNtB2I_3bit2B1ENtB3R_2B0EB45_EB45_EB45_EB45_ENtB1W_9OidSha256EENtB2_6Digest8finalizeCs2IvCg5PL8uK_11chia_traits
_RNvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB4_8core_api7wrapper11CoreWrapperINtNtBB_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2E_IB2E_IB2E_IB2E_IB2E_NtB2G_5UTermNtNtB2I_3bit2B1ENtB3R_2B0EB45_EB45_EB45_EB45_ENtB1W_9OidSha256EENtB2_6Digest8finalizeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
85
9.60k
    fn finalize(self) -> Output<Self> {
86
9.60k
        FixedOutput::finalize_fixed(self)
87
9.60k
    }
Unexecuted instantiation: _RNvXININtCsfSiVvAzsu9K_6digest6digest0pEpNtB5_6Digest8finalizeB7_
Unexecuted instantiation: _RNvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB4_8core_api7wrapper11CoreWrapperINtNtBB_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2E_IB2E_IB2E_IB2E_IB2E_NtB2G_5UTermNtNtB2I_3bit2B1ENtB3R_2B0EB45_EB45_EB45_EB45_ENtB1W_9OidSha256EENtB2_6Digest8finalizeCsjewTDwKBbyD_4k256
88
89
    #[inline]
90
0
    fn finalize_into(self, out: &mut Output<Self>) {
91
0
        FixedOutput::finalize_into(self, out);
92
0
    }
93
94
    #[inline]
95
0
    fn finalize_reset(&mut self) -> Output<Self>
96
0
    where
97
0
        Self: FixedOutputReset,
98
0
    {
99
0
        FixedOutputReset::finalize_fixed_reset(self)
100
0
    }
101
102
    #[inline]
103
0
    fn finalize_into_reset(&mut self, out: &mut Output<Self>)
104
0
    where
105
0
        Self: FixedOutputReset,
106
0
    {
107
0
        FixedOutputReset::finalize_into_reset(self, out);
108
0
    }
109
110
    #[inline]
111
0
    fn reset(&mut self)
112
0
    where
113
0
        Self: Reset,
114
0
    {
115
0
        Reset::reset(self)
116
0
    }
117
118
    #[inline]
119
0
    fn output_size() -> usize {
120
0
        Self::OutputSize::to_usize()
121
0
    }
122
123
    #[inline]
124
0
    fn digest(data: impl AsRef<[u8]>) -> Output<Self> {
125
0
        let mut hasher = Self::default();
126
0
        hasher.update(data.as_ref());
127
0
        hasher.finalize()
128
0
    }
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6digestRShECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXININtCsfSiVvAzsu9K_6digest6digest0pEpNtB6_6Digest6digestpEB8_
Unexecuted instantiation: _RINvXNtCsfSiVvAzsu9K_6digest6digestINtNtNtB5_8core_api7wrapper11CoreWrapperINtNtBC_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2F_IB2F_IB2F_IB2F_IB2F_NtB2H_5UTermNtNtB2J_3bit2B1ENtB3S_2B0EB46_EB46_EB46_EB46_ENtB1X_9OidSha256EENtB3_6Digest6digestRShECsjewTDwKBbyD_4k256
129
}
130
131
/// Modification of the [`Digest`] trait suitable for trait objects.
132
pub trait DynDigest {
133
    /// Digest input data.
134
    ///
135
    /// This method can be called repeatedly for use with streaming messages.
136
    fn update(&mut self, data: &[u8]);
137
138
    /// Retrieve result and reset hasher instance
139
    #[cfg(feature = "alloc")]
140
    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
141
0
    fn finalize_reset(&mut self) -> Box<[u8]> {
142
0
        let mut result = vec![0; self.output_size()];
143
0
        self.finalize_into_reset(&mut result).unwrap();
144
0
        result.into_boxed_slice()
145
0
    }
146
147
    /// Retrieve result and consume boxed hasher instance
148
    #[cfg(feature = "alloc")]
149
    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
150
    #[allow(clippy::boxed_local)]
151
0
    fn finalize(mut self: Box<Self>) -> Box<[u8]> {
152
0
        let mut result = vec![0; self.output_size()];
153
0
        self.finalize_into_reset(&mut result).unwrap();
154
0
        result.into_boxed_slice()
155
0
    }
156
157
    /// Write result into provided array and consume the hasher instance.
158
    ///
159
    /// Returns error if buffer length is not equal to `output_size`.
160
    fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferSize>;
161
162
    /// Write result into provided array and reset the hasher instance.
163
    ///
164
    /// Returns error if buffer length is not equal to `output_size`.
165
    fn finalize_into_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize>;
166
167
    /// Reset hasher instance to its initial state.
168
    fn reset(&mut self);
169
170
    /// Get output size of the hasher
171
    fn output_size(&self) -> usize;
172
173
    /// Clone hasher state into a boxed trait object
174
    #[cfg(feature = "alloc")]
175
    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
176
    fn box_clone(&self) -> Box<dyn DynDigest>;
177
}
178
179
impl<D: Update + FixedOutputReset + Reset + Clone + 'static> DynDigest for D {
180
0
    fn update(&mut self, data: &[u8]) {
181
0
        Update::update(self, data);
182
0
    }
183
184
    #[cfg(feature = "alloc")]
185
0
    fn finalize_reset(&mut self) -> Box<[u8]> {
186
0
        FixedOutputReset::finalize_fixed_reset(self)
187
0
            .to_vec()
188
0
            .into_boxed_slice()
189
0
    }
190
191
    #[cfg(feature = "alloc")]
192
0
    fn finalize(self: Box<Self>) -> Box<[u8]> {
193
0
        FixedOutput::finalize_fixed(*self)
194
0
            .to_vec()
195
0
            .into_boxed_slice()
196
0
    }
197
198
0
    fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferSize> {
199
0
        if buf.len() == self.output_size() {
200
0
            FixedOutput::finalize_into(self, Output::<Self>::from_mut_slice(buf));
201
0
            Ok(())
202
        } else {
203
0
            Err(InvalidBufferSize)
204
        }
205
0
    }
206
207
0
    fn finalize_into_reset(&mut self, buf: &mut [u8]) -> Result<(), InvalidBufferSize> {
208
0
        if buf.len() == self.output_size() {
209
0
            FixedOutputReset::finalize_into_reset(self, Output::<Self>::from_mut_slice(buf));
210
0
            Ok(())
211
        } else {
212
0
            Err(InvalidBufferSize)
213
        }
214
0
    }
215
216
0
    fn reset(&mut self) {
217
0
        Reset::reset(self);
218
0
    }
219
220
0
    fn output_size(&self) -> usize {
221
0
        <Self as OutputSizeUser>::OutputSize::to_usize()
222
0
    }
223
224
    #[cfg(feature = "alloc")]
225
0
    fn box_clone(&self) -> Box<dyn DynDigest> {
226
0
        Box::new(self.clone())
227
0
    }
228
}
229
230
#[cfg(feature = "alloc")]
231
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
232
impl Clone for Box<dyn DynDigest> {
233
0
    fn clone(&self) -> Self {
234
0
        self.box_clone()
235
0
    }
236
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/digest-0.10.7/src/lib.rs
Line
Count
Source
1
//! This crate provides traits which describe functionality of cryptographic hash
2
//! functions and Message Authentication algorithms.
3
//!
4
//! Traits in this repository are organized into the following levels:
5
//!
6
//! - **High-level convenience traits**: [`Digest`], [`DynDigest`], [`Mac`].
7
//!   Wrappers around lower-level traits for most common use-cases. Users should
8
//!   usually prefer using these traits.
9
//! - **Mid-level traits**: [`Update`], [`FixedOutput`], [`FixedOutputReset`],
10
//!   [`ExtendableOutput`], [`ExtendableOutputReset`], [`XofReader`],
11
//!   [`VariableOutput`], [`Reset`], [`KeyInit`], and [`InnerInit`]. These
12
//!   traits atomically describe available functionality of an algorithm.
13
//! - **Marker traits**: [`HashMarker`], [`MacMarker`]. Used to distinguish
14
//!   different algorithm classes.
15
//! - **Low-level traits** defined in the [`core_api`] module. These traits
16
//!   operate at a block-level and do not contain any built-in buffering.
17
//!   They are intended to be implemented by low-level algorithm providers only.
18
//!   Usually they should not be used in application-level code.
19
//!
20
//! Additionally hash functions implement traits from the standard library:
21
//! [`Default`], [`Clone`], [`Write`][std::io::Write]. The latter is
22
//! feature-gated behind `std` feature, which is usually enabled by default
23
//! by hash implementation crates.
24
25
#![no_std]
26
#![cfg_attr(docsrs, feature(doc_cfg))]
27
#![forbid(unsafe_code)]
28
#![doc(
29
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
30
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
31
)]
32
#![warn(missing_docs, rust_2018_idioms)]
33
34
#[cfg(feature = "alloc")]
35
#[macro_use]
36
extern crate alloc;
37
38
#[cfg(feature = "std")]
39
extern crate std;
40
41
#[cfg(feature = "rand_core")]
42
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
43
pub use crypto_common::rand_core;
44
45
#[cfg(feature = "alloc")]
46
use alloc::boxed::Box;
47
48
#[cfg(feature = "dev")]
49
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
50
pub mod dev;
51
52
#[cfg(feature = "core-api")]
53
#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))]
54
pub mod core_api;
55
mod digest;
56
#[cfg(feature = "mac")]
57
mod mac;
58
59
#[cfg(feature = "core-api")]
60
#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))]
61
pub use block_buffer;
62
#[cfg(feature = "oid")]
63
#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
64
pub use const_oid;
65
pub use crypto_common;
66
67
pub use crate::digest::{Digest, DynDigest, HashMarker};
68
pub use crypto_common::{generic_array, typenum, typenum::consts, Output, OutputSizeUser, Reset};
69
#[cfg(feature = "mac")]
70
pub use crypto_common::{InnerInit, InvalidLength, Key, KeyInit};
71
#[cfg(feature = "mac")]
72
pub use mac::{CtOutput, Mac, MacError, MacMarker};
73
74
use core::fmt;
75
76
/// Types which consume data with byte granularity.
77
pub trait Update {
78
    /// Update state using the provided data.
79
    fn update(&mut self, data: &[u8]);
80
81
    /// Digest input data in a chained manner.
82
    #[must_use]
83
0
    fn chain(mut self, data: impl AsRef<[u8]>) -> Self
84
0
    where
85
0
        Self: Sized,
86
0
    {
87
0
        self.update(data.as_ref());
88
0
        self
89
0
    }
90
}
91
92
/// Trait for hash functions with fixed-size output.
93
pub trait FixedOutput: Update + OutputSizeUser + Sized {
94
    /// Consume value and write result into provided array.
95
    fn finalize_into(self, out: &mut Output<Self>);
96
97
    /// Retrieve result and consume the hasher instance.
98
    #[inline]
99
9.60k
    fn finalize_fixed(self) -> Output<Self> {
100
9.60k
        let mut out = Default::default();
101
9.60k
        self.finalize_into(&mut out);
102
9.60k
        out
103
9.60k
    }
Unexecuted instantiation: _RNvYINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2s_IB2s_IB2s_IB2s_IB2s_NtB2u_5UTermNtNtB2w_3bit2B1ENtB3F_2B0EB3T_EB3T_EB3T_EB3T_ENtB1K_9OidSha256EENtB9_11FixedOutput14finalize_fixedCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvYINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIB3_INtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB39_IB39_IB39_IB39_IB39_NtB3b_5UTermNtNtB3d_3bit2B1ENtB4m_2B0EB4A_EB4A_EB4A_EB4A_ENtB2r_9OidSha256EEEENtB9_11FixedOutput14finalize_fixedCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvYINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2s_IB2s_IB2s_IB2s_IB2s_NtB2u_5UTermNtNtB2w_3bit2B1ENtB3F_2B0EB3T_EB3T_EB3T_EB3T_ENtB1K_9OidSha256EENtB9_11FixedOutput14finalize_fixedCs2IvCg5PL8uK_11chia_traits
_RNvYINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2s_IB2s_IB2s_IB2s_IB2s_NtB2u_5UTermNtNtB2w_3bit2B1ENtB3F_2B0EB3T_EB3T_EB3T_EB3T_ENtB1K_9OidSha256EENtB9_11FixedOutput14finalize_fixedCs4RkbDk9WRL5_5clvmr
Line
Count
Source
99
9.60k
    fn finalize_fixed(self) -> Output<Self> {
100
9.60k
        let mut out = Default::default();
101
9.60k
        self.finalize_into(&mut out);
102
9.60k
        out
103
9.60k
    }
Unexecuted instantiation: _RNvYpNtCsfSiVvAzsu9K_6digest11FixedOutput14finalize_fixedB5_
Unexecuted instantiation: _RNvYINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtB7_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2s_IB2s_IB2s_IB2s_IB2s_NtB2u_5UTermNtNtB2w_3bit2B1ENtB3F_2B0EB3T_EB3T_EB3T_EB3T_ENtB1K_9OidSha256EENtB9_11FixedOutput14finalize_fixedCsjewTDwKBbyD_4k256
104
}
105
106
/// Trait for hash functions with fixed-size output able to reset themselves.
107
pub trait FixedOutputReset: FixedOutput + Reset {
108
    /// Write result into provided array and reset the hasher state.
109
    fn finalize_into_reset(&mut self, out: &mut Output<Self>);
110
111
    /// Retrieve result and reset the hasher state.
112
    #[inline]
113
0
    fn finalize_fixed_reset(&mut self) -> Output<Self> {
114
0
        let mut out = Default::default();
115
0
        self.finalize_into_reset(&mut out);
116
0
        out
117
0
    }
118
}
119
120
/// Trait for reader types which are used to extract extendable output
121
/// from a XOF (extendable-output function) result.
122
pub trait XofReader {
123
    /// Read output into the `buffer`. Can be called an unlimited number of times.
124
    fn read(&mut self, buffer: &mut [u8]);
125
126
    /// Read output into a boxed slice of the specified size.
127
    ///
128
    /// Can be called an unlimited number of times in combination with `read`.
129
    ///
130
    /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
131
    /// they have size of 2 and 3 words respectively.
132
    #[cfg(feature = "alloc")]
133
    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
134
0
    fn read_boxed(&mut self, n: usize) -> Box<[u8]> {
135
0
        let mut buf = vec![0u8; n].into_boxed_slice();
136
0
        self.read(&mut buf);
137
0
        buf
138
0
    }
139
}
140
141
/// Trait for hash functions with extendable-output (XOF).
142
pub trait ExtendableOutput: Sized + Update {
143
    /// Reader
144
    type Reader: XofReader;
145
146
    /// Retrieve XOF reader and consume hasher instance.
147
    fn finalize_xof(self) -> Self::Reader;
148
149
    /// Finalize XOF and write result into `out`.
150
0
    fn finalize_xof_into(self, out: &mut [u8]) {
151
0
        self.finalize_xof().read(out);
152
0
    }
153
154
    /// Compute hash of `data` and write it into `output`.
155
0
    fn digest_xof(input: impl AsRef<[u8]>, output: &mut [u8])
156
0
    where
157
0
        Self: Default,
158
0
    {
159
0
        let mut hasher = Self::default();
160
0
        hasher.update(input.as_ref());
161
0
        hasher.finalize_xof().read(output);
162
0
    }
163
164
    /// Retrieve result into a boxed slice of the specified size and consume
165
    /// the hasher.
166
    ///
167
    /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
168
    /// they have size of 2 and 3 words respectively.
169
    #[cfg(feature = "alloc")]
170
    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
171
0
    fn finalize_boxed(self, output_size: usize) -> Box<[u8]> {
172
0
        let mut buf = vec![0u8; output_size].into_boxed_slice();
173
0
        self.finalize_xof().read(&mut buf);
174
0
        buf
175
0
    }
176
}
177
178
/// Trait for hash functions with extendable-output (XOF) able to reset themselves.
179
pub trait ExtendableOutputReset: ExtendableOutput + Reset {
180
    /// Retrieve XOF reader and reset hasher instance state.
181
    fn finalize_xof_reset(&mut self) -> Self::Reader;
182
183
    /// Finalize XOF, write result into `out`, and reset the hasher state.
184
0
    fn finalize_xof_reset_into(&mut self, out: &mut [u8]) {
185
0
        self.finalize_xof_reset().read(out);
186
0
    }
187
188
    /// Retrieve result into a boxed slice of the specified size and reset
189
    /// the hasher state.
190
    ///
191
    /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
192
    /// they have size of 2 and 3 words respectively.
193
    #[cfg(feature = "alloc")]
194
    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
195
0
    fn finalize_boxed_reset(&mut self, output_size: usize) -> Box<[u8]> {
196
0
        let mut buf = vec![0u8; output_size].into_boxed_slice();
197
0
        self.finalize_xof_reset().read(&mut buf);
198
0
        buf
199
0
    }
200
}
201
202
/// Trait for hash functions with variable-size output.
203
pub trait VariableOutput: Sized + Update {
204
    /// Maximum size of output hash.
205
    const MAX_OUTPUT_SIZE: usize;
206
207
    /// Create new hasher instance with the given output size.
208
    ///
209
    /// It will return `Err(InvalidOutputSize)` in case if hasher can not return
210
    /// hash of the specified output size.
211
    fn new(output_size: usize) -> Result<Self, InvalidOutputSize>;
212
213
    /// Get output size of the hasher instance provided to the `new` method
214
    fn output_size(&self) -> usize;
215
216
    /// Write result into the output buffer.
217
    ///
218
    /// Returns `Err(InvalidOutputSize)` if `out` size is not equal to
219
    /// `self.output_size()`.
220
    fn finalize_variable(self, out: &mut [u8]) -> Result<(), InvalidBufferSize>;
221
222
    /// Compute hash of `data` and write it to `output`.
223
    ///
224
    /// Length of the output hash is determined by `output`. If `output` is
225
    /// bigger than `Self::MAX_OUTPUT_SIZE`, this method returns
226
    /// `InvalidOutputSize`.
227
0
    fn digest_variable(
228
0
        input: impl AsRef<[u8]>,
229
0
        output: &mut [u8],
230
0
    ) -> Result<(), InvalidOutputSize> {
231
0
        let mut hasher = Self::new(output.len())?;
232
0
        hasher.update(input.as_ref());
233
0
        hasher
234
0
            .finalize_variable(output)
235
0
            .map_err(|_| InvalidOutputSize)
236
0
    }
237
238
    /// Retrieve result into a boxed slice and consume hasher.
239
    ///
240
    /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
241
    /// they have size of 2 and 3 words respectively.
242
    #[cfg(feature = "alloc")]
243
    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
244
0
    fn finalize_boxed(self) -> Box<[u8]> {
245
0
        let n = self.output_size();
246
0
        let mut buf = vec![0u8; n].into_boxed_slice();
247
0
        self.finalize_variable(&mut buf)
248
0
            .expect("buf length is equal to output_size");
249
0
        buf
250
0
    }
251
}
252
253
/// Trait for hash functions with variable-size output able to reset themselves.
254
pub trait VariableOutputReset: VariableOutput + Reset {
255
    /// Write result into the output buffer and reset the hasher state.
256
    ///
257
    /// Returns `Err(InvalidOutputSize)` if `out` size is not equal to
258
    /// `self.output_size()`.
259
    fn finalize_variable_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize>;
260
261
    /// Retrieve result into a boxed slice and reset the hasher state.
262
    ///
263
    /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
264
    /// they have size of 2 and 3 words respectively.
265
    #[cfg(feature = "alloc")]
266
    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
267
0
    fn finalize_boxed_reset(&mut self) -> Box<[u8]> {
268
0
        let n = self.output_size();
269
0
        let mut buf = vec![0u8; n].into_boxed_slice();
270
0
        self.finalize_variable_reset(&mut buf)
271
0
            .expect("buf length is equal to output_size");
272
0
        buf
273
0
    }
274
}
275
276
/// The error type used in variable hash traits.
277
#[derive(Clone, Copy, Debug, Default)]
278
pub struct InvalidOutputSize;
279
280
impl fmt::Display for InvalidOutputSize {
281
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282
0
        f.write_str("invalid output size")
283
0
    }
284
}
285
286
#[cfg(feature = "std")]
287
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
288
impl std::error::Error for InvalidOutputSize {}
289
290
/// Buffer length is not equal to hash output size.
291
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
292
pub struct InvalidBufferSize;
293
294
impl fmt::Display for InvalidBufferSize {
295
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
296
0
        f.write_str("invalid buffer length")
297
0
    }
298
}
299
300
#[cfg(feature = "std")]
301
impl std::error::Error for InvalidBufferSize {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/digest-0.10.7/src/mac.rs
Line
Count
Source
1
use crate::{FixedOutput, FixedOutputReset, Update};
2
use crypto_common::{InvalidLength, Key, KeyInit, Output, OutputSizeUser, Reset};
3
4
#[cfg(feature = "rand_core")]
5
use crate::rand_core::{CryptoRng, RngCore};
6
use core::fmt;
7
use crypto_common::typenum::Unsigned;
8
use subtle::{Choice, ConstantTimeEq};
9
10
/// Marker trait for Message Authentication algorithms.
11
#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
12
pub trait MacMarker {}
13
14
/// Convenience wrapper trait covering functionality of Message Authentication algorithms.
15
///
16
/// This trait wraps [`KeyInit`], [`Update`], [`FixedOutput`], and [`MacMarker`]
17
/// traits and provides additional convenience methods.
18
#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
19
pub trait Mac: OutputSizeUser + Sized {
20
    /// Create new value from fixed size key.
21
    fn new(key: &Key<Self>) -> Self
22
    where
23
        Self: KeyInit;
24
25
    /// Generate random key using the provided [`CryptoRng`].
26
    #[cfg(feature = "rand_core")]
27
    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
28
    fn generate_key(rng: impl CryptoRng + RngCore) -> Key<Self>
29
    where
30
        Self: KeyInit;
31
32
    /// Create new value from variable size key.
33
    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength>
34
    where
35
        Self: KeyInit;
36
37
    /// Update state using the provided data.
38
    fn update(&mut self, data: &[u8]);
39
40
    /// Process input data in a chained manner.
41
    #[must_use]
42
    fn chain_update(self, data: impl AsRef<[u8]>) -> Self;
43
44
    /// Obtain the result of a [`Mac`] computation as a [`CtOutput`] and consume
45
    /// [`Mac`] instance.
46
    fn finalize(self) -> CtOutput<Self>;
47
48
    /// Obtain the result of a [`Mac`] computation as a [`CtOutput`] and reset
49
    /// [`Mac`] instance.
50
    fn finalize_reset(&mut self) -> CtOutput<Self>
51
    where
52
        Self: FixedOutputReset;
53
54
    /// Reset MAC instance to its initial state.
55
    fn reset(&mut self)
56
    where
57
        Self: Reset;
58
59
    /// Check if tag/code value is correct for the processed input.
60
    fn verify(self, tag: &Output<Self>) -> Result<(), MacError>;
61
62
    /// Check if tag/code value is correct for the processed input and reset
63
    /// [`Mac`] instance.
64
    fn verify_reset(&mut self, tag: &Output<Self>) -> Result<(), MacError>
65
    where
66
        Self: FixedOutputReset;
67
68
    /// Check truncated tag correctness using all bytes
69
    /// of calculated tag.
70
    ///
71
    /// Returns `Error` if `tag` is not valid or not equal in length
72
    /// to MAC's output.
73
    fn verify_slice(self, tag: &[u8]) -> Result<(), MacError>;
74
75
    /// Check truncated tag correctness using all bytes
76
    /// of calculated tag and reset [`Mac`] instance.
77
    ///
78
    /// Returns `Error` if `tag` is not valid or not equal in length
79
    /// to MAC's output.
80
    fn verify_slice_reset(&mut self, tag: &[u8]) -> Result<(), MacError>
81
    where
82
        Self: FixedOutputReset;
83
84
    /// Check truncated tag correctness using left side bytes
85
    /// (i.e. `tag[..n]`) of calculated tag.
86
    ///
87
    /// Returns `Error` if `tag` is not valid or empty.
88
    fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError>;
89
90
    /// Check truncated tag correctness using right side bytes
91
    /// (i.e. `tag[n..]`) of calculated tag.
92
    ///
93
    /// Returns `Error` if `tag` is not valid or empty.
94
    fn verify_truncated_right(self, tag: &[u8]) -> Result<(), MacError>;
95
}
96
97
impl<T: Update + FixedOutput + MacMarker> Mac for T {
98
    #[inline(always)]
99
0
    fn new(key: &Key<Self>) -> Self
100
0
    where
101
0
        Self: KeyInit,
102
0
    {
103
0
        KeyInit::new(key)
104
0
    }
105
106
    #[inline(always)]
107
0
    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength>
108
0
    where
109
0
        Self: KeyInit,
110
0
    {
111
0
        KeyInit::new_from_slice(key)
112
0
    }
113
114
    #[inline]
115
0
    fn update(&mut self, data: &[u8]) {
116
0
        Update::update(self, data);
117
0
    }
118
119
    #[inline]
120
0
    fn chain_update(mut self, data: impl AsRef<[u8]>) -> Self {
121
0
        Update::update(&mut self, data.as_ref());
122
0
        self
123
0
    }
124
125
    #[inline]
126
0
    fn finalize(self) -> CtOutput<Self> {
127
0
        CtOutput::new(self.finalize_fixed())
128
0
    }
129
130
    #[inline(always)]
131
0
    fn finalize_reset(&mut self) -> CtOutput<Self>
132
0
    where
133
0
        Self: FixedOutputReset,
134
0
    {
135
0
        CtOutput::new(self.finalize_fixed_reset())
136
0
    }
137
138
    #[inline]
139
0
    fn reset(&mut self)
140
0
    where
141
0
        Self: Reset,
142
0
    {
143
0
        Reset::reset(self)
144
0
    }
145
146
    #[inline]
147
0
    fn verify(self, tag: &Output<Self>) -> Result<(), MacError> {
148
0
        if self.finalize() == tag.into() {
149
0
            Ok(())
150
        } else {
151
0
            Err(MacError)
152
        }
153
0
    }
154
155
    #[inline]
156
0
    fn verify_reset(&mut self, tag: &Output<Self>) -> Result<(), MacError>
157
0
    where
158
0
        Self: FixedOutputReset,
159
0
    {
160
0
        if self.finalize_reset() == tag.into() {
161
0
            Ok(())
162
        } else {
163
0
            Err(MacError)
164
        }
165
0
    }
166
167
    #[inline]
168
0
    fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> {
169
0
        let n = tag.len();
170
0
        if n != Self::OutputSize::USIZE {
171
0
            return Err(MacError);
172
0
        }
173
0
        let choice = self.finalize_fixed().ct_eq(tag);
174
0
        if choice.into() {
175
0
            Ok(())
176
        } else {
177
0
            Err(MacError)
178
        }
179
0
    }
180
181
    #[inline]
182
0
    fn verify_slice_reset(&mut self, tag: &[u8]) -> Result<(), MacError>
183
0
    where
184
0
        Self: FixedOutputReset,
185
0
    {
186
0
        let n = tag.len();
187
0
        if n != Self::OutputSize::USIZE {
188
0
            return Err(MacError);
189
0
        }
190
0
        let choice = self.finalize_fixed_reset().ct_eq(tag);
191
0
        if choice.into() {
192
0
            Ok(())
193
        } else {
194
0
            Err(MacError)
195
        }
196
0
    }
197
198
0
    fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> {
199
0
        let n = tag.len();
200
0
        if n == 0 || n > Self::OutputSize::USIZE {
201
0
            return Err(MacError);
202
0
        }
203
0
        let choice = self.finalize_fixed()[..n].ct_eq(tag);
204
0
205
0
        if choice.into() {
206
0
            Ok(())
207
        } else {
208
0
            Err(MacError)
209
        }
210
0
    }
211
212
0
    fn verify_truncated_right(self, tag: &[u8]) -> Result<(), MacError> {
213
0
        let n = tag.len();
214
0
        if n == 0 || n > Self::OutputSize::USIZE {
215
0
            return Err(MacError);
216
0
        }
217
0
        let m = Self::OutputSize::USIZE - n;
218
0
        let choice = self.finalize_fixed()[m..].ct_eq(tag);
219
0
220
0
        if choice.into() {
221
0
            Ok(())
222
        } else {
223
0
            Err(MacError)
224
        }
225
0
    }
226
227
    #[cfg(feature = "rand_core")]
228
    #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
229
    #[inline]
230
    fn generate_key(rng: impl CryptoRng + RngCore) -> Key<Self>
231
    where
232
        Self: KeyInit,
233
    {
234
        <T as KeyInit>::generate_key(rng)
235
    }
236
}
237
238
/// Fixed size output value which provides a safe [`Eq`] implementation that
239
/// runs in constant time.
240
///
241
/// It is useful for implementing Message Authentication Codes (MACs).
242
#[derive(Clone)]
243
#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
244
pub struct CtOutput<T: OutputSizeUser> {
245
    bytes: Output<T>,
246
}
247
248
impl<T: OutputSizeUser> CtOutput<T> {
249
    /// Create a new [`CtOutput`] value.
250
    #[inline(always)]
251
0
    pub fn new(bytes: Output<T>) -> Self {
252
0
        Self { bytes }
253
0
    }
254
255
    /// Get the inner [`Output`] array this type wraps.
256
    #[inline(always)]
257
0
    pub fn into_bytes(self) -> Output<T> {
258
0
        self.bytes
259
0
    }
260
}
261
262
impl<T: OutputSizeUser> From<Output<T>> for CtOutput<T> {
263
    #[inline(always)]
264
0
    fn from(bytes: Output<T>) -> Self {
265
0
        Self { bytes }
266
0
    }
267
}
268
269
impl<'a, T: OutputSizeUser> From<&'a Output<T>> for CtOutput<T> {
270
    #[inline(always)]
271
0
    fn from(bytes: &'a Output<T>) -> Self {
272
0
        bytes.clone().into()
273
0
    }
274
}
275
276
impl<T: OutputSizeUser> ConstantTimeEq for CtOutput<T> {
277
    #[inline(always)]
278
0
    fn ct_eq(&self, other: &Self) -> Choice {
279
0
        self.bytes.ct_eq(&other.bytes)
280
0
    }
281
}
282
283
impl<T: OutputSizeUser> PartialEq for CtOutput<T> {
284
    #[inline(always)]
285
0
    fn eq(&self, x: &CtOutput<T>) -> bool {
286
0
        self.ct_eq(x).into()
287
0
    }
288
}
289
290
impl<T: OutputSizeUser> Eq for CtOutput<T> {}
291
292
/// Error type for when the [`Output`] of a [`Mac`]
293
/// is not equal to the expected value.
294
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
295
#[cfg_attr(docsrs, doc(cfg(feature = "mac")))]
296
pub struct MacError;
297
298
impl fmt::Display for MacError {
299
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
300
0
        f.write_str("MAC tag mismatch")
301
0
    }
302
}
303
304
#[cfg(feature = "std")]
305
impl std::error::Error for MacError {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ecdsa-0.16.9/src/der.rs
Line
Count
Source
1
//! Support for ASN.1 DER-encoded ECDSA signatures as specified in
2
//! [RFC5912 Appendix A].
3
//!
4
//! [RFC5912 Appendix A]: https://www.rfc-editor.org/rfc/rfc5912#appendix-A
5
6
use crate::{Error, Result};
7
use core::{
8
    fmt::{self, Debug},
9
    ops::{Add, Range},
10
};
11
use der::{asn1::UintRef, Decode, Encode, FixedTag, Length, Reader, Tag, Writer};
12
use elliptic_curve::{
13
    consts::U9,
14
    generic_array::{typenum::Unsigned, ArrayLength, GenericArray},
15
    FieldBytesSize, PrimeCurve,
16
};
17
18
#[cfg(feature = "alloc")]
19
use {
20
    alloc::{boxed::Box, vec::Vec},
21
    signature::SignatureEncoding,
22
    spki::{der::asn1::BitString, SignatureBitStringEncoding},
23
};
24
25
#[cfg(feature = "serde")]
26
use serdect::serde::{de, ser, Deserialize, Serialize};
27
28
/// Maximum overhead of an ASN.1 DER-encoded ECDSA signature for a given curve:
29
/// 9-bytes.
30
///
31
/// Includes 3-byte ASN.1 DER header:
32
///
33
/// - 1-byte: ASN.1 `SEQUENCE` tag (0x30)
34
/// - 2-byte: length
35
///
36
/// ...followed by two ASN.1 `INTEGER` values, which each have a header whose
37
/// maximum length is the following:
38
///
39
/// - 1-byte: ASN.1 `INTEGER` tag (0x02)
40
/// - 1-byte: length
41
/// - 1-byte: zero to indicate value is positive (`INTEGER` is signed)
42
pub type MaxOverhead = U9;
43
44
/// Maximum size of an ASN.1 DER encoded signature for the given elliptic curve.
45
pub type MaxSize<C> = <<FieldBytesSize<C> as Add>::Output as Add<MaxOverhead>>::Output;
46
47
/// Byte array containing a serialized ASN.1 signature
48
type SignatureBytes<C> = GenericArray<u8, MaxSize<C>>;
49
50
/// ASN.1 DER-encoded signature as specified in [RFC5912 Appendix A]:
51
///
52
/// ```text
53
/// ECDSA-Sig-Value ::= SEQUENCE {
54
///   r  INTEGER,
55
///   s  INTEGER
56
/// }
57
/// ```
58
///
59
/// [RFC5912 Appendix A]: https://www.rfc-editor.org/rfc/rfc5912#appendix-A
60
pub struct Signature<C>
61
where
62
    C: PrimeCurve,
63
    MaxSize<C>: ArrayLength<u8>,
64
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
65
{
66
    /// ASN.1 DER-encoded signature data
67
    bytes: SignatureBytes<C>,
68
69
    /// Range of the `r` value within the signature
70
    r_range: Range<usize>,
71
72
    /// Range of the `s` value within the signature
73
    s_range: Range<usize>,
74
}
75
76
#[allow(clippy::len_without_is_empty)]
77
impl<C> Signature<C>
78
where
79
    C: PrimeCurve,
80
    MaxSize<C>: ArrayLength<u8>,
81
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
82
{
83
    /// Parse signature from DER-encoded bytes.
84
0
    pub fn from_bytes(input: &[u8]) -> Result<Self> {
85
0
        let (r, s) = decode_der(input).map_err(|_| Error::new())?;
86
87
0
        if r.as_bytes().len() > C::FieldBytesSize::USIZE
88
0
            || s.as_bytes().len() > C::FieldBytesSize::USIZE
89
        {
90
0
            return Err(Error::new());
91
0
        }
92
93
0
        let r_range = find_scalar_range(input, r.as_bytes())?;
94
0
        let s_range = find_scalar_range(input, s.as_bytes())?;
95
96
0
        if s_range.end != input.len() {
97
0
            return Err(Error::new());
98
0
        }
99
0
100
0
        let mut bytes = SignatureBytes::<C>::default();
101
0
        bytes[..s_range.end].copy_from_slice(input);
102
0
103
0
        Ok(Signature {
104
0
            bytes,
105
0
            r_range,
106
0
            s_range,
107
0
        })
108
0
    }
109
110
    /// Create an ASN.1 DER encoded signature from big endian `r` and `s` scalar
111
    /// components.
112
0
    pub(crate) fn from_components(r: &[u8], s: &[u8]) -> der::Result<Self> {
113
0
        let r = UintRef::new(r)?;
114
0
        let s = UintRef::new(s)?;
115
116
0
        let mut bytes = SignatureBytes::<C>::default();
117
0
        let mut writer = der::SliceWriter::new(&mut bytes);
118
0
119
0
        writer.sequence((r.encoded_len()? + s.encoded_len()?)?, |seq| {
120
0
            seq.encode(&r)?;
121
0
            seq.encode(&s)
122
0
        })?;
123
124
0
        writer
125
0
            .finish()?
126
0
            .try_into()
127
0
            .map_err(|_| der::Tag::Sequence.value_error())
128
0
    }
129
130
    /// Borrow this signature as a byte slice
131
0
    pub fn as_bytes(&self) -> &[u8] {
132
0
        &self.bytes.as_slice()[..self.len()]
133
0
    }
134
135
    /// Serialize this signature as a boxed byte slice
136
    #[cfg(feature = "alloc")]
137
0
    pub fn to_bytes(&self) -> Box<[u8]> {
138
0
        self.as_bytes().to_vec().into_boxed_slice()
139
0
    }
140
141
    /// Get the length of the signature in bytes
142
0
    pub fn len(&self) -> usize {
143
0
        self.s_range.end
144
0
    }
145
146
    /// Get the `r` component of the signature (leading zeros removed)
147
0
    pub(crate) fn r(&self) -> &[u8] {
148
0
        &self.bytes[self.r_range.clone()]
149
0
    }
150
151
    /// Get the `s` component of the signature (leading zeros removed)
152
0
    pub(crate) fn s(&self) -> &[u8] {
153
0
        &self.bytes[self.s_range.clone()]
154
0
    }
155
}
156
157
impl<C> AsRef<[u8]> for Signature<C>
158
where
159
    C: PrimeCurve,
160
    MaxSize<C>: ArrayLength<u8>,
161
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
162
{
163
0
    fn as_ref(&self) -> &[u8] {
164
0
        self.as_bytes()
165
0
    }
166
}
167
168
impl<C> Clone for Signature<C>
169
where
170
    C: PrimeCurve,
171
    MaxSize<C>: ArrayLength<u8>,
172
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
173
{
174
0
    fn clone(&self) -> Self {
175
0
        Self {
176
0
            bytes: self.bytes.clone(),
177
0
            r_range: self.r_range.clone(),
178
0
            s_range: self.s_range.clone(),
179
0
        }
180
0
    }
181
}
182
183
impl<C> Debug for Signature<C>
184
where
185
    C: PrimeCurve,
186
    MaxSize<C>: ArrayLength<u8>,
187
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
188
{
189
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190
0
        write!(f, "ecdsa::der::Signature<{:?}>(", C::default())?;
191
192
0
        for &byte in self.as_ref() {
193
0
            write!(f, "{:02X}", byte)?;
194
        }
195
196
0
        write!(f, ")")
197
0
    }
198
}
199
200
impl<'a, C> Decode<'a> for Signature<C>
201
where
202
    C: PrimeCurve,
203
    MaxSize<C>: ArrayLength<u8>,
204
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
205
{
206
0
    fn decode<R: Reader<'a>>(reader: &mut R) -> der::Result<Self> {
207
0
        let header = reader.peek_header()?;
208
0
        header.tag.assert_eq(Tag::Sequence)?;
209
210
0
        let mut buf = SignatureBytes::<C>::default();
211
0
        let len = (header.encoded_len()? + header.length)?;
212
0
        let slice = buf
213
0
            .get_mut(..usize::try_from(len)?)
214
0
            .ok_or_else(|| reader.error(Tag::Sequence.length_error().kind()))?;
215
216
0
        reader.read_into(slice)?;
217
0
        Self::from_bytes(slice).map_err(|_| Tag::Integer.value_error())
218
0
    }
219
}
220
221
impl<C> Encode for Signature<C>
222
where
223
    C: PrimeCurve,
224
    MaxSize<C>: ArrayLength<u8>,
225
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
226
{
227
0
    fn encoded_len(&self) -> der::Result<Length> {
228
0
        Length::try_from(self.len())
229
0
    }
230
231
0
    fn encode(&self, writer: &mut impl Writer) -> der::Result<()> {
232
0
        writer.write(self.as_bytes())
233
0
    }
234
}
235
236
impl<C> FixedTag for Signature<C>
237
where
238
    C: PrimeCurve,
239
    MaxSize<C>: ArrayLength<u8>,
240
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
241
{
242
    const TAG: Tag = Tag::Sequence;
243
}
244
245
impl<C> From<crate::Signature<C>> for Signature<C>
246
where
247
    C: PrimeCurve,
248
    MaxSize<C>: ArrayLength<u8>,
249
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
250
{
251
0
    fn from(sig: crate::Signature<C>) -> Signature<C> {
252
0
        sig.to_der()
253
0
    }
254
}
255
256
impl<C> TryFrom<&[u8]> for Signature<C>
257
where
258
    C: PrimeCurve,
259
    MaxSize<C>: ArrayLength<u8>,
260
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
261
{
262
    type Error = Error;
263
264
0
    fn try_from(input: &[u8]) -> Result<Self> {
265
0
        Self::from_bytes(input)
266
0
    }
267
}
268
269
impl<C> TryFrom<Signature<C>> for crate::Signature<C>
270
where
271
    C: PrimeCurve,
272
    MaxSize<C>: ArrayLength<u8>,
273
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
274
{
275
    type Error = Error;
276
277
0
    fn try_from(sig: Signature<C>) -> Result<super::Signature<C>> {
278
0
        let mut bytes = super::SignatureBytes::<C>::default();
279
0
        let r_begin = C::FieldBytesSize::USIZE.saturating_sub(sig.r().len());
280
0
        let s_begin = bytes.len().saturating_sub(sig.s().len());
281
0
        bytes[r_begin..C::FieldBytesSize::USIZE].copy_from_slice(sig.r());
282
0
        bytes[s_begin..].copy_from_slice(sig.s());
283
0
        Self::try_from(bytes.as_slice())
284
0
    }
285
}
286
287
#[cfg(feature = "alloc")]
288
impl<C> From<Signature<C>> for Box<[u8]>
289
where
290
    C: PrimeCurve,
291
    MaxSize<C>: ArrayLength<u8>,
292
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
293
{
294
0
    fn from(signature: Signature<C>) -> Box<[u8]> {
295
0
        signature.to_vec().into_boxed_slice()
296
0
    }
297
}
298
299
#[cfg(feature = "alloc")]
300
impl<C> SignatureEncoding for Signature<C>
301
where
302
    C: PrimeCurve,
303
    MaxSize<C>: ArrayLength<u8>,
304
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
305
{
306
    type Repr = Box<[u8]>;
307
308
0
    fn to_vec(&self) -> Vec<u8> {
309
0
        self.as_bytes().into()
310
0
    }
311
}
312
313
#[cfg(feature = "alloc")]
314
impl<C> SignatureBitStringEncoding for Signature<C>
315
where
316
    C: PrimeCurve,
317
    MaxSize<C>: ArrayLength<u8>,
318
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
319
{
320
0
    fn to_bitstring(&self) -> der::Result<BitString> {
321
0
        BitString::new(0, self.to_vec())
322
0
    }
323
}
324
325
#[cfg(feature = "serde")]
326
impl<C> Serialize for Signature<C>
327
where
328
    C: PrimeCurve,
329
    MaxSize<C>: ArrayLength<u8>,
330
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
331
{
332
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
333
    where
334
        S: ser::Serializer,
335
    {
336
        serdect::slice::serialize_hex_upper_or_bin(&self.as_bytes(), serializer)
337
    }
338
}
339
340
#[cfg(feature = "serde")]
341
impl<'de, C> Deserialize<'de> for Signature<C>
342
where
343
    C: PrimeCurve,
344
    MaxSize<C>: ArrayLength<u8>,
345
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
346
{
347
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
348
    where
349
        D: de::Deserializer<'de>,
350
    {
351
        let mut buf = SignatureBytes::<C>::default();
352
        let slice = serdect::slice::deserialize_hex_or_bin(&mut buf, deserializer)?;
353
        Self::try_from(slice).map_err(de::Error::custom)
354
    }
355
}
356
357
/// Decode the `r` and `s` components of a DER-encoded ECDSA signature.
358
0
fn decode_der(der_bytes: &[u8]) -> der::Result<(UintRef<'_>, UintRef<'_>)> {
359
0
    let mut reader = der::SliceReader::new(der_bytes)?;
360
0
    let header = der::Header::decode(&mut reader)?;
361
0
    header.tag.assert_eq(der::Tag::Sequence)?;
362
363
0
    let ret = reader.read_nested(header.length, |reader| {
364
0
        let r = UintRef::decode(reader)?;
365
0
        let s = UintRef::decode(reader)?;
366
0
        Ok((r, s))
367
0
    })?;
368
369
0
    reader.finish(ret)
370
0
}
371
372
/// Locate the range within a slice at which a particular subslice is located
373
0
fn find_scalar_range(outer: &[u8], inner: &[u8]) -> Result<Range<usize>> {
374
0
    let outer_start = outer.as_ptr() as usize;
375
0
    let inner_start = inner.as_ptr() as usize;
376
0
    let start = inner_start
377
0
        .checked_sub(outer_start)
378
0
        .ok_or_else(Error::new)?;
379
0
    let end = start.checked_add(inner.len()).ok_or_else(Error::new)?;
380
0
    Ok(Range { start, end })
381
0
}
382
383
#[cfg(all(feature = "digest", feature = "hazmat"))]
384
impl<C> signature::PrehashSignature for Signature<C>
385
where
386
    C: PrimeCurve + crate::hazmat::DigestPrimitive,
387
    MaxSize<C>: ArrayLength<u8>,
388
    <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
389
{
390
    type Digest = C::Digest;
391
}
392
393
#[cfg(all(test, feature = "arithmetic"))]
394
mod tests {
395
    use elliptic_curve::dev::MockCurve;
396
397
    type Signature = crate::Signature<MockCurve>;
398
399
    const EXAMPLE_SIGNATURE: [u8; 64] = [
400
        0xf3, 0xac, 0x80, 0x61, 0xb5, 0x14, 0x79, 0x5b, 0x88, 0x43, 0xe3, 0xd6, 0x62, 0x95, 0x27,
401
        0xed, 0x2a, 0xfd, 0x6b, 0x1f, 0x6a, 0x55, 0x5a, 0x7a, 0xca, 0xbb, 0x5e, 0x6f, 0x79, 0xc8,
402
        0xc2, 0xac, 0x8b, 0xf7, 0x78, 0x19, 0xca, 0x5, 0xa6, 0xb2, 0x78, 0x6c, 0x76, 0x26, 0x2b,
403
        0xf7, 0x37, 0x1c, 0xef, 0x97, 0xb2, 0x18, 0xe9, 0x6f, 0x17, 0x5a, 0x3c, 0xcd, 0xda, 0x2a,
404
        0xcc, 0x5, 0x89, 0x3,
405
    ];
406
407
    #[test]
408
    fn test_fixed_to_asn1_signature_roundtrip() {
409
        let signature1 = Signature::try_from(EXAMPLE_SIGNATURE.as_ref()).unwrap();
410
411
        // Convert to ASN.1 DER and back
412
        let asn1_signature = signature1.to_der();
413
        let signature2 = Signature::from_der(asn1_signature.as_ref()).unwrap();
414
415
        assert_eq!(signature1, signature2);
416
    }
417
418
    #[test]
419
    fn test_asn1_too_short_signature() {
420
        assert!(Signature::from_der(&[]).is_err());
421
        assert!(Signature::from_der(&[der::Tag::Sequence.into()]).is_err());
422
        assert!(Signature::from_der(&[der::Tag::Sequence.into(), 0x00]).is_err());
423
        assert!(Signature::from_der(&[
424
            der::Tag::Sequence.into(),
425
            0x03,
426
            der::Tag::Integer.into(),
427
            0x01,
428
            0x01
429
        ])
430
        .is_err());
431
    }
432
433
    #[test]
434
    fn test_asn1_non_der_signature() {
435
        // A minimal 8-byte ASN.1 signature parses OK.
436
        assert!(Signature::from_der(&[
437
            der::Tag::Sequence.into(),
438
            0x06, // length of below
439
            der::Tag::Integer.into(),
440
            0x01, // length of value
441
            0x01, // value=1
442
            der::Tag::Integer.into(),
443
            0x01, // length of value
444
            0x01, // value=1
445
        ])
446
        .is_ok());
447
448
        // But length fields that are not minimally encoded should be rejected, as they are not
449
        // valid DER, cf.
450
        // https://github.com/google/wycheproof/blob/2196000605e4/testvectors/ecdsa_secp256k1_sha256_test.json#L57-L66
451
        assert!(Signature::from_der(&[
452
            der::Tag::Sequence.into(),
453
            0x81, // extended length: 1 length byte to come
454
            0x06, // length of below
455
            der::Tag::Integer.into(),
456
            0x01, // length of value
457
            0x01, // value=1
458
            der::Tag::Integer.into(),
459
            0x01, // length of value
460
            0x01, // value=1
461
        ])
462
        .is_err());
463
    }
464
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ecdsa-0.16.9/src/hazmat.rs
Line
Count
Source
1
//! Low-level ECDSA primitives.
2
//!
3
//! # ⚠️ Warning: Hazmat!
4
//!
5
//! YOU PROBABLY DON'T WANT TO USE THESE!
6
//!
7
//! These primitives are easy-to-misuse low-level interfaces.
8
//!
9
//! If you are an end user / non-expert in cryptography, do not use these!
10
//! Failure to use them correctly can lead to catastrophic failures including
11
//! FULL PRIVATE KEY RECOVERY!
12
13
use crate::{Error, Result};
14
use core::cmp;
15
use elliptic_curve::{generic_array::typenum::Unsigned, FieldBytes, PrimeCurve};
16
17
#[cfg(feature = "arithmetic")]
18
use {
19
    crate::{RecoveryId, SignatureSize},
20
    elliptic_curve::{
21
        ff::{Field, PrimeField},
22
        group::{Curve as _, Group},
23
        ops::{Invert, LinearCombination, MulByGenerator, Reduce},
24
        point::AffineCoordinates,
25
        scalar::IsHigh,
26
        subtle::CtOption,
27
        CurveArithmetic, ProjectivePoint, Scalar,
28
    },
29
};
30
31
#[cfg(feature = "digest")]
32
use {
33
    elliptic_curve::FieldBytesSize,
34
    signature::{
35
        digest::{core_api::BlockSizeUser, Digest, FixedOutput, FixedOutputReset},
36
        PrehashSignature,
37
    },
38
};
39
40
#[cfg(feature = "rfc6979")]
41
use elliptic_curve::{FieldBytesEncoding, ScalarPrimitive};
42
43
#[cfg(any(feature = "arithmetic", feature = "digest"))]
44
use crate::{elliptic_curve::generic_array::ArrayLength, Signature};
45
46
/// Try to sign the given prehashed message using ECDSA.
47
///
48
/// This trait is intended to be implemented on a type with access to the
49
/// secret scalar via `&self`, such as particular curve's `Scalar` type.
50
#[cfg(feature = "arithmetic")]
51
pub trait SignPrimitive<C>:
52
    AsRef<Self>
53
    + Into<FieldBytes<C>>
54
    + IsHigh
55
    + PrimeField<Repr = FieldBytes<C>>
56
    + Reduce<C::Uint, Bytes = FieldBytes<C>>
57
    + Sized
58
where
59
    C: PrimeCurve + CurveArithmetic<Scalar = Self>,
60
    SignatureSize<C>: ArrayLength<u8>,
61
{
62
    /// Try to sign the prehashed message.
63
    ///
64
    /// Accepts the following arguments:
65
    ///
66
    /// - `k`: ephemeral scalar value. MUST BE UNIFORMLY RANDOM!!!
67
    /// - `z`: message digest to be signed. MUST BE OUTPUT OF A CRYPTOGRAPHICALLY
68
    ///        SECURE DIGEST ALGORITHM!!!
69
    ///
70
    /// # Returns
71
    ///
72
    /// ECDSA [`Signature`] and, when possible/desired, a [`RecoveryId`]
73
    /// which can be used to recover the verifying key for a given signature.
74
0
    fn try_sign_prehashed<K>(
75
0
        &self,
76
0
        k: K,
77
0
        z: &FieldBytes<C>,
78
0
    ) -> Result<(Signature<C>, Option<RecoveryId>)>
79
0
    where
80
0
        K: AsRef<Self> + Invert<Output = CtOption<Self>>,
81
0
    {
82
0
        sign_prehashed(self, k, z).map(|(sig, recid)| (sig, (Some(recid))))
83
0
    }
84
85
    /// Try to sign the given message digest deterministically using the method
86
    /// described in [RFC6979] for computing ECDSA ephemeral scalar `k`.
87
    ///
88
    /// Accepts the following parameters:
89
    /// - `z`: message digest to be signed.
90
    /// - `ad`: optional additional data, e.g. added entropy from an RNG
91
    ///
92
    /// [RFC6979]: https://datatracker.ietf.org/doc/html/rfc6979
93
    #[cfg(feature = "rfc6979")]
94
0
    fn try_sign_prehashed_rfc6979<D>(
95
0
        &self,
96
0
        z: &FieldBytes<C>,
97
0
        ad: &[u8],
98
0
    ) -> Result<(Signature<C>, Option<RecoveryId>)>
99
0
    where
100
0
        Self: From<ScalarPrimitive<C>> + Invert<Output = CtOption<Self>>,
101
0
        D: Digest + BlockSizeUser + FixedOutput<OutputSize = FieldBytesSize<C>> + FixedOutputReset,
102
0
    {
103
0
        let k = Scalar::<C>::from_repr(rfc6979::generate_k::<D, _>(
104
0
            &self.to_repr(),
105
0
            &C::ORDER.encode_field_bytes(),
106
0
            z,
107
0
            ad,
108
0
        ))
109
0
        .unwrap();
110
0
111
0
        self.try_sign_prehashed::<Self>(k, z)
112
0
    }
113
}
114
115
/// Verify the given prehashed message using ECDSA.
116
///
117
/// This trait is intended to be implemented on type which can access
118
/// the affine point represeting the public key via `&self`, such as a
119
/// particular curve's `AffinePoint` type.
120
#[cfg(feature = "arithmetic")]
121
pub trait VerifyPrimitive<C>: AffineCoordinates<FieldRepr = FieldBytes<C>> + Copy + Sized
122
where
123
    C: PrimeCurve + CurveArithmetic<AffinePoint = Self>,
124
    SignatureSize<C>: ArrayLength<u8>,
125
{
126
    /// Verify the prehashed message against the provided ECDSA signature.
127
    ///
128
    /// Accepts the following arguments:
129
    ///
130
    /// - `z`: message digest to be verified. MUST BE OUTPUT OF A
131
    ///        CRYPTOGRAPHICALLY SECURE DIGEST ALGORITHM!!!
132
    /// - `sig`: signature to be verified against the key and message
133
838
    fn verify_prehashed(&self, z: &FieldBytes<C>, sig: &Signature<C>) -> Result<()> {
134
838
        verify_prehashed(&ProjectivePoint::<C>::from(*self), z, sig)
135
838
    }
_RNvYINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCs56dDIOPvtI3_5ecdsa6hazmat15VerifyPrimitiveBR_E16verify_prehashedCs4RkbDk9WRL5_5clvmr
Line
Count
Source
133
838
    fn verify_prehashed(&self, z: &FieldBytes<C>, sig: &Signature<C>) -> Result<()> {
134
838
        verify_prehashed(&ProjectivePoint::<C>::from(*self), z, sig)
135
838
    }
Unexecuted instantiation: _RNvYpINtNtCs56dDIOPvtI3_5ecdsa6hazmat15VerifyPrimitivepE16verify_prehashedB8_
Unexecuted instantiation: _RNvYINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCs56dDIOPvtI3_5ecdsa6hazmat15VerifyPrimitiveBR_E16verify_prehashedBT_
136
137
    /// Verify message digest against the provided signature.
138
    #[cfg(feature = "digest")]
139
0
    fn verify_digest<D>(&self, msg_digest: D, sig: &Signature<C>) -> Result<()>
140
0
    where
141
0
        D: FixedOutput<OutputSize = FieldBytesSize<C>>,
142
0
    {
143
0
        self.verify_prehashed(&msg_digest.finalize_fixed(), sig)
144
0
    }
145
}
146
147
/// Bind a preferred [`Digest`] algorithm to an elliptic curve type.
148
///
149
/// Generally there is a preferred variety of the SHA-2 family used with ECDSA
150
/// for a particular elliptic curve.
151
///
152
/// This trait can be used to specify it, and with it receive a blanket impl of
153
/// [`PrehashSignature`], used by [`signature_derive`][1]) for the [`Signature`]
154
/// type for a particular elliptic curve.
155
///
156
/// [1]: https://github.com/RustCrypto/traits/tree/master/signature/derive
157
#[cfg(feature = "digest")]
158
pub trait DigestPrimitive: PrimeCurve {
159
    /// Preferred digest to use when computing ECDSA signatures for this
160
    /// elliptic curve. This is typically a member of the SHA-2 family.
161
    type Digest: BlockSizeUser
162
        + Digest
163
        + FixedOutput<OutputSize = FieldBytesSize<Self>>
164
        + FixedOutputReset;
165
}
166
167
#[cfg(feature = "digest")]
168
impl<C> PrehashSignature for Signature<C>
169
where
170
    C: DigestPrimitive,
171
    <FieldBytesSize<C> as core::ops::Add>::Output: ArrayLength<u8>,
172
{
173
    type Digest = C::Digest;
174
}
175
176
/// Partial implementation of the `bits2int` function as defined in
177
/// [RFC6979 § 2.3.2] as well as [SEC1] § 2.3.8.
178
///
179
/// This is used to convert a message digest whose size may be smaller or
180
/// larger than the size of the curve's scalar field into a serialized
181
/// (unreduced) field element.
182
///
183
/// [RFC6979 § 2.3.2]: https://datatracker.ietf.org/doc/html/rfc6979#section-2.3.2
184
/// [SEC1]: https://www.secg.org/sec1-v2.pdf
185
1.37k
pub fn bits2field<C: PrimeCurve>(bits: &[u8]) -> Result<FieldBytes<C>> {
186
1.37k
    // Minimum allowed bits size is half the field size
187
1.37k
    if bits.len() < C::FieldBytesSize::USIZE / 2 {
188
0
        return Err(Error::new());
189
1.37k
    }
190
1.37k
191
1.37k
    let mut field_bytes = FieldBytes::<C>::default();
192
1.37k
193
1.37k
    match bits.len().cmp(&C::FieldBytesSize::USIZE) {
194
1.37k
        cmp::Ordering::Equal => field_bytes.copy_from_slice(bits),
195
0
        cmp::Ordering::Less => {
196
0
            // If bits is smaller than the field size, pad with zeroes on the left
197
0
            field_bytes[(C::FieldBytesSize::USIZE - bits.len())..].copy_from_slice(bits);
198
0
        }
199
0
        cmp::Ordering::Greater => {
200
0
            // If bits is larger than the field size, truncate
201
0
            field_bytes.copy_from_slice(&bits[..C::FieldBytesSize::USIZE]);
202
0
        }
203
    }
204
205
1.37k
    Ok(field_bytes)
206
1.37k
}
_RINvNtCs56dDIOPvtI3_5ecdsa6hazmat10bits2fieldNtCsaHRNXv1Y9Bq_4p2568NistP256ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
185
838
pub fn bits2field<C: PrimeCurve>(bits: &[u8]) -> Result<FieldBytes<C>> {
186
838
    // Minimum allowed bits size is half the field size
187
838
    if bits.len() < C::FieldBytesSize::USIZE / 2 {
188
0
        return Err(Error::new());
189
838
    }
190
838
191
838
    let mut field_bytes = FieldBytes::<C>::default();
192
838
193
838
    match bits.len().cmp(&C::FieldBytesSize::USIZE) {
194
838
        cmp::Ordering::Equal => field_bytes.copy_from_slice(bits),
195
0
        cmp::Ordering::Less => {
196
0
            // If bits is smaller than the field size, pad with zeroes on the left
197
0
            field_bytes[(C::FieldBytesSize::USIZE - bits.len())..].copy_from_slice(bits);
198
0
        }
199
0
        cmp::Ordering::Greater => {
200
0
            // If bits is larger than the field size, truncate
201
0
            field_bytes.copy_from_slice(&bits[..C::FieldBytesSize::USIZE]);
202
0
        }
203
    }
204
205
838
    Ok(field_bytes)
206
838
}
_RINvNtCs56dDIOPvtI3_5ecdsa6hazmat10bits2fieldNtCsjewTDwKBbyD_4k2569Secp256k1ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
185
534
pub fn bits2field<C: PrimeCurve>(bits: &[u8]) -> Result<FieldBytes<C>> {
186
534
    // Minimum allowed bits size is half the field size
187
534
    if bits.len() < C::FieldBytesSize::USIZE / 2 {
188
0
        return Err(Error::new());
189
534
    }
190
534
191
534
    let mut field_bytes = FieldBytes::<C>::default();
192
534
193
534
    match bits.len().cmp(&C::FieldBytesSize::USIZE) {
194
534
        cmp::Ordering::Equal => field_bytes.copy_from_slice(bits),
195
0
        cmp::Ordering::Less => {
196
0
            // If bits is smaller than the field size, pad with zeroes on the left
197
0
            field_bytes[(C::FieldBytesSize::USIZE - bits.len())..].copy_from_slice(bits);
198
0
        }
199
0
        cmp::Ordering::Greater => {
200
0
            // If bits is larger than the field size, truncate
201
0
            field_bytes.copy_from_slice(&bits[..C::FieldBytesSize::USIZE]);
202
0
        }
203
    }
204
205
534
    Ok(field_bytes)
206
534
}
Unexecuted instantiation: _RINvNtCs56dDIOPvtI3_5ecdsa6hazmat10bits2fieldpEB4_
207
208
/// Sign a prehashed message digest using the provided secret scalar and
209
/// ephemeral scalar, returning an ECDSA signature.
210
///
211
/// Accepts the following arguments:
212
///
213
/// - `d`: signing key. MUST BE UNIFORMLY RANDOM!!!
214
/// - `k`: ephemeral scalar value. MUST BE UNIFORMLY RANDOM!!!
215
/// - `z`: message digest to be signed. MUST BE OUTPUT OF A CRYPTOGRAPHICALLY
216
///        SECURE DIGEST ALGORITHM!!!
217
///
218
/// # Returns
219
///
220
/// ECDSA [`Signature`] and, when possible/desired, a [`RecoveryId`]
221
/// which can be used to recover the verifying key for a given signature.
222
#[cfg(feature = "arithmetic")]
223
#[allow(non_snake_case)]
224
0
pub fn sign_prehashed<C, K>(
225
0
    d: &Scalar<C>,
226
0
    k: K,
227
0
    z: &FieldBytes<C>,
228
0
) -> Result<(Signature<C>, RecoveryId)>
229
0
where
230
0
    C: PrimeCurve + CurveArithmetic,
231
0
    K: AsRef<Scalar<C>> + Invert<Output = CtOption<Scalar<C>>>,
232
0
    SignatureSize<C>: ArrayLength<u8>,
233
0
{
234
0
    // TODO(tarcieri): use `NonZeroScalar<C>` for `k`.
235
0
    if k.as_ref().is_zero().into() {
236
0
        return Err(Error::new());
237
0
    }
238
0
239
0
    let z = <Scalar<C> as Reduce<C::Uint>>::reduce_bytes(z);
240
241
    // Compute scalar inversion of 𝑘
242
0
    let k_inv = Option::<Scalar<C>>::from(k.invert()).ok_or_else(Error::new)?;
243
244
    // Compute 𝑹 = 𝑘×𝑮
245
0
    let R = ProjectivePoint::<C>::mul_by_generator(k.as_ref()).to_affine();
246
0
247
0
    // Lift x-coordinate of 𝑹 (element of base field) into a serialized big
248
0
    // integer, then reduce it into an element of the scalar field
249
0
    let r = Scalar::<C>::reduce_bytes(&R.x());
250
0
    let x_is_reduced = r.to_repr() != R.x();
251
0
252
0
    // Compute 𝒔 as a signature over 𝒓 and 𝒛.
253
0
    let s = k_inv * (z + (r * d));
254
255
    // NOTE: `Signature::from_scalars` checks that both `r` and `s` are non-zero.
256
0
    let signature = Signature::from_scalars(r, s)?;
257
0
    let recovery_id = RecoveryId::new(R.y_is_odd().into(), x_is_reduced);
258
0
    Ok((signature, recovery_id))
259
0
}
260
261
/// Verify the prehashed message against the provided ECDSA signature.
262
///
263
/// Accepts the following arguments:
264
///
265
/// - `q`: public key with which to verify the signature.
266
/// - `z`: message digest to be verified. MUST BE OUTPUT OF A
267
///        CRYPTOGRAPHICALLY SECURE DIGEST ALGORITHM!!!
268
/// - `sig`: signature to be verified against the key and message.
269
#[cfg(feature = "arithmetic")]
270
1.36k
pub fn verify_prehashed<C>(
271
1.36k
    q: &ProjectivePoint<C>,
272
1.36k
    z: &FieldBytes<C>,
273
1.36k
    sig: &Signature<C>,
274
1.36k
) -> Result<()>
275
1.36k
where
276
1.36k
    C: PrimeCurve + CurveArithmetic,
277
1.36k
    SignatureSize<C>: ArrayLength<u8>,
278
1.36k
{
279
1.36k
    let z = Scalar::<C>::reduce_bytes(z);
280
1.36k
    let (r, s) = sig.split_scalars();
281
1.36k
    let s_inv = *s.invert_vartime();
282
1.36k
    let u1 = z * s_inv;
283
1.36k
    let u2 = *r * s_inv;
284
1.36k
    let x = ProjectivePoint::<C>::lincomb(&ProjectivePoint::<C>::generator(), &u1, q, &u2)
285
1.36k
        .to_affine()
286
1.36k
        .x();
287
1.36k
288
1.36k
    if *r == Scalar::<C>::reduce_bytes(&x) {
289
159
        Ok(())
290
    } else {
291
1.20k
        Err(Error::new())
292
    }
293
1.36k
}
_RINvNtCs56dDIOPvtI3_5ecdsa6hazmat16verify_prehashedNtCsaHRNXv1Y9Bq_4p2568NistP256ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
270
838
pub fn verify_prehashed<C>(
271
838
    q: &ProjectivePoint<C>,
272
838
    z: &FieldBytes<C>,
273
838
    sig: &Signature<C>,
274
838
) -> Result<()>
275
838
where
276
838
    C: PrimeCurve + CurveArithmetic,
277
838
    SignatureSize<C>: ArrayLength<u8>,
278
838
{
279
838
    let z = Scalar::<C>::reduce_bytes(z);
280
838
    let (r, s) = sig.split_scalars();
281
838
    let s_inv = *s.invert_vartime();
282
838
    let u1 = z * s_inv;
283
838
    let u2 = *r * s_inv;
284
838
    let x = ProjectivePoint::<C>::lincomb(&ProjectivePoint::<C>::generator(), &u1, q, &u2)
285
838
        .to_affine()
286
838
        .x();
287
838
288
838
    if *r == Scalar::<C>::reduce_bytes(&x) {
289
50
        Ok(())
290
    } else {
291
788
        Err(Error::new())
292
    }
293
838
}
Unexecuted instantiation: _RINvNtCs56dDIOPvtI3_5ecdsa6hazmat16verify_prehashedpEB4_
_RINvNtCs56dDIOPvtI3_5ecdsa6hazmat16verify_prehashedNtCsjewTDwKBbyD_4k2569Secp256k1EBP_
Line
Count
Source
270
523
pub fn verify_prehashed<C>(
271
523
    q: &ProjectivePoint<C>,
272
523
    z: &FieldBytes<C>,
273
523
    sig: &Signature<C>,
274
523
) -> Result<()>
275
523
where
276
523
    C: PrimeCurve + CurveArithmetic,
277
523
    SignatureSize<C>: ArrayLength<u8>,
278
523
{
279
523
    let z = Scalar::<C>::reduce_bytes(z);
280
523
    let (r, s) = sig.split_scalars();
281
523
    let s_inv = *s.invert_vartime();
282
523
    let u1 = z * s_inv;
283
523
    let u2 = *r * s_inv;
284
523
    let x = ProjectivePoint::<C>::lincomb(&ProjectivePoint::<C>::generator(), &u1, q, &u2)
285
523
        .to_affine()
286
523
        .x();
287
523
288
523
    if *r == Scalar::<C>::reduce_bytes(&x) {
289
109
        Ok(())
290
    } else {
291
414
        Err(Error::new())
292
    }
293
523
}
Unexecuted instantiation: _RINvNtCs56dDIOPvtI3_5ecdsa6hazmat16verify_prehashedNtCsaHRNXv1Y9Bq_4p2568NistP256EBP_
294
295
#[cfg(test)]
296
mod tests {
297
    use super::bits2field;
298
    use elliptic_curve::dev::MockCurve;
299
    use hex_literal::hex;
300
301
    #[test]
302
    fn bits2field_too_small() {
303
        assert!(bits2field::<MockCurve>(b"").is_err());
304
    }
305
306
    #[test]
307
    fn bits2field_size_less() {
308
        let prehash = hex!("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
309
        let field_bytes = bits2field::<MockCurve>(&prehash).unwrap();
310
        assert_eq!(
311
            field_bytes.as_slice(),
312
            &hex!("00000000000000000000000000000000AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
313
        );
314
    }
315
316
    #[test]
317
    fn bits2field_size_eq() {
318
        let prehash = hex!("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
319
        let field_bytes = bits2field::<MockCurve>(&prehash).unwrap();
320
        assert_eq!(field_bytes.as_slice(), &prehash);
321
    }
322
323
    #[test]
324
    fn bits2field_size_greater() {
325
        let prehash = hex!("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
326
        let field_bytes = bits2field::<MockCurve>(&prehash).unwrap();
327
        assert_eq!(
328
            field_bytes.as_slice(),
329
            &hex!("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
330
        );
331
    }
332
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ecdsa-0.16.9/src/lib.rs
Line
Count
Source
1
#![no_std]
2
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3
#![doc = include_str!("../README.md")]
4
#![doc(
5
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
6
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
7
)]
8
#![forbid(unsafe_code)]
9
#![warn(
10
    clippy::cast_lossless,
11
    clippy::cast_possible_truncation,
12
    clippy::cast_possible_wrap,
13
    clippy::cast_precision_loss,
14
    clippy::cast_sign_loss,
15
    clippy::checked_conversions,
16
    clippy::implicit_saturating_sub,
17
    clippy::panic,
18
    clippy::panic_in_result_fn,
19
    clippy::unwrap_used,
20
    missing_docs,
21
    rust_2018_idioms,
22
    unused_lifetimes,
23
    unused_qualifications
24
)]
25
26
//! ## `serde` support
27
//!
28
//! When the `serde` feature of this crate is enabled, `Serialize` and
29
//! `Deserialize` impls are provided for the [`Signature`] and [`VerifyingKey`]
30
//! types.
31
//!
32
//! Please see type-specific documentation for more information.
33
//!
34
//! ## Interop
35
//!
36
//! Any crates which provide an implementation of ECDSA for a particular
37
//! elliptic curve can leverage the types from this crate, along with the
38
//! [`k256`], [`p256`], and/or [`p384`] crates to expose ECDSA functionality in
39
//! a generic, interoperable way by leveraging the [`Signature`] type with in
40
//! conjunction with the [`signature::Signer`] and [`signature::Verifier`]
41
//! traits.
42
//!
43
//! For example, the [`ring-compat`] crate implements the [`signature::Signer`]
44
//! and [`signature::Verifier`] traits in conjunction with the
45
//! [`p256::ecdsa::Signature`] and [`p384::ecdsa::Signature`] types to
46
//! wrap the ECDSA implementations from [*ring*] in a generic, interoperable
47
//! API.
48
//!
49
//! [`k256`]: https://docs.rs/k256
50
//! [`p256`]: https://docs.rs/p256
51
//! [`p256::ecdsa::Signature`]: https://docs.rs/p256/latest/p256/ecdsa/type.Signature.html
52
//! [`p384`]: https://docs.rs/p384
53
//! [`p384::ecdsa::Signature`]: https://docs.rs/p384/latest/p384/ecdsa/type.Signature.html
54
//! [`ring-compat`]: https://docs.rs/ring-compat
55
//! [*ring*]: https://docs.rs/ring
56
57
#[cfg(feature = "alloc")]
58
extern crate alloc;
59
60
mod normalized;
61
mod recovery;
62
63
#[cfg(feature = "der")]
64
pub mod der;
65
#[cfg(feature = "dev")]
66
pub mod dev;
67
#[cfg(feature = "hazmat")]
68
pub mod hazmat;
69
#[cfg(feature = "signing")]
70
mod signing;
71
#[cfg(feature = "verifying")]
72
mod verifying;
73
74
pub use crate::{normalized::NormalizedSignature, recovery::RecoveryId};
75
76
// Re-export the `elliptic-curve` crate (and select types)
77
pub use elliptic_curve::{self, sec1::EncodedPoint, PrimeCurve};
78
79
// Re-export the `signature` crate (and select types)
80
pub use signature::{self, Error, Result, SignatureEncoding};
81
82
#[cfg(feature = "signing")]
83
pub use crate::signing::SigningKey;
84
#[cfg(feature = "verifying")]
85
pub use crate::verifying::VerifyingKey;
86
87
use core::{fmt, ops::Add};
88
use elliptic_curve::{
89
    generic_array::{typenum::Unsigned, ArrayLength, GenericArray},
90
    FieldBytes, FieldBytesSize, ScalarPrimitive,
91
};
92
93
#[cfg(feature = "alloc")]
94
use alloc::vec::Vec;
95
96
#[cfg(feature = "arithmetic")]
97
use {
98
    core::str,
99
    elliptic_curve::{scalar::IsHigh, CurveArithmetic, NonZeroScalar},
100
};
101
102
#[cfg(feature = "digest")]
103
use digest::{
104
    const_oid::{AssociatedOid, ObjectIdentifier},
105
    Digest,
106
};
107
108
#[cfg(feature = "pkcs8")]
109
use elliptic_curve::pkcs8::spki::{
110
    der::AnyRef, AlgorithmIdentifierRef, AssociatedAlgorithmIdentifier,
111
};
112
113
#[cfg(feature = "serde")]
114
use serdect::serde::{de, ser, Deserialize, Serialize};
115
116
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
117
use elliptic_curve::pkcs8::spki::{
118
    self, AlgorithmIdentifierOwned, DynAssociatedAlgorithmIdentifier,
119
};
120
121
/// OID for ECDSA with SHA-224 digests.
122
///
123
/// ```text
124
/// ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
125
///      us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 1 }
126
/// ```
127
// TODO(tarcieri): use `ObjectIdentifier::push_arc` when const unwrap is stable
128
#[cfg(feature = "digest")]
129
pub const ECDSA_SHA224_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.4.3.1");
130
131
/// OID for ECDSA with SHA-256 digests.
132
///
133
/// ```text
134
/// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
135
///      us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
136
/// ```
137
#[cfg(feature = "digest")]
138
pub const ECDSA_SHA256_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.4.3.2");
139
140
/// OID for ECDSA with SHA-384 digests.
141
///
142
/// ```text
143
/// ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
144
///      us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
145
/// ```
146
#[cfg(feature = "digest")]
147
pub const ECDSA_SHA384_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.4.3.3");
148
149
/// OID for ECDSA with SHA-512 digests.
150
///
151
/// ```text
152
/// ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
153
///      us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
154
/// ```
155
#[cfg(feature = "digest")]
156
pub const ECDSA_SHA512_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.4.3.4");
157
158
#[cfg(feature = "digest")]
159
const SHA224_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.4");
160
#[cfg(feature = "digest")]
161
const SHA256_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.1");
162
#[cfg(feature = "digest")]
163
const SHA384_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.2");
164
#[cfg(feature = "digest")]
165
const SHA512_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.3");
166
167
/// Size of a fixed sized signature for the given elliptic curve.
168
pub type SignatureSize<C> = <FieldBytesSize<C> as Add>::Output;
169
170
/// Fixed-size byte array containing an ECDSA signature
171
pub type SignatureBytes<C> = GenericArray<u8, SignatureSize<C>>;
172
173
/// ECDSA signature (fixed-size). Generic over elliptic curve types.
174
///
175
/// Serialized as fixed-sized big endian scalar values with no added framing:
176
///
177
/// - `r`: field element size for the given curve, big-endian
178
/// - `s`: field element size for the given curve, big-endian
179
///
180
/// Both `r` and `s` MUST be non-zero.
181
///
182
/// For example, in a curve with a 256-bit modulus like NIST P-256 or
183
/// secp256k1, `r` and `s` will both be 32-bytes and serialized as big endian,
184
/// resulting in a signature with a total of 64-bytes.
185
///
186
/// ASN.1 DER-encoded signatures also supported via the
187
/// [`Signature::from_der`] and [`Signature::to_der`] methods.
188
///
189
/// # `serde` support
190
///
191
/// When the `serde` feature of this crate is enabled, it provides support for
192
/// serializing and deserializing ECDSA signatures using the `Serialize` and
193
/// `Deserialize` traits.
194
///
195
/// The serialization uses a hexadecimal encoding when used with
196
/// "human readable" text formats, and a binary encoding otherwise.
197
#[derive(Clone, Eq, PartialEq)]
198
pub struct Signature<C: PrimeCurve> {
199
    r: ScalarPrimitive<C>,
200
    s: ScalarPrimitive<C>,
201
}
202
203
impl<C> Signature<C>
204
where
205
    C: PrimeCurve,
206
    SignatureSize<C>: ArrayLength<u8>,
207
{
208
    /// Parse a signature from fixed-width bytes, i.e. 2 * the size of
209
    /// [`FieldBytes`] for a particular curve.
210
    ///
211
    /// # Returns
212
    /// - `Ok(signature)` if the `r` and `s` components are both in the valid
213
    ///   range `1..n` when serialized as concatenated big endian integers.
214
    /// - `Err(err)` if the `r` and/or `s` component of the signature is
215
    ///   out-of-range when interpreted as a big endian integer.
216
1.42k
    pub fn from_bytes(bytes: &SignatureBytes<C>) -> Result<Self> {
217
1.42k
        let (r_bytes, s_bytes) = bytes.split_at(C::FieldBytesSize::USIZE);
218
1.42k
        let r = FieldBytes::<C>::clone_from_slice(r_bytes);
219
1.42k
        let s = FieldBytes::<C>::clone_from_slice(s_bytes);
220
1.42k
        Self::from_scalars(r, s)
221
1.42k
    }
_RNvMCs56dDIOPvtI3_5ecdsaINtB2_9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256E10from_bytesCs4RkbDk9WRL5_5clvmr
Line
Count
Source
216
871
    pub fn from_bytes(bytes: &SignatureBytes<C>) -> Result<Self> {
217
871
        let (r_bytes, s_bytes) = bytes.split_at(C::FieldBytesSize::USIZE);
218
871
        let r = FieldBytes::<C>::clone_from_slice(r_bytes);
219
871
        let s = FieldBytes::<C>::clone_from_slice(s_bytes);
220
871
        Self::from_scalars(r, s)
221
871
    }
_RNvMCs56dDIOPvtI3_5ecdsaINtB2_9SignatureNtCsjewTDwKBbyD_4k2569Secp256k1E10from_bytesCs4RkbDk9WRL5_5clvmr
Line
Count
Source
216
558
    pub fn from_bytes(bytes: &SignatureBytes<C>) -> Result<Self> {
217
558
        let (r_bytes, s_bytes) = bytes.split_at(C::FieldBytesSize::USIZE);
218
558
        let r = FieldBytes::<C>::clone_from_slice(r_bytes);
219
558
        let s = FieldBytes::<C>::clone_from_slice(s_bytes);
220
558
        Self::from_scalars(r, s)
221
558
    }
Unexecuted instantiation: _RNvMCs56dDIOPvtI3_5ecdsaINtB2_9SignaturepE10from_bytesB2_
222
223
    /// Parse a signature from a byte slice.
224
1.45k
    pub fn from_slice(slice: &[u8]) -> Result<Self> {
225
1.45k
        if slice.len() == SignatureSize::<C>::USIZE {
226
1.42k
            Self::from_bytes(SignatureBytes::<C>::from_slice(slice))
227
        } else {
228
24
            Err(Error::new())
229
        }
230
1.45k
    }
_RNvMCs56dDIOPvtI3_5ecdsaINtB2_9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256E10from_sliceCs4RkbDk9WRL5_5clvmr
Line
Count
Source
224
885
    pub fn from_slice(slice: &[u8]) -> Result<Self> {
225
885
        if slice.len() == SignatureSize::<C>::USIZE {
226
871
            Self::from_bytes(SignatureBytes::<C>::from_slice(slice))
227
        } else {
228
14
            Err(Error::new())
229
        }
230
885
    }
_RNvMCs56dDIOPvtI3_5ecdsaINtB2_9SignatureNtCsjewTDwKBbyD_4k2569Secp256k1E10from_sliceCs4RkbDk9WRL5_5clvmr
Line
Count
Source
224
568
    pub fn from_slice(slice: &[u8]) -> Result<Self> {
225
568
        if slice.len() == SignatureSize::<C>::USIZE {
226
558
            Self::from_bytes(SignatureBytes::<C>::from_slice(slice))
227
        } else {
228
10
            Err(Error::new())
229
        }
230
568
    }
Unexecuted instantiation: _RNvMCs56dDIOPvtI3_5ecdsaINtB2_9SignaturepE10from_sliceB2_
231
232
    /// Parse a signature from ASN.1 DER.
233
    #[cfg(feature = "der")]
234
0
    pub fn from_der(bytes: &[u8]) -> Result<Self>
235
0
    where
236
0
        der::MaxSize<C>: ArrayLength<u8>,
237
0
        <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
238
0
    {
239
0
        der::Signature::<C>::try_from(bytes).and_then(Self::try_from)
240
0
    }
241
242
    /// Create a [`Signature`] from the serialized `r` and `s` scalar values
243
    /// which comprise the signature.
244
    ///
245
    /// # Returns
246
    /// - `Ok(signature)` if the `r` and `s` components are both in the valid
247
    ///   range `1..n` when serialized as concatenated big endian integers.
248
    /// - `Err(err)` if the `r` and/or `s` component of the signature is
249
    ///   out-of-range when interpreted as a big endian integer.
250
1.42k
    pub fn from_scalars(r: impl Into<FieldBytes<C>>, s: impl Into<FieldBytes<C>>) -> Result<Self> {
251
1.42k
        let r = ScalarPrimitive::from_slice(&r.into()).map_err(|_| Error::new())?;
_RNCINvMCs56dDIOPvtI3_5ecdsaINtB5_9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256E12from_scalarsINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2a_IB2a_IB2a_IB2a_IB2a_NtB2c_5UTermNtNtB2e_3bit2B1ENtB3n_2B0EB3B_EB3B_EB3B_EB3B_EEB1o_E0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
251
10
        let r = ScalarPrimitive::from_slice(&r.into()).map_err(|_| Error::new())?;
Unexecuted instantiation: _RNCINvMCs56dDIOPvtI3_5ecdsaINtB5_9SignatureNtCsjewTDwKBbyD_4k2569Secp256k1E12from_scalarsINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2b_IB2b_IB2b_IB2b_IB2b_NtB2d_5UTermNtNtB2f_3bit2B1ENtB3o_2B0EB3C_EB3C_EB3C_EB3C_EEB1p_E0Cs4RkbDk9WRL5_5clvmr
Unexecuted instantiation: _RNCINvMCs56dDIOPvtI3_5ecdsaINtB5_9SignaturepE12from_scalarsppE0B5_
252
1.41k
        let s = ScalarPrimitive::from_slice(&s.into()).map_err(|_| Error::new())?;
_RNCINvMCs56dDIOPvtI3_5ecdsaINtB5_9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256E12from_scalarsINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2a_IB2a_IB2a_IB2a_IB2a_NtB2c_5UTermNtNtB2e_3bit2B1ENtB3n_2B0EB3B_EB3B_EB3B_EB3B_EEB1o_Es_0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
252
10
        let s = ScalarPrimitive::from_slice(&s.into()).map_err(|_| Error::new())?;
_RNCINvMCs56dDIOPvtI3_5ecdsaINtB5_9SignatureNtCsjewTDwKBbyD_4k2569Secp256k1E12from_scalarsINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2b_IB2b_IB2b_IB2b_IB2b_NtB2d_5UTermNtNtB2f_3bit2B1ENtB3o_2B0EB3C_EB3C_EB3C_EB3C_EEB1p_Es_0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
252
10
        let s = ScalarPrimitive::from_slice(&s.into()).map_err(|_| Error::new())?;
Unexecuted instantiation: _RNCINvMCs56dDIOPvtI3_5ecdsaINtB5_9SignaturepE12from_scalarsppEs_0B5_
253
254
1.39k
        if r.is_zero().into() || s.is_zero().into() {
255
27
            return Err(Error::new());
256
1.37k
        }
257
1.37k
258
1.37k
        Ok(Self { r, s })
259
1.42k
    }
_RINvMCs56dDIOPvtI3_5ecdsaINtB3_9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256E12from_scalarsINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB28_IB28_IB28_IB28_IB28_NtB2a_5UTermNtNtB2c_3bit2B1ENtB3l_2B0EB3z_EB3z_EB3z_EB3z_EEB1m_ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
250
871
    pub fn from_scalars(r: impl Into<FieldBytes<C>>, s: impl Into<FieldBytes<C>>) -> Result<Self> {
251
871
        let r = ScalarPrimitive::from_slice(&r.into()).map_err(|_| Error::new())?;
252
861
        let s = ScalarPrimitive::from_slice(&s.into()).map_err(|_| Error::new())?;
253
254
851
        if r.is_zero().into() || s.is_zero().into() {
255
13
            return Err(Error::new());
256
838
        }
257
838
258
838
        Ok(Self { r, s })
259
871
    }
_RINvMCs56dDIOPvtI3_5ecdsaINtB3_9SignatureNtCsjewTDwKBbyD_4k2569Secp256k1E12from_scalarsINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB29_IB29_IB29_IB29_IB29_NtB2b_5UTermNtNtB2d_3bit2B1ENtB3m_2B0EB3A_EB3A_EB3A_EB3A_EEB1n_ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
250
558
    pub fn from_scalars(r: impl Into<FieldBytes<C>>, s: impl Into<FieldBytes<C>>) -> Result<Self> {
251
558
        let r = ScalarPrimitive::from_slice(&r.into()).map_err(|_| Error::new())?;
252
558
        let s = ScalarPrimitive::from_slice(&s.into()).map_err(|_| Error::new())?;
253
254
548
        if r.is_zero().into() || s.is_zero().into() {
255
14
            return Err(Error::new());
256
534
        }
257
534
258
534
        Ok(Self { r, s })
259
558
    }
Unexecuted instantiation: _RINvMCs56dDIOPvtI3_5ecdsaINtB3_9SignaturepE12from_scalarsppEB3_
260
261
    /// Split the signature into its `r` and `s` components, represented as bytes.
262
0
    pub fn split_bytes(&self) -> (FieldBytes<C>, FieldBytes<C>) {
263
0
        (self.r.to_bytes(), self.s.to_bytes())
264
0
    }
265
266
    /// Serialize this signature as bytes.
267
0
    pub fn to_bytes(&self) -> SignatureBytes<C> {
268
0
        let mut bytes = SignatureBytes::<C>::default();
269
0
        let (r_bytes, s_bytes) = bytes.split_at_mut(C::FieldBytesSize::USIZE);
270
0
        r_bytes.copy_from_slice(&self.r.to_bytes());
271
0
        s_bytes.copy_from_slice(&self.s.to_bytes());
272
0
        bytes
273
0
    }
274
275
    /// Serialize this signature as ASN.1 DER.
276
    #[cfg(feature = "der")]
277
0
    pub fn to_der(&self) -> der::Signature<C>
278
0
    where
279
0
        der::MaxSize<C>: ArrayLength<u8>,
280
0
        <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
281
0
    {
282
0
        let (r, s) = self.split_bytes();
283
0
        der::Signature::from_components(&r, &s).expect("DER encoding error")
284
0
    }
285
286
    /// Convert this signature into a byte vector.
287
    #[cfg(feature = "alloc")]
288
0
    pub fn to_vec(&self) -> Vec<u8> {
289
0
        self.to_bytes().to_vec()
290
0
    }
291
}
292
293
#[cfg(feature = "arithmetic")]
294
impl<C> Signature<C>
295
where
296
    C: PrimeCurve + CurveArithmetic,
297
    SignatureSize<C>: ArrayLength<u8>,
298
{
299
    /// Get the `r` component of this signature
300
1.36k
    pub fn r(&self) -> NonZeroScalar<C> {
301
1.36k
        NonZeroScalar::new(self.r.into()).unwrap()
302
1.36k
    }
_RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256E1rCs4RkbDk9WRL5_5clvmr
Line
Count
Source
300
838
    pub fn r(&self) -> NonZeroScalar<C> {
301
838
        NonZeroScalar::new(self.r.into()).unwrap()
302
838
    }
Unexecuted instantiation: _RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignaturepE1rB4_
_RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignatureNtCsjewTDwKBbyD_4k2569Secp256k1E1rBG_
Line
Count
Source
300
523
    pub fn r(&self) -> NonZeroScalar<C> {
301
523
        NonZeroScalar::new(self.r.into()).unwrap()
302
523
    }
Unexecuted instantiation: _RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256E1rBG_
303
304
    /// Get the `s` component of this signature
305
1.89k
    pub fn s(&self) -> NonZeroScalar<C> {
306
1.89k
        NonZeroScalar::new(self.s.into()).unwrap()
307
1.89k
    }
_RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256E1sCs4RkbDk9WRL5_5clvmr
Line
Count
Source
305
838
    pub fn s(&self) -> NonZeroScalar<C> {
306
838
        NonZeroScalar::new(self.s.into()).unwrap()
307
838
    }
Unexecuted instantiation: _RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignaturepE1sB4_
_RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignatureNtCsjewTDwKBbyD_4k2569Secp256k1E1sBG_
Line
Count
Source
305
1.05k
    pub fn s(&self) -> NonZeroScalar<C> {
306
1.05k
        NonZeroScalar::new(self.s.into()).unwrap()
307
1.05k
    }
Unexecuted instantiation: _RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256E1sBG_
308
309
    /// Split the signature into its `r` and `s` scalars.
310
1.36k
    pub fn split_scalars(&self) -> (NonZeroScalar<C>, NonZeroScalar<C>) {
311
1.36k
        (self.r(), self.s())
312
1.36k
    }
_RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256E13split_scalarsCs4RkbDk9WRL5_5clvmr
Line
Count
Source
310
838
    pub fn split_scalars(&self) -> (NonZeroScalar<C>, NonZeroScalar<C>) {
311
838
        (self.r(), self.s())
312
838
    }
Unexecuted instantiation: _RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignaturepE13split_scalarsB4_
_RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignatureNtCsjewTDwKBbyD_4k2569Secp256k1E13split_scalarsBG_
Line
Count
Source
310
523
    pub fn split_scalars(&self) -> (NonZeroScalar<C>, NonZeroScalar<C>) {
311
523
        (self.r(), self.s())
312
523
    }
Unexecuted instantiation: _RNvMs_Cs56dDIOPvtI3_5ecdsaINtB4_9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256E13split_scalarsBG_
313
314
    /// Normalize signature into "low S" form as described in
315
    /// [BIP 0062: Dealing with Malleability][1].
316
    ///
317
    /// [1]: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
318
0
    pub fn normalize_s(&self) -> Option<Self> {
319
0
        let s = self.s();
320
0
321
0
        if s.is_high().into() {
322
0
            let mut result = self.clone();
323
0
            result.s = ScalarPrimitive::from(-s);
324
0
            Some(result)
325
        } else {
326
0
            None
327
        }
328
0
    }
329
}
330
331
impl<C> Copy for Signature<C>
332
where
333
    C: PrimeCurve,
334
    SignatureSize<C>: ArrayLength<u8>,
335
    <SignatureSize<C> as ArrayLength<u8>>::ArrayType: Copy,
336
{
337
}
338
339
impl<C> From<Signature<C>> for SignatureBytes<C>
340
where
341
    C: PrimeCurve,
342
    SignatureSize<C>: ArrayLength<u8>,
343
{
344
0
    fn from(signature: Signature<C>) -> SignatureBytes<C> {
345
0
        signature.to_bytes()
346
0
    }
347
}
348
349
impl<C> SignatureEncoding for Signature<C>
350
where
351
    C: PrimeCurve,
352
    SignatureSize<C>: ArrayLength<u8>,
353
{
354
    type Repr = SignatureBytes<C>;
355
}
356
357
impl<C> TryFrom<&[u8]> for Signature<C>
358
where
359
    C: PrimeCurve,
360
    SignatureSize<C>: ArrayLength<u8>,
361
{
362
    type Error = Error;
363
364
0
    fn try_from(slice: &[u8]) -> Result<Self> {
365
0
        Self::from_slice(slice)
366
0
    }
367
}
368
369
impl<C> fmt::Debug for Signature<C>
370
where
371
    C: PrimeCurve,
372
    SignatureSize<C>: ArrayLength<u8>,
373
{
374
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
375
0
        write!(f, "ecdsa::Signature<{:?}>(", C::default())?;
376
377
0
        for byte in self.to_bytes() {
378
0
            write!(f, "{:02X}", byte)?;
379
        }
380
381
0
        write!(f, ")")
382
0
    }
383
}
384
385
impl<C> fmt::Display for Signature<C>
386
where
387
    C: PrimeCurve,
388
    SignatureSize<C>: ArrayLength<u8>,
389
{
390
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
391
0
        write!(f, "{:X}", self)
392
0
    }
393
}
394
395
impl<C> fmt::LowerHex for Signature<C>
396
where
397
    C: PrimeCurve,
398
    SignatureSize<C>: ArrayLength<u8>,
399
{
400
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
401
0
        for byte in self.to_bytes() {
402
0
            write!(f, "{:02x}", byte)?;
403
        }
404
0
        Ok(())
405
0
    }
406
}
407
408
impl<C> fmt::UpperHex for Signature<C>
409
where
410
    C: PrimeCurve,
411
    SignatureSize<C>: ArrayLength<u8>,
412
{
413
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
414
0
        for byte in self.to_bytes() {
415
0
            write!(f, "{:02X}", byte)?;
416
        }
417
0
        Ok(())
418
0
    }
419
}
420
421
#[cfg(feature = "arithmetic")]
422
impl<C> str::FromStr for Signature<C>
423
where
424
    C: PrimeCurve + CurveArithmetic,
425
    SignatureSize<C>: ArrayLength<u8>,
426
{
427
    type Err = Error;
428
429
0
    fn from_str(hex: &str) -> Result<Self> {
430
0
        if hex.as_bytes().len() != C::FieldBytesSize::USIZE * 4 {
431
0
            return Err(Error::new());
432
0
        }
433
0
434
0
        // This check is mainly to ensure `hex.split_at` below won't panic
435
0
        if !hex
436
0
            .as_bytes()
437
0
            .iter()
438
0
            .all(|&byte| matches!(byte, b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z'))
439
        {
440
0
            return Err(Error::new());
441
0
        }
442
0
443
0
        let (r_hex, s_hex) = hex.split_at(C::FieldBytesSize::USIZE * 2);
444
445
0
        let r = r_hex
446
0
            .parse::<NonZeroScalar<C>>()
447
0
            .map_err(|_| Error::new())?;
448
449
0
        let s = s_hex
450
0
            .parse::<NonZeroScalar<C>>()
451
0
            .map_err(|_| Error::new())?;
452
453
0
        Self::from_scalars(r, s)
454
0
    }
455
}
456
457
/// ECDSA [`ObjectIdentifier`] which identifies the digest used by default
458
/// with the `Signer` and `Verifier` traits.
459
///
460
/// To support non-default digest algorithms, use the [`SignatureWithOid`]
461
/// type instead.
462
#[cfg(all(feature = "digest", feature = "hazmat"))]
463
impl<C> AssociatedOid for Signature<C>
464
where
465
    C: hazmat::DigestPrimitive,
466
    C::Digest: AssociatedOid,
467
{
468
    const OID: ObjectIdentifier = match ecdsa_oid_for_digest(C::Digest::OID) {
469
        Some(oid) => oid,
470
        None => panic!("no RFC5758 ECDSA OID defined for DigestPrimitive::Digest"),
471
    };
472
}
473
474
/// ECDSA `AlgorithmIdentifier` which identifies the digest used by default
475
/// with the `Signer` and `Verifier` traits.
476
#[cfg(feature = "pkcs8")]
477
impl<C> AssociatedAlgorithmIdentifier for Signature<C>
478
where
479
    C: PrimeCurve,
480
    Self: AssociatedOid,
481
{
482
    type Params = AnyRef<'static>;
483
484
    const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = AlgorithmIdentifierRef {
485
        oid: Self::OID,
486
        parameters: None,
487
    };
488
}
489
490
#[cfg(feature = "serde")]
491
impl<C> Serialize for Signature<C>
492
where
493
    C: PrimeCurve,
494
    SignatureSize<C>: ArrayLength<u8>,
495
{
496
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
497
    where
498
        S: ser::Serializer,
499
    {
500
        serdect::array::serialize_hex_upper_or_bin(&self.to_bytes(), serializer)
501
    }
502
}
503
504
#[cfg(feature = "serde")]
505
impl<'de, C> Deserialize<'de> for Signature<C>
506
where
507
    C: PrimeCurve,
508
    SignatureSize<C>: ArrayLength<u8>,
509
{
510
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
511
    where
512
        D: de::Deserializer<'de>,
513
    {
514
        let mut bytes = SignatureBytes::<C>::default();
515
        serdect::array::deserialize_hex_or_bin(&mut bytes, deserializer)?;
516
        Self::try_from(bytes.as_slice()).map_err(de::Error::custom)
517
    }
518
}
519
520
/// An extended [`Signature`] type which is parameterized by an
521
/// `ObjectIdentifier` which identifies the ECDSA variant used by a
522
/// particular signature.
523
///
524
/// Valid `ObjectIdentifiers` are defined in [RFC5758 § 3.2]:
525
///
526
/// - SHA-224: [`ECDSA_SHA224_OID`] (1.2.840.10045.4.3.1)
527
/// - SHA-256: [`ECDSA_SHA256_OID`] (1.2.840.10045.4.3.2)
528
/// - SHA-384: [`ECDSA_SHA384_OID`] (1.2.840.10045.4.3.3)
529
/// - SHA-512: [`ECDSA_SHA512_OID`] (1.2.840.10045.4.3.4)
530
///
531
/// [RFC5758 § 3.2]: https://www.rfc-editor.org/rfc/rfc5758#section-3.2
532
#[cfg(feature = "digest")]
533
#[derive(Clone, Eq, PartialEq)]
534
pub struct SignatureWithOid<C: PrimeCurve> {
535
    /// Inner signature type.
536
    signature: Signature<C>,
537
538
    /// OID which identifies the ECDSA variant used.
539
    ///
540
    /// MUST be one of the ECDSA algorithm variants as defined in RFC5758.
541
    ///
542
    /// These OIDs begin with `1.2.840.10045.4`.
543
    oid: ObjectIdentifier,
544
}
545
546
#[cfg(feature = "digest")]
547
impl<C> SignatureWithOid<C>
548
where
549
    C: PrimeCurve,
550
{
551
    /// Create a new signature with an explicitly provided OID.
552
    ///
553
    /// OID must begin with `1.2.840.10045.4`, the [RFC5758] OID prefix for
554
    /// ECDSA variants.
555
    ///
556
    /// [RFC5758]: https://www.rfc-editor.org/rfc/rfc5758#section-3.2
557
0
    pub fn new(signature: Signature<C>, oid: ObjectIdentifier) -> Result<Self> {
558
        // TODO(tarcieri): use `ObjectIdentifier::starts_with`
559
0
        for (arc1, arc2) in ObjectIdentifier::new_unwrap("1.2.840.10045.4.3")
560
0
            .arcs()
561
0
            .zip(oid.arcs())
562
        {
563
0
            if arc1 != arc2 {
564
0
                return Err(Error::new());
565
0
            }
566
        }
567
568
0
        Ok(Self { signature, oid })
569
0
    }
570
571
    /// Create a new signature, determining the OID from the given digest.
572
    ///
573
    /// Supports SHA-2 family digests as enumerated in [RFC5758 § 3.2], i.e.
574
    /// SHA-224, SHA-256, SHA-384, or SHA-512.
575
    ///
576
    /// [RFC5758 § 3.2]: https://www.rfc-editor.org/rfc/rfc5758#section-3.2
577
0
    pub fn new_with_digest<D>(signature: Signature<C>) -> Result<Self>
578
0
    where
579
0
        D: AssociatedOid + Digest,
580
0
    {
581
0
        let oid = ecdsa_oid_for_digest(D::OID).ok_or_else(Error::new)?;
582
0
        Ok(Self { signature, oid })
583
0
    }
584
585
    /// Parse a signature from fixed-with bytes.
586
0
    pub fn from_bytes_with_digest<D>(bytes: &SignatureBytes<C>) -> Result<Self>
587
0
    where
588
0
        D: AssociatedOid + Digest,
589
0
        SignatureSize<C>: ArrayLength<u8>,
590
0
    {
591
0
        Self::new_with_digest::<D>(Signature::<C>::from_bytes(bytes)?)
592
0
    }
593
594
    /// Parse a signature from a byte slice.
595
0
    pub fn from_slice_with_digest<D>(slice: &[u8]) -> Result<Self>
596
0
    where
597
0
        D: AssociatedOid + Digest,
598
0
        SignatureSize<C>: ArrayLength<u8>,
599
0
    {
600
0
        Self::new_with_digest::<D>(Signature::<C>::from_slice(slice)?)
601
0
    }
602
603
    /// Get the fixed-width ECDSA signature.
604
0
    pub fn signature(&self) -> &Signature<C> {
605
0
        &self.signature
606
0
    }
607
608
    /// Get the ECDSA OID for this signature.
609
0
    pub fn oid(&self) -> ObjectIdentifier {
610
0
        self.oid
611
0
    }
612
613
    /// Serialize this signature as bytes.
614
0
    pub fn to_bytes(&self) -> SignatureBytes<C>
615
0
    where
616
0
        SignatureSize<C>: ArrayLength<u8>,
617
0
    {
618
0
        self.signature.to_bytes()
619
0
    }
620
}
621
622
#[cfg(feature = "digest")]
623
impl<C> Copy for SignatureWithOid<C>
624
where
625
    C: PrimeCurve,
626
    SignatureSize<C>: ArrayLength<u8>,
627
    <SignatureSize<C> as ArrayLength<u8>>::ArrayType: Copy,
628
{
629
}
630
631
#[cfg(feature = "digest")]
632
impl<C> From<SignatureWithOid<C>> for Signature<C>
633
where
634
    C: PrimeCurve,
635
{
636
0
    fn from(sig: SignatureWithOid<C>) -> Signature<C> {
637
0
        sig.signature
638
0
    }
639
}
640
641
#[cfg(feature = "digest")]
642
impl<C> From<SignatureWithOid<C>> for SignatureBytes<C>
643
where
644
    C: PrimeCurve,
645
    SignatureSize<C>: ArrayLength<u8>,
646
{
647
0
    fn from(signature: SignatureWithOid<C>) -> SignatureBytes<C> {
648
0
        signature.to_bytes()
649
0
    }
650
}
651
652
/// NOTE: this implementation assumes the default digest for the given elliptic
653
/// curve as defined by [`hazmat::DigestPrimitive`].
654
///
655
/// When working with alternative digests, you will need to use e.g.
656
/// [`SignatureWithOid::new_with_digest`].
657
#[cfg(all(feature = "digest", feature = "hazmat"))]
658
impl<C> SignatureEncoding for SignatureWithOid<C>
659
where
660
    C: hazmat::DigestPrimitive,
661
    C::Digest: AssociatedOid,
662
    SignatureSize<C>: ArrayLength<u8>,
663
{
664
    type Repr = SignatureBytes<C>;
665
}
666
667
/// NOTE: this implementation assumes the default digest for the given elliptic
668
/// curve as defined by [`hazmat::DigestPrimitive`].
669
///
670
/// When working with alternative digests, you will need to use e.g.
671
/// [`SignatureWithOid::new_with_digest`].
672
#[cfg(all(feature = "digest", feature = "hazmat"))]
673
impl<C> TryFrom<&[u8]> for SignatureWithOid<C>
674
where
675
    C: hazmat::DigestPrimitive,
676
    C::Digest: AssociatedOid,
677
    SignatureSize<C>: ArrayLength<u8>,
678
{
679
    type Error = Error;
680
681
0
    fn try_from(slice: &[u8]) -> Result<Self> {
682
0
        Self::new(Signature::<C>::from_slice(slice)?, C::Digest::OID)
683
0
    }
684
}
685
686
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
687
impl<C> DynAssociatedAlgorithmIdentifier for SignatureWithOid<C>
688
where
689
    C: PrimeCurve,
690
{
691
0
    fn algorithm_identifier(&self) -> spki::Result<AlgorithmIdentifierOwned> {
692
0
        Ok(AlgorithmIdentifierOwned {
693
0
            oid: self.oid,
694
0
            parameters: None,
695
0
        })
696
0
    }
697
}
698
699
/// Get the ECDSA OID for a given digest OID.
700
#[cfg(feature = "digest")]
701
0
const fn ecdsa_oid_for_digest(digest_oid: ObjectIdentifier) -> Option<ObjectIdentifier> {
702
0
    match digest_oid {
703
0
        SHA224_OID => Some(ECDSA_SHA224_OID),
704
0
        SHA256_OID => Some(ECDSA_SHA256_OID),
705
0
        SHA384_OID => Some(ECDSA_SHA384_OID),
706
0
        SHA512_OID => Some(ECDSA_SHA512_OID),
707
0
        _ => None,
708
    }
709
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ecdsa-0.16.9/src/recovery.rs
Line
Count
Source
1
//! Public key recovery support.
2
3
use crate::{Error, Result};
4
5
#[cfg(feature = "signing")]
6
use {
7
    crate::{hazmat::SignPrimitive, SigningKey},
8
    elliptic_curve::subtle::CtOption,
9
    signature::{hazmat::PrehashSigner, DigestSigner, Signer},
10
};
11
12
#[cfg(feature = "verifying")]
13
use {
14
    crate::{hazmat::VerifyPrimitive, VerifyingKey},
15
    elliptic_curve::{
16
        bigint::CheckedAdd,
17
        ops::{LinearCombination, Reduce},
18
        point::DecompressPoint,
19
        sec1::{self, FromEncodedPoint, ToEncodedPoint},
20
        AffinePoint, FieldBytesEncoding, FieldBytesSize, Group, PrimeField, ProjectivePoint,
21
    },
22
    signature::hazmat::PrehashVerifier,
23
};
24
25
#[cfg(any(feature = "signing", feature = "verifying"))]
26
use {
27
    crate::{
28
        hazmat::{bits2field, DigestPrimitive},
29
        Signature, SignatureSize,
30
    },
31
    elliptic_curve::{
32
        generic_array::ArrayLength, ops::Invert, CurveArithmetic, PrimeCurve, Scalar,
33
    },
34
    signature::digest::Digest,
35
};
36
37
/// Recovery IDs, a.k.a. "recid".
38
///
39
/// This is an integer value `0`, `1`, `2`, or `3` included along with a
40
/// signature which is used during the recovery process to select the correct
41
/// public key from the signature.
42
///
43
/// It consists of two bits of information:
44
///
45
/// - low bit (0/1): was the y-coordinate of the affine point resulting from
46
///   the fixed-base multiplication 𝑘×𝑮 odd? This part of the algorithm
47
///   functions similar to point decompression.
48
/// - hi bit (3/4): did the affine x-coordinate of 𝑘×𝑮 overflow the order of
49
///   the scalar field, requiring a reduction when computing `r`?
50
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
51
pub struct RecoveryId(u8);
52
53
impl RecoveryId {
54
    /// Maximum supported value for the recovery ID (inclusive).
55
    pub const MAX: u8 = 3;
56
57
    /// Create a new [`RecoveryId`] from the following 1-bit arguments:
58
    ///
59
    /// - `is_y_odd`: is the affine y-coordinate of 𝑘×𝑮 odd?
60
    /// - `is_x_reduced`: did the affine x-coordinate of 𝑘×𝑮 overflow the curve order?
61
0
    pub const fn new(is_y_odd: bool, is_x_reduced: bool) -> Self {
62
0
        Self((is_x_reduced as u8) << 1 | (is_y_odd as u8))
63
0
    }
64
65
    /// Did the affine x-coordinate of 𝑘×𝑮 overflow the curve order?
66
0
    pub const fn is_x_reduced(self) -> bool {
67
0
        (self.0 & 0b10) != 0
68
0
    }
69
70
    /// Is the affine y-coordinate of 𝑘×𝑮 odd?
71
0
    pub const fn is_y_odd(self) -> bool {
72
0
        (self.0 & 1) != 0
73
0
    }
74
75
    /// Convert a `u8` into a [`RecoveryId`].
76
0
    pub const fn from_byte(byte: u8) -> Option<Self> {
77
0
        if byte <= Self::MAX {
78
0
            Some(Self(byte))
79
        } else {
80
0
            None
81
        }
82
0
    }
83
84
    /// Convert this [`RecoveryId`] into a `u8`.
85
0
    pub const fn to_byte(self) -> u8 {
86
0
        self.0
87
0
    }
88
}
89
90
#[cfg(feature = "verifying")]
91
impl RecoveryId {
92
    /// Given a public key, message, and signature, use trial recovery
93
    /// to determine if a suitable recovery ID exists, or return an error
94
    /// otherwise.
95
0
    pub fn trial_recovery_from_msg<C>(
96
0
        verifying_key: &VerifyingKey<C>,
97
0
        msg: &[u8],
98
0
        signature: &Signature<C>,
99
0
    ) -> Result<Self>
100
0
    where
101
0
        C: DigestPrimitive + PrimeCurve + CurveArithmetic,
102
0
        AffinePoint<C>:
103
0
            DecompressPoint<C> + FromEncodedPoint<C> + ToEncodedPoint<C> + VerifyPrimitive<C>,
104
0
        FieldBytesSize<C>: sec1::ModulusSize,
105
0
        SignatureSize<C>: ArrayLength<u8>,
106
0
    {
107
0
        Self::trial_recovery_from_digest(verifying_key, C::Digest::new_with_prefix(msg), signature)
108
0
    }
109
110
    /// Given a public key, message digest, and signature, use trial recovery
111
    /// to determine if a suitable recovery ID exists, or return an error
112
    /// otherwise.
113
0
    pub fn trial_recovery_from_digest<C, D>(
114
0
        verifying_key: &VerifyingKey<C>,
115
0
        digest: D,
116
0
        signature: &Signature<C>,
117
0
    ) -> Result<Self>
118
0
    where
119
0
        C: PrimeCurve + CurveArithmetic,
120
0
        D: Digest,
121
0
        AffinePoint<C>:
122
0
            DecompressPoint<C> + FromEncodedPoint<C> + ToEncodedPoint<C> + VerifyPrimitive<C>,
123
0
        FieldBytesSize<C>: sec1::ModulusSize,
124
0
        SignatureSize<C>: ArrayLength<u8>,
125
0
    {
126
0
        Self::trial_recovery_from_prehash(verifying_key, &digest.finalize(), signature)
127
0
    }
128
129
    /// Given a public key, message digest, and signature, use trial recovery
130
    /// to determine if a suitable recovery ID exists, or return an error
131
    /// otherwise.
132
0
    pub fn trial_recovery_from_prehash<C>(
133
0
        verifying_key: &VerifyingKey<C>,
134
0
        prehash: &[u8],
135
0
        signature: &Signature<C>,
136
0
    ) -> Result<Self>
137
0
    where
138
0
        C: PrimeCurve + CurveArithmetic,
139
0
        AffinePoint<C>:
140
0
            DecompressPoint<C> + FromEncodedPoint<C> + ToEncodedPoint<C> + VerifyPrimitive<C>,
141
0
        FieldBytesSize<C>: sec1::ModulusSize,
142
0
        SignatureSize<C>: ArrayLength<u8>,
143
0
    {
144
0
        for id in 0..=Self::MAX {
145
0
            let recovery_id = RecoveryId(id);
146
147
0
            if let Ok(vk) = VerifyingKey::recover_from_prehash(prehash, signature, recovery_id) {
148
0
                if verifying_key == &vk {
149
0
                    return Ok(recovery_id);
150
0
                }
151
0
            }
152
        }
153
154
0
        Err(Error::new())
155
0
    }
156
}
157
158
impl TryFrom<u8> for RecoveryId {
159
    type Error = Error;
160
161
0
    fn try_from(byte: u8) -> Result<Self> {
162
0
        Self::from_byte(byte).ok_or_else(Error::new)
163
0
    }
164
}
165
166
impl From<RecoveryId> for u8 {
167
0
    fn from(id: RecoveryId) -> u8 {
168
0
        id.0
169
0
    }
170
}
171
172
#[cfg(feature = "signing")]
173
impl<C> SigningKey<C>
174
where
175
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
176
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
177
    SignatureSize<C>: ArrayLength<u8>,
178
{
179
    /// Sign the given message prehash, returning a signature and recovery ID.
180
0
    pub fn sign_prehash_recoverable(&self, prehash: &[u8]) -> Result<(Signature<C>, RecoveryId)> {
181
0
        let z = bits2field::<C>(prehash)?;
182
0
        let (sig, recid) = self
183
0
            .as_nonzero_scalar()
184
0
            .try_sign_prehashed_rfc6979::<C::Digest>(&z, &[])?;
185
186
0
        Ok((sig, recid.ok_or_else(Error::new)?))
187
0
    }
188
189
    /// Sign the given message digest, returning a signature and recovery ID.
190
0
    pub fn sign_digest_recoverable<D>(&self, msg_digest: D) -> Result<(Signature<C>, RecoveryId)>
191
0
    where
192
0
        D: Digest,
193
0
    {
194
0
        self.sign_prehash_recoverable(&msg_digest.finalize())
195
0
    }
196
197
    /// Sign the given message, hashing it with the curve's default digest
198
    /// function, and returning a signature and recovery ID.
199
0
    pub fn sign_recoverable(&self, msg: &[u8]) -> Result<(Signature<C>, RecoveryId)> {
200
0
        self.sign_digest_recoverable(C::Digest::new_with_prefix(msg))
201
0
    }
202
}
203
204
#[cfg(feature = "signing")]
205
impl<C, D> DigestSigner<D, (Signature<C>, RecoveryId)> for SigningKey<C>
206
where
207
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
208
    D: Digest,
209
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
210
    SignatureSize<C>: ArrayLength<u8>,
211
{
212
0
    fn try_sign_digest(&self, msg_digest: D) -> Result<(Signature<C>, RecoveryId)> {
213
0
        self.sign_digest_recoverable(msg_digest)
214
0
    }
215
}
216
217
#[cfg(feature = "signing")]
218
impl<C> PrehashSigner<(Signature<C>, RecoveryId)> for SigningKey<C>
219
where
220
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
221
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
222
    SignatureSize<C>: ArrayLength<u8>,
223
{
224
0
    fn sign_prehash(&self, prehash: &[u8]) -> Result<(Signature<C>, RecoveryId)> {
225
0
        self.sign_prehash_recoverable(prehash)
226
0
    }
227
}
228
229
#[cfg(feature = "signing")]
230
impl<C> Signer<(Signature<C>, RecoveryId)> for SigningKey<C>
231
where
232
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
233
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
234
    SignatureSize<C>: ArrayLength<u8>,
235
{
236
0
    fn try_sign(&self, msg: &[u8]) -> Result<(Signature<C>, RecoveryId)> {
237
0
        self.sign_recoverable(msg)
238
0
    }
239
}
240
241
#[cfg(feature = "verifying")]
242
impl<C> VerifyingKey<C>
243
where
244
    C: PrimeCurve + CurveArithmetic,
245
    AffinePoint<C>:
246
        DecompressPoint<C> + FromEncodedPoint<C> + ToEncodedPoint<C> + VerifyPrimitive<C>,
247
    FieldBytesSize<C>: sec1::ModulusSize,
248
    SignatureSize<C>: ArrayLength<u8>,
249
{
250
    /// Recover a [`VerifyingKey`] from the given message, signature, and
251
    /// [`RecoveryId`].
252
    ///
253
    /// The message is first hashed using this curve's [`DigestPrimitive`].
254
0
    pub fn recover_from_msg(
255
0
        msg: &[u8],
256
0
        signature: &Signature<C>,
257
0
        recovery_id: RecoveryId,
258
0
    ) -> Result<Self>
259
0
    where
260
0
        C: DigestPrimitive,
261
0
    {
262
0
        Self::recover_from_digest(C::Digest::new_with_prefix(msg), signature, recovery_id)
263
0
    }
264
265
    /// Recover a [`VerifyingKey`] from the given message [`Digest`],
266
    /// signature, and [`RecoveryId`].
267
0
    pub fn recover_from_digest<D>(
268
0
        msg_digest: D,
269
0
        signature: &Signature<C>,
270
0
        recovery_id: RecoveryId,
271
0
    ) -> Result<Self>
272
0
    where
273
0
        D: Digest,
274
0
    {
275
0
        Self::recover_from_prehash(&msg_digest.finalize(), signature, recovery_id)
276
0
    }
277
278
    /// Recover a [`VerifyingKey`] from the given `prehash` of a message, the
279
    /// signature over that prehashed message, and a [`RecoveryId`].
280
    #[allow(non_snake_case)]
281
0
    pub fn recover_from_prehash(
282
0
        prehash: &[u8],
283
0
        signature: &Signature<C>,
284
0
        recovery_id: RecoveryId,
285
0
    ) -> Result<Self> {
286
0
        let (r, s) = signature.split_scalars();
287
0
        let z = <Scalar<C> as Reduce<C::Uint>>::reduce_bytes(&bits2field::<C>(prehash)?);
288
289
0
        let mut r_bytes = r.to_repr();
290
0
        if recovery_id.is_x_reduced() {
291
0
            match Option::<C::Uint>::from(
292
0
                C::Uint::decode_field_bytes(&r_bytes).checked_add(&C::ORDER),
293
0
            ) {
294
0
                Some(restored) => r_bytes = restored.encode_field_bytes(),
295
                // No reduction should happen here if r was reduced
296
0
                None => return Err(Error::new()),
297
            };
298
0
        }
299
0
        let R = AffinePoint::<C>::decompress(&r_bytes, u8::from(recovery_id.is_y_odd()).into());
300
0
301
0
        if R.is_none().into() {
302
0
            return Err(Error::new());
303
0
        }
304
0
305
0
        let R = ProjectivePoint::<C>::from(R.unwrap());
306
0
        let r_inv = *r.invert();
307
0
        let u1 = -(r_inv * z);
308
0
        let u2 = r_inv * *s;
309
0
        let pk = ProjectivePoint::<C>::lincomb(&ProjectivePoint::<C>::generator(), &u1, &R, &u2);
310
0
        let vk = Self::from_affine(pk.into())?;
311
312
        // Ensure signature verifies with the recovered key
313
0
        vk.verify_prehash(prehash, signature)?;
314
315
0
        Ok(vk)
316
0
    }
317
}
318
319
#[cfg(test)]
320
mod tests {
321
    use super::RecoveryId;
322
323
    #[test]
324
    fn new() {
325
        assert_eq!(RecoveryId::new(false, false).to_byte(), 0);
326
        assert_eq!(RecoveryId::new(true, false).to_byte(), 1);
327
        assert_eq!(RecoveryId::new(false, true).to_byte(), 2);
328
        assert_eq!(RecoveryId::new(true, true).to_byte(), 3);
329
    }
330
331
    #[test]
332
    fn try_from() {
333
        for n in 0u8..=3 {
334
            assert_eq!(RecoveryId::try_from(n).unwrap().to_byte(), n);
335
        }
336
337
        for n in 4u8..=255 {
338
            assert!(RecoveryId::try_from(n).is_err());
339
        }
340
    }
341
342
    #[test]
343
    fn is_x_reduced() {
344
        assert_eq!(RecoveryId::try_from(0).unwrap().is_x_reduced(), false);
345
        assert_eq!(RecoveryId::try_from(1).unwrap().is_x_reduced(), false);
346
        assert_eq!(RecoveryId::try_from(2).unwrap().is_x_reduced(), true);
347
        assert_eq!(RecoveryId::try_from(3).unwrap().is_x_reduced(), true);
348
    }
349
350
    #[test]
351
    fn is_y_odd() {
352
        assert_eq!(RecoveryId::try_from(0).unwrap().is_y_odd(), false);
353
        assert_eq!(RecoveryId::try_from(1).unwrap().is_y_odd(), true);
354
        assert_eq!(RecoveryId::try_from(2).unwrap().is_y_odd(), false);
355
        assert_eq!(RecoveryId::try_from(3).unwrap().is_y_odd(), true);
356
    }
357
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ecdsa-0.16.9/src/signing.rs
Line
Count
Source
1
//! ECDSA signing: producing signatures using a [`SigningKey`].
2
3
use crate::{
4
    ecdsa_oid_for_digest,
5
    hazmat::{bits2field, DigestPrimitive, SignPrimitive},
6
    Error, Result, Signature, SignatureSize, SignatureWithOid,
7
};
8
use core::fmt::{self, Debug};
9
use digest::{const_oid::AssociatedOid, Digest, FixedOutput};
10
use elliptic_curve::{
11
    generic_array::ArrayLength,
12
    group::ff::PrimeField,
13
    ops::Invert,
14
    subtle::{Choice, ConstantTimeEq, CtOption},
15
    zeroize::{Zeroize, ZeroizeOnDrop},
16
    CurveArithmetic, FieldBytes, FieldBytesSize, NonZeroScalar, PrimeCurve, Scalar, SecretKey,
17
};
18
use signature::{
19
    hazmat::{PrehashSigner, RandomizedPrehashSigner},
20
    rand_core::CryptoRngCore,
21
    DigestSigner, RandomizedDigestSigner, RandomizedSigner, Signer,
22
};
23
24
#[cfg(feature = "der")]
25
use {crate::der, core::ops::Add};
26
27
#[cfg(feature = "pem")]
28
use {
29
    crate::elliptic_curve::pkcs8::{DecodePrivateKey, EncodePrivateKey, SecretDocument},
30
    core::str::FromStr,
31
};
32
33
#[cfg(feature = "pkcs8")]
34
use crate::elliptic_curve::{
35
    pkcs8::{
36
        self,
37
        der::AnyRef,
38
        spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier, SignatureAlgorithmIdentifier},
39
        ObjectIdentifier,
40
    },
41
    sec1::{self, FromEncodedPoint, ToEncodedPoint},
42
    AffinePoint,
43
};
44
45
#[cfg(feature = "verifying")]
46
use {crate::VerifyingKey, elliptic_curve::PublicKey, signature::KeypairRef};
47
48
/// ECDSA secret key used for signing. Generic over prime order elliptic curves
49
/// (e.g. NIST P-curves)
50
///
51
/// Requires an [`elliptic_curve::CurveArithmetic`] impl on the curve, and a
52
/// [`SignPrimitive`] impl on its associated `Scalar` type.
53
///
54
/// ## Usage
55
///
56
/// The [`signature`] crate defines the following traits which are the
57
/// primary API for signing:
58
///
59
/// - [`Signer`]: sign a message using this key
60
/// - [`DigestSigner`]: sign the output of a [`Digest`] using this key
61
/// - [`PrehashSigner`]: sign the low-level raw output bytes of a message digest
62
///
63
/// See the [`p256` crate](https://docs.rs/p256/latest/p256/ecdsa/index.html)
64
/// for examples of using this type with a concrete elliptic curve.
65
#[derive(Clone)]
66
pub struct SigningKey<C>
67
where
68
    C: PrimeCurve + CurveArithmetic,
69
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
70
    SignatureSize<C>: ArrayLength<u8>,
71
{
72
    /// ECDSA signing keys are non-zero elements of a given curve's scalar field.
73
    secret_scalar: NonZeroScalar<C>,
74
75
    /// Verifying key which corresponds to this signing key.
76
    #[cfg(feature = "verifying")]
77
    verifying_key: VerifyingKey<C>,
78
}
79
80
impl<C> SigningKey<C>
81
where
82
    C: PrimeCurve + CurveArithmetic,
83
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
84
    SignatureSize<C>: ArrayLength<u8>,
85
{
86
    /// Generate a cryptographically random [`SigningKey`].
87
0
    pub fn random(rng: &mut impl CryptoRngCore) -> Self {
88
0
        NonZeroScalar::<C>::random(rng).into()
89
0
    }
90
91
    /// Initialize signing key from a raw scalar serialized as a byte array.
92
0
    pub fn from_bytes(bytes: &FieldBytes<C>) -> Result<Self> {
93
0
        SecretKey::<C>::from_bytes(bytes)
94
0
            .map(Into::into)
95
0
            .map_err(|_| Error::new())
96
0
    }
97
98
    /// Initialize signing key from a raw scalar serialized as a byte slice.
99
0
    pub fn from_slice(bytes: &[u8]) -> Result<Self> {
100
0
        SecretKey::<C>::from_slice(bytes)
101
0
            .map(Into::into)
102
0
            .map_err(|_| Error::new())
103
0
    }
104
105
    /// Serialize this [`SigningKey`] as bytes
106
0
    pub fn to_bytes(&self) -> FieldBytes<C> {
107
0
        self.secret_scalar.to_repr()
108
0
    }
109
110
    /// Borrow the secret [`NonZeroScalar`] value for this key.
111
    ///
112
    /// # ⚠️ Warning
113
    ///
114
    /// This value is key material.
115
    ///
116
    /// Please treat it with the care it deserves!
117
0
    pub fn as_nonzero_scalar(&self) -> &NonZeroScalar<C> {
118
0
        &self.secret_scalar
119
0
    }
120
121
    /// Get the [`VerifyingKey`] which corresponds to this [`SigningKey`].
122
    #[cfg(feature = "verifying")]
123
0
    pub fn verifying_key(&self) -> &VerifyingKey<C> {
124
0
        &self.verifying_key
125
0
    }
126
}
127
128
//
129
// `*Signer` trait impls
130
//
131
132
/// Sign message digest using a deterministic ephemeral scalar (`k`)
133
/// computed using the algorithm described in [RFC6979 § 3.2].
134
///
135
/// [RFC6979 § 3.2]: https://tools.ietf.org/html/rfc6979#section-3
136
impl<C, D> DigestSigner<D, Signature<C>> for SigningKey<C>
137
where
138
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
139
    D: Digest + FixedOutput<OutputSize = FieldBytesSize<C>>,
140
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
141
    SignatureSize<C>: ArrayLength<u8>,
142
{
143
0
    fn try_sign_digest(&self, msg_digest: D) -> Result<Signature<C>> {
144
0
        self.sign_prehash(&msg_digest.finalize_fixed())
145
0
    }
146
}
147
148
/// Sign message prehash using a deterministic ephemeral scalar (`k`)
149
/// computed using the algorithm described in [RFC6979 § 3.2].
150
///
151
/// [RFC6979 § 3.2]: https://tools.ietf.org/html/rfc6979#section-3
152
impl<C> PrehashSigner<Signature<C>> for SigningKey<C>
153
where
154
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
155
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
156
    SignatureSize<C>: ArrayLength<u8>,
157
{
158
0
    fn sign_prehash(&self, prehash: &[u8]) -> Result<Signature<C>> {
159
0
        let z = bits2field::<C>(prehash)?;
160
0
        Ok(self
161
0
            .secret_scalar
162
0
            .try_sign_prehashed_rfc6979::<C::Digest>(&z, &[])?
163
            .0)
164
0
    }
165
}
166
167
/// Sign message using a deterministic ephemeral scalar (`k`)
168
/// computed using the algorithm described in [RFC6979 § 3.2].
169
///
170
/// [RFC6979 § 3.2]: https://tools.ietf.org/html/rfc6979#section-3
171
impl<C> Signer<Signature<C>> for SigningKey<C>
172
where
173
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
174
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
175
    SignatureSize<C>: ArrayLength<u8>,
176
{
177
0
    fn try_sign(&self, msg: &[u8]) -> Result<Signature<C>> {
178
0
        self.try_sign_digest(C::Digest::new_with_prefix(msg))
179
0
    }
180
}
181
182
impl<C, D> RandomizedDigestSigner<D, Signature<C>> for SigningKey<C>
183
where
184
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
185
    D: Digest + FixedOutput<OutputSize = FieldBytesSize<C>>,
186
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
187
    SignatureSize<C>: ArrayLength<u8>,
188
{
189
0
    fn try_sign_digest_with_rng(
190
0
        &self,
191
0
        rng: &mut impl CryptoRngCore,
192
0
        msg_digest: D,
193
0
    ) -> Result<Signature<C>> {
194
0
        self.sign_prehash_with_rng(rng, &msg_digest.finalize_fixed())
195
0
    }
196
}
197
198
impl<C> RandomizedPrehashSigner<Signature<C>> for SigningKey<C>
199
where
200
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
201
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
202
    SignatureSize<C>: ArrayLength<u8>,
203
{
204
0
    fn sign_prehash_with_rng(
205
0
        &self,
206
0
        rng: &mut impl CryptoRngCore,
207
0
        prehash: &[u8],
208
0
    ) -> Result<Signature<C>> {
209
0
        let z = bits2field::<C>(prehash)?;
210
0
        let mut ad = FieldBytes::<C>::default();
211
0
        rng.fill_bytes(&mut ad);
212
0
        Ok(self
213
0
            .secret_scalar
214
0
            .try_sign_prehashed_rfc6979::<C::Digest>(&z, &ad)?
215
            .0)
216
0
    }
217
}
218
219
impl<C> RandomizedSigner<Signature<C>> for SigningKey<C>
220
where
221
    Self: RandomizedDigestSigner<C::Digest, Signature<C>>,
222
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
223
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
224
    SignatureSize<C>: ArrayLength<u8>,
225
{
226
0
    fn try_sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result<Signature<C>> {
227
0
        self.try_sign_digest_with_rng(rng, C::Digest::new_with_prefix(msg))
228
0
    }
229
}
230
231
impl<C, D> DigestSigner<D, SignatureWithOid<C>> for SigningKey<C>
232
where
233
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
234
    D: AssociatedOid + Digest + FixedOutput<OutputSize = FieldBytesSize<C>>,
235
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
236
    SignatureSize<C>: ArrayLength<u8>,
237
{
238
0
    fn try_sign_digest(&self, msg_digest: D) -> Result<SignatureWithOid<C>> {
239
0
        let signature: Signature<C> = self.try_sign_digest(msg_digest)?;
240
0
        let oid = ecdsa_oid_for_digest(D::OID).ok_or_else(Error::new)?;
241
0
        SignatureWithOid::new(signature, oid)
242
0
    }
243
}
244
245
impl<C> Signer<SignatureWithOid<C>> for SigningKey<C>
246
where
247
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
248
    C::Digest: AssociatedOid,
249
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
250
    SignatureSize<C>: ArrayLength<u8>,
251
{
252
0
    fn try_sign(&self, msg: &[u8]) -> Result<SignatureWithOid<C>> {
253
0
        self.try_sign_digest(C::Digest::new_with_prefix(msg))
254
0
    }
255
}
256
257
#[cfg(feature = "der")]
258
impl<C> PrehashSigner<der::Signature<C>> for SigningKey<C>
259
where
260
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
261
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
262
    SignatureSize<C>: ArrayLength<u8>,
263
    der::MaxSize<C>: ArrayLength<u8>,
264
    <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
265
{
266
0
    fn sign_prehash(&self, prehash: &[u8]) -> Result<der::Signature<C>> {
267
0
        PrehashSigner::<Signature<C>>::sign_prehash(self, prehash).map(Into::into)
268
0
    }
269
}
270
271
#[cfg(feature = "der")]
272
impl<C> Signer<der::Signature<C>> for SigningKey<C>
273
where
274
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
275
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
276
    SignatureSize<C>: ArrayLength<u8>,
277
    der::MaxSize<C>: ArrayLength<u8>,
278
    <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
279
{
280
0
    fn try_sign(&self, msg: &[u8]) -> Result<der::Signature<C>> {
281
0
        Signer::<Signature<C>>::try_sign(self, msg).map(Into::into)
282
0
    }
283
}
284
285
#[cfg(feature = "der")]
286
impl<C, D> RandomizedDigestSigner<D, der::Signature<C>> for SigningKey<C>
287
where
288
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
289
    D: Digest + FixedOutput<OutputSize = FieldBytesSize<C>>,
290
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
291
    SignatureSize<C>: ArrayLength<u8>,
292
    der::MaxSize<C>: ArrayLength<u8>,
293
    <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
294
{
295
0
    fn try_sign_digest_with_rng(
296
0
        &self,
297
0
        rng: &mut impl CryptoRngCore,
298
0
        msg_digest: D,
299
0
    ) -> Result<der::Signature<C>> {
300
0
        RandomizedDigestSigner::<D, Signature<C>>::try_sign_digest_with_rng(self, rng, msg_digest)
301
0
            .map(Into::into)
302
0
    }
303
}
304
305
#[cfg(feature = "der")]
306
impl<C> RandomizedPrehashSigner<der::Signature<C>> for SigningKey<C>
307
where
308
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
309
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
310
    SignatureSize<C>: ArrayLength<u8>,
311
    der::MaxSize<C>: ArrayLength<u8>,
312
    <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
313
{
314
0
    fn sign_prehash_with_rng(
315
0
        &self,
316
0
        rng: &mut impl CryptoRngCore,
317
0
        prehash: &[u8],
318
0
    ) -> Result<der::Signature<C>> {
319
0
        RandomizedPrehashSigner::<Signature<C>>::sign_prehash_with_rng(self, rng, prehash)
320
0
            .map(Into::into)
321
0
    }
322
}
323
324
#[cfg(feature = "der")]
325
impl<C> RandomizedSigner<der::Signature<C>> for SigningKey<C>
326
where
327
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
328
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
329
    SignatureSize<C>: ArrayLength<u8>,
330
    der::MaxSize<C>: ArrayLength<u8>,
331
    <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
332
{
333
0
    fn try_sign_with_rng(
334
0
        &self,
335
0
        rng: &mut impl CryptoRngCore,
336
0
        msg: &[u8],
337
0
    ) -> Result<der::Signature<C>> {
338
0
        RandomizedSigner::<Signature<C>>::try_sign_with_rng(self, rng, msg).map(Into::into)
339
0
    }
340
}
341
342
//
343
// Other trait impls
344
//
345
346
#[cfg(feature = "verifying")]
347
impl<C> AsRef<VerifyingKey<C>> for SigningKey<C>
348
where
349
    C: PrimeCurve + CurveArithmetic,
350
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
351
    SignatureSize<C>: ArrayLength<u8>,
352
{
353
0
    fn as_ref(&self) -> &VerifyingKey<C> {
354
0
        &self.verifying_key
355
0
    }
356
}
357
358
impl<C> ConstantTimeEq for SigningKey<C>
359
where
360
    C: PrimeCurve + CurveArithmetic,
361
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
362
    SignatureSize<C>: ArrayLength<u8>,
363
{
364
0
    fn ct_eq(&self, other: &Self) -> Choice {
365
0
        self.secret_scalar.ct_eq(&other.secret_scalar)
366
0
    }
367
}
368
369
impl<C> Debug for SigningKey<C>
370
where
371
    C: PrimeCurve + CurveArithmetic,
372
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
373
    SignatureSize<C>: ArrayLength<u8>,
374
{
375
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
376
0
        f.debug_struct("SigningKey").finish_non_exhaustive()
377
0
    }
378
}
379
380
impl<C> Drop for SigningKey<C>
381
where
382
    C: PrimeCurve + CurveArithmetic,
383
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
384
    SignatureSize<C>: ArrayLength<u8>,
385
{
386
0
    fn drop(&mut self) {
387
0
        self.secret_scalar.zeroize();
388
0
    }
389
}
390
391
/// Constant-time comparison
392
impl<C> Eq for SigningKey<C>
393
where
394
    C: PrimeCurve + CurveArithmetic,
395
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
396
    SignatureSize<C>: ArrayLength<u8>,
397
{
398
}
399
impl<C> PartialEq for SigningKey<C>
400
where
401
    C: PrimeCurve + CurveArithmetic,
402
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
403
    SignatureSize<C>: ArrayLength<u8>,
404
{
405
0
    fn eq(&self, other: &SigningKey<C>) -> bool {
406
0
        self.ct_eq(other).into()
407
0
    }
408
}
409
410
impl<C> From<NonZeroScalar<C>> for SigningKey<C>
411
where
412
    C: PrimeCurve + CurveArithmetic,
413
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
414
    SignatureSize<C>: ArrayLength<u8>,
415
{
416
0
    fn from(secret_scalar: NonZeroScalar<C>) -> Self {
417
0
        #[cfg(feature = "verifying")]
418
0
        let public_key = PublicKey::from_secret_scalar(&secret_scalar);
419
0
420
0
        Self {
421
0
            secret_scalar,
422
0
            #[cfg(feature = "verifying")]
423
0
            verifying_key: public_key.into(),
424
0
        }
425
0
    }
426
}
427
428
impl<C> From<SecretKey<C>> for SigningKey<C>
429
where
430
    C: PrimeCurve + CurveArithmetic,
431
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
432
    SignatureSize<C>: ArrayLength<u8>,
433
{
434
0
    fn from(secret_key: SecretKey<C>) -> Self {
435
0
        Self::from(&secret_key)
436
0
    }
437
}
438
439
impl<C> From<&SecretKey<C>> for SigningKey<C>
440
where
441
    C: PrimeCurve + CurveArithmetic,
442
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
443
    SignatureSize<C>: ArrayLength<u8>,
444
{
445
0
    fn from(secret_key: &SecretKey<C>) -> Self {
446
0
        secret_key.to_nonzero_scalar().into()
447
0
    }
448
}
449
450
impl<C> From<SigningKey<C>> for SecretKey<C>
451
where
452
    C: PrimeCurve + CurveArithmetic,
453
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
454
    SignatureSize<C>: ArrayLength<u8>,
455
{
456
0
    fn from(key: SigningKey<C>) -> Self {
457
0
        key.secret_scalar.into()
458
0
    }
459
}
460
461
impl<C> From<&SigningKey<C>> for SecretKey<C>
462
where
463
    C: PrimeCurve + CurveArithmetic,
464
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
465
    SignatureSize<C>: ArrayLength<u8>,
466
{
467
0
    fn from(secret_key: &SigningKey<C>) -> Self {
468
0
        secret_key.secret_scalar.into()
469
0
    }
470
}
471
472
impl<C> TryFrom<&[u8]> for SigningKey<C>
473
where
474
    C: PrimeCurve + CurveArithmetic,
475
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
476
    SignatureSize<C>: ArrayLength<u8>,
477
{
478
    type Error = Error;
479
480
0
    fn try_from(bytes: &[u8]) -> Result<Self> {
481
0
        Self::from_slice(bytes)
482
0
    }
483
}
484
485
impl<C> ZeroizeOnDrop for SigningKey<C>
486
where
487
    C: PrimeCurve + CurveArithmetic,
488
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
489
    SignatureSize<C>: ArrayLength<u8>,
490
{
491
}
492
493
#[cfg(feature = "verifying")]
494
impl<C> From<SigningKey<C>> for VerifyingKey<C>
495
where
496
    C: PrimeCurve + CurveArithmetic,
497
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
498
    SignatureSize<C>: ArrayLength<u8>,
499
{
500
0
    fn from(signing_key: SigningKey<C>) -> VerifyingKey<C> {
501
0
        signing_key.verifying_key
502
0
    }
503
}
504
505
#[cfg(feature = "verifying")]
506
impl<C> From<&SigningKey<C>> for VerifyingKey<C>
507
where
508
    C: PrimeCurve + CurveArithmetic,
509
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
510
    SignatureSize<C>: ArrayLength<u8>,
511
{
512
0
    fn from(signing_key: &SigningKey<C>) -> VerifyingKey<C> {
513
0
        signing_key.verifying_key
514
0
    }
515
}
516
517
#[cfg(feature = "verifying")]
518
impl<C> KeypairRef for SigningKey<C>
519
where
520
    C: PrimeCurve + CurveArithmetic,
521
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
522
    SignatureSize<C>: ArrayLength<u8>,
523
{
524
    type VerifyingKey = VerifyingKey<C>;
525
}
526
527
#[cfg(feature = "pkcs8")]
528
impl<C> AssociatedAlgorithmIdentifier for SigningKey<C>
529
where
530
    C: AssociatedOid + CurveArithmetic + PrimeCurve,
531
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
532
    SignatureSize<C>: ArrayLength<u8>,
533
{
534
    type Params = ObjectIdentifier;
535
536
    const ALGORITHM_IDENTIFIER: AlgorithmIdentifier<ObjectIdentifier> =
537
        SecretKey::<C>::ALGORITHM_IDENTIFIER;
538
}
539
540
#[cfg(feature = "pkcs8")]
541
impl<C> SignatureAlgorithmIdentifier for SigningKey<C>
542
where
543
    C: PrimeCurve + CurveArithmetic,
544
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
545
    SignatureSize<C>: ArrayLength<u8>,
546
    Signature<C>: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>,
547
{
548
    type Params = AnyRef<'static>;
549
550
    const SIGNATURE_ALGORITHM_IDENTIFIER: AlgorithmIdentifier<Self::Params> =
551
        Signature::<C>::ALGORITHM_IDENTIFIER;
552
}
553
554
#[cfg(feature = "pkcs8")]
555
impl<C> TryFrom<pkcs8::PrivateKeyInfo<'_>> for SigningKey<C>
556
where
557
    C: PrimeCurve + AssociatedOid + CurveArithmetic,
558
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
559
    FieldBytesSize<C>: sec1::ModulusSize,
560
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
561
    SignatureSize<C>: ArrayLength<u8>,
562
{
563
    type Error = pkcs8::Error;
564
565
0
    fn try_from(private_key_info: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result<Self> {
566
0
        SecretKey::try_from(private_key_info).map(Into::into)
567
0
    }
568
}
569
570
#[cfg(feature = "pem")]
571
impl<C> EncodePrivateKey for SigningKey<C>
572
where
573
    C: AssociatedOid + PrimeCurve + CurveArithmetic,
574
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
575
    FieldBytesSize<C>: sec1::ModulusSize,
576
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
577
    SignatureSize<C>: ArrayLength<u8>,
578
{
579
0
    fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument> {
580
0
        SecretKey::from(self.secret_scalar).to_pkcs8_der()
581
0
    }
582
}
583
584
#[cfg(feature = "pem")]
585
impl<C> FromStr for SigningKey<C>
586
where
587
    C: PrimeCurve + AssociatedOid + CurveArithmetic,
588
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
589
    FieldBytesSize<C>: sec1::ModulusSize,
590
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
591
    SignatureSize<C>: ArrayLength<u8>,
592
{
593
    type Err = Error;
594
595
0
    fn from_str(s: &str) -> Result<Self> {
596
0
        Self::from_pkcs8_pem(s).map_err(|_| Error::new())
597
0
    }
598
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ecdsa-0.16.9/src/verifying.rs
Line
Count
Source
1
//! ECDSA verifying: checking signatures are authentic using a [`VerifyingKey`].
2
3
use crate::{
4
    hazmat::{bits2field, DigestPrimitive, VerifyPrimitive},
5
    Error, Result, Signature, SignatureSize,
6
};
7
use core::{cmp::Ordering, fmt::Debug};
8
use elliptic_curve::{
9
    generic_array::ArrayLength,
10
    point::PointCompression,
11
    sec1::{self, CompressedPoint, EncodedPoint, FromEncodedPoint, ToEncodedPoint},
12
    AffinePoint, CurveArithmetic, FieldBytesSize, PrimeCurve, PublicKey,
13
};
14
use signature::{
15
    digest::{Digest, FixedOutput},
16
    hazmat::PrehashVerifier,
17
    DigestVerifier, Verifier,
18
};
19
20
#[cfg(feature = "alloc")]
21
use alloc::boxed::Box;
22
23
#[cfg(feature = "der")]
24
use {crate::der, core::ops::Add};
25
26
#[cfg(feature = "pem")]
27
use {
28
    core::str::FromStr,
29
    elliptic_curve::pkcs8::{DecodePublicKey, EncodePublicKey},
30
};
31
32
#[cfg(feature = "pkcs8")]
33
use elliptic_curve::pkcs8::{
34
    self,
35
    der::AnyRef,
36
    spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier, SignatureAlgorithmIdentifier},
37
    AssociatedOid, ObjectIdentifier,
38
};
39
40
#[cfg(feature = "sha2")]
41
use {
42
    crate::{
43
        SignatureWithOid, ECDSA_SHA224_OID, ECDSA_SHA256_OID, ECDSA_SHA384_OID, ECDSA_SHA512_OID,
44
    },
45
    sha2::{Sha224, Sha256, Sha384, Sha512},
46
};
47
48
#[cfg(all(feature = "pem", feature = "serde"))]
49
use serdect::serde::{de, ser, Deserialize, Serialize};
50
51
/// ECDSA public key used for verifying signatures. Generic over prime order
52
/// elliptic curves (e.g. NIST P-curves)
53
///
54
/// Requires an [`elliptic_curve::CurveArithmetic`] impl on the curve, and a
55
/// [`VerifyPrimitive`] impl on its associated `AffinePoint` type.
56
///
57
/// ## Usage
58
///
59
/// The [`signature`] crate defines the following traits which are the
60
/// primary API for verifying:
61
///
62
/// - [`Verifier`]: verify a message against a provided key and signature
63
/// - [`DigestVerifier`]: verify a message [`Digest`] against a provided key and signature
64
/// - [`PrehashVerifier`]: verify the low-level raw output bytes of a message digest
65
///
66
/// See the [`p256` crate](https://docs.rs/p256/latest/p256/ecdsa/index.html)
67
/// for examples of using this type with a concrete elliptic curve.
68
///
69
/// # `serde` support
70
///
71
/// When the `serde` feature of this crate is enabled, it provides support for
72
/// serializing and deserializing ECDSA signatures using the `Serialize` and
73
/// `Deserialize` traits.
74
///
75
/// The serialization leverages the encoding used by the [`PublicKey`] type,
76
/// which is a binary-oriented ASN.1 DER encoding.
77
#[derive(Clone, Debug)]
78
pub struct VerifyingKey<C>
79
where
80
    C: PrimeCurve + CurveArithmetic,
81
{
82
    pub(crate) inner: PublicKey<C>,
83
}
84
85
impl<C> VerifyingKey<C>
86
where
87
    C: PrimeCurve + CurveArithmetic,
88
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
89
    FieldBytesSize<C>: sec1::ModulusSize,
90
{
91
    /// Initialize [`VerifyingKey`] from a SEC1-encoded public key.
92
2.51k
    pub fn from_sec1_bytes(bytes: &[u8]) -> Result<Self> {
93
2.51k
        PublicKey::from_sec1_bytes(bytes)
94
2.51k
            .map(|pk| Self { inner: pk })
_RNCNvMNtCs56dDIOPvtI3_5ecdsa9verifyingINtB4_12VerifyingKeyNtCsaHRNXv1Y9Bq_4p2568NistP256E15from_sec1_bytes0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
94
1.14k
            .map(|pk| Self { inner: pk })
_RNCNvMNtCs56dDIOPvtI3_5ecdsa9verifyingINtB4_12VerifyingKeyNtCsjewTDwKBbyD_4k2569Secp256k1E15from_sec1_bytes0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
94
712
            .map(|pk| Self { inner: pk })
Unexecuted instantiation: _RNCNvMNtCs56dDIOPvtI3_5ecdsa9verifyingINtB4_12VerifyingKeypE15from_sec1_bytes0B6_
95
2.51k
            .map_err(|_| Error::new())
_RNCNvMNtCs56dDIOPvtI3_5ecdsa9verifyingINtB4_12VerifyingKeyNtCsaHRNXv1Y9Bq_4p2568NistP256E15from_sec1_bytess_0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
95
65
            .map_err(|_| Error::new())
_RNCNvMNtCs56dDIOPvtI3_5ecdsa9verifyingINtB4_12VerifyingKeyNtCsjewTDwKBbyD_4k2569Secp256k1E15from_sec1_bytess_0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
95
595
            .map_err(|_| Error::new())
Unexecuted instantiation: _RNCNvMNtCs56dDIOPvtI3_5ecdsa9verifyingINtB4_12VerifyingKeypE15from_sec1_bytess_0B6_
96
2.51k
    }
_RNvMNtCs56dDIOPvtI3_5ecdsa9verifyingINtB2_12VerifyingKeyNtCsaHRNXv1Y9Bq_4p2568NistP256E15from_sec1_bytesCs4RkbDk9WRL5_5clvmr
Line
Count
Source
92
1.21k
    pub fn from_sec1_bytes(bytes: &[u8]) -> Result<Self> {
93
1.21k
        PublicKey::from_sec1_bytes(bytes)
94
1.21k
            .map(|pk| Self { inner: pk })
95
1.21k
            .map_err(|_| Error::new())
96
1.21k
    }
_RNvMNtCs56dDIOPvtI3_5ecdsa9verifyingINtB2_12VerifyingKeyNtCsjewTDwKBbyD_4k2569Secp256k1E15from_sec1_bytesCs4RkbDk9WRL5_5clvmr
Line
Count
Source
92
1.30k
    pub fn from_sec1_bytes(bytes: &[u8]) -> Result<Self> {
93
1.30k
        PublicKey::from_sec1_bytes(bytes)
94
1.30k
            .map(|pk| Self { inner: pk })
95
1.30k
            .map_err(|_| Error::new())
96
1.30k
    }
Unexecuted instantiation: _RNvMNtCs56dDIOPvtI3_5ecdsa9verifyingINtB2_12VerifyingKeypE15from_sec1_bytesB4_
97
98
    /// Initialize [`VerifyingKey`] from an affine point.
99
    ///
100
    /// Returns an [`Error`] if the given affine point is the additive identity
101
    /// (a.k.a. point at infinity).
102
0
    pub fn from_affine(affine: AffinePoint<C>) -> Result<Self> {
103
0
        Ok(Self {
104
0
            inner: PublicKey::from_affine(affine).map_err(|_| Error::new())?,
105
        })
106
0
    }
107
108
    /// Initialize [`VerifyingKey`] from an [`EncodedPoint`].
109
0
    pub fn from_encoded_point(public_key: &EncodedPoint<C>) -> Result<Self> {
110
0
        Option::from(PublicKey::<C>::from_encoded_point(public_key))
111
0
            .map(|public_key| Self { inner: public_key })
112
0
            .ok_or_else(Error::new)
113
0
    }
114
115
    /// Serialize this [`VerifyingKey`] as a SEC1 [`EncodedPoint`], optionally
116
    /// applying point compression.
117
0
    pub fn to_encoded_point(&self, compress: bool) -> EncodedPoint<C> {
118
0
        self.inner.to_encoded_point(compress)
119
0
    }
120
121
    /// Convert this [`VerifyingKey`] into the
122
    /// `Elliptic-Curve-Point-to-Octet-String` encoding described in
123
    /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section 2.3.3
124
    /// (page 10).
125
    ///
126
    /// <http://www.secg.org/sec1-v2.pdf>
127
    #[cfg(feature = "alloc")]
128
0
    pub fn to_sec1_bytes(&self) -> Box<[u8]>
129
0
    where
130
0
        C: PointCompression,
131
0
    {
132
0
        self.inner.to_sec1_bytes()
133
0
    }
134
135
    /// Borrow the inner [`AffinePoint`] for this public key.
136
0
    pub fn as_affine(&self) -> &AffinePoint<C> {
137
0
        self.inner.as_affine()
138
0
    }
139
}
140
141
//
142
// `*Verifier` trait impls
143
//
144
145
impl<C, D> DigestVerifier<D, Signature<C>> for VerifyingKey<C>
146
where
147
    C: PrimeCurve + CurveArithmetic,
148
    D: Digest + FixedOutput<OutputSize = FieldBytesSize<C>>,
149
    AffinePoint<C>: VerifyPrimitive<C>,
150
    SignatureSize<C>: ArrayLength<u8>,
151
{
152
0
    fn verify_digest(&self, msg_digest: D, signature: &Signature<C>) -> Result<()> {
153
0
        self.inner.as_affine().verify_digest(msg_digest, signature)
154
0
    }
155
}
156
157
impl<C> PrehashVerifier<Signature<C>> for VerifyingKey<C>
158
where
159
    C: PrimeCurve + CurveArithmetic,
160
    AffinePoint<C>: VerifyPrimitive<C>,
161
    SignatureSize<C>: ArrayLength<u8>,
162
{
163
1.37k
    fn verify_prehash(&self, prehash: &[u8], signature: &Signature<C>) -> Result<()> {
164
1.37k
        let field = bits2field::<C>(prehash)?;
165
1.37k
        self.inner.as_affine().verify_prehashed(&field, signature)
166
1.37k
    }
_RNvXs0_NtCs56dDIOPvtI3_5ecdsa9verifyingINtB5_12VerifyingKeyNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCs9XGzgUPXFy2_9signature6hazmat15PrehashVerifierINtB7_9SignatureBV_EE14verify_prehashCs4RkbDk9WRL5_5clvmr
Line
Count
Source
163
838
    fn verify_prehash(&self, prehash: &[u8], signature: &Signature<C>) -> Result<()> {
164
838
        let field = bits2field::<C>(prehash)?;
165
838
        self.inner.as_affine().verify_prehashed(&field, signature)
166
838
    }
_RNvXs0_NtCs56dDIOPvtI3_5ecdsa9verifyingINtB5_12VerifyingKeyNtCsjewTDwKBbyD_4k2569Secp256k1EINtNtCs9XGzgUPXFy2_9signature6hazmat15PrehashVerifierINtB7_9SignatureBV_EE14verify_prehashCs4RkbDk9WRL5_5clvmr
Line
Count
Source
163
534
    fn verify_prehash(&self, prehash: &[u8], signature: &Signature<C>) -> Result<()> {
164
534
        let field = bits2field::<C>(prehash)?;
165
534
        self.inner.as_affine().verify_prehashed(&field, signature)
166
534
    }
Unexecuted instantiation: _RNvXININtCs56dDIOPvtI3_5ecdsa9verifyings0_0pEINtB5_12VerifyingKeypEINtNtCs9XGzgUPXFy2_9signature6hazmat15PrehashVerifierINtB7_9SignaturepEE14verify_prehashB7_
167
}
168
169
impl<C> Verifier<Signature<C>> for VerifyingKey<C>
170
where
171
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
172
    AffinePoint<C>: VerifyPrimitive<C>,
173
    SignatureSize<C>: ArrayLength<u8>,
174
{
175
0
    fn verify(&self, msg: &[u8], signature: &Signature<C>) -> Result<()> {
176
0
        self.verify_digest(C::Digest::new_with_prefix(msg), signature)
177
0
    }
178
}
179
180
#[cfg(feature = "sha2")]
181
impl<C> Verifier<SignatureWithOid<C>> for VerifyingKey<C>
182
where
183
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
184
    AffinePoint<C>: VerifyPrimitive<C>,
185
    SignatureSize<C>: ArrayLength<u8>,
186
{
187
    fn verify(&self, msg: &[u8], sig: &SignatureWithOid<C>) -> Result<()> {
188
        match sig.oid() {
189
            ECDSA_SHA224_OID => self.verify_prehash(&Sha224::digest(msg), sig.signature()),
190
            ECDSA_SHA256_OID => self.verify_prehash(&Sha256::digest(msg), sig.signature()),
191
            ECDSA_SHA384_OID => self.verify_prehash(&Sha384::digest(msg), sig.signature()),
192
            ECDSA_SHA512_OID => self.verify_prehash(&Sha512::digest(msg), sig.signature()),
193
            _ => Err(Error::new()),
194
        }
195
    }
196
}
197
198
#[cfg(feature = "der")]
199
impl<C, D> DigestVerifier<D, der::Signature<C>> for VerifyingKey<C>
200
where
201
    C: PrimeCurve + CurveArithmetic,
202
    D: Digest + FixedOutput<OutputSize = FieldBytesSize<C>>,
203
    AffinePoint<C>: VerifyPrimitive<C>,
204
    SignatureSize<C>: ArrayLength<u8>,
205
    der::MaxSize<C>: ArrayLength<u8>,
206
    <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
207
{
208
0
    fn verify_digest(&self, msg_digest: D, signature: &der::Signature<C>) -> Result<()> {
209
0
        let signature = Signature::<C>::try_from(signature.clone())?;
210
0
        DigestVerifier::<D, Signature<C>>::verify_digest(self, msg_digest, &signature)
211
0
    }
212
}
213
214
#[cfg(feature = "der")]
215
impl<C> PrehashVerifier<der::Signature<C>> for VerifyingKey<C>
216
where
217
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
218
    AffinePoint<C>: VerifyPrimitive<C>,
219
    SignatureSize<C>: ArrayLength<u8>,
220
    der::MaxSize<C>: ArrayLength<u8>,
221
    <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
222
{
223
0
    fn verify_prehash(&self, prehash: &[u8], signature: &der::Signature<C>) -> Result<()> {
224
0
        let signature = Signature::<C>::try_from(signature.clone())?;
225
0
        PrehashVerifier::<Signature<C>>::verify_prehash(self, prehash, &signature)
226
0
    }
227
}
228
229
#[cfg(feature = "der")]
230
impl<C> Verifier<der::Signature<C>> for VerifyingKey<C>
231
where
232
    C: PrimeCurve + CurveArithmetic + DigestPrimitive,
233
    AffinePoint<C>: VerifyPrimitive<C>,
234
    SignatureSize<C>: ArrayLength<u8>,
235
    der::MaxSize<C>: ArrayLength<u8>,
236
    <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
237
{
238
0
    fn verify(&self, msg: &[u8], signature: &der::Signature<C>) -> Result<()> {
239
0
        let signature = Signature::<C>::try_from(signature.clone())?;
240
0
        Verifier::<Signature<C>>::verify(self, msg, &signature)
241
0
    }
242
}
243
244
//
245
// Other trait impls
246
//
247
248
impl<C> AsRef<AffinePoint<C>> for VerifyingKey<C>
249
where
250
    C: PrimeCurve + CurveArithmetic,
251
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
252
    FieldBytesSize<C>: sec1::ModulusSize,
253
{
254
0
    fn as_ref(&self) -> &AffinePoint<C> {
255
0
        self.as_affine()
256
0
    }
257
}
258
259
impl<C> Copy for VerifyingKey<C> where C: PrimeCurve + CurveArithmetic {}
260
261
impl<C> From<VerifyingKey<C>> for CompressedPoint<C>
262
where
263
    C: PrimeCurve + CurveArithmetic + PointCompression,
264
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
265
    FieldBytesSize<C>: sec1::ModulusSize,
266
{
267
0
    fn from(verifying_key: VerifyingKey<C>) -> CompressedPoint<C> {
268
0
        verifying_key.inner.into()
269
0
    }
270
}
271
272
impl<C> From<&VerifyingKey<C>> for CompressedPoint<C>
273
where
274
    C: PrimeCurve + CurveArithmetic + PointCompression,
275
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
276
    FieldBytesSize<C>: sec1::ModulusSize,
277
{
278
0
    fn from(verifying_key: &VerifyingKey<C>) -> CompressedPoint<C> {
279
0
        verifying_key.inner.into()
280
0
    }
281
}
282
283
impl<C> From<VerifyingKey<C>> for EncodedPoint<C>
284
where
285
    C: PrimeCurve + CurveArithmetic + PointCompression,
286
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
287
    FieldBytesSize<C>: sec1::ModulusSize,
288
{
289
0
    fn from(verifying_key: VerifyingKey<C>) -> EncodedPoint<C> {
290
0
        verifying_key.inner.into()
291
0
    }
292
}
293
294
impl<C> From<&VerifyingKey<C>> for EncodedPoint<C>
295
where
296
    C: PrimeCurve + CurveArithmetic + PointCompression,
297
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
298
    FieldBytesSize<C>: sec1::ModulusSize,
299
{
300
0
    fn from(verifying_key: &VerifyingKey<C>) -> EncodedPoint<C> {
301
0
        verifying_key.inner.into()
302
0
    }
303
}
304
305
impl<C> Eq for VerifyingKey<C> where C: PrimeCurve + CurveArithmetic {}
306
307
impl<C> PartialEq for VerifyingKey<C>
308
where
309
    C: PrimeCurve + CurveArithmetic,
310
{
311
0
    fn eq(&self, other: &Self) -> bool {
312
0
        self.inner.eq(&other.inner)
313
0
    }
314
}
315
316
impl<C> From<PublicKey<C>> for VerifyingKey<C>
317
where
318
    C: PrimeCurve + CurveArithmetic,
319
{
320
0
    fn from(public_key: PublicKey<C>) -> VerifyingKey<C> {
321
0
        VerifyingKey { inner: public_key }
322
0
    }
323
}
324
325
impl<C> From<&PublicKey<C>> for VerifyingKey<C>
326
where
327
    C: PrimeCurve + CurveArithmetic,
328
{
329
0
    fn from(public_key: &PublicKey<C>) -> VerifyingKey<C> {
330
0
        (*public_key).into()
331
0
    }
332
}
333
334
impl<C> From<VerifyingKey<C>> for PublicKey<C>
335
where
336
    C: PrimeCurve + CurveArithmetic,
337
{
338
0
    fn from(verifying_key: VerifyingKey<C>) -> PublicKey<C> {
339
0
        verifying_key.inner
340
0
    }
341
}
342
343
impl<C> From<&VerifyingKey<C>> for PublicKey<C>
344
where
345
    C: PrimeCurve + CurveArithmetic,
346
{
347
0
    fn from(verifying_key: &VerifyingKey<C>) -> PublicKey<C> {
348
0
        (*verifying_key).into()
349
0
    }
350
}
351
352
impl<C> PartialOrd for VerifyingKey<C>
353
where
354
    C: PrimeCurve + CurveArithmetic,
355
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
356
    FieldBytesSize<C>: sec1::ModulusSize,
357
{
358
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
359
0
        self.inner.partial_cmp(&other.inner)
360
0
    }
361
}
362
363
impl<C> Ord for VerifyingKey<C>
364
where
365
    C: PrimeCurve + CurveArithmetic,
366
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
367
    FieldBytesSize<C>: sec1::ModulusSize,
368
{
369
0
    fn cmp(&self, other: &Self) -> Ordering {
370
0
        self.inner.cmp(&other.inner)
371
0
    }
372
}
373
374
impl<C> TryFrom<&[u8]> for VerifyingKey<C>
375
where
376
    C: PrimeCurve + CurveArithmetic,
377
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
378
    FieldBytesSize<C>: sec1::ModulusSize,
379
{
380
    type Error = Error;
381
382
0
    fn try_from(bytes: &[u8]) -> Result<Self> {
383
0
        Self::from_sec1_bytes(bytes)
384
0
    }
385
}
386
387
#[cfg(feature = "pkcs8")]
388
impl<C> AssociatedAlgorithmIdentifier for VerifyingKey<C>
389
where
390
    C: AssociatedOid + CurveArithmetic + PrimeCurve,
391
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
392
    FieldBytesSize<C>: sec1::ModulusSize,
393
{
394
    type Params = ObjectIdentifier;
395
396
    const ALGORITHM_IDENTIFIER: AlgorithmIdentifier<ObjectIdentifier> =
397
        PublicKey::<C>::ALGORITHM_IDENTIFIER;
398
}
399
400
#[cfg(feature = "pkcs8")]
401
impl<C> SignatureAlgorithmIdentifier for VerifyingKey<C>
402
where
403
    C: PrimeCurve + CurveArithmetic,
404
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
405
    FieldBytesSize<C>: sec1::ModulusSize,
406
    Signature<C>: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>,
407
{
408
    type Params = AnyRef<'static>;
409
410
    const SIGNATURE_ALGORITHM_IDENTIFIER: AlgorithmIdentifier<Self::Params> =
411
        Signature::<C>::ALGORITHM_IDENTIFIER;
412
}
413
414
#[cfg(feature = "pkcs8")]
415
impl<C> TryFrom<pkcs8::SubjectPublicKeyInfoRef<'_>> for VerifyingKey<C>
416
where
417
    C: PrimeCurve + AssociatedOid + CurveArithmetic + PointCompression,
418
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
419
    FieldBytesSize<C>: sec1::ModulusSize,
420
{
421
    type Error = pkcs8::spki::Error;
422
423
0
    fn try_from(spki: pkcs8::SubjectPublicKeyInfoRef<'_>) -> pkcs8::spki::Result<Self> {
424
0
        PublicKey::try_from(spki).map(|inner| Self { inner })
425
0
    }
426
}
427
428
#[cfg(feature = "pem")]
429
impl<C> EncodePublicKey for VerifyingKey<C>
430
where
431
    C: PrimeCurve + AssociatedOid + CurveArithmetic + PointCompression,
432
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
433
    FieldBytesSize<C>: sec1::ModulusSize,
434
{
435
0
    fn to_public_key_der(&self) -> pkcs8::spki::Result<pkcs8::Document> {
436
0
        self.inner.to_public_key_der()
437
0
    }
438
}
439
440
#[cfg(feature = "pem")]
441
impl<C> FromStr for VerifyingKey<C>
442
where
443
    C: PrimeCurve + AssociatedOid + CurveArithmetic + PointCompression,
444
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
445
    FieldBytesSize<C>: sec1::ModulusSize,
446
{
447
    type Err = Error;
448
449
0
    fn from_str(s: &str) -> Result<Self> {
450
0
        Self::from_public_key_pem(s).map_err(|_| Error::new())
451
0
    }
452
}
453
454
#[cfg(all(feature = "pem", feature = "serde"))]
455
impl<C> Serialize for VerifyingKey<C>
456
where
457
    C: PrimeCurve + AssociatedOid + CurveArithmetic + PointCompression,
458
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
459
    FieldBytesSize<C>: sec1::ModulusSize,
460
{
461
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
462
    where
463
        S: ser::Serializer,
464
    {
465
        self.inner.serialize(serializer)
466
    }
467
}
468
469
#[cfg(all(feature = "pem", feature = "serde"))]
470
impl<'de, C> Deserialize<'de> for VerifyingKey<C>
471
where
472
    C: PrimeCurve + AssociatedOid + CurveArithmetic + PointCompression,
473
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
474
    FieldBytesSize<C>: sec1::ModulusSize,
475
{
476
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
477
    where
478
        D: de::Deserializer<'de>,
479
    {
480
        PublicKey::<C>::deserialize(deserializer).map(Into::into)
481
    }
482
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/error.rs
Line
Count
Source
1
//! Error type.
2
3
use core::fmt::{self, Display};
4
5
#[cfg(feature = "pkcs8")]
6
use crate::pkcs8;
7
8
/// Result type with the `elliptic-curve` crate's [`Error`] type.
9
pub type Result<T> = core::result::Result<T, Error>;
10
11
/// Elliptic curve errors.
12
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
13
pub struct Error;
14
15
impl Display for Error {
16
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17
0
        f.write_str("crypto error")
18
0
    }
19
}
20
21
impl From<base16ct::Error> for Error {
22
0
    fn from(_: base16ct::Error) -> Error {
23
0
        Error
24
0
    }
25
}
26
27
#[cfg(feature = "pkcs8")]
28
impl From<pkcs8::Error> for Error {
29
0
    fn from(_: pkcs8::Error) -> Error {
30
0
        Error
31
0
    }
32
}
33
34
#[cfg(feature = "sec1")]
35
impl From<sec1::Error> for Error {
36
0
    fn from(_: sec1::Error) -> Error {
37
0
        Error
38
0
    }
39
}
40
41
#[cfg(feature = "std")]
42
impl std::error::Error for Error {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/field.rs
Line
Count
Source
1
//! Field elements.
2
3
use crate::{
4
    bigint::{ArrayEncoding, ByteArray, Integer},
5
    Curve,
6
};
7
use generic_array::{typenum::Unsigned, GenericArray};
8
9
/// Size of serialized field elements of this elliptic curve.
10
pub type FieldBytesSize<C> = <C as Curve>::FieldBytesSize;
11
12
/// Byte representation of a base/scalar field element of a given curve.
13
pub type FieldBytes<C> = GenericArray<u8, FieldBytesSize<C>>;
14
15
/// Trait for decoding/encoding `Curve::Uint` from/to [`FieldBytes`] using
16
/// curve-specific rules.
17
///
18
/// Namely a curve's modulus may be smaller than the big integer type used to
19
/// internally represent field elements (since the latter are multiples of the
20
/// limb size), such as in the case of curves like NIST P-224 and P-521, and so
21
/// it may need to be padded/truncated to the right length.
22
///
23
/// Additionally, different curves have different endianness conventions, also
24
/// captured here.
25
pub trait FieldBytesEncoding<C>: ArrayEncoding + Integer
26
where
27
    C: Curve,
28
{
29
    /// Decode unsigned integer from serialized field element.
30
    ///
31
    /// The default implementation assumes a big endian encoding.
32
0
    fn decode_field_bytes(field_bytes: &FieldBytes<C>) -> Self {
33
0
        debug_assert!(field_bytes.len() <= Self::ByteSize::USIZE);
34
0
        let mut byte_array = ByteArray::<Self>::default();
35
0
        let offset = Self::ByteSize::USIZE.saturating_sub(field_bytes.len());
36
0
        byte_array[offset..].copy_from_slice(field_bytes);
37
0
        Self::from_be_byte_array(byte_array)
38
0
    }
39
40
    /// Encode unsigned integer into serialized field element.
41
    ///
42
    /// The default implementation assumes a big endian encoding.
43
0
    fn encode_field_bytes(&self) -> FieldBytes<C> {
44
0
        let mut field_bytes = FieldBytes::<C>::default();
45
0
        debug_assert!(field_bytes.len() <= Self::ByteSize::USIZE);
46
47
0
        let offset = Self::ByteSize::USIZE.saturating_sub(field_bytes.len());
48
0
        field_bytes.copy_from_slice(&self.to_be_byte_array()[offset..]);
49
0
        field_bytes
50
0
    }
51
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/ops.rs
Line
Count
Source
1
//! Traits for arithmetic operations on elliptic curve field elements.
2
3
pub use core::ops::{Add, AddAssign, Mul, Neg, Shr, ShrAssign, Sub, SubAssign};
4
5
use crypto_bigint::Integer;
6
use group::Group;
7
use subtle::{Choice, ConditionallySelectable, CtOption};
8
9
#[cfg(feature = "alloc")]
10
use alloc::vec::Vec;
11
12
/// Perform an inversion on a field element (i.e. base field element or scalar)
13
pub trait Invert {
14
    /// Field element type
15
    type Output;
16
17
    /// Invert a field element.
18
    fn invert(&self) -> Self::Output;
19
20
    /// Invert a field element in variable time.
21
    ///
22
    /// ⚠️ WARNING!
23
    ///
24
    /// This method should not be used with secret values, as its variable-time
25
    /// operation can potentially leak secrets through sidechannels.
26
0
    fn invert_vartime(&self) -> Self::Output {
27
0
        // Fall back on constant-time implementation by default.
28
0
        self.invert()
29
0
    }
Unexecuted instantiation: _RNvYpNtNtCs8yVsO3EKNkV_14elliptic_curve3ops6Invert14invert_vartimeB7_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementNtNtCs8yVsO3EKNkV_14elliptic_curve3ops6Invert14invert_vartimeB8_
30
}
31
32
/// Perform a batched inversion on a sequence of field elements (i.e. base field elements or scalars)
33
/// at an amortized cost that should be practically as efficient as a single inversion.
34
pub trait BatchInvert<FieldElements: ?Sized>: Invert + Sized {
35
    /// The output of batch inversion. A container of field elements.
36
    type Output: AsRef<[Self]>;
37
38
    /// Invert a batch of field elements.
39
    fn batch_invert(
40
        field_elements: &FieldElements,
41
    ) -> CtOption<<Self as BatchInvert<FieldElements>>::Output>;
42
}
43
44
impl<const N: usize, T> BatchInvert<[T; N]> for T
45
where
46
    T: Invert<Output = CtOption<Self>>
47
        + Mul<Self, Output = Self>
48
        + Copy
49
        + Default
50
        + ConditionallySelectable,
51
{
52
    type Output = [Self; N];
53
54
0
    fn batch_invert(field_elements: &[Self; N]) -> CtOption<[Self; N]> {
55
0
        let mut field_elements_multiples = [Self::default(); N];
56
0
        let mut field_elements_multiples_inverses = [Self::default(); N];
57
0
        let mut field_elements_inverses = [Self::default(); N];
58
0
59
0
        let inversion_succeeded = invert_batch_internal(
60
0
            field_elements,
61
0
            &mut field_elements_multiples,
62
0
            &mut field_elements_multiples_inverses,
63
0
            &mut field_elements_inverses,
64
0
        );
65
0
66
0
        CtOption::new(field_elements_inverses, inversion_succeeded)
67
0
    }
68
}
69
70
#[cfg(feature = "alloc")]
71
impl<T> BatchInvert<[T]> for T
72
where
73
    T: Invert<Output = CtOption<Self>>
74
        + Mul<Self, Output = Self>
75
        + Copy
76
        + Default
77
        + ConditionallySelectable,
78
{
79
    type Output = Vec<Self>;
80
81
0
    fn batch_invert(field_elements: &[Self]) -> CtOption<Vec<Self>> {
82
0
        let mut field_elements_multiples: Vec<Self> = vec![Self::default(); field_elements.len()];
83
0
        let mut field_elements_multiples_inverses: Vec<Self> =
84
0
            vec![Self::default(); field_elements.len()];
85
0
        let mut field_elements_inverses: Vec<Self> = vec![Self::default(); field_elements.len()];
86
0
87
0
        let inversion_succeeded = invert_batch_internal(
88
0
            field_elements,
89
0
            field_elements_multiples.as_mut(),
90
0
            field_elements_multiples_inverses.as_mut(),
91
0
            field_elements_inverses.as_mut(),
92
0
        );
93
0
94
0
        CtOption::new(
95
0
            field_elements_inverses.into_iter().collect(),
96
0
            inversion_succeeded,
97
0
        )
98
0
    }
Unexecuted instantiation: _RNvXININtCs8yVsO3EKNkV_14elliptic_curve3opss_0pEpINtB5_11BatchInvertSpE12batch_invertB7_
Unexecuted instantiation: _RNvXs_NtCs8yVsO3EKNkV_14elliptic_curve3opsNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementINtB4_11BatchInvertSBE_E12batch_invertBK_
99
}
100
101
/// Implements "Montgomery's trick", a trick for computing many modular inverses at once.
102
///
103
/// "Montgomery's trick" works by reducing the problem of computing `n` inverses
104
/// to computing a single inversion, plus some storage and `O(n)` extra multiplications.
105
///
106
/// See: https://iacr.org/archive/pkc2004/29470042/29470042.pdf section 2.2.
107
0
fn invert_batch_internal<
108
0
    T: Invert<Output = CtOption<T>> + Mul<T, Output = T> + Default + ConditionallySelectable,
109
0
>(
110
0
    field_elements: &[T],
111
0
    field_elements_multiples: &mut [T],
112
0
    field_elements_multiples_inverses: &mut [T],
113
0
    field_elements_inverses: &mut [T],
114
0
) -> Choice {
115
0
    let batch_size = field_elements.len();
116
0
    if batch_size == 0
117
0
        || batch_size != field_elements_multiples.len()
118
0
        || batch_size != field_elements_multiples_inverses.len()
119
    {
120
0
        return Choice::from(0);
121
0
    }
122
0
123
0
    field_elements_multiples[0] = field_elements[0];
124
0
    for i in 1..batch_size {
125
0
        // $ a_n = a_{n-1}*x_n $
126
0
        field_elements_multiples[i] = field_elements_multiples[i - 1] * field_elements[i];
127
0
    }
128
129
0
    field_elements_multiples[batch_size - 1]
130
0
        .invert()
131
0
        .map(|multiple_of_inverses_of_all_field_elements| {
132
0
            field_elements_multiples_inverses[batch_size - 1] =
133
0
                multiple_of_inverses_of_all_field_elements;
134
0
            for i in (1..batch_size).rev() {
135
0
                // $ a_{n-1} = {a_n}^{-1}*x_n $
136
0
                field_elements_multiples_inverses[i - 1] =
137
0
                    field_elements_multiples_inverses[i] * field_elements[i];
138
0
            }
139
140
0
            field_elements_inverses[0] = field_elements_multiples_inverses[0];
141
0
            for i in 1..batch_size {
142
0
                // $ {x_n}^{-1} = a_{n}^{-1}*a_{n-1} $
143
0
                field_elements_inverses[i] =
144
0
                    field_elements_multiples_inverses[i] * field_elements_multiples[i - 1];
145
0
            }
146
0
        })
Unexecuted instantiation: _RNCINvNtCs8yVsO3EKNkV_14elliptic_curve3ops21invert_batch_internalpE0B6_
Unexecuted instantiation: _RNCINvNtCs8yVsO3EKNkV_14elliptic_curve3ops21invert_batch_internalNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementE0B17_
147
0
        .is_some()
148
0
}
Unexecuted instantiation: _RINvNtCs8yVsO3EKNkV_14elliptic_curve3ops21invert_batch_internalpEB4_
Unexecuted instantiation: _RINvNtCs8yVsO3EKNkV_14elliptic_curve3ops21invert_batch_internalNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementEB15_
149
150
/// Linear combination.
151
///
152
/// This trait enables crates to provide an optimized implementation of
153
/// linear combinations (e.g. Shamir's Trick), or otherwise provides a default
154
/// non-optimized implementation.
155
// TODO(tarcieri): replace this with a trait from the `group` crate? (see zkcrypto/group#25)
156
pub trait LinearCombination: Group {
157
    /// Calculates `x * k + y * l`.
158
838
    fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self {
159
838
        (*x * k) + (*y * l)
160
838
    }
_RNvYINtNtCs2J0Yj5ID6sO_10primeorder10projective15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtCs8yVsO3EKNkV_14elliptic_curve3ops17LinearCombination7lincombCs4RkbDk9WRL5_5clvmr
Line
Count
Source
158
838
    fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self {
159
838
        (*x * k) + (*y * l)
160
838
    }
Unexecuted instantiation: _RNvYpNtNtCs8yVsO3EKNkV_14elliptic_curve3ops17LinearCombination7lincombB7_
Unexecuted instantiation: _RNvYINtNtCs2J0Yj5ID6sO_10primeorder10projective15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtCs8yVsO3EKNkV_14elliptic_curve3ops17LinearCombination7lincombB12_
161
}
162
163
/// Linear combination (extended version).
164
///
165
/// This trait enables providing an optimized implementation of
166
/// linear combinations (e.g. Shamir's Trick).
167
// TODO(tarcieri): replace the current `LinearCombination` with this in the next release
168
pub trait LinearCombinationExt<PointsAndScalars>: group::Curve
169
where
170
    PointsAndScalars: AsRef<[(Self, Self::Scalar)]> + ?Sized,
171
{
172
    /// Calculates `x1 * k1 + ... + xn * kn`.
173
0
    fn lincomb_ext(points_and_scalars: &PointsAndScalars) -> Self {
174
0
        points_and_scalars
175
0
            .as_ref()
176
0
            .iter()
177
0
            .copied()
178
0
            .map(|(point, scalar)| point * scalar)
179
0
            .sum()
180
0
    }
181
}
182
183
/// Blanket impl of the legacy [`LinearCombination`] trait for types which impl the new
184
/// [`LinearCombinationExt`] trait for 2-element arrays.
185
impl<P: LinearCombinationExt<[(P, Self::Scalar); 2]>> LinearCombination for P {
186
523
    fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self {
187
523
        Self::lincomb_ext(&[(*x, *k), (*y, *l)])
188
523
    }
Unexecuted instantiation: _RNvXININtCs8yVsO3EKNkV_14elliptic_curve3opss0_0pEpNtB5_17LinearCombination7lincombB7_
_RNvXs0_NtCs8yVsO3EKNkV_14elliptic_curve3opsNtNtNtCsjewTDwKBbyD_4k25610arithmetic10projective15ProjectivePointNtB5_17LinearCombination7lincombBL_
Line
Count
Source
186
523
    fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self {
187
523
        Self::lincomb_ext(&[(*x, *k), (*y, *l)])
188
523
    }
189
}
190
191
/// Multiplication by the generator.
192
///
193
/// May use optimizations (e.g. precomputed tables) when available.
194
// TODO(tarcieri): replace this with `Group::mul_by_generator``? (see zkcrypto/group#44)
195
pub trait MulByGenerator: Group {
196
    /// Multiply by the generator of the prime-order subgroup.
197
    #[must_use]
198
0
    fn mul_by_generator(scalar: &Self::Scalar) -> Self {
199
0
        Self::generator() * scalar
200
0
    }
201
}
202
203
/// Modular reduction.
204
pub trait Reduce<Uint: Integer>: Sized {
205
    /// Bytes used as input to [`Reduce::reduce_bytes`].
206
    type Bytes: AsRef<[u8]>;
207
208
    /// Perform a modular reduction, returning a field element.
209
    fn reduce(n: Uint) -> Self;
210
211
    /// Interpret the given bytes as an integer and perform a modular reduction.
212
    fn reduce_bytes(bytes: &Self::Bytes) -> Self;
213
}
214
215
/// Modular reduction to a non-zero output.
216
///
217
/// This trait is primarily intended for use by curve implementations such
218
/// as the `k256` and `p256` crates.
219
///
220
/// End users should use the [`Reduce`] impl on
221
/// [`NonZeroScalar`][`crate::NonZeroScalar`] instead.
222
pub trait ReduceNonZero<Uint: Integer>: Reduce<Uint> + Sized {
223
    /// Perform a modular reduction, returning a field element.
224
    fn reduce_nonzero(n: Uint) -> Self;
225
226
    /// Interpret the given bytes as an integer and perform a modular reduction
227
    /// to a non-zero output.
228
    fn reduce_nonzero_bytes(bytes: &Self::Bytes) -> Self;
229
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/point/non_identity.rs
Line
Count
Source
1
//! Non-identity point type.
2
3
use core::ops::{Deref, Mul};
4
5
use group::{prime::PrimeCurveAffine, Curve, GroupEncoding};
6
use rand_core::{CryptoRng, RngCore};
7
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
8
9
#[cfg(feature = "serde")]
10
use serdect::serde::{de, ser, Deserialize, Serialize};
11
12
use crate::{CurveArithmetic, NonZeroScalar, Scalar};
13
14
/// Non-identity point type.
15
///
16
/// This type ensures that its value is not the identity point, ala `core::num::NonZero*`.
17
///
18
/// In the context of ECC, it's useful for ensuring that certain arithmetic
19
/// cannot result in the identity point.
20
#[derive(Clone, Copy)]
21
pub struct NonIdentity<P> {
22
    point: P,
23
}
24
25
impl<P> NonIdentity<P>
26
where
27
    P: ConditionallySelectable + ConstantTimeEq + Default,
28
{
29
    /// Create a [`NonIdentity`] from a point.
30
0
    pub fn new(point: P) -> CtOption<Self> {
31
0
        CtOption::new(Self { point }, !point.ct_eq(&P::default()))
32
0
    }
33
34
0
    pub(crate) fn new_unchecked(point: P) -> Self {
35
0
        Self { point }
36
0
    }
37
}
38
39
impl<P> NonIdentity<P>
40
where
41
    P: ConditionallySelectable + ConstantTimeEq + Default + GroupEncoding,
42
{
43
    /// Decode a [`NonIdentity`] from its encoding.
44
0
    pub fn from_repr(repr: &P::Repr) -> CtOption<Self> {
45
0
        Self::from_bytes(repr)
46
0
    }
47
}
48
49
impl<P: Copy> NonIdentity<P> {
50
    /// Return wrapped point.
51
0
    pub fn to_point(self) -> P {
52
0
        self.point
53
0
    }
54
}
55
56
impl<P> NonIdentity<P>
57
where
58
    P: ConditionallySelectable + ConstantTimeEq + Curve + Default,
59
{
60
    /// Generate a random `NonIdentity<ProjectivePoint>`.
61
0
    pub fn random(mut rng: impl CryptoRng + RngCore) -> Self {
62
        loop {
63
0
            if let Some(point) = Self::new(P::random(&mut rng)).into() {
64
0
                break point;
65
0
            }
66
        }
67
0
    }
68
69
    /// Converts this element into its affine representation.
70
0
    pub fn to_affine(self) -> NonIdentity<P::AffineRepr> {
71
0
        NonIdentity {
72
0
            point: self.point.to_affine(),
73
0
        }
74
0
    }
75
}
76
77
impl<P> NonIdentity<P>
78
where
79
    P: PrimeCurveAffine,
80
{
81
    /// Converts this element to its curve representation.
82
0
    pub fn to_curve(self) -> NonIdentity<P::Curve> {
83
0
        NonIdentity {
84
0
            point: self.point.to_curve(),
85
0
        }
86
0
    }
87
}
88
89
impl<P> AsRef<P> for NonIdentity<P> {
90
0
    fn as_ref(&self) -> &P {
91
0
        &self.point
92
0
    }
93
}
94
95
impl<P> ConditionallySelectable for NonIdentity<P>
96
where
97
    P: ConditionallySelectable,
98
{
99
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
100
0
        Self {
101
0
            point: P::conditional_select(&a.point, &b.point, choice),
102
0
        }
103
0
    }
104
}
105
106
impl<P> ConstantTimeEq for NonIdentity<P>
107
where
108
    P: ConstantTimeEq,
109
{
110
0
    fn ct_eq(&self, other: &Self) -> Choice {
111
0
        self.point.ct_eq(&other.point)
112
0
    }
113
}
114
115
impl<P> Deref for NonIdentity<P> {
116
    type Target = P;
117
118
0
    fn deref(&self) -> &Self::Target {
119
0
        &self.point
120
0
    }
121
}
122
123
impl<P> GroupEncoding for NonIdentity<P>
124
where
125
    P: ConditionallySelectable + ConstantTimeEq + Default + GroupEncoding,
126
{
127
    type Repr = P::Repr;
128
129
0
    fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
130
0
        let point = P::from_bytes(bytes);
131
0
        point.and_then(|point| CtOption::new(Self { point }, !point.ct_eq(&P::default())))
132
0
    }
133
134
0
    fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
135
0
        P::from_bytes_unchecked(bytes).map(|point| Self { point })
136
0
    }
137
138
0
    fn to_bytes(&self) -> Self::Repr {
139
0
        self.point.to_bytes()
140
0
    }
141
}
142
143
impl<C, P> Mul<NonZeroScalar<C>> for NonIdentity<P>
144
where
145
    C: CurveArithmetic,
146
    P: Copy + Mul<Scalar<C>, Output = P>,
147
{
148
    type Output = NonIdentity<P>;
149
150
0
    fn mul(self, rhs: NonZeroScalar<C>) -> Self::Output {
151
0
        &self * &rhs
152
0
    }
153
}
154
155
impl<C, P> Mul<&NonZeroScalar<C>> for &NonIdentity<P>
156
where
157
    C: CurveArithmetic,
158
    P: Copy + Mul<Scalar<C>, Output = P>,
159
{
160
    type Output = NonIdentity<P>;
161
162
0
    fn mul(self, rhs: &NonZeroScalar<C>) -> Self::Output {
163
0
        NonIdentity {
164
0
            point: self.point * *rhs.as_ref(),
165
0
        }
166
0
    }
167
}
168
169
#[cfg(feature = "serde")]
170
impl<P> Serialize for NonIdentity<P>
171
where
172
    P: Serialize,
173
{
174
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
175
    where
176
        S: ser::Serializer,
177
    {
178
        self.point.serialize(serializer)
179
    }
180
}
181
182
#[cfg(feature = "serde")]
183
impl<'de, P> Deserialize<'de> for NonIdentity<P>
184
where
185
    P: ConditionallySelectable + ConstantTimeEq + Default + Deserialize<'de> + GroupEncoding,
186
{
187
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
188
    where
189
        D: de::Deserializer<'de>,
190
    {
191
        Option::from(Self::new(P::deserialize(deserializer)?))
192
            .ok_or_else(|| de::Error::custom("expected non-identity point"))
193
    }
194
}
195
196
#[cfg(all(test, feature = "dev"))]
197
mod tests {
198
    use super::NonIdentity;
199
    use crate::dev::{AffinePoint, ProjectivePoint};
200
    use group::GroupEncoding;
201
    use hex_literal::hex;
202
203
    #[test]
204
    fn new_success() {
205
        let point = ProjectivePoint::from_bytes(
206
            &hex!("02c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721").into(),
207
        )
208
        .unwrap();
209
210
        assert!(bool::from(NonIdentity::new(point).is_some()));
211
212
        assert!(bool::from(
213
            NonIdentity::new(AffinePoint::from(point)).is_some()
214
        ));
215
    }
216
217
    #[test]
218
    fn new_fail() {
219
        assert!(bool::from(
220
            NonIdentity::new(ProjectivePoint::default()).is_none()
221
        ));
222
        assert!(bool::from(
223
            NonIdentity::new(AffinePoint::default()).is_none()
224
        ));
225
    }
226
227
    #[test]
228
    fn round_trip() {
229
        let bytes = hex!("02c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721");
230
        let point = NonIdentity::<ProjectivePoint>::from_repr(&bytes.into()).unwrap();
231
        assert_eq!(&bytes, point.to_bytes().as_slice());
232
233
        let bytes = hex!("02c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721");
234
        let point = NonIdentity::<AffinePoint>::from_repr(&bytes.into()).unwrap();
235
        assert_eq!(&bytes, point.to_bytes().as_slice());
236
    }
237
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/public_key.rs
Line
Count
Source
1
//! Elliptic curve public keys.
2
3
use crate::{
4
    point::NonIdentity, AffinePoint, CurveArithmetic, Error, NonZeroScalar, ProjectivePoint, Result,
5
};
6
use core::fmt::Debug;
7
use group::{Curve, Group};
8
9
#[cfg(feature = "jwk")]
10
use crate::{JwkEcKey, JwkParameters};
11
12
#[cfg(feature = "pkcs8")]
13
use pkcs8::spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier, ObjectIdentifier};
14
15
#[cfg(feature = "pem")]
16
use core::str::FromStr;
17
18
#[cfg(feature = "sec1")]
19
use {
20
    crate::{
21
        point::PointCompression,
22
        sec1::{CompressedPoint, EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint},
23
        FieldBytesSize,
24
    },
25
    core::cmp::Ordering,
26
    subtle::{Choice, CtOption},
27
};
28
29
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
30
use pkcs8::EncodePublicKey;
31
32
#[cfg(all(feature = "alloc", feature = "sec1"))]
33
use alloc::boxed::Box;
34
35
#[cfg(any(feature = "jwk", feature = "pem"))]
36
use alloc::string::{String, ToString};
37
38
#[cfg(feature = "serde")]
39
use serdect::serde::{de, ser, Deserialize, Serialize};
40
41
#[cfg(any(feature = "pem", feature = "serde"))]
42
use pkcs8::DecodePublicKey;
43
44
#[cfg(all(feature = "sec1", feature = "pkcs8"))]
45
use {
46
    crate::{
47
        pkcs8::{self, AssociatedOid},
48
        ALGORITHM_OID,
49
    },
50
    pkcs8::der,
51
};
52
53
/// Elliptic curve public keys.
54
///
55
/// This is a wrapper type for [`AffinePoint`] which ensures an inner
56
/// non-identity point and provides a common place to handle encoding/decoding.
57
///
58
/// # Parsing "SPKI" Keys
59
///
60
/// X.509 `SubjectPublicKeyInfo` (SPKI) is a commonly used format for encoding
61
/// public keys, notably public keys corresponding to PKCS#8 private keys.
62
/// (especially ones generated by OpenSSL).
63
///
64
/// Keys in SPKI format are either binary (ASN.1 BER/DER), or PEM encoded
65
/// (ASCII) and begin with the following:
66
///
67
/// ```text
68
/// -----BEGIN PUBLIC KEY-----
69
/// ```
70
///
71
/// To decode an elliptic curve public key from SPKI, enable the `pkcs8`
72
/// feature of this crate (or the `pkcs8` feature of a specific RustCrypto
73
/// elliptic curve crate) and use the
74
/// [`elliptic_curve::pkcs8::DecodePublicKey`][`pkcs8::DecodePublicKey`]
75
/// trait to parse it.
76
///
77
/// When the `pem` feature of this crate (or a specific RustCrypto elliptic
78
/// curve crate) is enabled, a [`FromStr`] impl is also available.
79
///
80
/// # `serde` support
81
///
82
/// When the optional `serde` feature of this create is enabled, [`Serialize`]
83
/// and [`Deserialize`] impls are provided for this type.
84
///
85
/// The serialization is binary-oriented and supports ASN.1 DER
86
/// Subject Public Key Info (SPKI) as the encoding format.
87
///
88
/// For a more text-friendly encoding of public keys, use [`JwkEcKey`] instead.
89
#[derive(Clone, Debug, Eq, PartialEq)]
90
pub struct PublicKey<C>
91
where
92
    C: CurveArithmetic,
93
{
94
    point: AffinePoint<C>,
95
}
96
97
impl<C> PublicKey<C>
98
where
99
    C: CurveArithmetic,
100
{
101
    /// Convert an [`AffinePoint`] into a [`PublicKey`]
102
0
    pub fn from_affine(point: AffinePoint<C>) -> Result<Self> {
103
0
        if ProjectivePoint::<C>::from(point).is_identity().into() {
104
0
            Err(Error)
105
        } else {
106
0
            Ok(Self { point })
107
        }
108
0
    }
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeypE11from_affineB4_
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1E11from_affineB12_
109
110
    /// Compute a [`PublicKey`] from a secret [`NonZeroScalar`] value
111
    /// (i.e. a secret key represented as a raw scalar value)
112
0
    pub fn from_secret_scalar(scalar: &NonZeroScalar<C>) -> Self {
113
0
        // `NonZeroScalar` ensures the resulting point is not the identity
114
0
        Self {
115
0
            point: (C::ProjectivePoint::generator() * scalar.as_ref()).to_affine(),
116
0
        }
117
0
    }
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeypE18from_secret_scalarB4_
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1E18from_secret_scalarB12_
118
119
    /// Decode [`PublicKey`] (compressed or uncompressed) from the
120
    /// `Elliptic-Curve-Point-to-Octet-String` encoding described in
121
    /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section
122
    /// 2.3.3 (page 10).
123
    ///
124
    /// <http://www.secg.org/sec1-v2.pdf>
125
    #[cfg(feature = "sec1")]
126
2.51k
    pub fn from_sec1_bytes(bytes: &[u8]) -> Result<Self>
127
2.51k
    where
128
2.51k
        FieldBytesSize<C>: ModulusSize,
129
2.51k
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
130
2.51k
    {
131
2.51k
        let point = EncodedPoint::<C>::from_bytes(bytes).map_err(|_| Error)?;
_RNCNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB4_9PublicKeyNtCsaHRNXv1Y9Bq_4p2568NistP256E15from_sec1_bytes0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
131
30
        let point = EncodedPoint::<C>::from_bytes(bytes).map_err(|_| Error)?;
_RNCNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB4_9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1E15from_sec1_bytes0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
131
34
        let point = EncodedPoint::<C>::from_bytes(bytes).map_err(|_| Error)?;
Unexecuted instantiation: _RNCNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB4_9PublicKeypE15from_sec1_bytes0B6_
132
2.45k
        Option::from(Self::from_encoded_point(&point)).ok_or(Error)
133
2.51k
    }
_RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeyNtCsaHRNXv1Y9Bq_4p2568NistP256E15from_sec1_bytesCs4RkbDk9WRL5_5clvmr
Line
Count
Source
126
1.21k
    pub fn from_sec1_bytes(bytes: &[u8]) -> Result<Self>
127
1.21k
    where
128
1.21k
        FieldBytesSize<C>: ModulusSize,
129
1.21k
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
130
1.21k
    {
131
1.21k
        let point = EncodedPoint::<C>::from_bytes(bytes).map_err(|_| Error)?;
132
1.18k
        Option::from(Self::from_encoded_point(&point)).ok_or(Error)
133
1.21k
    }
_RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1E15from_sec1_bytesCs4RkbDk9WRL5_5clvmr
Line
Count
Source
126
1.30k
    pub fn from_sec1_bytes(bytes: &[u8]) -> Result<Self>
127
1.30k
    where
128
1.30k
        FieldBytesSize<C>: ModulusSize,
129
1.30k
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
130
1.30k
    {
131
1.30k
        let point = EncodedPoint::<C>::from_bytes(bytes).map_err(|_| Error)?;
132
1.27k
        Option::from(Self::from_encoded_point(&point)).ok_or(Error)
133
1.30k
    }
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeypE15from_sec1_bytesB4_
134
135
    /// Convert this [`PublicKey`] into the
136
    /// `Elliptic-Curve-Point-to-Octet-String` encoding described in
137
    /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section 2.3.3
138
    /// (page 10).
139
    ///
140
    /// <http://www.secg.org/sec1-v2.pdf>
141
    #[cfg(all(feature = "alloc", feature = "sec1"))]
142
0
    pub fn to_sec1_bytes(&self) -> Box<[u8]>
143
0
    where
144
0
        C: PointCompression,
145
0
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
146
0
        FieldBytesSize<C>: ModulusSize,
147
0
    {
148
0
        EncodedPoint::<C>::from(self).to_bytes()
149
0
    }
150
151
    /// Borrow the inner [`AffinePoint`] from this [`PublicKey`].
152
    ///
153
    /// In ECC, public keys are elliptic curve points.
154
1.37k
    pub fn as_affine(&self) -> &AffinePoint<C> {
155
1.37k
        &self.point
156
1.37k
    }
_RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeyNtCsaHRNXv1Y9Bq_4p2568NistP256E9as_affineCs4RkbDk9WRL5_5clvmr
Line
Count
Source
154
838
    pub fn as_affine(&self) -> &AffinePoint<C> {
155
838
        &self.point
156
838
    }
_RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1E9as_affineCs4RkbDk9WRL5_5clvmr
Line
Count
Source
154
534
    pub fn as_affine(&self) -> &AffinePoint<C> {
155
534
        &self.point
156
534
    }
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeypE9as_affineB4_
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1E9as_affineB12_
157
158
    /// Convert this [`PublicKey`] to a [`ProjectivePoint`] for the given curve
159
0
    pub fn to_projective(&self) -> ProjectivePoint<C> {
160
0
        self.point.into()
161
0
    }
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeypE13to_projectiveB4_
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB2_9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1E13to_projectiveB12_
162
163
    /// Convert this [`PublicKey`] to a [`NonIdentity`] of the inner [`AffinePoint`]
164
0
    pub fn to_nonidentity(&self) -> NonIdentity<AffinePoint<C>> {
165
0
        NonIdentity::new_unchecked(self.point)
166
0
    }
167
168
    /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`PublicKey`].
169
    #[cfg(feature = "jwk")]
170
    pub fn from_jwk(jwk: &JwkEcKey) -> Result<Self>
171
    where
172
        C: JwkParameters,
173
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
174
        FieldBytesSize<C>: ModulusSize,
175
    {
176
        jwk.to_public_key::<C>()
177
    }
178
179
    /// Parse a string containing a JSON Web Key (JWK) into a [`PublicKey`].
180
    #[cfg(feature = "jwk")]
181
    pub fn from_jwk_str(jwk: &str) -> Result<Self>
182
    where
183
        C: JwkParameters,
184
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
185
        FieldBytesSize<C>: ModulusSize,
186
    {
187
        jwk.parse::<JwkEcKey>().and_then(|jwk| Self::from_jwk(&jwk))
188
    }
189
190
    /// Serialize this public key as [`JwkEcKey`] JSON Web Key (JWK).
191
    #[cfg(feature = "jwk")]
192
    pub fn to_jwk(&self) -> JwkEcKey
193
    where
194
        C: JwkParameters,
195
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
196
        FieldBytesSize<C>: ModulusSize,
197
    {
198
        self.into()
199
    }
200
201
    /// Serialize this public key as JSON Web Key (JWK) string.
202
    #[cfg(feature = "jwk")]
203
    pub fn to_jwk_string(&self) -> String
204
    where
205
        C: JwkParameters,
206
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
207
        FieldBytesSize<C>: ModulusSize,
208
    {
209
        self.to_jwk().to_string()
210
    }
211
}
212
213
impl<C> AsRef<AffinePoint<C>> for PublicKey<C>
214
where
215
    C: CurveArithmetic,
216
{
217
0
    fn as_ref(&self) -> &AffinePoint<C> {
218
0
        self.as_affine()
219
0
    }
220
}
221
222
impl<C> Copy for PublicKey<C> where C: CurveArithmetic {}
223
224
#[cfg(feature = "sec1")]
225
impl<C> FromEncodedPoint<C> for PublicKey<C>
226
where
227
    C: CurveArithmetic,
228
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
229
    FieldBytesSize<C>: ModulusSize,
230
{
231
    /// Initialize [`PublicKey`] from an [`EncodedPoint`]
232
2.45k
    fn from_encoded_point(encoded_point: &EncodedPoint<C>) -> CtOption<Self> {
233
2.45k
        AffinePoint::<C>::from_encoded_point(encoded_point).and_then(|point| {
234
2.45k
            // Defeating the point of `subtle`, but the use case is specifically a public key
235
2.45k
            let is_identity = Choice::from(u8::from(encoded_point.is_identity()));
236
2.45k
            CtOption::new(PublicKey { point }, !is_identity)
237
2.45k
        })
_RNCNvXs1_NtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB7_9PublicKeyNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtB9_4sec116FromEncodedPointB15_E18from_encoded_point0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
233
1.18k
        AffinePoint::<C>::from_encoded_point(encoded_point).and_then(|point| {
234
1.18k
            // Defeating the point of `subtle`, but the use case is specifically a public key
235
1.18k
            let is_identity = Choice::from(u8::from(encoded_point.is_identity()));
236
1.18k
            CtOption::new(PublicKey { point }, !is_identity)
237
1.18k
        })
_RNCNvXs1_NtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB7_9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1EINtNtB9_4sec116FromEncodedPointB15_E18from_encoded_point0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
233
1.27k
        AffinePoint::<C>::from_encoded_point(encoded_point).and_then(|point| {
234
1.27k
            // Defeating the point of `subtle`, but the use case is specifically a public key
235
1.27k
            let is_identity = Choice::from(u8::from(encoded_point.is_identity()));
236
1.27k
            CtOption::new(PublicKey { point }, !is_identity)
237
1.27k
        })
Unexecuted instantiation: _RNCNvXININtCs8yVsO3EKNkV_14elliptic_curve10public_keys1_0pEINtB7_9PublicKeypEINtNtB9_4sec116FromEncodedPointpE18from_encoded_point0B9_
238
2.45k
    }
_RNvXs1_NtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB5_9PublicKeyNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtB7_4sec116FromEncodedPointB13_E18from_encoded_pointCs4RkbDk9WRL5_5clvmr
Line
Count
Source
232
1.18k
    fn from_encoded_point(encoded_point: &EncodedPoint<C>) -> CtOption<Self> {
233
1.18k
        AffinePoint::<C>::from_encoded_point(encoded_point).and_then(|point| {
234
            // Defeating the point of `subtle`, but the use case is specifically a public key
235
            let is_identity = Choice::from(u8::from(encoded_point.is_identity()));
236
            CtOption::new(PublicKey { point }, !is_identity)
237
1.18k
        })
238
1.18k
    }
_RNvXs1_NtCs8yVsO3EKNkV_14elliptic_curve10public_keyINtB5_9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1EINtNtB7_4sec116FromEncodedPointB13_E18from_encoded_pointCs4RkbDk9WRL5_5clvmr
Line
Count
Source
232
1.27k
    fn from_encoded_point(encoded_point: &EncodedPoint<C>) -> CtOption<Self> {
233
1.27k
        AffinePoint::<C>::from_encoded_point(encoded_point).and_then(|point| {
234
            // Defeating the point of `subtle`, but the use case is specifically a public key
235
            let is_identity = Choice::from(u8::from(encoded_point.is_identity()));
236
            CtOption::new(PublicKey { point }, !is_identity)
237
1.27k
        })
238
1.27k
    }
Unexecuted instantiation: _RNvXININtCs8yVsO3EKNkV_14elliptic_curve10public_keys1_0pEINtB5_9PublicKeypEINtNtB7_4sec116FromEncodedPointpE18from_encoded_pointB7_
239
}
240
241
#[cfg(feature = "sec1")]
242
impl<C> ToEncodedPoint<C> for PublicKey<C>
243
where
244
    C: CurveArithmetic,
245
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
246
    FieldBytesSize<C>: ModulusSize,
247
{
248
    /// Serialize this [`PublicKey`] as a SEC1 [`EncodedPoint`], optionally applying
249
    /// point compression
250
0
    fn to_encoded_point(&self, compress: bool) -> EncodedPoint<C> {
251
0
        self.point.to_encoded_point(compress)
252
0
    }
253
}
254
255
#[cfg(feature = "sec1")]
256
impl<C> From<PublicKey<C>> for CompressedPoint<C>
257
where
258
    C: CurveArithmetic + PointCompression,
259
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
260
    FieldBytesSize<C>: ModulusSize,
261
{
262
0
    fn from(public_key: PublicKey<C>) -> CompressedPoint<C> {
263
0
        CompressedPoint::<C>::from(&public_key)
264
0
    }
265
}
266
267
#[cfg(feature = "sec1")]
268
impl<C> From<&PublicKey<C>> for CompressedPoint<C>
269
where
270
    C: CurveArithmetic + PointCompression,
271
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
272
    FieldBytesSize<C>: ModulusSize,
273
{
274
0
    fn from(public_key: &PublicKey<C>) -> CompressedPoint<C> {
275
0
        CompressedPoint::<C>::clone_from_slice(public_key.to_encoded_point(true).as_bytes())
276
0
    }
277
}
278
279
#[cfg(feature = "sec1")]
280
impl<C> From<PublicKey<C>> for EncodedPoint<C>
281
where
282
    C: CurveArithmetic + PointCompression,
283
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
284
    FieldBytesSize<C>: ModulusSize,
285
{
286
0
    fn from(public_key: PublicKey<C>) -> EncodedPoint<C> {
287
0
        EncodedPoint::<C>::from(&public_key)
288
0
    }
289
}
290
291
#[cfg(feature = "sec1")]
292
impl<C> From<&PublicKey<C>> for EncodedPoint<C>
293
where
294
    C: CurveArithmetic + PointCompression,
295
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
296
    FieldBytesSize<C>: ModulusSize,
297
{
298
0
    fn from(public_key: &PublicKey<C>) -> EncodedPoint<C> {
299
0
        public_key.to_encoded_point(C::COMPRESS_POINTS)
300
0
    }
301
}
302
303
impl<C, P> From<NonIdentity<P>> for PublicKey<C>
304
where
305
    C: CurveArithmetic,
306
    P: Copy + Into<AffinePoint<C>>,
307
{
308
0
    fn from(value: NonIdentity<P>) -> Self {
309
0
        Self::from(&value)
310
0
    }
311
}
312
313
impl<C, P> From<&NonIdentity<P>> for PublicKey<C>
314
where
315
    C: CurveArithmetic,
316
    P: Copy + Into<AffinePoint<C>>,
317
{
318
0
    fn from(value: &NonIdentity<P>) -> Self {
319
0
        Self {
320
0
            point: value.to_point().into(),
321
0
        }
322
0
    }
323
}
324
325
impl<C> From<PublicKey<C>> for NonIdentity<AffinePoint<C>>
326
where
327
    C: CurveArithmetic,
328
{
329
0
    fn from(value: PublicKey<C>) -> Self {
330
0
        Self::from(&value)
331
0
    }
332
}
333
334
impl<C> From<&PublicKey<C>> for NonIdentity<AffinePoint<C>>
335
where
336
    C: CurveArithmetic,
337
{
338
0
    fn from(value: &PublicKey<C>) -> Self {
339
0
        PublicKey::to_nonidentity(value)
340
0
    }
341
}
342
343
#[cfg(feature = "sec1")]
344
impl<C> PartialOrd for PublicKey<C>
345
where
346
    C: CurveArithmetic,
347
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
348
    FieldBytesSize<C>: ModulusSize,
349
{
350
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
351
0
        Some(self.cmp(other))
352
0
    }
353
}
354
355
#[cfg(feature = "sec1")]
356
impl<C> Ord for PublicKey<C>
357
where
358
    C: CurveArithmetic,
359
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
360
    FieldBytesSize<C>: ModulusSize,
361
{
362
0
    fn cmp(&self, other: &Self) -> Ordering {
363
0
        // TODO(tarcieri): more efficient implementation?
364
0
        // This is implemented this way to reduce bounds for `AffinePoint<C>`
365
0
        self.to_encoded_point(false)
366
0
            .cmp(&other.to_encoded_point(false))
367
0
    }
368
}
369
370
#[cfg(feature = "sec1")]
371
impl<C> TryFrom<CompressedPoint<C>> for PublicKey<C>
372
where
373
    C: CurveArithmetic,
374
    FieldBytesSize<C>: ModulusSize,
375
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
376
{
377
    type Error = Error;
378
379
0
    fn try_from(point: CompressedPoint<C>) -> Result<Self> {
380
0
        Self::from_sec1_bytes(&point)
381
0
    }
382
}
383
384
#[cfg(feature = "sec1")]
385
impl<C> TryFrom<&CompressedPoint<C>> for PublicKey<C>
386
where
387
    C: CurveArithmetic,
388
    FieldBytesSize<C>: ModulusSize,
389
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
390
{
391
    type Error = Error;
392
393
0
    fn try_from(point: &CompressedPoint<C>) -> Result<Self> {
394
0
        Self::from_sec1_bytes(point)
395
0
    }
396
}
397
398
#[cfg(feature = "sec1")]
399
impl<C> TryFrom<EncodedPoint<C>> for PublicKey<C>
400
where
401
    C: CurveArithmetic,
402
    FieldBytesSize<C>: ModulusSize,
403
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
404
{
405
    type Error = Error;
406
407
0
    fn try_from(point: EncodedPoint<C>) -> Result<Self> {
408
0
        Self::from_sec1_bytes(point.as_bytes())
409
0
    }
410
}
411
412
#[cfg(feature = "sec1")]
413
impl<C> TryFrom<&EncodedPoint<C>> for PublicKey<C>
414
where
415
    C: CurveArithmetic,
416
    FieldBytesSize<C>: ModulusSize,
417
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
418
{
419
    type Error = Error;
420
421
0
    fn try_from(point: &EncodedPoint<C>) -> Result<Self> {
422
0
        Self::from_sec1_bytes(point.as_bytes())
423
0
    }
424
}
425
426
#[cfg(feature = "pkcs8")]
427
impl<C> AssociatedAlgorithmIdentifier for PublicKey<C>
428
where
429
    C: AssociatedOid + CurveArithmetic,
430
{
431
    type Params = ObjectIdentifier;
432
433
    const ALGORITHM_IDENTIFIER: AlgorithmIdentifier<ObjectIdentifier> = AlgorithmIdentifier {
434
        oid: ALGORITHM_OID,
435
        parameters: Some(C::OID),
436
    };
437
}
438
439
#[cfg(feature = "pkcs8")]
440
impl<C> TryFrom<pkcs8::SubjectPublicKeyInfoRef<'_>> for PublicKey<C>
441
where
442
    C: AssociatedOid + CurveArithmetic,
443
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
444
    FieldBytesSize<C>: ModulusSize,
445
{
446
    type Error = pkcs8::spki::Error;
447
448
0
    fn try_from(spki: pkcs8::SubjectPublicKeyInfoRef<'_>) -> pkcs8::spki::Result<Self> {
449
0
        Self::try_from(&spki)
450
0
    }
451
}
452
453
#[cfg(feature = "pkcs8")]
454
impl<C> TryFrom<&pkcs8::SubjectPublicKeyInfoRef<'_>> for PublicKey<C>
455
where
456
    C: AssociatedOid + CurveArithmetic,
457
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
458
    FieldBytesSize<C>: ModulusSize,
459
{
460
    type Error = pkcs8::spki::Error;
461
462
0
    fn try_from(spki: &pkcs8::SubjectPublicKeyInfoRef<'_>) -> pkcs8::spki::Result<Self> {
463
0
        spki.algorithm.assert_oids(ALGORITHM_OID, C::OID)?;
464
465
0
        let public_key_bytes = spki
466
0
            .subject_public_key
467
0
            .as_bytes()
468
0
            .ok_or_else(|| der::Tag::BitString.value_error())?;
469
470
0
        Self::from_sec1_bytes(public_key_bytes)
471
0
            .map_err(|_| der::Tag::BitString.value_error().into())
472
0
    }
473
}
474
475
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
476
impl<C> EncodePublicKey for PublicKey<C>
477
where
478
    C: AssociatedOid + CurveArithmetic,
479
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
480
    FieldBytesSize<C>: ModulusSize,
481
{
482
0
    fn to_public_key_der(&self) -> pkcs8::spki::Result<der::Document> {
483
0
        let public_key_bytes = self.to_encoded_point(false);
484
0
        let subject_public_key = der::asn1::BitStringRef::new(0, public_key_bytes.as_bytes())?;
485
486
0
        pkcs8::SubjectPublicKeyInfo {
487
0
            algorithm: Self::ALGORITHM_IDENTIFIER,
488
0
            subject_public_key,
489
0
        }
490
0
        .try_into()
491
0
    }
492
}
493
494
#[cfg(feature = "pem")]
495
impl<C> FromStr for PublicKey<C>
496
where
497
    C: AssociatedOid + CurveArithmetic,
498
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
499
    FieldBytesSize<C>: ModulusSize,
500
{
501
    type Err = Error;
502
503
0
    fn from_str(s: &str) -> Result<Self> {
504
0
        Self::from_public_key_pem(s).map_err(|_| Error)
505
0
    }
506
}
507
508
#[cfg(feature = "pem")]
509
impl<C> ToString for PublicKey<C>
510
where
511
    C: AssociatedOid + CurveArithmetic,
512
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
513
    FieldBytesSize<C>: ModulusSize,
514
{
515
0
    fn to_string(&self) -> String {
516
0
        self.to_public_key_pem(Default::default())
517
0
            .expect("PEM encoding error")
518
0
    }
519
}
520
521
#[cfg(feature = "serde")]
522
impl<C> Serialize for PublicKey<C>
523
where
524
    C: AssociatedOid + CurveArithmetic,
525
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
526
    FieldBytesSize<C>: ModulusSize,
527
{
528
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
529
    where
530
        S: ser::Serializer,
531
    {
532
        let der = self.to_public_key_der().map_err(ser::Error::custom)?;
533
        serdect::slice::serialize_hex_upper_or_bin(&der, serializer)
534
    }
535
}
536
537
#[cfg(feature = "serde")]
538
impl<'de, C> Deserialize<'de> for PublicKey<C>
539
where
540
    C: AssociatedOid + CurveArithmetic,
541
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
542
    FieldBytesSize<C>: ModulusSize,
543
{
544
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
545
    where
546
        D: de::Deserializer<'de>,
547
    {
548
        let der_bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?;
549
        Self::from_public_key_der(&der_bytes).map_err(de::Error::custom)
550
    }
551
}
552
553
#[cfg(all(feature = "dev", test))]
554
mod tests {
555
    use crate::{dev::MockCurve, sec1::FromEncodedPoint};
556
557
    type EncodedPoint = crate::sec1::EncodedPoint<MockCurve>;
558
    type PublicKey = super::PublicKey<MockCurve>;
559
560
    #[test]
561
    fn from_encoded_point_rejects_identity() {
562
        let identity = EncodedPoint::identity();
563
        assert!(bool::from(
564
            PublicKey::from_encoded_point(&identity).is_none()
565
        ));
566
    }
567
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/scalar/blinded.rs
Line
Count
Source
1
//! Random blinding support for [`Scalar`]
2
3
use super::Scalar;
4
use crate::{ops::Invert, CurveArithmetic};
5
use group::ff::Field;
6
use rand_core::CryptoRngCore;
7
use subtle::CtOption;
8
use zeroize::Zeroize;
9
10
/// Scalar blinded with a randomly generated masking value.
11
///
12
/// This provides a randomly blinded impl of [`Invert`] which is useful for
13
/// e.g. ECDSA ephemeral (`k`) scalars.
14
///
15
/// It implements masked variable-time inversions using Stein's algorithm, which
16
/// may be helpful for performance on embedded platforms.
17
#[derive(Clone)]
18
pub struct BlindedScalar<C>
19
where
20
    C: CurveArithmetic,
21
{
22
    /// Actual scalar value.
23
    scalar: Scalar<C>,
24
25
    /// Mask value.
26
    mask: Scalar<C>,
27
}
28
29
impl<C> BlindedScalar<C>
30
where
31
    C: CurveArithmetic,
32
{
33
    /// Create a new [`BlindedScalar`] from a scalar and a [`CryptoRngCore`].
34
0
    pub fn new(scalar: Scalar<C>, rng: &mut impl CryptoRngCore) -> Self {
35
0
        Self {
36
0
            scalar,
37
0
            mask: Scalar::<C>::random(rng),
38
0
        }
39
0
    }
40
}
41
42
impl<C> AsRef<Scalar<C>> for BlindedScalar<C>
43
where
44
    C: CurveArithmetic,
45
{
46
0
    fn as_ref(&self) -> &Scalar<C> {
47
0
        &self.scalar
48
0
    }
49
}
50
51
impl<C> Invert for BlindedScalar<C>
52
where
53
    C: CurveArithmetic,
54
{
55
    type Output = CtOption<Scalar<C>>;
56
57
0
    fn invert(&self) -> CtOption<Scalar<C>> {
58
0
        // prevent side channel analysis of scalar inversion by pre-and-post-multiplying
59
0
        // with the random masking scalar
60
0
        (self.scalar * self.mask)
61
0
            .invert_vartime()
62
0
            .map(|s| s * self.mask)
63
0
    }
64
}
65
66
impl<C> Drop for BlindedScalar<C>
67
where
68
    C: CurveArithmetic,
69
{
70
0
    fn drop(&mut self) {
71
0
        self.scalar.zeroize();
72
0
        self.mask.zeroize();
73
0
    }
74
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/scalar/nonzero.rs
Line
Count
Source
1
//! Non-zero scalar type.
2
3
use crate::{
4
    ops::{Invert, Reduce, ReduceNonZero},
5
    scalar::IsHigh,
6
    CurveArithmetic, Error, FieldBytes, PrimeCurve, Scalar, ScalarPrimitive, SecretKey,
7
};
8
use base16ct::HexDisplay;
9
use core::{
10
    fmt,
11
    ops::{Deref, Mul, Neg},
12
    str,
13
};
14
use crypto_bigint::{ArrayEncoding, Integer};
15
use ff::{Field, PrimeField};
16
use generic_array::{typenum::Unsigned, GenericArray};
17
use rand_core::CryptoRngCore;
18
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
19
use zeroize::Zeroize;
20
21
#[cfg(feature = "serde")]
22
use serdect::serde::{de, ser, Deserialize, Serialize};
23
24
/// Non-zero scalar type.
25
///
26
/// This type ensures that its value is not zero, ala `core::num::NonZero*`.
27
/// To do this, the generic `S` type must impl both `Default` and
28
/// `ConstantTimeEq`, with the requirement that `S::default()` returns 0.
29
///
30
/// In the context of ECC, it's useful for ensuring that scalar multiplication
31
/// cannot result in the point at infinity.
32
#[derive(Clone)]
33
pub struct NonZeroScalar<C>
34
where
35
    C: CurveArithmetic,
36
{
37
    scalar: Scalar<C>,
38
}
39
40
impl<C> NonZeroScalar<C>
41
where
42
    C: CurveArithmetic,
43
{
44
    /// Generate a random `NonZeroScalar`.
45
0
    pub fn random(mut rng: &mut impl CryptoRngCore) -> Self {
46
        // Use rejection sampling to eliminate zero values.
47
        // While this method isn't constant-time, the attacker shouldn't learn
48
        // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`.
49
        loop {
50
0
            if let Some(result) = Self::new(Field::random(&mut rng)).into() {
51
0
                break result;
52
0
            }
53
        }
54
0
    }
55
56
    /// Create a [`NonZeroScalar`] from a scalar.
57
3.25k
    pub fn new(scalar: Scalar<C>) -> CtOption<Self> {
58
3.25k
        CtOption::new(Self { scalar }, !scalar.is_zero())
59
3.25k
    }
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB2_13NonZeroScalarNtCsaHRNXv1Y9Bq_4p2568NistP256E3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
57
1.67k
    pub fn new(scalar: Scalar<C>) -> CtOption<Self> {
58
1.67k
        CtOption::new(Self { scalar }, !scalar.is_zero())
59
1.67k
    }
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB2_13NonZeroScalarpE3newB6_
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB2_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1E3newB1c_
Line
Count
Source
57
1.58k
    pub fn new(scalar: Scalar<C>) -> CtOption<Self> {
58
1.58k
        CtOption::new(Self { scalar }, !scalar.is_zero())
59
1.58k
    }
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB2_13NonZeroScalarNtCsaHRNXv1Y9Bq_4p2568NistP256E3newB1c_
60
61
    /// Decode a [`NonZeroScalar`] from a big endian-serialized field element.
62
0
    pub fn from_repr(repr: FieldBytes<C>) -> CtOption<Self> {
63
0
        Scalar::<C>::from_repr(repr).and_then(Self::new)
64
0
    }
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB2_13NonZeroScalarpE9from_reprB6_
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB2_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1E9from_reprB1c_
65
66
    /// Create a [`NonZeroScalar`] from a `C::Uint`.
67
0
    pub fn from_uint(uint: C::Uint) -> CtOption<Self> {
68
0
        ScalarPrimitive::new(uint).and_then(|scalar| Self::new(scalar.into()))
69
0
    }
70
}
71
72
impl<C> AsRef<Scalar<C>> for NonZeroScalar<C>
73
where
74
    C: CurveArithmetic,
75
{
76
0
    fn as_ref(&self) -> &Scalar<C> {
77
0
        &self.scalar
78
0
    }
Unexecuted instantiation: _RNvXININtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeros_0pEINtB5_13NonZeroScalarpEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefNtYpNtNtB9_10arithmetic15CurveArithmetic6ScalarE6as_refB9_
Unexecuted instantiation: _RNvXs_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB4_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1EINtNtCsbQ8arDwx5Xq_4core7convert5AsRefNtNtNtB1e_10arithmetic6scalar6ScalarE6as_refB1e_
79
}
80
81
impl<C> ConditionallySelectable for NonZeroScalar<C>
82
where
83
    C: CurveArithmetic,
84
{
85
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
86
0
        Self {
87
0
            scalar: Scalar::<C>::conditional_select(&a.scalar, &b.scalar, choice),
88
0
        }
89
0
    }
Unexecuted instantiation: _RNvXININtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeros0_0pEINtB5_13NonZeroScalarpENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectB9_
Unexecuted instantiation: _RNvXs0_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1ENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectB1f_
90
}
91
92
impl<C> ConstantTimeEq for NonZeroScalar<C>
93
where
94
    C: CurveArithmetic,
95
{
96
0
    fn ct_eq(&self, other: &Self) -> Choice {
97
0
        self.scalar.ct_eq(&other.scalar)
98
0
    }
Unexecuted instantiation: _RNvXININtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeros1_0pEINtB5_13NonZeroScalarpENtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_eqB9_
Unexecuted instantiation: _RNvXs1_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1ENtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_eqB1f_
99
}
100
101
impl<C> Copy for NonZeroScalar<C> where C: CurveArithmetic {}
102
103
impl<C> Deref for NonZeroScalar<C>
104
where
105
    C: CurveArithmetic,
106
{
107
    type Target = Scalar<C>;
108
109
4.08k
    fn deref(&self) -> &Scalar<C> {
110
4.08k
        &self.scalar
111
4.08k
    }
_RNvXs3_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCs4RkbDk9WRL5_5clvmr
Line
Count
Source
109
2.51k
    fn deref(&self) -> &Scalar<C> {
110
2.51k
        &self.scalar
111
2.51k
    }
Unexecuted instantiation: _RNvXININtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeros3_0pEINtB5_13NonZeroScalarpENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefB9_
_RNvXs3_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1ENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefB1f_
Line
Count
Source
109
1.56k
    fn deref(&self) -> &Scalar<C> {
110
1.56k
        &self.scalar
111
1.56k
    }
Unexecuted instantiation: _RNvXs3_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefB1f_
112
}
113
114
impl<C> From<NonZeroScalar<C>> for FieldBytes<C>
115
where
116
    C: CurveArithmetic,
117
{
118
0
    fn from(scalar: NonZeroScalar<C>) -> FieldBytes<C> {
119
0
        Self::from(&scalar)
120
0
    }
121
}
122
123
impl<C> From<&NonZeroScalar<C>> for FieldBytes<C>
124
where
125
    C: CurveArithmetic,
126
{
127
0
    fn from(scalar: &NonZeroScalar<C>) -> FieldBytes<C> {
128
0
        scalar.to_repr()
129
0
    }
130
}
131
132
impl<C> From<NonZeroScalar<C>> for ScalarPrimitive<C>
133
where
134
    C: CurveArithmetic,
135
{
136
    #[inline]
137
0
    fn from(scalar: NonZeroScalar<C>) -> ScalarPrimitive<C> {
138
0
        Self::from(&scalar)
139
0
    }
140
}
141
142
impl<C> From<&NonZeroScalar<C>> for ScalarPrimitive<C>
143
where
144
    C: CurveArithmetic,
145
{
146
0
    fn from(scalar: &NonZeroScalar<C>) -> ScalarPrimitive<C> {
147
0
        ScalarPrimitive::from_bytes(&scalar.to_repr()).unwrap()
148
0
    }
149
}
150
151
impl<C> From<SecretKey<C>> for NonZeroScalar<C>
152
where
153
    C: CurveArithmetic,
154
{
155
0
    fn from(sk: SecretKey<C>) -> NonZeroScalar<C> {
156
0
        Self::from(&sk)
157
0
    }
158
}
159
160
impl<C> From<&SecretKey<C>> for NonZeroScalar<C>
161
where
162
    C: CurveArithmetic,
163
{
164
0
    fn from(sk: &SecretKey<C>) -> NonZeroScalar<C> {
165
0
        let scalar = sk.as_scalar_primitive().to_scalar();
166
0
        debug_assert!(!bool::from(scalar.is_zero()));
167
0
        Self { scalar }
168
0
    }
Unexecuted instantiation: _RNvXININtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeros9_0pEINtB5_13NonZeroScalarpEINtNtCsbQ8arDwx5Xq_4core7convert4FromRINtNtB9_10secret_key9SecretKeypEE4fromB9_
Unexecuted instantiation: _RNvXs9_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1EINtNtCsbQ8arDwx5Xq_4core7convert4FromRINtNtB9_10secret_key9SecretKeyB1d_EE4fromB1f_
Unexecuted instantiation: _RNvXs9_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCsbQ8arDwx5Xq_4core7convert4FromRINtNtB9_10secret_key9SecretKeyB1d_EE4fromB1f_
169
}
170
171
impl<C> Invert for NonZeroScalar<C>
172
where
173
    C: CurveArithmetic,
174
    Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
175
{
176
    type Output = Self;
177
178
0
    fn invert(&self) -> Self {
179
0
        Self {
180
0
            // This will always succeed since `scalar` will never be 0
181
0
            scalar: Invert::invert(&self.scalar).unwrap(),
182
0
        }
183
0
    }
184
185
1.36k
    fn invert_vartime(&self) -> Self::Output {
186
1.36k
        Self {
187
1.36k
            // This will always succeed since `scalar` will never be 0
188
1.36k
            scalar: Invert::invert_vartime(&self.scalar).unwrap(),
189
1.36k
        }
190
1.36k
    }
_RNvXsa_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtB9_3ops6Invert14invert_vartimeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
185
838
    fn invert_vartime(&self) -> Self::Output {
186
838
        Self {
187
838
            // This will always succeed since `scalar` will never be 0
188
838
            scalar: Invert::invert_vartime(&self.scalar).unwrap(),
189
838
        }
190
838
    }
Unexecuted instantiation: _RNvXININtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzerosa_0pEINtB5_13NonZeroScalarpENtNtB9_3ops6Invert14invert_vartimeB9_
_RNvXsa_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1ENtNtB9_3ops6Invert14invert_vartimeB1f_
Line
Count
Source
185
523
    fn invert_vartime(&self) -> Self::Output {
186
523
        Self {
187
523
            // This will always succeed since `scalar` will never be 0
188
523
            scalar: Invert::invert_vartime(&self.scalar).unwrap(),
189
523
        }
190
523
    }
Unexecuted instantiation: _RNvXsa_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtB9_3ops6Invert14invert_vartimeB1f_
191
}
192
193
impl<C> IsHigh for NonZeroScalar<C>
194
where
195
    C: CurveArithmetic,
196
{
197
534
    fn is_high(&self) -> Choice {
198
534
        self.scalar.is_high()
199
534
    }
Unexecuted instantiation: _RNvXININtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzerosb_0pEINtB5_13NonZeroScalarpENtB7_6IsHigh7is_highB9_
_RNvXsb_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1ENtB7_6IsHigh7is_highB1f_
Line
Count
Source
197
534
    fn is_high(&self) -> Choice {
198
534
        self.scalar.is_high()
199
534
    }
200
}
201
202
impl<C> Neg for NonZeroScalar<C>
203
where
204
    C: CurveArithmetic,
205
{
206
    type Output = NonZeroScalar<C>;
207
208
0
    fn neg(self) -> NonZeroScalar<C> {
209
0
        let scalar = -self.scalar;
210
0
        debug_assert!(!bool::from(scalar.is_zero()));
211
0
        NonZeroScalar { scalar }
212
0
    }
Unexecuted instantiation: _RNvXININtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzerosc_0pEINtB5_13NonZeroScalarpENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Neg3negB9_
Unexecuted instantiation: _RNvXsc_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Neg3negB1f_
213
}
214
215
impl<C> Mul<NonZeroScalar<C>> for NonZeroScalar<C>
216
where
217
    C: PrimeCurve + CurveArithmetic,
218
{
219
    type Output = Self;
220
221
    #[inline]
222
0
    fn mul(self, other: Self) -> Self {
223
0
        Self::mul(self, &other)
224
0
    }
225
}
226
227
impl<C> Mul<&NonZeroScalar<C>> for NonZeroScalar<C>
228
where
229
    C: PrimeCurve + CurveArithmetic,
230
{
231
    type Output = Self;
232
233
0
    fn mul(self, other: &Self) -> Self {
234
0
        // Multiplication is modulo a prime, so the product of two non-zero
235
0
        // scalars is also non-zero.
236
0
        let scalar = self.scalar * other.scalar;
237
0
        debug_assert!(!bool::from(scalar.is_zero()));
238
0
        NonZeroScalar { scalar }
239
0
    }
240
}
241
242
/// Note: this is a non-zero reduction, as it's impl'd for [`NonZeroScalar`].
243
impl<C, I> Reduce<I> for NonZeroScalar<C>
244
where
245
    C: CurveArithmetic,
246
    I: Integer + ArrayEncoding,
247
    Scalar<C>: Reduce<I> + ReduceNonZero<I>,
248
{
249
    type Bytes = <Scalar<C> as Reduce<I>>::Bytes;
250
251
0
    fn reduce(n: I) -> Self {
252
0
        let scalar = Scalar::<C>::reduce_nonzero(n);
253
0
        debug_assert!(!bool::from(scalar.is_zero()));
254
0
        Self { scalar }
255
0
    }
256
257
0
    fn reduce_bytes(bytes: &Self::Bytes) -> Self {
258
0
        let scalar = Scalar::<C>::reduce_nonzero_bytes(bytes);
259
0
        debug_assert!(!bool::from(scalar.is_zero()));
260
0
        Self { scalar }
261
0
    }
262
}
263
264
/// Note: forwards to the [`Reduce`] impl.
265
impl<C, I> ReduceNonZero<I> for NonZeroScalar<C>
266
where
267
    Self: Reduce<I>,
268
    C: CurveArithmetic,
269
    I: Integer + ArrayEncoding,
270
    Scalar<C>: Reduce<I, Bytes = Self::Bytes> + ReduceNonZero<I>,
271
{
272
0
    fn reduce_nonzero(n: I) -> Self {
273
0
        Self::reduce(n)
274
0
    }
275
276
0
    fn reduce_nonzero_bytes(bytes: &Self::Bytes) -> Self {
277
0
        Self::reduce_bytes(bytes)
278
0
    }
279
}
280
281
impl<C> TryFrom<&[u8]> for NonZeroScalar<C>
282
where
283
    C: CurveArithmetic,
284
{
285
    type Error = Error;
286
287
0
    fn try_from(bytes: &[u8]) -> Result<Self, Error> {
288
0
        if bytes.len() == C::FieldBytesSize::USIZE {
289
0
            Option::from(NonZeroScalar::from_repr(GenericArray::clone_from_slice(
290
0
                bytes,
291
0
            )))
292
0
            .ok_or(Error)
293
        } else {
294
0
            Err(Error)
295
        }
296
0
    }
Unexecuted instantiation: _RNvXININtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzerosh_0pEINtB5_13NonZeroScalarpEINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRShE8try_fromB9_
Unexecuted instantiation: _RNvXsh_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1EINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRShE8try_fromB1f_
297
}
298
299
impl<C> Zeroize for NonZeroScalar<C>
300
where
301
    C: CurveArithmetic,
302
{
303
0
    fn zeroize(&mut self) {
304
0
        // Use zeroize's volatile writes to ensure value is cleared.
305
0
        self.scalar.zeroize();
306
0
307
0
        // Write a 1 instead of a 0 to ensure this type's non-zero invariant
308
0
        // is upheld.
309
0
        self.scalar = Scalar::<C>::ONE;
310
0
    }
Unexecuted instantiation: _RNvXININtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzerosi_0pEINtB5_13NonZeroScalarpENtCs6qnKa1vNaZb_7zeroize7Zeroize7zeroizeB9_
Unexecuted instantiation: _RNvXsi_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzeroINtB5_13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1ENtCs6qnKa1vNaZb_7zeroize7Zeroize7zeroizeB1f_
311
}
312
313
impl<C> fmt::Display for NonZeroScalar<C>
314
where
315
    C: CurveArithmetic,
316
{
317
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
318
0
        write!(f, "{self:X}")
319
0
    }
320
}
321
322
impl<C> fmt::LowerHex for NonZeroScalar<C>
323
where
324
    C: CurveArithmetic,
325
{
326
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
327
0
        write!(f, "{:x}", HexDisplay(&self.to_repr()))
328
0
    }
329
}
330
331
impl<C> fmt::UpperHex for NonZeroScalar<C>
332
where
333
    C: CurveArithmetic,
334
{
335
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
336
0
        write!(f, "{:}", HexDisplay(&self.to_repr()))
337
0
    }
338
}
339
340
impl<C> str::FromStr for NonZeroScalar<C>
341
where
342
    C: CurveArithmetic,
343
{
344
    type Err = Error;
345
346
0
    fn from_str(hex: &str) -> Result<Self, Error> {
347
0
        let mut bytes = FieldBytes::<C>::default();
348
0
349
0
        if base16ct::mixed::decode(hex, &mut bytes)?.len() == bytes.len() {
350
0
            Option::from(Self::from_repr(bytes)).ok_or(Error)
351
        } else {
352
0
            Err(Error)
353
        }
354
0
    }
355
}
356
357
#[cfg(feature = "serde")]
358
impl<C> Serialize for NonZeroScalar<C>
359
where
360
    C: CurveArithmetic,
361
{
362
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
363
    where
364
        S: ser::Serializer,
365
    {
366
        ScalarPrimitive::from(self).serialize(serializer)
367
    }
368
}
369
370
#[cfg(feature = "serde")]
371
impl<'de, C> Deserialize<'de> for NonZeroScalar<C>
372
where
373
    C: CurveArithmetic,
374
{
375
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
376
    where
377
        D: de::Deserializer<'de>,
378
    {
379
        let scalar = ScalarPrimitive::deserialize(deserializer)?;
380
        Option::from(Self::new(scalar.into()))
381
            .ok_or_else(|| de::Error::custom("expected non-zero scalar"))
382
    }
383
}
384
385
#[cfg(all(test, feature = "dev"))]
386
mod tests {
387
    use crate::dev::{NonZeroScalar, Scalar};
388
    use ff::{Field, PrimeField};
389
    use hex_literal::hex;
390
    use zeroize::Zeroize;
391
392
    #[test]
393
    fn round_trip() {
394
        let bytes = hex!("c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721");
395
        let scalar = NonZeroScalar::from_repr(bytes.into()).unwrap();
396
        assert_eq!(&bytes, scalar.to_repr().as_slice());
397
    }
398
399
    #[test]
400
    fn zeroize() {
401
        let mut scalar = NonZeroScalar::new(Scalar::from(42u64)).unwrap();
402
        scalar.zeroize();
403
        assert_eq!(*scalar, Scalar::ONE);
404
    }
405
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/scalar/primitive.rs
Line
Count
Source
1
//! Generic scalar type with primitive functionality.
2
3
use crate::{
4
    bigint::{prelude::*, Limb, NonZero},
5
    scalar::FromUintUnchecked,
6
    scalar::IsHigh,
7
    Curve, Error, FieldBytes, FieldBytesEncoding, Result,
8
};
9
use base16ct::HexDisplay;
10
use core::{
11
    cmp::Ordering,
12
    fmt,
13
    ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign},
14
    str,
15
};
16
use generic_array::{typenum::Unsigned, GenericArray};
17
use rand_core::CryptoRngCore;
18
use subtle::{
19
    Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
20
    CtOption,
21
};
22
use zeroize::DefaultIsZeroes;
23
24
#[cfg(feature = "arithmetic")]
25
use super::{CurveArithmetic, Scalar};
26
27
#[cfg(feature = "serde")]
28
use serdect::serde::{de, ser, Deserialize, Serialize};
29
30
/// Generic scalar type with primitive functionality.
31
///
32
/// This type provides a baseline level of scalar arithmetic functionality
33
/// which is always available for all curves, regardless of if they implement
34
/// any arithmetic traits.
35
///
36
/// # `serde` support
37
///
38
/// When the optional `serde` feature of this create is enabled, [`Serialize`]
39
/// and [`Deserialize`] impls are provided for this type.
40
///
41
/// The serialization is a fixed-width big endian encoding. When used with
42
/// textual formats, the binary data is encoded as hexadecimal.
43
// TODO(tarcieri): use `crypto-bigint`'s `Residue` type, expose more functionality?
44
#[derive(Copy, Clone, Debug, Default)]
45
pub struct ScalarPrimitive<C: Curve> {
46
    /// Inner unsigned integer type.
47
    inner: C::Uint,
48
}
49
50
impl<C> ScalarPrimitive<C>
51
where
52
    C: Curve,
53
{
54
    /// Zero scalar.
55
    pub const ZERO: Self = Self {
56
        inner: C::Uint::ZERO,
57
    };
58
59
    /// Multiplicative identity.
60
    pub const ONE: Self = Self {
61
        inner: C::Uint::ONE,
62
    };
63
64
    /// Scalar modulus.
65
    pub const MODULUS: C::Uint = C::ORDER;
66
67
    /// Generate a random [`ScalarPrimitive`].
68
0
    pub fn random(rng: &mut impl CryptoRngCore) -> Self {
69
0
        Self {
70
0
            inner: C::Uint::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()),
71
0
        }
72
0
    }
73
74
    /// Create a new scalar from [`Curve::Uint`].
75
2.84k
    pub fn new(uint: C::Uint) -> CtOption<Self> {
76
2.84k
        CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS))
77
2.84k
    }
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256E3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
75
1.73k
    pub fn new(uint: C::Uint) -> CtOption<Self> {
76
1.73k
        CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS))
77
1.73k
    }
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1E3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
75
1.11k
    pub fn new(uint: C::Uint) -> CtOption<Self> {
76
1.11k
        CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS))
77
1.11k
    }
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitivepE3newB6_
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1E3newB1g_
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256E3newB1g_
78
79
    /// Decode [`ScalarPrimitive`] from a serialized field element
80
2.84k
    pub fn from_bytes(bytes: &FieldBytes<C>) -> CtOption<Self> {
81
2.84k
        Self::new(C::Uint::decode_field_bytes(bytes))
82
2.84k
    }
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256E10from_bytesCs4RkbDk9WRL5_5clvmr
Line
Count
Source
80
1.73k
    pub fn from_bytes(bytes: &FieldBytes<C>) -> CtOption<Self> {
81
1.73k
        Self::new(C::Uint::decode_field_bytes(bytes))
82
1.73k
    }
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1E10from_bytesCs4RkbDk9WRL5_5clvmr
Line
Count
Source
80
1.11k
    pub fn from_bytes(bytes: &FieldBytes<C>) -> CtOption<Self> {
81
1.11k
        Self::new(C::Uint::decode_field_bytes(bytes))
82
1.11k
    }
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitivepE10from_bytesB6_
83
84
    /// Decode [`ScalarPrimitive`] from a big endian byte slice.
85
2.84k
    pub fn from_slice(slice: &[u8]) -> Result<Self> {
86
2.84k
        if slice.len() == C::FieldBytesSize::USIZE {
87
2.84k
            Option::from(Self::from_bytes(GenericArray::from_slice(slice))).ok_or(Error)
88
        } else {
89
0
            Err(Error)
90
        }
91
2.84k
    }
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256E10from_sliceCs4RkbDk9WRL5_5clvmr
Line
Count
Source
85
1.73k
    pub fn from_slice(slice: &[u8]) -> Result<Self> {
86
1.73k
        if slice.len() == C::FieldBytesSize::USIZE {
87
1.73k
            Option::from(Self::from_bytes(GenericArray::from_slice(slice))).ok_or(Error)
88
        } else {
89
0
            Err(Error)
90
        }
91
1.73k
    }
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1E10from_sliceCs4RkbDk9WRL5_5clvmr
Line
Count
Source
85
1.11k
    pub fn from_slice(slice: &[u8]) -> Result<Self> {
86
1.11k
        if slice.len() == C::FieldBytesSize::USIZE {
87
1.11k
            Option::from(Self::from_bytes(GenericArray::from_slice(slice))).ok_or(Error)
88
        } else {
89
0
            Err(Error)
90
        }
91
1.11k
    }
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitivepE10from_sliceB6_
92
93
    /// Borrow the inner `C::Uint`.
94
3.25k
    pub fn as_uint(&self) -> &C::Uint {
95
3.25k
        &self.inner
96
3.25k
    }
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256E7as_uintCs4RkbDk9WRL5_5clvmr
Line
Count
Source
94
1.67k
    pub fn as_uint(&self) -> &C::Uint {
95
1.67k
        &self.inner
96
1.67k
    }
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitivepE7as_uintB6_
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1E7as_uintB1g_
Line
Count
Source
94
1.58k
    pub fn as_uint(&self) -> &C::Uint {
95
1.58k
        &self.inner
96
1.58k
    }
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256E7as_uintB1g_
97
98
    /// Borrow the inner limbs as a slice.
99
0
    pub fn as_limbs(&self) -> &[Limb] {
100
0
        self.inner.as_ref()
101
0
    }
102
103
    /// Is this [`ScalarPrimitive`] value equal to zero?
104
2.77k
    pub fn is_zero(&self) -> Choice {
105
2.77k
        self.inner.is_zero()
106
2.77k
    }
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256E7is_zeroCs4RkbDk9WRL5_5clvmr
Line
Count
Source
104
1.69k
    pub fn is_zero(&self) -> Choice {
105
1.69k
        self.inner.is_zero()
106
1.69k
    }
_RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1E7is_zeroCs4RkbDk9WRL5_5clvmr
Line
Count
Source
104
1.08k
    pub fn is_zero(&self) -> Choice {
105
1.08k
        self.inner.is_zero()
106
1.08k
    }
Unexecuted instantiation: _RNvMNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB2_15ScalarPrimitivepE7is_zeroB6_
107
108
    /// Is this [`ScalarPrimitive`] value even?
109
0
    pub fn is_even(&self) -> Choice {
110
0
        self.inner.is_even()
111
0
    }
112
113
    /// Is this [`ScalarPrimitive`] value odd?
114
0
    pub fn is_odd(&self) -> Choice {
115
0
        self.inner.is_odd()
116
0
    }
117
118
    /// Encode [`ScalarPrimitive`] as a serialized field element.
119
0
    pub fn to_bytes(&self) -> FieldBytes<C> {
120
0
        self.inner.encode_field_bytes()
121
0
    }
122
123
    /// Convert to a `C::Uint`.
124
0
    pub fn to_uint(&self) -> C::Uint {
125
0
        self.inner
126
0
    }
127
}
128
129
impl<C> FromUintUnchecked for ScalarPrimitive<C>
130
where
131
    C: Curve,
132
{
133
    type Uint = C::Uint;
134
135
0
    fn from_uint_unchecked(uint: C::Uint) -> Self {
136
0
        Self { inner: uint }
137
0
    }
138
}
139
140
#[cfg(feature = "arithmetic")]
141
impl<C> ScalarPrimitive<C>
142
where
143
    C: CurveArithmetic,
144
{
145
    /// Convert [`ScalarPrimitive`] into a given curve's scalar type.
146
0
    pub(super) fn to_scalar(self) -> Scalar<C> {
147
0
        Scalar::<C>::from_uint_unchecked(self.inner)
148
0
    }
Unexecuted instantiation: _RNvMs0_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB5_15ScalarPrimitivepE9to_scalarB9_
Unexecuted instantiation: _RNvMs0_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB5_15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1E9to_scalarB1j_
Unexecuted instantiation: _RNvMs0_NtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitiveINtB5_15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256E9to_scalarB1j_
149
}
150
151
// TODO(tarcieri): better encapsulate this?
152
impl<C> AsRef<[Limb]> for ScalarPrimitive<C>
153
where
154
    C: Curve,
155
{
156
0
    fn as_ref(&self) -> &[Limb] {
157
0
        self.as_limbs()
158
0
    }
159
}
160
161
impl<C> ConditionallySelectable for ScalarPrimitive<C>
162
where
163
    C: Curve,
164
{
165
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
166
0
        Self {
167
0
            inner: C::Uint::conditional_select(&a.inner, &b.inner, choice),
168
0
        }
169
0
    }
170
}
171
172
impl<C> ConstantTimeEq for ScalarPrimitive<C>
173
where
174
    C: Curve,
175
{
176
0
    fn ct_eq(&self, other: &Self) -> Choice {
177
0
        self.inner.ct_eq(&other.inner)
178
0
    }
179
}
180
181
impl<C> ConstantTimeLess for ScalarPrimitive<C>
182
where
183
    C: Curve,
184
{
185
0
    fn ct_lt(&self, other: &Self) -> Choice {
186
0
        self.inner.ct_lt(&other.inner)
187
0
    }
188
}
189
190
impl<C> ConstantTimeGreater for ScalarPrimitive<C>
191
where
192
    C: Curve,
193
{
194
0
    fn ct_gt(&self, other: &Self) -> Choice {
195
0
        self.inner.ct_gt(&other.inner)
196
0
    }
197
}
198
199
impl<C: Curve> DefaultIsZeroes for ScalarPrimitive<C> {}
200
201
impl<C: Curve> Eq for ScalarPrimitive<C> {}
202
203
impl<C> PartialEq for ScalarPrimitive<C>
204
where
205
    C: Curve,
206
{
207
0
    fn eq(&self, other: &Self) -> bool {
208
0
        self.ct_eq(other).into()
209
0
    }
210
}
211
212
impl<C> PartialOrd for ScalarPrimitive<C>
213
where
214
    C: Curve,
215
{
216
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
217
0
        Some(self.cmp(other))
218
0
    }
219
}
220
221
impl<C> Ord for ScalarPrimitive<C>
222
where
223
    C: Curve,
224
{
225
0
    fn cmp(&self, other: &Self) -> Ordering {
226
0
        self.inner.cmp(&other.inner)
227
0
    }
228
}
229
230
impl<C> From<u64> for ScalarPrimitive<C>
231
where
232
    C: Curve,
233
{
234
0
    fn from(n: u64) -> Self {
235
0
        Self {
236
0
            inner: C::Uint::from(n),
237
0
        }
238
0
    }
239
}
240
241
impl<C> Add<ScalarPrimitive<C>> for ScalarPrimitive<C>
242
where
243
    C: Curve,
244
{
245
    type Output = Self;
246
247
0
    fn add(self, other: Self) -> Self {
248
0
        self.add(&other)
249
0
    }
250
}
251
252
impl<C> Add<&ScalarPrimitive<C>> for ScalarPrimitive<C>
253
where
254
    C: Curve,
255
{
256
    type Output = Self;
257
258
0
    fn add(self, other: &Self) -> Self {
259
0
        Self {
260
0
            inner: self.inner.add_mod(&other.inner, &Self::MODULUS),
261
0
        }
262
0
    }
263
}
264
265
impl<C> AddAssign<ScalarPrimitive<C>> for ScalarPrimitive<C>
266
where
267
    C: Curve,
268
{
269
0
    fn add_assign(&mut self, other: Self) {
270
0
        *self = *self + other;
271
0
    }
272
}
273
274
impl<C> AddAssign<&ScalarPrimitive<C>> for ScalarPrimitive<C>
275
where
276
    C: Curve,
277
{
278
0
    fn add_assign(&mut self, other: &Self) {
279
0
        *self = *self + other;
280
0
    }
281
}
282
283
impl<C> Sub<ScalarPrimitive<C>> for ScalarPrimitive<C>
284
where
285
    C: Curve,
286
{
287
    type Output = Self;
288
289
0
    fn sub(self, other: Self) -> Self {
290
0
        self.sub(&other)
291
0
    }
292
}
293
294
impl<C> Sub<&ScalarPrimitive<C>> for ScalarPrimitive<C>
295
where
296
    C: Curve,
297
{
298
    type Output = Self;
299
300
0
    fn sub(self, other: &Self) -> Self {
301
0
        Self {
302
0
            inner: self.inner.sub_mod(&other.inner, &Self::MODULUS),
303
0
        }
304
0
    }
305
}
306
307
impl<C> SubAssign<ScalarPrimitive<C>> for ScalarPrimitive<C>
308
where
309
    C: Curve,
310
{
311
0
    fn sub_assign(&mut self, other: Self) {
312
0
        *self = *self - other;
313
0
    }
314
}
315
316
impl<C> SubAssign<&ScalarPrimitive<C>> for ScalarPrimitive<C>
317
where
318
    C: Curve,
319
{
320
0
    fn sub_assign(&mut self, other: &Self) {
321
0
        *self = *self - other;
322
0
    }
323
}
324
325
impl<C> Neg for ScalarPrimitive<C>
326
where
327
    C: Curve,
328
{
329
    type Output = Self;
330
331
0
    fn neg(self) -> Self {
332
0
        Self {
333
0
            inner: self.inner.neg_mod(&Self::MODULUS),
334
0
        }
335
0
    }
336
}
337
338
impl<C> Neg for &ScalarPrimitive<C>
339
where
340
    C: Curve,
341
{
342
    type Output = ScalarPrimitive<C>;
343
344
0
    fn neg(self) -> ScalarPrimitive<C> {
345
0
        -*self
346
0
    }
347
}
348
349
impl<C> ShrAssign<usize> for ScalarPrimitive<C>
350
where
351
    C: Curve,
352
{
353
0
    fn shr_assign(&mut self, rhs: usize) {
354
0
        self.inner >>= rhs;
355
0
    }
356
}
357
358
impl<C> IsHigh for ScalarPrimitive<C>
359
where
360
    C: Curve,
361
{
362
0
    fn is_high(&self) -> Choice {
363
0
        let n_2 = C::ORDER >> 1;
364
0
        self.inner.ct_gt(&n_2)
365
0
    }
366
}
367
368
impl<C> fmt::Display for ScalarPrimitive<C>
369
where
370
    C: Curve,
371
{
372
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
373
0
        write!(f, "{self:X}")
374
0
    }
375
}
376
377
impl<C> fmt::LowerHex for ScalarPrimitive<C>
378
where
379
    C: Curve,
380
{
381
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
382
0
        write!(f, "{:x}", HexDisplay(&self.to_bytes()))
383
0
    }
384
}
385
386
impl<C> fmt::UpperHex for ScalarPrimitive<C>
387
where
388
    C: Curve,
389
{
390
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
391
0
        write!(f, "{:X}", HexDisplay(&self.to_bytes()))
392
0
    }
393
}
394
395
impl<C> str::FromStr for ScalarPrimitive<C>
396
where
397
    C: Curve,
398
{
399
    type Err = Error;
400
401
0
    fn from_str(hex: &str) -> Result<Self> {
402
0
        let mut bytes = FieldBytes::<C>::default();
403
0
        base16ct::lower::decode(hex, &mut bytes)?;
404
0
        Self::from_slice(&bytes)
405
0
    }
406
}
407
408
#[cfg(feature = "serde")]
409
impl<C> Serialize for ScalarPrimitive<C>
410
where
411
    C: Curve,
412
{
413
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
414
    where
415
        S: ser::Serializer,
416
    {
417
        serdect::array::serialize_hex_upper_or_bin(&self.to_bytes(), serializer)
418
    }
419
}
420
421
#[cfg(feature = "serde")]
422
impl<'de, C> Deserialize<'de> for ScalarPrimitive<C>
423
where
424
    C: Curve,
425
{
426
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
427
    where
428
        D: de::Deserializer<'de>,
429
    {
430
        let mut bytes = FieldBytes::<C>::default();
431
        serdect::array::deserialize_hex_or_bin(&mut bytes, deserializer)?;
432
        Self::from_slice(&bytes).map_err(|_| de::Error::custom("scalar out of range"))
433
    }
434
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/sec1.rs
Line
Count
Source
1
//! Support for SEC1 elliptic curve encoding formats.
2
//!
3
//! <https://www.secg.org/sec1-v2.pdf>
4
5
pub use sec1::point::{Coordinates, ModulusSize, Tag};
6
7
use crate::{Curve, FieldBytesSize, Result, SecretKey};
8
use generic_array::GenericArray;
9
use subtle::CtOption;
10
11
#[cfg(feature = "arithmetic")]
12
use crate::{AffinePoint, CurveArithmetic, Error};
13
14
/// Encoded elliptic curve point with point compression.
15
pub type CompressedPoint<C> = GenericArray<u8, CompressedPointSize<C>>;
16
17
/// Size of a compressed elliptic curve point.
18
pub type CompressedPointSize<C> = <FieldBytesSize<C> as ModulusSize>::CompressedPointSize;
19
20
/// Encoded elliptic curve point sized appropriately for a given curve.
21
pub type EncodedPoint<C> = sec1::point::EncodedPoint<FieldBytesSize<C>>;
22
23
/// Encoded elliptic curve point *without* point compression.
24
pub type UncompressedPoint<C> = GenericArray<u8, UncompressedPointSize<C>>;
25
26
/// Size of an uncompressed elliptic curve point.
27
pub type UncompressedPointSize<C> = <FieldBytesSize<C> as ModulusSize>::UncompressedPointSize;
28
29
/// Trait for deserializing a value from a SEC1 encoded curve point.
30
///
31
/// This is intended for use with the `AffinePoint` type for a given elliptic curve.
32
pub trait FromEncodedPoint<C>
33
where
34
    Self: Sized,
35
    C: Curve,
36
    FieldBytesSize<C>: ModulusSize,
37
{
38
    /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`].
39
    fn from_encoded_point(point: &EncodedPoint<C>) -> CtOption<Self>;
40
}
41
42
/// Trait for serializing a value to a SEC1 encoded curve point.
43
///
44
/// This is intended for use with the `AffinePoint` type for a given elliptic curve.
45
pub trait ToEncodedPoint<C>
46
where
47
    C: Curve,
48
    FieldBytesSize<C>: ModulusSize,
49
{
50
    /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying
51
    /// point compression.
52
    fn to_encoded_point(&self, compress: bool) -> EncodedPoint<C>;
53
}
54
55
/// Trait for serializing a value to a SEC1 encoded curve point with compaction.
56
///
57
/// This is intended for use with the `AffinePoint` type for a given elliptic curve.
58
pub trait ToCompactEncodedPoint<C>
59
where
60
    C: Curve,
61
    FieldBytesSize<C>: ModulusSize,
62
{
63
    /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying
64
    /// point compression.
65
    fn to_compact_encoded_point(&self) -> CtOption<EncodedPoint<C>>;
66
}
67
68
/// Validate that the given [`EncodedPoint`] represents the encoded public key
69
/// value of the given secret.
70
///
71
/// Curve implementations which also impl [`CurveArithmetic`] will receive
72
/// a blanket default impl of this trait.
73
pub trait ValidatePublicKey
74
where
75
    Self: Curve,
76
    FieldBytesSize<Self>: ModulusSize,
77
{
78
    /// Validate that the given [`EncodedPoint`] is a valid public key for the
79
    /// provided secret value.
80
    #[allow(unused_variables)]
81
0
    fn validate_public_key(
82
0
        secret_key: &SecretKey<Self>,
83
0
        public_key: &EncodedPoint<Self>,
84
0
    ) -> Result<()> {
85
0
        // Provide a default "always succeeds" implementation.
86
0
        // This is the intended default for curve implementations which
87
0
        // do not provide an arithmetic implementation, since they have no
88
0
        // way to verify this.
89
0
        //
90
0
        // Implementations with an arithmetic impl will receive a blanket impl
91
0
        // of this trait.
92
0
        Ok(())
93
0
    }
94
}
95
96
#[cfg(feature = "arithmetic")]
97
impl<C> ValidatePublicKey for C
98
where
99
    C: CurveArithmetic,
100
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
101
    FieldBytesSize<C>: ModulusSize,
102
{
103
0
    fn validate_public_key(secret_key: &SecretKey<C>, public_key: &EncodedPoint<C>) -> Result<()> {
104
0
        let pk = secret_key
105
0
            .public_key()
106
0
            .to_encoded_point(public_key.is_compressed());
107
0
108
0
        if public_key == &pk {
109
0
            Ok(())
110
        } else {
111
0
            Err(Error)
112
        }
113
0
    }
114
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/secret_key.rs
Line
Count
Source
1
//! Secret keys for elliptic curves (i.e. private scalars).
2
//!
3
//! The [`SecretKey`] type is a wrapper around a secret scalar value which is
4
//! designed to prevent unintentional exposure (e.g. via `Debug` or other
5
//! logging). It also handles zeroing the secret value out of memory securely
6
//! on drop.
7
8
#[cfg(all(feature = "pkcs8", feature = "sec1"))]
9
mod pkcs8;
10
11
use crate::{Curve, Error, FieldBytes, Result, ScalarPrimitive};
12
use core::fmt::{self, Debug};
13
use generic_array::typenum::Unsigned;
14
use subtle::{Choice, ConstantTimeEq};
15
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
16
17
#[cfg(feature = "arithmetic")]
18
use crate::{rand_core::CryptoRngCore, CurveArithmetic, NonZeroScalar, PublicKey};
19
20
#[cfg(feature = "jwk")]
21
use crate::jwk::{JwkEcKey, JwkParameters};
22
23
#[cfg(feature = "pem")]
24
use pem_rfc7468::{self as pem, PemLabel};
25
26
#[cfg(feature = "sec1")]
27
use {
28
    crate::{
29
        sec1::{EncodedPoint, ModulusSize, ValidatePublicKey},
30
        FieldBytesSize,
31
    },
32
    sec1::der,
33
};
34
35
#[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))]
36
use {
37
    crate::{
38
        sec1::{FromEncodedPoint, ToEncodedPoint},
39
        AffinePoint,
40
    },
41
    alloc::vec::Vec,
42
    sec1::der::Encode,
43
};
44
45
#[cfg(all(feature = "arithmetic", any(feature = "jwk", feature = "pem")))]
46
use alloc::string::String;
47
48
#[cfg(all(feature = "arithmetic", feature = "jwk"))]
49
use alloc::string::ToString;
50
51
#[cfg(all(doc, feature = "pkcs8"))]
52
use {crate::pkcs8::DecodePrivateKey, core::str::FromStr};
53
54
/// Elliptic curve secret keys.
55
///
56
/// This type wraps a secret scalar value, helping to prevent accidental
57
/// exposure and securely erasing the value from memory when dropped.
58
///
59
/// # Parsing PKCS#8 Keys
60
///
61
/// PKCS#8 is a commonly used format for encoding secret keys (especially ones
62
/// generated by OpenSSL).
63
///
64
/// Keys in PKCS#8 format are either binary (ASN.1 BER/DER), or PEM encoded
65
/// (ASCII) and begin with the following:
66
///
67
/// ```text
68
/// -----BEGIN PRIVATE KEY-----
69
/// ```
70
///
71
/// To decode an elliptic curve private key from PKCS#8, enable the `pkcs8`
72
/// feature of this crate (or the `pkcs8` feature of a specific RustCrypto
73
/// elliptic curve crate) and use the [`DecodePrivateKey`]  trait to parse it.
74
///
75
/// When the `pem` feature of this crate (or a specific RustCrypto elliptic
76
/// curve crate) is enabled, a [`FromStr`] impl is also available.
77
#[derive(Clone)]
78
pub struct SecretKey<C: Curve> {
79
    /// Scalar value
80
    inner: ScalarPrimitive<C>,
81
}
82
83
impl<C> SecretKey<C>
84
where
85
    C: Curve,
86
{
87
    /// Minimum allowed size of an elliptic curve secret key in bytes.
88
    ///
89
    /// This provides the equivalent of 96-bits of symmetric security.
90
    const MIN_SIZE: usize = 24;
91
92
    /// Generate a random [`SecretKey`].
93
    #[cfg(feature = "arithmetic")]
94
0
    pub fn random(rng: &mut impl CryptoRngCore) -> Self
95
0
    where
96
0
        C: CurveArithmetic,
97
0
    {
98
0
        Self {
99
0
            inner: NonZeroScalar::<C>::random(rng).into(),
100
0
        }
101
0
    }
102
103
    /// Create a new secret key from a scalar value.
104
0
    pub fn new(scalar: ScalarPrimitive<C>) -> Self {
105
0
        Self { inner: scalar }
106
0
    }
107
108
    /// Borrow the inner secret [`ScalarPrimitive`] value.
109
    ///
110
    /// # ⚠️ Warning
111
    ///
112
    /// This value is key material.
113
    ///
114
    /// Please treat it with the care it deserves!
115
0
    pub fn as_scalar_primitive(&self) -> &ScalarPrimitive<C> {
116
0
        &self.inner
117
0
    }
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10secret_keyINtB2_9SecretKeypE19as_scalar_primitiveB4_
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10secret_keyINtB2_9SecretKeyNtCsjewTDwKBbyD_4k2569Secp256k1E19as_scalar_primitiveB12_
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10secret_keyINtB2_9SecretKeyNtCsaHRNXv1Y9Bq_4p2568NistP256E19as_scalar_primitiveB12_
118
119
    /// Get the secret [`NonZeroScalar`] value for this key.
120
    ///
121
    /// # ⚠️ Warning
122
    ///
123
    /// This value is key material.
124
    ///
125
    /// Please treat it with the care it deserves!
126
    #[cfg(feature = "arithmetic")]
127
0
    pub fn to_nonzero_scalar(&self) -> NonZeroScalar<C>
128
0
    where
129
0
        C: CurveArithmetic,
130
0
    {
131
0
        self.into()
132
0
    }
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10secret_keyINtB2_9SecretKeypE17to_nonzero_scalarB4_
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10secret_keyINtB2_9SecretKeyNtCsjewTDwKBbyD_4k2569Secp256k1E17to_nonzero_scalarB12_
Unexecuted instantiation: _RNvMNtCs8yVsO3EKNkV_14elliptic_curve10secret_keyINtB2_9SecretKeyNtCsaHRNXv1Y9Bq_4p2568NistP256E17to_nonzero_scalarB12_
133
134
    /// Get the [`PublicKey`] which corresponds to this secret key
135
    #[cfg(feature = "arithmetic")]
136
0
    pub fn public_key(&self) -> PublicKey<C>
137
0
    where
138
0
        C: CurveArithmetic,
139
0
    {
140
0
        PublicKey::from_secret_scalar(&self.to_nonzero_scalar())
141
0
    }
142
143
    /// Deserialize secret key from an encoded secret scalar.
144
0
    pub fn from_bytes(bytes: &FieldBytes<C>) -> Result<Self> {
145
0
        let inner: ScalarPrimitive<C> =
146
0
            Option::from(ScalarPrimitive::from_bytes(bytes)).ok_or(Error)?;
147
148
0
        if inner.is_zero().into() {
149
0
            return Err(Error);
150
0
        }
151
0
152
0
        Ok(Self { inner })
153
0
    }
154
155
    /// Deserialize secret key from an encoded secret scalar passed as a byte slice.
156
    ///
157
    /// The slice is expected to be a minimum of 24-bytes (192-byts) and at most `C::FieldBytesSize`
158
    /// bytes in length.
159
    ///
160
    /// Byte slices shorter than the field size are handled by zero padding the input.
161
0
    pub fn from_slice(slice: &[u8]) -> Result<Self> {
162
0
        if slice.len() == C::FieldBytesSize::USIZE {
163
0
            Self::from_bytes(FieldBytes::<C>::from_slice(slice))
164
0
        } else if (Self::MIN_SIZE..C::FieldBytesSize::USIZE).contains(&slice.len()) {
165
0
            let mut bytes = Zeroizing::new(FieldBytes::<C>::default());
166
0
            let offset = C::FieldBytesSize::USIZE.saturating_sub(slice.len());
167
0
            bytes[offset..].copy_from_slice(slice);
168
0
            Self::from_bytes(&bytes)
169
        } else {
170
0
            Err(Error)
171
        }
172
0
    }
173
174
    /// Serialize raw secret scalar as a big endian integer.
175
0
    pub fn to_bytes(&self) -> FieldBytes<C> {
176
0
        self.inner.to_bytes()
177
0
    }
178
179
    /// Deserialize secret key encoded in the SEC1 ASN.1 DER `ECPrivateKey` format.
180
    #[cfg(feature = "sec1")]
181
0
    pub fn from_sec1_der(der_bytes: &[u8]) -> Result<Self>
182
0
    where
183
0
        C: Curve + ValidatePublicKey,
184
0
        FieldBytesSize<C>: ModulusSize,
185
0
    {
186
0
        sec1::EcPrivateKey::try_from(der_bytes)?
187
0
            .try_into()
188
0
            .map_err(|_| Error)
189
0
    }
190
191
    /// Serialize secret key in the SEC1 ASN.1 DER `ECPrivateKey` format.
192
    #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))]
193
0
    pub fn to_sec1_der(&self) -> der::Result<Zeroizing<Vec<u8>>>
194
0
    where
195
0
        C: CurveArithmetic,
196
0
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
197
0
        FieldBytesSize<C>: ModulusSize,
198
0
    {
199
0
        let private_key_bytes = Zeroizing::new(self.to_bytes());
200
0
        let public_key_bytes = self.public_key().to_encoded_point(false);
201
202
0
        let ec_private_key = Zeroizing::new(
203
0
            sec1::EcPrivateKey {
204
0
                private_key: &private_key_bytes,
205
0
                parameters: None,
206
0
                public_key: Some(public_key_bytes.as_bytes()),
207
0
            }
208
0
            .to_der()?,
209
        );
210
211
0
        Ok(ec_private_key)
212
0
    }
213
214
    /// Parse [`SecretKey`] from PEM-encoded SEC1 `ECPrivateKey` format.
215
    ///
216
    /// PEM-encoded SEC1 keys can be identified by the leading delimiter:
217
    ///
218
    /// ```text
219
    /// -----BEGIN EC PRIVATE KEY-----
220
    /// ```
221
    #[cfg(feature = "pem")]
222
0
    pub fn from_sec1_pem(s: &str) -> Result<Self>
223
0
    where
224
0
        C: Curve + ValidatePublicKey,
225
0
        FieldBytesSize<C>: ModulusSize,
226
0
    {
227
0
        let (label, der_bytes) = pem::decode_vec(s.as_bytes()).map_err(|_| Error)?;
228
229
0
        if label != sec1::EcPrivateKey::PEM_LABEL {
230
0
            return Err(Error);
231
0
        }
232
0
233
0
        Self::from_sec1_der(&der_bytes).map_err(|_| Error)
234
0
    }
235
236
    /// Serialize private key as self-zeroizing PEM-encoded SEC1 `ECPrivateKey`
237
    /// with the given [`pem::LineEnding`].
238
    ///
239
    /// Pass `Default::default()` to use the OS's native line endings.
240
    #[cfg(feature = "pem")]
241
0
    pub fn to_sec1_pem(&self, line_ending: pem::LineEnding) -> Result<Zeroizing<String>>
242
0
    where
243
0
        C: CurveArithmetic,
244
0
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
245
0
        FieldBytesSize<C>: ModulusSize,
246
0
    {
247
0
        self.to_sec1_der()
248
0
            .ok()
249
0
            .and_then(|der| {
250
0
                pem::encode_string(sec1::EcPrivateKey::PEM_LABEL, line_ending, &der).ok()
251
0
            })
252
0
            .map(Zeroizing::new)
253
0
            .ok_or(Error)
254
0
    }
255
256
    /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`SecretKey`].
257
    #[cfg(feature = "jwk")]
258
    pub fn from_jwk(jwk: &JwkEcKey) -> Result<Self>
259
    where
260
        C: JwkParameters + ValidatePublicKey,
261
        FieldBytesSize<C>: ModulusSize,
262
    {
263
        Self::try_from(jwk)
264
    }
265
266
    /// Parse a string containing a JSON Web Key (JWK) into a [`SecretKey`].
267
    #[cfg(feature = "jwk")]
268
    pub fn from_jwk_str(jwk: &str) -> Result<Self>
269
    where
270
        C: JwkParameters + ValidatePublicKey,
271
        FieldBytesSize<C>: ModulusSize,
272
    {
273
        jwk.parse::<JwkEcKey>().and_then(|jwk| Self::from_jwk(&jwk))
274
    }
275
276
    /// Serialize this secret key as [`JwkEcKey`] JSON Web Key (JWK).
277
    #[cfg(all(feature = "arithmetic", feature = "jwk"))]
278
    pub fn to_jwk(&self) -> JwkEcKey
279
    where
280
        C: CurveArithmetic + JwkParameters,
281
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
282
        FieldBytesSize<C>: ModulusSize,
283
    {
284
        self.into()
285
    }
286
287
    /// Serialize this secret key as JSON Web Key (JWK) string.
288
    #[cfg(all(feature = "arithmetic", feature = "jwk"))]
289
    pub fn to_jwk_string(&self) -> Zeroizing<String>
290
    where
291
        C: CurveArithmetic + JwkParameters,
292
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
293
        FieldBytesSize<C>: ModulusSize,
294
    {
295
        Zeroizing::new(self.to_jwk().to_string())
296
    }
297
}
298
299
impl<C> ConstantTimeEq for SecretKey<C>
300
where
301
    C: Curve,
302
{
303
0
    fn ct_eq(&self, other: &Self) -> Choice {
304
0
        self.inner.ct_eq(&other.inner)
305
0
    }
306
}
307
308
impl<C> Debug for SecretKey<C>
309
where
310
    C: Curve,
311
{
312
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
313
0
        f.debug_struct(core::any::type_name::<Self>())
314
0
            .finish_non_exhaustive()
315
0
    }
316
}
317
318
impl<C> ZeroizeOnDrop for SecretKey<C> where C: Curve {}
319
320
impl<C> Drop for SecretKey<C>
321
where
322
    C: Curve,
323
{
324
0
    fn drop(&mut self) {
325
0
        self.inner.zeroize();
326
0
    }
Unexecuted instantiation: _RNvXININtCs8yVsO3EKNkV_14elliptic_curve10secret_keys2_0pEINtB5_9SecretKeypENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropB7_
Unexecuted instantiation: _RNvXs2_NtCs8yVsO3EKNkV_14elliptic_curve10secret_keyINtB5_9SecretKeyNtCsjewTDwKBbyD_4k2569Secp256k1ENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropB15_
327
}
328
329
impl<C: Curve> Eq for SecretKey<C> {}
330
331
impl<C> PartialEq for SecretKey<C>
332
where
333
    C: Curve,
334
{
335
0
    fn eq(&self, other: &Self) -> bool {
336
0
        self.ct_eq(other).into()
337
0
    }
338
}
339
340
#[cfg(feature = "sec1")]
341
impl<C> TryFrom<sec1::EcPrivateKey<'_>> for SecretKey<C>
342
where
343
    C: Curve + ValidatePublicKey,
344
    FieldBytesSize<C>: ModulusSize,
345
{
346
    type Error = der::Error;
347
348
0
    fn try_from(sec1_private_key: sec1::EcPrivateKey<'_>) -> der::Result<Self> {
349
0
        let secret_key = Self::from_slice(sec1_private_key.private_key)
350
0
            .map_err(|_| der::Tag::Sequence.value_error())?;
351
352
        // TODO(tarcieri): validate `sec1_private_key.params`?
353
0
        if let Some(pk_bytes) = sec1_private_key.public_key {
354
0
            let pk = EncodedPoint::<C>::from_bytes(pk_bytes)
355
0
                .map_err(|_| der::Tag::BitString.value_error())?;
356
357
0
            if C::validate_public_key(&secret_key, &pk).is_err() {
358
0
                return Err(der::Tag::BitString.value_error());
359
0
            }
360
0
        }
361
362
0
        Ok(secret_key)
363
0
    }
364
}
365
366
#[cfg(feature = "arithmetic")]
367
impl<C> From<NonZeroScalar<C>> for SecretKey<C>
368
where
369
    C: CurveArithmetic,
370
{
371
0
    fn from(scalar: NonZeroScalar<C>) -> SecretKey<C> {
372
0
        SecretKey::from(&scalar)
373
0
    }
374
}
375
376
#[cfg(feature = "arithmetic")]
377
impl<C> From<&NonZeroScalar<C>> for SecretKey<C>
378
where
379
    C: CurveArithmetic,
380
{
381
0
    fn from(scalar: &NonZeroScalar<C>) -> SecretKey<C> {
382
0
        SecretKey {
383
0
            inner: scalar.into(),
384
0
        }
385
0
    }
386
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/secret_key/pkcs8.rs
Line
Count
Source
1
//! PKCS#8 encoding/decoding support.
2
3
use super::SecretKey;
4
use crate::{
5
    pkcs8::{self, der::Decode, AssociatedOid},
6
    sec1::{ModulusSize, ValidatePublicKey},
7
    Curve, FieldBytesSize, ALGORITHM_OID,
8
};
9
use pkcs8::spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier, ObjectIdentifier};
10
use sec1::EcPrivateKey;
11
12
// Imports for the `EncodePrivateKey` impl
13
#[cfg(all(feature = "alloc", feature = "arithmetic"))]
14
use {
15
    crate::{
16
        sec1::{FromEncodedPoint, ToEncodedPoint},
17
        AffinePoint, CurveArithmetic,
18
    },
19
    pkcs8::{der, EncodePrivateKey},
20
};
21
22
// Imports for actual PEM support
23
#[cfg(feature = "pem")]
24
use {
25
    crate::{error::Error, Result},
26
    core::str::FromStr,
27
    pkcs8::DecodePrivateKey,
28
};
29
30
impl<C> AssociatedAlgorithmIdentifier for SecretKey<C>
31
where
32
    C: AssociatedOid + Curve,
33
{
34
    type Params = ObjectIdentifier;
35
36
    const ALGORITHM_IDENTIFIER: AlgorithmIdentifier<ObjectIdentifier> = AlgorithmIdentifier {
37
        oid: ALGORITHM_OID,
38
        parameters: Some(C::OID),
39
    };
40
}
41
42
impl<C> TryFrom<pkcs8::PrivateKeyInfo<'_>> for SecretKey<C>
43
where
44
    C: AssociatedOid + Curve + ValidatePublicKey,
45
    FieldBytesSize<C>: ModulusSize,
46
{
47
    type Error = pkcs8::Error;
48
49
0
    fn try_from(private_key_info: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result<Self> {
50
0
        private_key_info
51
0
            .algorithm
52
0
            .assert_oids(ALGORITHM_OID, C::OID)?;
53
54
0
        let ec_private_key = EcPrivateKey::from_der(private_key_info.private_key)?;
55
0
        Ok(Self::try_from(ec_private_key)?)
56
0
    }
57
}
58
59
#[cfg(all(feature = "alloc", feature = "arithmetic"))]
60
impl<C> EncodePrivateKey for SecretKey<C>
61
where
62
    C: AssociatedOid + CurveArithmetic,
63
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
64
    FieldBytesSize<C>: ModulusSize,
65
{
66
0
    fn to_pkcs8_der(&self) -> pkcs8::Result<der::SecretDocument> {
67
0
        // TODO(tarcieri): make `PrivateKeyInfo` generic around `Params`
68
0
        let algorithm_identifier = pkcs8::AlgorithmIdentifierRef {
69
0
            oid: ALGORITHM_OID,
70
0
            parameters: Some((&C::OID).into()),
71
0
        };
72
73
0
        let ec_private_key = self.to_sec1_der()?;
74
0
        let pkcs8_key = pkcs8::PrivateKeyInfo::new(algorithm_identifier, &ec_private_key);
75
0
        Ok(der::SecretDocument::encode_msg(&pkcs8_key)?)
76
0
    }
77
}
78
79
#[cfg(feature = "pem")]
80
impl<C> FromStr for SecretKey<C>
81
where
82
    C: Curve + AssociatedOid + ValidatePublicKey,
83
    FieldBytesSize<C>: ModulusSize,
84
{
85
    type Err = Error;
86
87
0
    fn from_str(s: &str) -> Result<Self> {
88
0
        Self::from_pkcs8_pem(s).map_err(|_| Error)
89
0
    }
90
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/elliptic-curve-0.13.8/src/weierstrass.rs
Line
Count
Source
1
//! Complete projective formulas for prime order elliptic curves as described
2
//! in [Renes-Costello-Batina 2015].
3
//!
4
//! [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
5
6
#![allow(clippy::op_ref)]
7
8
use ff::Field;
9
10
/// Affine point whose coordinates are represented by the given field element.
11
pub type AffinePoint<Fe> = (Fe, Fe);
12
13
/// Projective point whose coordinates are represented by the given field element.
14
pub type ProjectivePoint<Fe> = (Fe, Fe, Fe);
15
16
/// Implements the complete addition formula from [Renes-Costello-Batina 2015]
17
/// (Algorithm 4).
18
///
19
/// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
20
#[inline(always)]
21
0
pub fn add<Fe>(
22
0
    (ax, ay, az): ProjectivePoint<Fe>,
23
0
    (bx, by, bz): ProjectivePoint<Fe>,
24
0
    curve_equation_b: Fe,
25
0
) -> ProjectivePoint<Fe>
26
0
where
27
0
    Fe: Field,
28
0
{
29
0
    // The comments after each line indicate which algorithm steps are being
30
0
    // performed.
31
0
    let xx = ax * bx; // 1
32
0
    let yy = ay * by; // 2
33
0
    let zz = az * bz; // 3
34
0
    let xy_pairs = ((ax + ay) * &(bx + by)) - &(xx + &yy); // 4, 5, 6, 7, 8
35
0
    let yz_pairs = ((ay + az) * &(by + bz)) - &(yy + &zz); // 9, 10, 11, 12, 13
36
0
    let xz_pairs = ((ax + az) * &(bx + bz)) - &(xx + &zz); // 14, 15, 16, 17, 18
37
0
38
0
    let bzz_part = xz_pairs - &(curve_equation_b * &zz); // 19, 20
39
0
    let bzz3_part = bzz_part.double() + &bzz_part; // 21, 22
40
0
    let yy_m_bzz3 = yy - &bzz3_part; // 23
41
0
    let yy_p_bzz3 = yy + &bzz3_part; // 24
42
0
43
0
    let zz3 = zz.double() + &zz; // 26, 27
44
0
    let bxz_part = (curve_equation_b * &xz_pairs) - &(zz3 + &xx); // 25, 28, 29
45
0
    let bxz3_part = bxz_part.double() + &bxz_part; // 30, 31
46
0
    let xx3_m_zz3 = xx.double() + &xx - &zz3; // 32, 33, 34
47
0
48
0
    (
49
0
        (yy_p_bzz3 * &xy_pairs) - &(yz_pairs * &bxz3_part), // 35, 39, 40
50
0
        (yy_p_bzz3 * &yy_m_bzz3) + &(xx3_m_zz3 * &bxz3_part), // 36, 37, 38
51
0
        (yy_m_bzz3 * &yz_pairs) + &(xy_pairs * &xx3_m_zz3), // 41, 42, 43
52
0
    )
53
0
}
54
55
/// Implements the complete mixed addition formula from
56
/// [Renes-Costello-Batina 2015] (Algorithm 5).
57
///
58
/// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
59
#[inline(always)]
60
0
pub fn add_mixed<Fe>(
61
0
    (ax, ay, az): ProjectivePoint<Fe>,
62
0
    (bx, by): AffinePoint<Fe>,
63
0
    curve_equation_b: Fe,
64
0
) -> ProjectivePoint<Fe>
65
0
where
66
0
    Fe: Field,
67
0
{
68
0
    // The comments after each line indicate which algorithm steps are being
69
0
    // performed.
70
0
    let xx = ax * &bx; // 1
71
0
    let yy = ay * &by; // 2
72
0
    let xy_pairs = ((ax + &ay) * &(bx + &by)) - &(xx + &yy); // 3, 4, 5, 6, 7
73
0
    let yz_pairs = (by * &az) + &ay; // 8, 9 (t4)
74
0
    let xz_pairs = (bx * &az) + &ax; // 10, 11 (y3)
75
0
76
0
    let bz_part = xz_pairs - &(curve_equation_b * &az); // 12, 13
77
0
    let bz3_part = bz_part.double() + &bz_part; // 14, 15
78
0
    let yy_m_bzz3 = yy - &bz3_part; // 16
79
0
    let yy_p_bzz3 = yy + &bz3_part; // 17
80
0
81
0
    let z3 = az.double() + &az; // 19, 20
82
0
    let bxz_part = (curve_equation_b * &xz_pairs) - &(z3 + &xx); // 18, 21, 22
83
0
    let bxz3_part = bxz_part.double() + &bxz_part; // 23, 24
84
0
    let xx3_m_zz3 = xx.double() + &xx - &z3; // 25, 26, 27
85
0
86
0
    (
87
0
        (yy_p_bzz3 * &xy_pairs) - &(yz_pairs * &bxz3_part), // 28, 32, 33
88
0
        (yy_p_bzz3 * &yy_m_bzz3) + &(xx3_m_zz3 * &bxz3_part), // 29, 30, 31
89
0
        (yy_m_bzz3 * &yz_pairs) + &(xy_pairs * &xx3_m_zz3), // 34, 35, 36
90
0
    )
91
0
}
92
93
/// Implements the exception-free point doubling formula from
94
/// [Renes-Costello-Batina 2015] (Algorithm 6).
95
///
96
/// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
97
#[inline(always)]
98
0
pub fn double<Fe>((x, y, z): ProjectivePoint<Fe>, curve_equation_b: Fe) -> ProjectivePoint<Fe>
99
0
where
100
0
    Fe: Field,
101
0
{
102
0
    // The comments after each line indicate which algorithm steps are being
103
0
    // performed.
104
0
    let xx = x.square(); // 1
105
0
    let yy = y.square(); // 2
106
0
    let zz = z.square(); // 3
107
0
    let xy2 = (x * &y).double(); // 4, 5
108
0
    let xz2 = (x * &z).double(); // 6, 7
109
0
110
0
    let bzz_part = (curve_equation_b * &zz) - &xz2; // 8, 9
111
0
    let bzz3_part = bzz_part.double() + &bzz_part; // 10, 11
112
0
    let yy_m_bzz3 = yy - &bzz3_part; // 12
113
0
    let yy_p_bzz3 = yy + &bzz3_part; // 13
114
0
    let y_frag = yy_p_bzz3 * &yy_m_bzz3; // 14
115
0
    let x_frag = yy_m_bzz3 * &xy2; // 15
116
0
117
0
    let zz3 = zz.double() + &zz; // 16, 17
118
0
    let bxz2_part = (curve_equation_b * &xz2) - &(zz3 + &xx); // 18, 19, 20
119
0
    let bxz6_part = bxz2_part.double() + &bxz2_part; // 21, 22
120
0
    let xx3_m_zz3 = xx.double() + &xx - &zz3; // 23, 24, 25
121
0
122
0
    let dy = y_frag + &(xx3_m_zz3 * &bxz6_part); // 26, 27
123
0
    let yz2 = (y * &z).double(); // 28, 29
124
0
    let dx = x_frag - &(bxz6_part * &yz2); // 30, 31
125
0
    let dz = (yz2 * &yy).double().double(); // 32, 33, 34
126
0
127
0
    (dx, dy, dz)
128
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ff-0.13.0/src/batch.rs
Line
Count
Source
1
//! Batched field inversion APIs, using [Montgomery's trick].
2
//!
3
//! [Montgomery's trick]: https://zcash.github.io/halo2/background/fields.html#montgomerys-trick
4
5
use subtle::ConstantTimeEq;
6
7
use crate::Field;
8
9
/// Extension trait for iterators over mutable field elements which allows those field
10
/// elements to be inverted in a batch.
11
///
12
/// `I: IntoIterator<Item = &'a mut F: Field + ConstantTimeEq>` implements this trait when
13
/// the `alloc` feature flag is enabled.
14
///
15
/// For non-allocating contexts, see the [`BatchInverter`] struct.
16
#[cfg(feature = "alloc")]
17
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
18
pub trait BatchInvert<F: Field> {
19
    /// Consumes this iterator and inverts each field element (when nonzero). Zero-valued
20
    /// elements are left as zero.
21
    ///
22
    /// Returns the inverse of the product of all nonzero field elements.
23
    fn batch_invert(self) -> F;
24
}
25
26
#[cfg(feature = "alloc")]
27
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
28
impl<'a, F, I> BatchInvert<F> for I
29
where
30
    F: Field + ConstantTimeEq,
31
    I: IntoIterator<Item = &'a mut F>,
32
{
33
0
    fn batch_invert(self) -> F {
34
0
        let mut acc = F::ONE;
35
0
        let iter = self.into_iter();
36
0
        let mut tmp = alloc::vec::Vec::with_capacity(iter.size_hint().0);
37
0
        for p in iter {
38
0
            let q = *p;
39
0
            tmp.push((acc, p));
40
0
            acc = F::conditional_select(&(acc * q), &acc, q.is_zero());
41
0
        }
42
0
        acc = acc.invert().unwrap();
43
0
        let allinv = acc;
44
45
0
        for (tmp, p) in tmp.into_iter().rev() {
46
0
            let skip = p.is_zero();
47
0
48
0
            let tmp = tmp * acc;
49
0
            acc = F::conditional_select(&(acc * *p), &acc, skip);
50
0
            *p = F::conditional_select(&tmp, p, skip);
51
0
        }
52
53
0
        allinv
54
0
    }
55
}
56
57
/// A non-allocating batch inverter.
58
pub struct BatchInverter {}
59
60
impl BatchInverter {
61
    /// Inverts each field element in `elements` (when nonzero). Zero-valued elements are
62
    /// left as zero.
63
    ///
64
    /// - `scratch_space` is a slice of field elements that can be freely overwritten.
65
    ///
66
    /// Returns the inverse of the product of all nonzero field elements.
67
    ///
68
    /// # Panics
69
    ///
70
    /// This function will panic if `elements.len() != scratch_space.len()`.
71
0
    pub fn invert_with_external_scratch<F>(elements: &mut [F], scratch_space: &mut [F]) -> F
72
0
    where
73
0
        F: Field + ConstantTimeEq,
74
0
    {
75
0
        assert_eq!(elements.len(), scratch_space.len());
76
77
0
        let mut acc = F::ONE;
78
0
        for (p, scratch) in elements.iter().zip(scratch_space.iter_mut()) {
79
0
            *scratch = acc;
80
0
            acc = F::conditional_select(&(acc * *p), &acc, p.is_zero());
81
0
        }
82
0
        acc = acc.invert().unwrap();
83
0
        let allinv = acc;
84
85
0
        for (p, scratch) in elements.iter_mut().zip(scratch_space.iter()).rev() {
86
0
            let tmp = *scratch * acc;
87
0
            let skip = p.is_zero();
88
0
            acc = F::conditional_select(&(acc * *p), &acc, skip);
89
0
            *p = F::conditional_select(&tmp, &p, skip);
90
0
        }
91
92
0
        allinv
93
0
    }
94
95
    /// Inverts each field element in `items` (when nonzero). Zero-valued elements are
96
    /// left as zero.
97
    ///
98
    /// - `element` is a function that extracts the element to be inverted from `items`.
99
    /// - `scratch_space` is a function that extracts the scratch space from `items`.
100
    ///
101
    /// Returns the inverse of the product of all nonzero field elements.
102
0
    pub fn invert_with_internal_scratch<F, T, TE, TS>(
103
0
        items: &mut [T],
104
0
        element: TE,
105
0
        scratch_space: TS,
106
0
    ) -> F
107
0
    where
108
0
        F: Field + ConstantTimeEq,
109
0
        TE: Fn(&mut T) -> &mut F,
110
0
        TS: Fn(&mut T) -> &mut F,
111
0
    {
112
0
        let mut acc = F::ONE;
113
0
        for item in items.iter_mut() {
114
0
            *(scratch_space)(item) = acc;
115
0
            let p = (element)(item);
116
0
            acc = F::conditional_select(&(acc * *p), &acc, p.is_zero());
117
0
        }
118
0
        acc = acc.invert().unwrap();
119
0
        let allinv = acc;
120
121
0
        for item in items.iter_mut().rev() {
122
0
            let tmp = *(scratch_space)(item) * acc;
123
0
            let p = (element)(item);
124
0
            let skip = p.is_zero();
125
0
            acc = F::conditional_select(&(acc * *p), &acc, skip);
126
0
            *p = F::conditional_select(&tmp, &p, skip);
127
0
        }
128
129
0
        allinv
130
0
    }
131
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ff-0.13.0/src/helpers.rs
Line
Count
Source
1
//! Helper methods for implementing the `ff` traits.
2
3
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
4
5
use crate::PrimeField;
6
7
/// Constant-time implementation of Tonelli–Shanks' square-root algorithm for
8
/// `p mod 16 = 1`.
9
///
10
/// `tm1d2` should be set to `(t - 1) // 2`, where `t = (modulus - 1) >> F::S`.
11
///
12
/// ## Implementing [`Field::sqrt`]
13
///
14
/// This function can be used to implement [`Field::sqrt`] for fields that both implement
15
/// [`PrimeField`] and satisfy `p mod 16 = 1`.
16
///
17
/// [`Field::sqrt`]: crate::Field::sqrt
18
0
pub fn sqrt_tonelli_shanks<F: PrimeField, S: AsRef<[u64]>>(f: &F, tm1d2: S) -> CtOption<F> {
19
0
    // This is a constant-time version of https://eprint.iacr.org/2012/685.pdf (page 12,
20
0
    // algorithm 5). Steps 2-5 of the algorithm are omitted because they are only needed
21
0
    // to detect non-square input; it is more efficient to do that by checking at the end
22
0
    // whether the square of the result is the input.
23
0
24
0
    // w = self^((t - 1) // 2)
25
0
    let w = f.pow_vartime(tm1d2);
26
0
27
0
    let mut v = F::S;
28
0
    let mut x = w * f;
29
0
    let mut b = x * w;
30
0
31
0
    // Initialize z as the 2^S root of unity.
32
0
    let mut z = F::ROOT_OF_UNITY;
33
34
0
    for max_v in (1..=F::S).rev() {
35
0
        let mut k = 1;
36
0
        let mut b2k = b.square();
37
0
        let mut j_less_than_v: Choice = 1.into();
38
39
        // This loop has three phases based on the value of k for algorithm 5:
40
        // - for j <= k, we square b2k in order to calculate b^{2^k}.
41
        // - for k < j <= v, we square z in order to calculate ω.
42
        // - for j > v, we do nothing.
43
0
        for j in 2..max_v {
44
0
            let b2k_is_one = b2k.ct_eq(&F::ONE);
45
0
            let squared = F::conditional_select(&b2k, &z, b2k_is_one).square();
46
0
            b2k = F::conditional_select(&squared, &b2k, b2k_is_one);
47
0
            let new_z = F::conditional_select(&z, &squared, b2k_is_one);
48
0
            j_less_than_v &= !j.ct_eq(&v);
49
0
            k = u32::conditional_select(&j, &k, b2k_is_one);
50
0
            z = F::conditional_select(&z, &new_z, j_less_than_v);
51
0
        }
52
53
0
        let result = x * z;
54
0
        x = F::conditional_select(&result, &x, b.ct_eq(&F::ONE));
55
0
        z = z.square();
56
0
        b *= z;
57
0
        v = k;
58
    }
59
60
0
    CtOption::new(
61
0
        x,
62
0
        (x * x).ct_eq(f), // Only return Some if it's the square root.
63
0
    )
64
0
}
65
66
/// Computes:
67
///
68
/// - $(\textsf{true}, \sqrt{\textsf{num}/\textsf{div}})$, if $\textsf{num}$ and
69
///   $\textsf{div}$ are nonzero and $\textsf{num}/\textsf{div}$ is a square in the
70
///   field;
71
/// - $(\textsf{true}, 0)$, if $\textsf{num}$ is zero;
72
/// - $(\textsf{false}, 0)$, if $\textsf{num}$ is nonzero and $\textsf{div}$ is zero;
73
/// - $(\textsf{false}, \sqrt{G_S \cdot \textsf{num}/\textsf{div}})$, if
74
///   $\textsf{num}$ and $\textsf{div}$ are nonzero and $\textsf{num}/\textsf{div}$ is
75
///   a nonsquare in the field;
76
///
77
/// where $G_S$ is a non-square.
78
///
79
/// For this method, $G_S$ is currently [`PrimeField::ROOT_OF_UNITY`], a generator of the
80
/// order $2^S$ subgroup. Users of this crate should not rely on this generator being
81
/// fixed; it may be changed in future crate versions to simplify the implementation of
82
/// the SSWU hash-to-curve algorithm.
83
///
84
/// The choice of root from sqrt is unspecified.
85
///
86
/// ## Implementing [`Field::sqrt_ratio`]
87
///
88
/// This function can be used to implement [`Field::sqrt_ratio`] for fields that also
89
/// implement [`PrimeField`]. If doing so, the default implementation of [`Field::sqrt`]
90
/// *MUST* be overridden, or else both functions will recurse in a cycle until a stack
91
/// overflow occurs.
92
///
93
/// [`Field::sqrt_ratio`]: crate::Field::sqrt_ratio
94
/// [`Field::sqrt`]: crate::Field::sqrt
95
0
pub fn sqrt_ratio_generic<F: PrimeField>(num: &F, div: &F) -> (Choice, F) {
96
0
    // General implementation:
97
0
    //
98
0
    // a = num * inv0(div)
99
0
    //   = {    0    if div is zero
100
0
    //     { num/div otherwise
101
0
    //
102
0
    // b = G_S * a
103
0
    //   = {      0      if div is zero
104
0
    //     { G_S*num/div otherwise
105
0
    //
106
0
    // Since G_S is non-square, a and b are either both zero (and both square), or
107
0
    // only one of them is square. We can therefore choose the square root to return
108
0
    // based on whether a is square, but for the boolean output we need to handle the
109
0
    // num != 0 && div == 0 case specifically.
110
0
111
0
    let a = div.invert().unwrap_or(F::ZERO) * num;
112
0
    let b = a * F::ROOT_OF_UNITY;
113
0
    let sqrt_a = a.sqrt();
114
0
    let sqrt_b = b.sqrt();
115
0
116
0
    let num_is_zero = num.is_zero();
117
0
    let div_is_zero = div.is_zero();
118
0
    let is_square = sqrt_a.is_some();
119
0
    let is_nonsquare = sqrt_b.is_some();
120
0
    assert!(bool::from(
121
0
        num_is_zero | div_is_zero | (is_square ^ is_nonsquare)
122
0
    ));
123
124
0
    (
125
0
        is_square & (num_is_zero | !div_is_zero),
126
0
        CtOption::conditional_select(&sqrt_b, &sqrt_a, is_square).unwrap(),
127
0
    )
128
0
}
Unexecuted instantiation: _RINvNtCs1xjs03Q5HzH_2ff7helpers18sqrt_ratio_genericpEB4_
Unexecuted instantiation: _RINvNtCs1xjs03Q5HzH_2ff7helpers18sqrt_ratio_genericNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementEBT_
Unexecuted instantiation: _RINvNtCs1xjs03Q5HzH_2ff7helpers18sqrt_ratio_genericNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarEBT_
Unexecuted instantiation: _RINvNtCs1xjs03Q5HzH_2ff7helpers18sqrt_ratio_genericNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementEBT_
Unexecuted instantiation: _RINvNtCs1xjs03Q5HzH_2ff7helpers18sqrt_ratio_genericNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarEBT_
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ff-0.13.0/src/lib.rs
Line
Count
Source
1
//! This crate provides traits for working with finite fields.
2
3
// Catch documentation errors caused by code changes.
4
#![no_std]
5
#![cfg_attr(docsrs, feature(doc_cfg))]
6
#![deny(rustdoc::broken_intra_doc_links)]
7
#![forbid(unsafe_code)]
8
9
#[cfg(feature = "alloc")]
10
extern crate alloc;
11
12
mod batch;
13
pub use batch::*;
14
15
pub mod helpers;
16
17
#[cfg(feature = "derive")]
18
#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
19
pub use ff_derive::PrimeField;
20
21
#[cfg(feature = "bits")]
22
#[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
23
pub use bitvec::view::BitViewSized;
24
25
#[cfg(feature = "bits")]
26
use bitvec::{array::BitArray, order::Lsb0};
27
28
use core::fmt;
29
use core::iter::{Product, Sum};
30
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
31
32
use rand_core::RngCore;
33
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
34
35
/// Bit representation of a field element.
36
#[cfg(feature = "bits")]
37
#[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
38
pub type FieldBits<V> = BitArray<V, Lsb0>;
39
40
/// This trait represents an element of a field.
41
pub trait Field:
42
    Sized
43
    + Eq
44
    + Copy
45
    + Clone
46
    + Default
47
    + Send
48
    + Sync
49
    + fmt::Debug
50
    + 'static
51
    + ConditionallySelectable
52
    + ConstantTimeEq
53
    + Neg<Output = Self>
54
    + Add<Output = Self>
55
    + Sub<Output = Self>
56
    + Mul<Output = Self>
57
    + Sum
58
    + Product
59
    + for<'a> Add<&'a Self, Output = Self>
60
    + for<'a> Sub<&'a Self, Output = Self>
61
    + for<'a> Mul<&'a Self, Output = Self>
62
    + for<'a> Sum<&'a Self>
63
    + for<'a> Product<&'a Self>
64
    + AddAssign
65
    + SubAssign
66
    + MulAssign
67
    + for<'a> AddAssign<&'a Self>
68
    + for<'a> SubAssign<&'a Self>
69
    + for<'a> MulAssign<&'a Self>
70
{
71
    /// The zero element of the field, the additive identity.
72
    const ZERO: Self;
73
74
    /// The one element of the field, the multiplicative identity.
75
    const ONE: Self;
76
77
    /// Returns an element chosen uniformly at random using a user-provided RNG.
78
    fn random(rng: impl RngCore) -> Self;
79
80
    /// Returns true iff this element is zero.
81
159k
    fn is_zero(&self) -> Choice {
82
159k
        self.ct_eq(&Self::ZERO)
83
159k
    }
_RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff5Field7is_zeroCs4RkbDk9WRL5_5clvmr
Line
Count
Source
81
1.67k
    fn is_zero(&self) -> Choice {
82
1.67k
        self.ct_eq(&Self::ZERO)
83
1.67k
    }
Unexecuted instantiation: _RNvYpNtCs1xjs03Q5HzH_2ff5Field7is_zeroB5_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff5Field7is_zeroB8_
_RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff5Field7is_zeroB8_
Line
Count
Source
81
1.58k
    fn is_zero(&self) -> Choice {
82
1.58k
        self.ct_eq(&Self::ZERO)
83
1.58k
    }
_RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff5Field7is_zeroB8_
Line
Count
Source
81
155k
    fn is_zero(&self) -> Choice {
82
155k
        self.ct_eq(&Self::ZERO)
83
155k
    }
84
85
    /// Returns true iff this element is zero.
86
    ///
87
    /// # Security
88
    ///
89
    /// This method provides **no** constant-time guarantees. Implementors of the
90
    /// `Field` trait **may** optimise this method using non-constant-time logic.
91
0
    fn is_zero_vartime(&self) -> bool {
92
0
        self.is_zero().into()
93
0
    }
Unexecuted instantiation: _RNvYpNtCs1xjs03Q5HzH_2ff5Field15is_zero_vartimeB5_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff5Field15is_zero_vartimeB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff5Field15is_zero_vartimeB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff5Field15is_zero_vartimeB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff5Field15is_zero_vartimeB8_
94
95
    /// Squares this element.
96
    #[must_use]
97
    fn square(&self) -> Self;
98
99
    /// Cubes this element.
100
    #[must_use]
101
0
    fn cube(&self) -> Self {
102
0
        self.square() * self
103
0
    }
Unexecuted instantiation: _RNvYpNtCs1xjs03Q5HzH_2ff5Field4cubeB5_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff5Field4cubeB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff5Field4cubeB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff5Field4cubeB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff5Field4cubeB8_
104
105
    /// Doubles this element.
106
    #[must_use]
107
    fn double(&self) -> Self;
108
109
    /// Computes the multiplicative inverse of this element,
110
    /// failing if the element is zero.
111
    fn invert(&self) -> CtOption<Self>;
112
113
    /// Computes:
114
    ///
115
    /// - $(\textsf{true}, \sqrt{\textsf{num}/\textsf{div}})$, if $\textsf{num}$ and
116
    ///   $\textsf{div}$ are nonzero and $\textsf{num}/\textsf{div}$ is a square in the
117
    ///   field;
118
    /// - $(\textsf{true}, 0)$, if $\textsf{num}$ is zero;
119
    /// - $(\textsf{false}, 0)$, if $\textsf{num}$ is nonzero and $\textsf{div}$ is zero;
120
    /// - $(\textsf{false}, \sqrt{G_S \cdot \textsf{num}/\textsf{div}})$, if
121
    ///   $\textsf{num}$ and $\textsf{div}$ are nonzero and $\textsf{num}/\textsf{div}$ is
122
    ///   a nonsquare in the field;
123
    ///
124
    /// where $G_S$ is a non-square.
125
    ///
126
    /// # Warnings
127
    ///
128
    /// - The choice of root from `sqrt` is unspecified.
129
    /// - The value of $G_S$ is unspecified, and cannot be assumed to have any specific
130
    ///   value in a generic context.
131
    fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self);
132
133
    /// Equivalent to `Self::sqrt_ratio(self, one())`.
134
    ///
135
    /// The provided method is implemented in terms of [`Self::sqrt_ratio`].
136
0
    fn sqrt_alt(&self) -> (Choice, Self) {
137
0
        Self::sqrt_ratio(self, &Self::ONE)
138
0
    }
Unexecuted instantiation: _RNvYpNtCs1xjs03Q5HzH_2ff5Field8sqrt_altB5_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff5Field8sqrt_altB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff5Field8sqrt_altB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff5Field8sqrt_altB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff5Field8sqrt_altB8_
139
140
    /// Returns the square root of the field element, if it is
141
    /// quadratic residue.
142
    ///
143
    /// The provided method is implemented in terms of [`Self::sqrt_ratio`].
144
0
    fn sqrt(&self) -> CtOption<Self> {
145
0
        let (is_square, res) = Self::sqrt_ratio(self, &Self::ONE);
146
0
        CtOption::new(res, is_square)
147
0
    }
148
149
    /// Exponentiates `self` by `exp`, where `exp` is a little-endian order integer
150
    /// exponent.
151
    ///
152
    /// # Guarantees
153
    ///
154
    /// This operation is constant time with respect to `self`, for all exponents with the
155
    /// same number of digits (`exp.as_ref().len()`). It is variable time with respect to
156
    /// the number of digits in the exponent.
157
0
    fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
158
0
        let mut res = Self::ONE;
159
0
        for e in exp.as_ref().iter().rev() {
160
0
            for i in (0..64).rev() {
161
0
                res = res.square();
162
0
                let mut tmp = res;
163
0
                tmp *= self;
164
0
                res.conditional_assign(&tmp, (((*e >> i) & 1) as u8).into());
165
0
            }
166
        }
167
0
        res
168
0
    }
169
170
    /// Exponentiates `self` by `exp`, where `exp` is a little-endian order integer
171
    /// exponent.
172
    ///
173
    /// # Guarantees
174
    ///
175
    /// **This operation is variable time with respect to `self`, for all exponent.** If
176
    /// the exponent is fixed, this operation is effectively constant time. However, for
177
    /// stronger constant-time guarantees, [`Field::pow`] should be used.
178
0
    fn pow_vartime<S: AsRef<[u64]>>(&self, exp: S) -> Self {
179
0
        let mut res = Self::ONE;
180
0
        for e in exp.as_ref().iter().rev() {
181
0
            for i in (0..64).rev() {
182
0
                res = res.square();
183
0
184
0
                if ((*e >> i) & 1) == 1 {
185
0
                    res.mul_assign(self);
186
0
                }
187
            }
188
        }
189
190
0
        res
191
0
    }
Unexecuted instantiation: _RINvYpNtCs1xjs03Q5HzH_2ff5Field11pow_vartimepEB6_
Unexecuted instantiation: _RINvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff5Field11pow_vartimeAyj4_EB9_
192
}
193
194
/// This represents an element of a non-binary prime field.
195
pub trait PrimeField: Field + From<u64> {
196
    /// The prime field can be converted back and forth into this binary
197
    /// representation.
198
    type Repr: Copy + Default + Send + Sync + 'static + AsRef<[u8]> + AsMut<[u8]>;
199
200
    /// Interpret a string of numbers as a (congruent) prime field element.
201
    /// Does not accept unnecessary leading zeroes or a blank string.
202
    ///
203
    /// # Security
204
    ///
205
    /// This method provides **no** constant-time guarantees.
206
0
    fn from_str_vartime(s: &str) -> Option<Self> {
207
0
        if s.is_empty() {
208
0
            return None;
209
0
        }
210
0
211
0
        if s == "0" {
212
0
            return Some(Self::ZERO);
213
0
        }
214
0
215
0
        let mut res = Self::ZERO;
216
0
217
0
        let ten = Self::from(10);
218
0
219
0
        let mut first_digit = true;
220
221
0
        for c in s.chars() {
222
0
            match c.to_digit(10) {
223
0
                Some(c) => {
224
0
                    if first_digit {
225
0
                        if c == 0 {
226
0
                            return None;
227
0
                        }
228
0
229
0
                        first_digit = false;
230
0
                    }
231
232
0
                    res.mul_assign(&ten);
233
0
                    res.add_assign(&Self::from(u64::from(c)));
234
                }
235
                None => {
236
0
                    return None;
237
                }
238
            }
239
        }
240
241
0
        Some(res)
242
0
    }
Unexecuted instantiation: _RNvYpNtCs1xjs03Q5HzH_2ff10PrimeField16from_str_vartimeB5_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField16from_str_vartimeB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff10PrimeField16from_str_vartimeB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField16from_str_vartimeB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff10PrimeField16from_str_vartimeB8_
243
244
    /// Obtains a field element congruent to the integer `v`.
245
    ///
246
    /// For fields where `Self::CAPACITY >= 128`, this is injective and will produce a
247
    /// unique field element.
248
    ///
249
    /// For fields where `Self::CAPACITY < 128`, this is surjective; some field elements
250
    /// will be produced by multiple values of `v`.
251
    ///
252
    /// If you want to deterministically sample a field element representing a value, use
253
    /// [`FromUniformBytes`] instead.
254
0
    fn from_u128(v: u128) -> Self {
255
0
        let lower = v as u64;
256
0
        let upper = (v >> 64) as u64;
257
0
        let mut tmp = Self::from(upper);
258
0
        for _ in 0..64 {
259
0
            tmp = tmp.double();
260
0
        }
261
0
        tmp + Self::from(lower)
262
0
    }
Unexecuted instantiation: _RNvYpNtCs1xjs03Q5HzH_2ff10PrimeField9from_u128B5_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField9from_u128B8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff10PrimeField9from_u128B8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField9from_u128B8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff10PrimeField9from_u128B8_
263
264
    /// Attempts to convert a byte representation of a field element into an element of
265
    /// this prime field, failing if the input is not canonical (is not smaller than the
266
    /// field's modulus).
267
    ///
268
    /// The byte representation is interpreted with the same endianness as elements
269
    /// returned by [`PrimeField::to_repr`].
270
    fn from_repr(repr: Self::Repr) -> CtOption<Self>;
271
272
    /// Attempts to convert a byte representation of a field element into an element of
273
    /// this prime field, failing if the input is not canonical (is not smaller than the
274
    /// field's modulus).
275
    ///
276
    /// The byte representation is interpreted with the same endianness as elements
277
    /// returned by [`PrimeField::to_repr`].
278
    ///
279
    /// # Security
280
    ///
281
    /// This method provides **no** constant-time guarantees. Implementors of the
282
    /// `PrimeField` trait **may** optimise this method using non-constant-time logic.
283
0
    fn from_repr_vartime(repr: Self::Repr) -> Option<Self> {
284
0
        Self::from_repr(repr).into()
285
0
    }
Unexecuted instantiation: _RNvYpNtCs1xjs03Q5HzH_2ff10PrimeField17from_repr_vartimeB5_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField17from_repr_vartimeB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff10PrimeField17from_repr_vartimeB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField17from_repr_vartimeB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff10PrimeField17from_repr_vartimeB8_
286
287
    /// Converts an element of the prime field into the standard byte representation for
288
    /// this field.
289
    ///
290
    /// The endianness of the byte representation is implementation-specific. Generic
291
    /// encodings of field elements should be treated as opaque.
292
    fn to_repr(&self) -> Self::Repr;
293
294
    /// Returns true iff this element is odd.
295
    fn is_odd(&self) -> Choice;
296
297
    /// Returns true iff this element is even.
298
    #[inline(always)]
299
373k
    fn is_even(&self) -> Choice {
300
373k
        !self.is_odd()
301
373k
    }
Unexecuted instantiation: _RNvYpNtCs1xjs03Q5HzH_2ff10PrimeField7is_evenB5_
_RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs1xjs03Q5HzH_2ff10PrimeField7is_evenB8_
Line
Count
Source
299
373k
    fn is_even(&self) -> Choice {
300
373k
        !self.is_odd()
301
373k
    }
302
303
    /// Modulus of the field written as a string for debugging purposes.
304
    ///
305
    /// The encoding of the modulus is implementation-specific. Generic users of the
306
    /// `PrimeField` trait should treat this string as opaque.
307
    const MODULUS: &'static str;
308
309
    /// How many bits are needed to represent an element of this field.
310
    const NUM_BITS: u32;
311
312
    /// How many bits of information can be reliably stored in the field element.
313
    ///
314
    /// This is usually `Self::NUM_BITS - 1`.
315
    const CAPACITY: u32;
316
317
    /// Inverse of $2$ in the field.
318
    const TWO_INV: Self;
319
320
    /// A fixed multiplicative generator of `modulus - 1` order. This element must also be
321
    /// a quadratic nonresidue.
322
    ///
323
    /// It can be calculated using [SageMath] as `GF(modulus).primitive_element()`.
324
    ///
325
    /// Implementations of this trait MUST ensure that this is the generator used to
326
    /// derive `Self::ROOT_OF_UNITY`.
327
    ///
328
    /// [SageMath]: https://www.sagemath.org/
329
    const MULTIPLICATIVE_GENERATOR: Self;
330
331
    /// An integer `s` satisfying the equation `2^s * t = modulus - 1` with `t` odd.
332
    ///
333
    /// This is the number of leading zero bits in the little-endian bit representation of
334
    /// `modulus - 1`.
335
    const S: u32;
336
337
    /// The `2^s` root of unity.
338
    ///
339
    /// It can be calculated by exponentiating `Self::MULTIPLICATIVE_GENERATOR` by `t`,
340
    /// where `t = (modulus - 1) >> Self::S`.
341
    const ROOT_OF_UNITY: Self;
342
343
    /// Inverse of [`Self::ROOT_OF_UNITY`].
344
    const ROOT_OF_UNITY_INV: Self;
345
346
    /// Generator of the `t-order` multiplicative subgroup.
347
    ///
348
    /// It can be calculated by exponentiating [`Self::MULTIPLICATIVE_GENERATOR`] by `2^s`,
349
    /// where `s` is [`Self::S`].
350
    const DELTA: Self;
351
}
352
353
/// The subset of prime-order fields such that `(modulus - 1)` is divisible by `N`.
354
///
355
/// If `N` is prime, there will be `N - 1` valid choices of [`Self::ZETA`]. Similarly to
356
/// [`PrimeField::MULTIPLICATIVE_GENERATOR`], the specific choice does not matter, as long
357
/// as the choice is consistent across all uses of the field.
358
pub trait WithSmallOrderMulGroup<const N: u8>: PrimeField {
359
    /// A field element of small multiplicative order $N$.
360
    ///
361
    /// The presense of this element allows you to perform (certain types of)
362
    /// endomorphisms on some elliptic curves.
363
    ///
364
    /// It can be calculated using [SageMath] as
365
    /// `GF(modulus).primitive_element() ^ ((modulus - 1) // N)`.
366
    /// Choosing the element of order $N$ that is smallest, when considered
367
    /// as an integer, may help to ensure consistency.
368
    ///
369
    /// [SageMath]: https://www.sagemath.org/
370
    const ZETA: Self;
371
}
372
373
/// Trait for constructing a [`PrimeField`] element from a fixed-length uniform byte
374
/// array.
375
///
376
/// "Uniform" means that the byte array's contents must be indistinguishable from the
377
/// [discrete uniform distribution]. Suitable byte arrays can be obtained:
378
/// - from a cryptographically-secure randomness source (which makes this constructor
379
///   equivalent to [`Field::random`]).
380
/// - from a cryptographic hash function output, which enables a "random" field element to
381
///   be selected deterministically. This is the primary use case for `FromUniformBytes`.
382
///
383
/// The length `N` of the byte array is chosen by the trait implementer such that the loss
384
/// of uniformity in the mapping from byte arrays to field elements is cryptographically
385
/// negligible.
386
///
387
/// [discrete uniform distribution]: https://en.wikipedia.org/wiki/Discrete_uniform_distribution
388
///
389
/// # Examples
390
///
391
/// ```
392
/// # #[cfg(feature = "derive")] {
393
/// # // Fake this so we don't actually need a dev-dependency on bls12_381.
394
/// # mod bls12_381 {
395
/// #     use ff::{Field, PrimeField};
396
/// #
397
/// #     #[derive(PrimeField)]
398
/// #     #[PrimeFieldModulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
399
/// #     #[PrimeFieldGenerator = "7"]
400
/// #     #[PrimeFieldReprEndianness = "little"]
401
/// #     pub struct Scalar([u64; 4]);
402
/// #
403
/// #     impl ff::FromUniformBytes<64> for Scalar {
404
/// #         fn from_uniform_bytes(_bytes: &[u8; 64]) -> Self {
405
/// #             // Fake impl for doctest
406
/// #             Scalar::ONE
407
/// #         }
408
/// #     }
409
/// # }
410
/// #
411
/// use blake2b_simd::blake2b;
412
/// use bls12_381::Scalar;
413
/// use ff::FromUniformBytes;
414
///
415
/// // `bls12_381::Scalar` implements `FromUniformBytes<64>`, and BLAKE2b (by default)
416
/// // produces a 64-byte hash.
417
/// let hash = blake2b(b"Some message");
418
/// let val = Scalar::from_uniform_bytes(hash.as_array());
419
/// # }
420
/// ```
421
///
422
/// # Implementing `FromUniformBytes`
423
///
424
/// [`Self::from_uniform_bytes`] should always be implemented by interpreting the provided
425
/// byte array as the little endian unsigned encoding of an integer, and then reducing that
426
/// integer modulo the field modulus.
427
///
428
/// For security, `N` must be chosen so that `N * 8 >= Self::NUM_BITS + 128`. A larger
429
/// value of `N` may be chosen for convenience; for example, for a field with a 255-bit
430
/// modulus, `N = 64` is convenient as it matches the output length of several common
431
/// cryptographic hash functions (such as SHA-512 and BLAKE2b).
432
///
433
/// ## Trait design
434
///
435
/// This trait exists because `PrimeField::from_uniform_bytes([u8; N])` cannot currently
436
/// exist (trait methods cannot use associated constants in the const positions of their
437
/// type signature, and we do not want `PrimeField` to require a generic const parameter).
438
/// However, this has the side-effect that `FromUniformBytes` can be implemented multiple
439
/// times for different values of `N`. Most implementations of [`PrimeField`] should only
440
/// need to implement `FromUniformBytes` trait for one value of `N` (chosen following the
441
/// above considerations); if you find yourself needing to implement it multiple times,
442
/// please [let us know about your use case](https://github.com/zkcrypto/ff/issues/new) so
443
/// we can take it into consideration for future evolutions of the `ff` traits.
444
pub trait FromUniformBytes<const N: usize>: PrimeField {
445
    /// Returns a field element that is congruent to the provided little endian unsigned
446
    /// byte representation of an integer.
447
    fn from_uniform_bytes(bytes: &[u8; N]) -> Self;
448
}
449
450
/// This represents the bits of an element of a prime field.
451
#[cfg(feature = "bits")]
452
#[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
453
pub trait PrimeFieldBits: PrimeField {
454
    /// The backing store for a bit representation of a prime field element.
455
    type ReprBits: BitViewSized + Send + Sync;
456
457
    /// Converts an element of the prime field into a little-endian sequence of bits.
458
    fn to_le_bits(&self) -> FieldBits<Self::ReprBits>;
459
460
    /// Returns the bits of the field characteristic (the modulus) in little-endian order.
461
    fn char_le_bits() -> FieldBits<Self::ReprBits>;
462
}
463
464
/// Functions and re-exported crates used by the [`PrimeField`] derive macro.
465
#[cfg(feature = "derive")]
466
#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
467
pub mod derive {
468
    pub use crate::arith_impl::*;
469
470
    pub use {byteorder, rand_core, subtle};
471
472
    #[cfg(feature = "bits")]
473
    pub use bitvec;
474
}
475
476
#[cfg(feature = "derive")]
477
mod arith_impl {
478
    /// Computes `a - (b + borrow)`, returning the result and the new borrow.
479
    #[inline(always)]
480
    pub const fn sbb(a: u64, b: u64, borrow: u64) -> (u64, u64) {
481
        let ret = (a as u128).wrapping_sub((b as u128) + ((borrow >> 63) as u128));
482
        (ret as u64, (ret >> 64) as u64)
483
    }
484
485
    /// Computes `a + b + carry`, returning the result and the new carry over.
486
    #[inline(always)]
487
    pub const fn adc(a: u64, b: u64, carry: u64) -> (u64, u64) {
488
        let ret = (a as u128) + (b as u128) + (carry as u128);
489
        (ret as u64, (ret >> 64) as u64)
490
    }
491
492
    /// Computes `a + (b * c) + carry`, returning the result and the new carry over.
493
    #[inline(always)]
494
    pub const fn mac(a: u64, b: u64, c: u64, carry: u64) -> (u64, u64) {
495
        let ret = (a as u128) + ((b as u128) * (c as u128)) + (carry as u128);
496
        (ret as u64, (ret >> 64) as u64)
497
    }
498
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/generic-array-0.14.7/src/functional.rs
Line
Count
Source
1
//! Functional programming with generic sequences
2
//!
3
//! Please see `tests/generics.rs` for examples of how to best use these in your generic functions.
4
5
use super::ArrayLength;
6
use core::iter::FromIterator;
7
8
use crate::sequence::*;
9
10
/// Defines the relationship between one generic sequence and another,
11
/// for operations such as `map` and `zip`.
12
pub unsafe trait MappedGenericSequence<T, U>: GenericSequence<T>
13
where
14
    Self::Length: ArrayLength<U>,
15
{
16
    /// Mapped sequence type
17
    type Mapped: GenericSequence<U, Length = Self::Length>;
18
}
19
20
unsafe impl<'a, T, U, S: MappedGenericSequence<T, U>> MappedGenericSequence<T, U> for &'a S
21
where
22
    &'a S: GenericSequence<T>,
23
    S: GenericSequence<T, Length = <&'a S as GenericSequence<T>>::Length>,
24
    <S as GenericSequence<T>>::Length: ArrayLength<U>,
25
{
26
    type Mapped = <S as MappedGenericSequence<T, U>>::Mapped;
27
}
28
29
unsafe impl<'a, T, U, S: MappedGenericSequence<T, U>> MappedGenericSequence<T, U> for &'a mut S
30
where
31
    &'a mut S: GenericSequence<T>,
32
    S: GenericSequence<T, Length = <&'a mut S as GenericSequence<T>>::Length>,
33
    <S as GenericSequence<T>>::Length: ArrayLength<U>,
34
{
35
    type Mapped = <S as MappedGenericSequence<T, U>>::Mapped;
36
}
37
38
/// Accessor type for a mapped generic sequence
39
pub type MappedSequence<S, T, U> =
40
    <<S as MappedGenericSequence<T, U>>::Mapped as GenericSequence<U>>::Sequence;
41
42
/// Defines functional programming methods for generic sequences
43
pub unsafe trait FunctionalSequence<T>: GenericSequence<T> {
44
    /// Maps a `GenericSequence` to another `GenericSequence`.
45
    ///
46
    /// If the mapping function panics, any already initialized elements in the new sequence
47
    /// will be dropped, AND any unused elements in the source sequence will also be dropped.
48
0
    fn map<U, F>(self, f: F) -> MappedSequence<Self, T, U>
49
0
    where
50
0
        Self: MappedGenericSequence<T, U>,
51
0
        Self::Length: ArrayLength<U>,
52
0
        F: FnMut(Self::Item) -> U,
53
0
    {
54
0
        FromIterator::from_iter(self.into_iter().map(f))
55
0
    }
Unexecuted instantiation: _RINvYRINtCskVr04X3DebC_13generic_array12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBQ_IBQ_IBQ_IBQ_IBQ_IBQ_NtBS_5UTermNtNtBU_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EB2e_EEINtNtB7_10functional18FunctionalSequencehE3maphNvYhNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneECs4RkbDk9WRL5_5clvmr
Unexecuted instantiation: _RINvYpINtNtCskVr04X3DebC_13generic_array10functional18FunctionalSequencepE3mapppEB9_
56
57
    /// Combines two `GenericSequence` instances and iterates through both of them,
58
    /// initializing a new `GenericSequence` with the result of the zipped mapping function.
59
    ///
60
    /// If the mapping function panics, any already initialized elements in the new sequence
61
    /// will be dropped, AND any unused elements in the source sequences will also be dropped.
62
    #[inline]
63
0
    fn zip<B, Rhs, U, F>(self, rhs: Rhs, f: F) -> MappedSequence<Self, T, U>
64
0
    where
65
0
        Self: MappedGenericSequence<T, U>,
66
0
        Rhs: MappedGenericSequence<B, U, Mapped = MappedSequence<Self, T, U>>,
67
0
        Self::Length: ArrayLength<B> + ArrayLength<U>,
68
0
        Rhs: GenericSequence<B, Length = Self::Length>,
69
0
        F: FnMut(Self::Item, Rhs::Item) -> U,
70
0
    {
71
0
        rhs.inverted_zip2(self, f)
72
0
    }
73
74
    /// Folds (or reduces) a sequence of data into a single value.
75
    ///
76
    /// If the fold function panics, any unused elements will be dropped.
77
0
    fn fold<U, F>(self, init: U, f: F) -> U
78
0
    where
79
0
        F: FnMut(U, Self::Item) -> U,
80
0
    {
81
0
        self.into_iter().fold(init, f)
82
0
    }
83
}
84
85
unsafe impl<'a, T, S: GenericSequence<T>> FunctionalSequence<T> for &'a S
86
where
87
    &'a S: GenericSequence<T>,
88
{
89
}
90
91
unsafe impl<'a, T, S: GenericSequence<T>> FunctionalSequence<T> for &'a mut S
92
where
93
    &'a mut S: GenericSequence<T>,
94
{
95
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/generic-array-0.14.7/src/hex.rs
Line
Count
Source
1
//! Generic array are commonly used as a return value for hash digests, so
2
//! it's a good idea to allow to hexlify them easily. This module implements
3
//! `std::fmt::LowerHex` and `std::fmt::UpperHex` traits.
4
//!
5
//! Example:
6
//!
7
//! ```rust
8
//! # #[macro_use]
9
//! # extern crate generic_array;
10
//! # extern crate typenum;
11
//! # fn main() {
12
//! let array = arr![u8; 10, 20, 30];
13
//! assert_eq!(format!("{:x}", array), "0a141e");
14
//! # }
15
//! ```
16
//!
17
18
use core::{fmt, str, ops::Add, cmp::min};
19
20
use typenum::*;
21
22
use crate::{ArrayLength, GenericArray};
23
24
static LOWER_CHARS: &'static [u8] = b"0123456789abcdef";
25
static UPPER_CHARS: &'static [u8] = b"0123456789ABCDEF";
26
27
impl<T: ArrayLength<u8>> fmt::LowerHex for GenericArray<u8, T>
28
where
29
    T: Add<T>,
30
    <T as Add<T>>::Output: ArrayLength<u8>,
31
{
32
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33
0
        let max_digits = f.precision().unwrap_or_else(|| self.len() * 2);
34
0
        let max_hex = (max_digits >> 1) + (max_digits & 1);
35
0
36
0
        if T::USIZE < 1024 {
37
            // For small arrays use a stack allocated
38
            // buffer of 2x number of bytes
39
0
            let mut res = GenericArray::<u8, Sum<T, T>>::default();
40
0
41
0
            self.iter().take(max_hex).enumerate().for_each(|(i, c)| {
42
0
                res[i * 2] = LOWER_CHARS[(c >> 4) as usize];
43
0
                res[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
44
0
            });
45
0
46
0
            f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?;
47
        } else {
48
            // For large array use chunks of up to 1024 bytes (2048 hex chars)
49
0
            let mut buf = [0u8; 2048];
50
0
            let mut digits_left = max_digits;
51
52
0
            for chunk in self[..max_hex].chunks(1024) {
53
0
                chunk.iter().enumerate().for_each(|(i, c)| {
54
0
                    buf[i * 2] = LOWER_CHARS[(c >> 4) as usize];
55
0
                    buf[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
56
0
                });
57
0
58
0
                let n = min(chunk.len() * 2, digits_left);
59
0
                f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?;
60
0
                digits_left -= n;
61
            }
62
        }
63
0
        Ok(())
64
0
    }
65
}
66
67
impl<T: ArrayLength<u8>> fmt::UpperHex for GenericArray<u8, T>
68
where
69
    T: Add<T>,
70
    <T as Add<T>>::Output: ArrayLength<u8>,
71
{
72
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73
0
        let max_digits = f.precision().unwrap_or_else(|| self.len() * 2);
74
0
        let max_hex = (max_digits >> 1) + (max_digits & 1);
75
0
76
0
        if T::USIZE < 1024 {
77
            // For small arrays use a stack allocated
78
            // buffer of 2x number of bytes
79
0
            let mut res = GenericArray::<u8, Sum<T, T>>::default();
80
0
81
0
            self.iter().take(max_hex).enumerate().for_each(|(i, c)| {
82
0
                res[i * 2] = UPPER_CHARS[(c >> 4) as usize];
83
0
                res[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
84
0
            });
85
0
86
0
            f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?;
87
        } else {
88
            // For large array use chunks of up to 1024 bytes (2048 hex chars)
89
0
            let mut buf = [0u8; 2048];
90
0
            let mut digits_left = max_digits;
91
92
0
            for chunk in self[..max_hex].chunks(1024) {
93
0
                chunk.iter().enumerate().for_each(|(i, c)| {
94
0
                    buf[i * 2] = UPPER_CHARS[(c >> 4) as usize];
95
0
                    buf[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
96
0
                });
97
0
98
0
                let n = min(chunk.len() * 2, digits_left);
99
0
                f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?;
100
0
                digits_left -= n;
101
            }
102
        }
103
0
        Ok(())
104
0
    }
105
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/generic-array-0.14.7/src/impl_zeroize.rs
Line
Count
Source
1
use crate::{ArrayLength, GenericArray};
2
3
use zeroize::Zeroize;
4
5
impl<T: Zeroize, N: ArrayLength<T>> Zeroize for GenericArray<T, N> {
6
0
    fn zeroize(&mut self) {
7
0
        self.as_mut_slice().iter_mut().zeroize()
8
0
    }
9
}
10
11
#[cfg(test)]
12
mod tests {
13
    use super::*;
14
15
    #[test]
16
    fn test_zeroize() {
17
        let mut array = GenericArray::<u8, typenum::U2>::default();
18
        array[0] = 4;
19
        array[1] = 9;
20
        array.zeroize();
21
        assert_eq!(array[0], 0);
22
        assert_eq!(array[1], 0);
23
    }
24
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/generic-array-0.14.7/src/impls.rs
Line
Count
Source
1
use core::borrow::{Borrow, BorrowMut};
2
use core::cmp::Ordering;
3
use core::fmt::{self, Debug};
4
use core::hash::{Hash, Hasher};
5
6
use super::{ArrayLength, GenericArray};
7
8
use crate::functional::*;
9
use crate::sequence::*;
10
11
impl<T: Default, N> Default for GenericArray<T, N>
12
where
13
    N: ArrayLength<T>,
14
{
15
    #[inline(always)]
16
38.1k
    fn default() -> Self {
17
1.62M
        Self::generate(|_| T::default())
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2j_2B0EB2x_EB2x_EB2x_EB2x_EB2x_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2e_2B0EB2s_EB2s_EB2s_EB2s_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2j_2B0EB2x_EB2x_EB2x_EB2x_EB2x_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0Cs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2e_2B0EB2s_EB2s_EB2s_EB2s_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0Cs2IvCg5PL8uK_11chia_traits
_RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2j_2B0EB2x_EB2x_EB2x_EB2x_EB2h_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
17
159k
        Self::generate(|_| T::default())
_RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2j_2B0EB2x_EB2x_EB2x_EB2x_EB2x_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
17
638k
        Self::generate(|_| T::default())
_RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2e_2B0EB2s_EB2s_EB2s_EB2s_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
17
712k
        Self::generate(|_| T::default())
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2D_2B0EB2R_EB2R_EB2R_EB2R_EB2R_EB2R_EB2R_EB2R_EB2R_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1EB2w_ENtB2y_2B0EB2R_EB2R_EB2R_EB2R_EB2R_EB2R_EB2R_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2y_2B0EB2M_EB2M_EB2M_EB2M_EB2M_EB2M_EB2M_EB2M_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1EB2r_EB2r_ENtB2t_2B0EB2R_EB2R_EB2R_EB2R_EB2R_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1EB2r_ENtB2t_2B0EB2M_EB2M_EB2M_EB2M_EB2M_EB2M_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2t_2B0EB2H_EB2H_EB2H_EB2H_EB2H_EB2H_EB2H_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1EB2m_EB2m_ENtB2o_2B0EB2M_EB2M_EB2M_EB2M_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1EB2m_ENtB2o_2B0EB2H_EB2H_EB2H_EB2H_EB2H_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2o_2B0EB2C_EB2C_EB2C_EB2C_EB2C_EB2C_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1EB2h_EB2h_ENtB2j_2B0EB2H_EB2H_EB2H_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1EB2h_ENtB2j_2B0EB2C_EB2C_EB2C_EB2C_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1EB2h_ENtB2j_2B0EB2h_EB2C_EB2C_EB2C_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2j_2B0EB2x_EB2h_EB2x_EB2x_EB2x_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2j_2B0EB2x_EB2x_EB2x_EB2x_EB2x_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1EB2c_EB2c_ENtB2e_2B0EB2C_EB2C_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1EB2c_ENtB2e_2B0EB2x_EB2x_EB2x_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2e_2B0EB2s_EB2s_EB2s_EB2s_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1EB27_ENtB29_2B0EB2s_EB2s_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB29_2B0EB2n_EB2n_EB2n_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB24_2B0EB2i_EB2i_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCNvXININtCskVr04X3DebC_13generic_array5impls0ppEINtB9_12GenericArrayppENtNtCsbQ8arDwx5Xq_4core7default7Default7default0B9_
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2j_2B0EB2x_EB2x_EB2x_EB2x_EB2h_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2j_2B0EB2x_EB2x_EB2x_EB2x_EB2x_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2e_2B0EB2s_EB2s_EB2s_EB2c_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CsjewTDwKBbyD_4k256
_RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2e_2B0EB2s_EB2s_EB2s_EB2s_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CsjewTDwKBbyD_4k256
Line
Count
Source
17
83.6k
        Self::generate(|_| T::default())
_RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2e_2B0EB2s_EB2s_EB2s_EB2s_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0CsaHRNXv1Y9Bq_4p256
Line
Count
Source
17
27.7k
        Self::generate(|_| T::default())
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2o_2B0EB2C_EB2C_EB2C_EB2C_EB2C_EB2C_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0Cs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNCNvXNtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2j_2B0EB2x_EB2x_EB2x_EB2x_EB2x_EENtNtCsbQ8arDwx5Xq_4core7default7Default7default0Cs23lnNM1woOA_4sha2
18
38.1k
    }
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2b_2B0EB2p_EB2p_EB2p_EB2p_EB2p_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB27_2B0EB2l_EB2l_EB2l_EB2l_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2b_2B0EB2p_EB2p_EB2p_EB2p_EB2p_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB27_2B0EB2l_EB2l_EB2l_EB2l_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs2IvCg5PL8uK_11chia_traits
_RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2b_2B0EB2p_EB2p_EB2p_EB2p_EB29_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs4RkbDk9WRL5_5clvmr
Line
Count
Source
16
2.45k
    fn default() -> Self {
17
2.45k
        Self::generate(|_| T::default())
18
2.45k
    }
_RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2b_2B0EB2p_EB2p_EB2p_EB2p_EB2p_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs4RkbDk9WRL5_5clvmr
Line
Count
Source
16
9.97k
    fn default() -> Self {
17
9.97k
        Self::generate(|_| T::default())
18
9.97k
    }
_RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB27_2B0EB2l_EB2l_EB2l_EB2l_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs4RkbDk9WRL5_5clvmr
Line
Count
Source
16
22.2k
    fn default() -> Self {
17
22.2k
        Self::generate(|_| T::default())
18
22.2k
    }
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB1Z_2B0EB2d_EB2d_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB23_2B0EB2h_EB2h_EB2h_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1EB21_ENtB23_2B0EB2m_EB2m_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB27_2B0EB2l_EB2l_EB2l_EB2l_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1EB25_ENtB27_2B0EB2q_EB2q_EB2q_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1EB25_EB25_ENtB27_2B0EB2v_EB2v_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2b_2B0EB2p_EB2p_EB2p_EB2p_EB2p_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2b_2B0EB2p_EB29_EB2p_EB2p_EB2p_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1EB29_ENtB2b_2B0EB2u_EB2u_EB2u_EB2u_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1EB29_ENtB2b_2B0EB29_EB2u_EB2u_EB2u_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1EB29_EB29_ENtB2b_2B0EB2z_EB2z_EB2z_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2f_2B0EB2t_EB2t_EB2t_EB2t_EB2t_EB2t_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1EB2d_ENtB2f_2B0EB2y_EB2y_EB2y_EB2y_EB2y_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1EB2d_EB2d_ENtB2f_2B0EB2D_EB2D_EB2D_EB2D_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2j_2B0EB2x_EB2x_EB2x_EB2x_EB2x_EB2x_EB2x_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1EB2h_ENtB2j_2B0EB2C_EB2C_EB2C_EB2C_EB2C_EB2C_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1EB2h_EB2h_ENtB2j_2B0EB2H_EB2H_EB2H_EB2H_EB2H_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2n_2B0EB2B_EB2B_EB2B_EB2B_EB2B_EB2B_EB2B_EB2B_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1EB2l_ENtB2n_2B0EB2G_EB2G_EB2G_EB2G_EB2G_EB2G_EB2G_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2r_2B0EB2F_EB2F_EB2F_EB2F_EB2F_EB2F_EB2F_EB2F_EB2F_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5impls0ppEINtB7_12GenericArrayppENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultB7_
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2b_2B0EB2p_EB2p_EB2p_EB2p_EB29_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2b_2B0EB2p_EB2p_EB2p_EB2p_EB2p_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCsjewTDwKBbyD_4k256
_RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB27_2B0EB2l_EB2l_EB2l_EB2l_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCsjewTDwKBbyD_4k256
Line
Count
Source
16
2.61k
    fn default() -> Self {
17
2.61k
        Self::generate(|_| T::default())
18
2.61k
    }
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB27_2B0EB2l_EB2l_EB2l_EB25_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCsjewTDwKBbyD_4k256
_RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB27_2B0EB2l_EB2l_EB2l_EB2l_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCsaHRNXv1Y9Bq_4p256
Line
Count
Source
16
866
    fn default() -> Self {
17
866
        Self::generate(|_| T::default())
18
866
    }
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2f_2B0EB2t_EB2t_EB2t_EB2t_EB2t_EB2t_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNvXNtCskVr04X3DebC_13generic_array5implsINtB4_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBZ_IBZ_IBZ_IBZ_IBZ_IBZ_NtB11_5UTermNtNtB13_3bit2B1ENtB2b_2B0EB2p_EB2p_EB2p_EB2p_EB2p_EENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs23lnNM1woOA_4sha2
19
}
20
21
impl<T: Clone, N> Clone for GenericArray<T, N>
22
where
23
    N: ArrayLength<T>,
24
{
25
0
    fn clone(&self) -> GenericArray<T, N> {
26
0
        self.map(Clone::clone)
27
0
    }
Unexecuted instantiation: _RNvXs_NtCskVr04X3DebC_13generic_array5implsINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2j_2B0EB2x_EB2x_EB2x_EB2x_EB2x_EENtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneCs4RkbDk9WRL5_5clvmr
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss_0ppEINtB7_12GenericArrayppENtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
28
}
29
30
impl<T: Copy, N> Copy for GenericArray<T, N>
31
where
32
    N: ArrayLength<T>,
33
    N::ArrayType: Copy,
34
{
35
}
36
37
impl<T: PartialEq, N> PartialEq for GenericArray<T, N>
38
where
39
    N: ArrayLength<T>,
40
{
41
0
    fn eq(&self, other: &Self) -> bool {
42
0
        **self == **other
43
0
    }
44
}
45
impl<T: Eq, N> Eq for GenericArray<T, N> where N: ArrayLength<T> {}
46
47
impl<T: PartialOrd, N> PartialOrd for GenericArray<T, N>
48
where
49
    N: ArrayLength<T>,
50
{
51
0
    fn partial_cmp(&self, other: &GenericArray<T, N>) -> Option<Ordering> {
52
0
        PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
53
0
    }
54
}
55
56
impl<T: Ord, N> Ord for GenericArray<T, N>
57
where
58
    N: ArrayLength<T>,
59
{
60
0
    fn cmp(&self, other: &GenericArray<T, N>) -> Ordering {
61
0
        Ord::cmp(self.as_slice(), other.as_slice())
62
0
    }
63
}
64
65
impl<T: Debug, N> Debug for GenericArray<T, N>
66
where
67
    N: ArrayLength<T>,
68
{
69
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
70
0
        self[..].fmt(fmt)
71
0
    }
72
}
73
74
impl<T, N> Borrow<[T]> for GenericArray<T, N>
75
where
76
    N: ArrayLength<T>,
77
{
78
    #[inline(always)]
79
0
    fn borrow(&self) -> &[T] {
80
0
        &self[..]
81
0
    }
82
}
83
84
impl<T, N> BorrowMut<[T]> for GenericArray<T, N>
85
where
86
    N: ArrayLength<T>,
87
{
88
    #[inline(always)]
89
0
    fn borrow_mut(&mut self) -> &mut [T] {
90
0
        &mut self[..]
91
0
    }
92
}
93
94
impl<T, N> AsRef<[T]> for GenericArray<T, N>
95
where
96
    N: ArrayLength<T>,
97
{
98
    #[inline(always)]
99
0
    fn as_ref(&self) -> &[T] {
100
0
        &self[..]
101
0
    }
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss8_0ppEINtB7_12GenericArrayppEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefSpE6as_refB7_
Unexecuted instantiation: _RNvXs8_NtCskVr04X3DebC_13generic_array5implsINtB7_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB12_IB12_IB12_IB12_IB12_NtB14_5UTermNtNtB16_3bit2B1ENtB2f_2B0EB2t_EB2t_EB2t_EB2d_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_refCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs8_NtCskVr04X3DebC_13generic_array5implsINtB7_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB12_IB12_IB12_IB12_IB12_NtB14_5UTermNtNtB16_3bit2B1ENtB2f_2B0EB2t_EB2t_EB2t_EB2t_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefShE6as_refCsjewTDwKBbyD_4k256
102
}
103
104
impl<T, N> AsMut<[T]> for GenericArray<T, N>
105
where
106
    N: ArrayLength<T>,
107
{
108
    #[inline(always)]
109
0
    fn as_mut(&mut self) -> &mut [T] {
110
0
        &mut self[..]
111
0
    }
112
}
113
114
impl<T: Hash, N> Hash for GenericArray<T, N>
115
where
116
    N: ArrayLength<T>,
117
{
118
0
    fn hash<H>(&self, state: &mut H)
119
0
    where
120
0
        H: Hasher,
121
0
    {
122
0
        Hash::hash(&self[..], state)
123
0
    }
124
}
125
126
macro_rules! impl_from {
127
    ($($n: expr => $ty: ty),*) => {
128
        $(
129
            impl<T> From<[T; $n]> for GenericArray<T, $ty> {
130
                #[inline(always)]
131
0
                fn from(arr: [T; $n]) -> Self {
132
0
                    unsafe { $crate::transmute(arr) }
133
0
                }
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssb_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntNtB1a_5UTermNtNtB1c_3bit2B1EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj1_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssh_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB21_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj2_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssn_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_NtB1a_5UTermNtNtB1c_3bit2B1EB1Z_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj3_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implsst_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB26_2B0EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj4_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssz_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB26_2B0EB24_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj5_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssF_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1EB24_ENtB26_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj6_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssL_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1EB24_EB24_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj7_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssR_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB2b_2B0EB2p_EB2p_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj8_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssX_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB2b_2B0EB2p_EB29_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj9_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss13_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2c_2B0EB2a_EB2q_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApja_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss19_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2c_2B0EB2a_EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApjb_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1f_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_ENtB2c_2B0EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApjc_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1l_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_ENtB2c_2B0EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApjd_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1r_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_EB2a_ENtB2c_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApje_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1x_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_EB2a_EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApjf_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1D_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2v_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj10_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1J_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2v_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj11_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1P_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2f_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj12_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1V_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj13_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss21_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2v_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj14_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss27_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2v_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj15_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2d_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2f_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj16_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2j_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj17_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2p_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj18_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2v_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2A_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj19_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2B_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2f_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj1a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2H_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj1b_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2N_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_ENtB2h_2B0EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj1c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2T_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_ENtB2h_2B0EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj1d_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2Z_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_EB2f_ENtB2h_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj1e_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss35_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj1f_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3b_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj20_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3h_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj21_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3n_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj22_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3t_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj23_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3z_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj24_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3F_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj25_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3L_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj26_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3R_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj27_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3X_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj28_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss43_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj29_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss49_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj2a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4f_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj2b_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4l_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj2c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4r_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj2d_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4x_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj2e_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4D_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj2f_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4J_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj30_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4P_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2F_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj31_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4V_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2k_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj32_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss51_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj33_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss57_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj34_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5d_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2F_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj35_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5j_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2k_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj36_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5p_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj37_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5v_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2K_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj38_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5B_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2K_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj39_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5H_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2k_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj3a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5N_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj3b_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5T_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_ENtB2m_2B0EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj3c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5Z_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_ENtB2m_2B0EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj3d_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss65_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_EB2k_ENtB2m_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj3e_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6b_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj3f_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6h_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2F_EB2F_EB2F_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj40_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6n_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2F_EB2F_EB2p_EB2p_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj46_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6t_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2p_EB2F_EB2F_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj50_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6z_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2p_EB2p_EB2F_EB2p_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj5a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6F_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2p_ENtB2r_2B0EB2K_EB2p_EB2K_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj64_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6L_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2u_ENtB2w_2B0EB2P_EB2u_EB2P_EB2P_EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApjc8_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6R_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2B_2B0EB2P_EB2z_EB2P_EB2z_EB2z_EB2P_EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj12c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6X_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2z_ENtB2B_2B0EB2U_EB2z_EB2U_EB2U_EB2U_EB2U_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj190_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss73_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2z_EB2z_EB2z_EB2z_ENtB2B_2B0EB2z_EB39_EB39_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj1f4_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss79_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2w_2B0EB2K_EB2K_EB2K_EB2K_EB2K_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj80_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7f_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2B_2B0EB2P_EB2P_EB2P_EB2P_EB2P_EB2P_EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj100_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7l_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2G_2B0EB2U_EB2U_EB2U_EB2U_EB2U_EB2U_EB2U_EB2U_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj200_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7r_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2E_EB2E_EB2E_EB2E_ENtB2G_2B0EB2E_EB3e_EB3e_EB3e_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj3e8_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7x_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2L_2B0EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromApj400_E4fromB7_
134
            }
135
136
            #[cfg(relaxed_coherence)]
137
            impl<T> From<GenericArray<T, $ty>> for [T; $n] {
138
                #[inline(always)]
139
9.60k
                fn from(sel: GenericArray<T, $ty>) -> [T; $n] {
140
9.60k
                    unsafe { $crate::transmute(sel) }
141
9.60k
                }
Unexecuted instantiation: _RNvXs3c_NtCskVr04X3DebC_13generic_array5implsAhj20_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1K_IB1K_IB1K_IB1K_IB1K_NtB1M_5UTermNtNtB1O_3bit2B1ENtB2X_2B0EB3b_EB3b_EB3b_EB3b_EEE4fromCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs3c_NtCskVr04X3DebC_13generic_array5implsAhj20_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1K_IB1K_IB1K_IB1K_IB1K_NtB1M_5UTermNtNtB1O_3bit2B1ENtB2X_2B0EB3b_EB3b_EB3b_EB3b_EEE4fromCs2IvCg5PL8uK_11chia_traits
_RNvXs3c_NtCskVr04X3DebC_13generic_array5implsAhj20_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1K_IB1K_IB1K_IB1K_IB1K_NtB1M_5UTermNtNtB1O_3bit2B1ENtB2X_2B0EB3b_EB3b_EB3b_EB3b_EEE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
139
9.60k
                fn from(sel: GenericArray<T, $ty>) -> [T; $n] {
140
9.60k
                    unsafe { $crate::transmute(sel) }
141
9.60k
                }
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssc_0pEApj1_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntNtB1Q_5UTermNtNtB1S_3bit2B1EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssi_0pEApj2_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1O_NtB1Q_5UTermNtNtB1S_3bit2B1ENtB2H_2B0EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implsso_0pEApj3_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1O_NtB1Q_5UTermNtNtB1S_3bit2B1EB2F_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssu_0pEApj4_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1O_IB1O_NtB1Q_5UTermNtNtB1S_3bit2B1ENtB2M_2B0EB30_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssA_0pEApj5_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1O_IB1O_NtB1Q_5UTermNtNtB1S_3bit2B1ENtB2M_2B0EB2K_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssG_0pEApj6_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1O_IB1O_NtB1Q_5UTermNtNtB1S_3bit2B1EB2K_ENtB2M_2B0EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssM_0pEApj7_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1O_IB1O_NtB1Q_5UTermNtNtB1S_3bit2B1EB2K_EB2K_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssS_0pEApj8_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1O_IB1O_IB1O_NtB1Q_5UTermNtNtB1S_3bit2B1ENtB2R_2B0EB35_EB35_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssY_0pEApj9_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1O_IB1O_IB1O_NtB1Q_5UTermNtNtB1S_3bit2B1ENtB2R_2B0EB35_EB2P_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss14_0pEApja_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1P_IB1P_IB1P_NtB1R_5UTermNtNtB1T_3bit2B1ENtB2S_2B0EB2Q_EB36_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1a_0pEApjb_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1P_IB1P_IB1P_NtB1R_5UTermNtNtB1T_3bit2B1ENtB2S_2B0EB2Q_EB2Q_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1g_0pEApjc_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1P_IB1P_IB1P_NtB1R_5UTermNtNtB1T_3bit2B1EB2Q_ENtB2S_2B0EB3b_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1m_0pEApjd_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1P_IB1P_IB1P_NtB1R_5UTermNtNtB1T_3bit2B1EB2Q_ENtB2S_2B0EB2Q_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1s_0pEApje_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1P_IB1P_IB1P_NtB1R_5UTermNtNtB1T_3bit2B1EB2Q_EB2Q_ENtB2S_2B0EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1y_0pEApjf_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1P_IB1P_IB1P_NtB1R_5UTermNtNtB1T_3bit2B1EB2Q_EB2Q_EB2Q_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1E_0pEApj10_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB2Y_2B0EB3c_EB3c_EB3c_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1K_0pEApj11_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB2Y_2B0EB3c_EB3c_EB2W_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1Q_0pEApj12_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB2Y_2B0EB3c_EB2W_EB3c_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1W_0pEApj13_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB2Y_2B0EB3c_EB2W_EB2W_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss22_0pEApj14_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB2Y_2B0EB2W_EB3c_EB3c_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss28_0pEApj15_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB2Y_2B0EB2W_EB3c_EB2W_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2e_0pEApj16_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB2Y_2B0EB2W_EB2W_EB3c_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2k_0pEApj17_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB2Y_2B0EB2W_EB2W_EB2W_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2q_0pEApj18_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB2W_ENtB2Y_2B0EB3h_EB3h_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2w_0pEApj19_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB2W_ENtB2Y_2B0EB3h_EB2W_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2C_0pEApj1a_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB2W_ENtB2Y_2B0EB2W_EB3h_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2I_0pEApj1b_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB2W_ENtB2Y_2B0EB2W_EB2W_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2O_0pEApj1c_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB2W_EB2W_ENtB2Y_2B0EB3m_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2U_0pEApj1d_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB2W_EB2W_ENtB2Y_2B0EB2W_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss30_0pEApj1e_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB2W_EB2W_EB2W_ENtB2Y_2B0EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss36_0pEApj1f_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB2W_EB2W_EB2W_EB2W_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3c_0pEApj20_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB3h_EB3h_EB3h_EB3h_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3i_0pEApj21_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB3h_EB3h_EB3h_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3o_0pEApj22_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB3h_EB3h_EB31_EB3h_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3u_0pEApj23_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB3h_EB3h_EB31_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3A_0pEApj24_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB3h_EB31_EB3h_EB3h_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3G_0pEApj25_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB3h_EB31_EB3h_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3M_0pEApj26_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB3h_EB31_EB31_EB3h_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3S_0pEApj27_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB3h_EB31_EB31_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3Y_0pEApj28_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB31_EB3h_EB3h_EB3h_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss44_0pEApj29_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB31_EB3h_EB3h_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4a_0pEApj2a_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB31_EB3h_EB31_EB3h_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4g_0pEApj2b_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB31_EB3h_EB31_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4m_0pEApj2c_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB31_EB31_EB3h_EB3h_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4s_0pEApj2d_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB31_EB31_EB3h_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4y_0pEApj2e_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB31_EB31_EB31_EB3h_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4E_0pEApj2f_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB33_2B0EB31_EB31_EB31_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4K_0pEApj30_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_ENtB33_2B0EB3m_EB3m_EB3m_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4Q_0pEApj31_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_ENtB33_2B0EB3m_EB3m_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4W_0pEApj32_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_ENtB33_2B0EB3m_EB31_EB3m_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss52_0pEApj33_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_ENtB33_2B0EB3m_EB31_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss58_0pEApj34_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_ENtB33_2B0EB31_EB3m_EB3m_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5e_0pEApj35_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_ENtB33_2B0EB31_EB3m_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5k_0pEApj36_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_ENtB33_2B0EB31_EB31_EB3m_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5q_0pEApj37_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_ENtB33_2B0EB31_EB31_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5w_0pEApj38_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_EB31_ENtB33_2B0EB3r_EB3r_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5C_0pEApj39_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_EB31_ENtB33_2B0EB3r_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5I_0pEApj3a_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_EB31_ENtB33_2B0EB31_EB3r_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5O_0pEApj3b_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_EB31_ENtB33_2B0EB31_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5U_0pEApj3c_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_EB31_EB31_ENtB33_2B0EB3w_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss60_0pEApj3d_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_EB31_EB31_ENtB33_2B0EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss66_0pEApj3e_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_EB31_EB31_EB31_ENtB33_2B0EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6c_0pEApj3f_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB31_EB31_EB31_EB31_EB31_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6i_0pEApj40_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB38_2B0EB3m_EB3m_EB3m_EB3m_EB3m_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6o_0pEApj46_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB38_2B0EB3m_EB3m_EB36_EB36_EB3m_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6u_0pEApj50_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB38_2B0EB36_EB3m_EB3m_EB3m_EB3m_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6A_0pEApj5a_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB38_2B0EB36_EB36_EB3m_EB36_EB3m_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6G_0pEApj64_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB36_ENtB38_2B0EB3r_EB36_EB3r_EB3r_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6M_0pEApjc8_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1EB3b_ENtB3d_2B0EB3w_EB3b_EB3w_EB3w_EB3w_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6S_0pEApj12c_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_NtB1T_5UTermNtNtB1V_3bit2B1ENtB3j_2B0EB3x_EB3h_EB3x_EB3h_EB3h_EB3x_EB3x_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6Y_0pEApj190_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_NtB1T_5UTermNtNtB1V_3bit2B1EB3h_ENtB3j_2B0EB3C_EB3h_EB3C_EB3C_EB3C_EB3C_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss74_0pEApj1f4_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_NtB1T_5UTermNtNtB1V_3bit2B1EB3h_EB3h_EB3h_EB3h_ENtB3j_2B0EB3h_EB3R_EB3R_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7a_0pEApj80_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1Q_IB1Q_IB1Q_IB1Q_IB1Q_IB1Q_IB1Q_NtB1S_5UTermNtNtB1U_3bit2B1ENtB3d_2B0EB3r_EB3r_EB3r_EB3r_EB3r_EB3r_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7g_0pEApj100_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_NtB1T_5UTermNtNtB1V_3bit2B1ENtB3j_2B0EB3x_EB3x_EB3x_EB3x_EB3x_EB3x_EB3x_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7m_0pEApj200_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_NtB1T_5UTermNtNtB1V_3bit2B1ENtB3o_2B0EB3C_EB3C_EB3C_EB3C_EB3C_EB3C_EB3C_EB3C_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7s_0pEApj3e8_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_NtB1T_5UTermNtNtB1V_3bit2B1EB3m_EB3m_EB3m_EB3m_ENtB3o_2B0EB3m_EB3W_EB3W_EB3W_EEE4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7y_0pEApj400_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_IB1R_NtB1T_5UTermNtNtB1V_3bit2B1ENtB3t_2B0EB3H_EB3H_EB3H_EB3H_EB3H_EB3H_EB3H_EB3H_EB3H_EEE4fromB7_
Unexecuted instantiation: _RNvXs3c_NtCskVr04X3DebC_13generic_array5implsAhj20_INtNtCsbQ8arDwx5Xq_4core7convert4FromINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1K_IB1K_IB1K_IB1K_IB1K_NtB1M_5UTermNtNtB1O_3bit2B1ENtB2X_2B0EB3b_EB3b_EB3b_EB3b_EEE4fromCsjewTDwKBbyD_4k256
142
            }
143
144
            impl<'a, T> From<&'a [T; $n]> for &'a GenericArray<T, $ty> {
145
                #[inline]
146
0
                fn from(slice: &[T; $n]) -> &GenericArray<T, $ty> {
147
0
                    unsafe { &*(slice.as_ptr() as *const GenericArray<T, $ty>) }
148
0
                }
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssd_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntNtB1b_5UTermNtNtB1d_3bit2B1EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj1_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssj_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB22_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj2_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssp_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_NtB1b_5UTermNtNtB1d_3bit2B1EB20_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj3_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssv_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB27_2B0EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj4_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssB_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB27_2B0EB25_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj5_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssH_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB25_ENtB27_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj6_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssN_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB25_EB25_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj7_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssT_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2c_2B0EB2q_EB2q_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj8_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssZ_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2c_2B0EB2q_EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj9_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss15_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2d_2B0EB2b_EB2r_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApja_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1b_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2d_2B0EB2b_EB2b_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApjb_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1h_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2b_ENtB2d_2B0EB2w_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApjc_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1n_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2b_ENtB2d_2B0EB2b_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApjd_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1t_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2b_EB2b_ENtB2d_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApje_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1z_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2b_EB2b_EB2b_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApjf_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1F_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2w_EB2w_EB2w_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj10_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1L_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2w_EB2w_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj11_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1R_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2w_EB2g_EB2w_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj12_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1X_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2w_EB2g_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj13_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss23_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2g_EB2w_EB2w_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj14_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss29_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2g_EB2w_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj15_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2f_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2g_EB2g_EB2w_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj16_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2l_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2g_EB2g_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj17_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2r_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_ENtB2i_2B0EB2B_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj18_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2x_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_ENtB2i_2B0EB2B_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj19_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2D_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_ENtB2i_2B0EB2g_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj1a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2J_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_ENtB2i_2B0EB2g_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj1b_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2P_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_EB2g_ENtB2i_2B0EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj1c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2V_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_EB2g_ENtB2i_2B0EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj1d_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss31_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_EB2g_EB2g_ENtB2i_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj1e_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss37_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_EB2g_EB2g_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj1f_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3d_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2B_EB2B_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj20_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3j_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2B_EB2B_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj21_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3p_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2B_EB2l_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj22_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3v_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2B_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj23_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3B_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2l_EB2B_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj24_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3H_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2l_EB2B_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj25_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3N_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2l_EB2l_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj26_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3T_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2l_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj27_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3Z_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2B_EB2B_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj28_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss45_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2B_EB2B_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj29_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4b_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2B_EB2l_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj2a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4h_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2B_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj2b_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4n_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2l_EB2B_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj2c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4t_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2l_EB2B_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj2d_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4z_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2l_EB2l_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj2e_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4F_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2l_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj2f_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4L_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2G_EB2G_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj30_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4R_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2G_EB2G_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj31_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4X_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2G_EB2l_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj32_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss53_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2G_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj33_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss59_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2l_EB2G_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj34_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5f_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2l_EB2G_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj35_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5l_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2l_EB2l_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj36_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5r_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2l_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj37_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5x_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_ENtB2n_2B0EB2L_EB2L_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj38_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5D_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_ENtB2n_2B0EB2L_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj39_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5J_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_ENtB2n_2B0EB2l_EB2L_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj3a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5P_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_ENtB2n_2B0EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj3b_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5V_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_EB2l_ENtB2n_2B0EB2Q_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj3c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss61_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_EB2l_ENtB2n_2B0EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj3d_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss67_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_EB2l_EB2l_ENtB2n_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj3e_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6d_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_EB2l_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj3f_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6j_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2s_2B0EB2G_EB2G_EB2G_EB2G_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj40_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6p_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2s_2B0EB2G_EB2G_EB2q_EB2q_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj46_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6v_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2s_2B0EB2q_EB2G_EB2G_EB2G_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj50_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6B_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2s_2B0EB2q_EB2q_EB2G_EB2q_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj5a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6H_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2q_ENtB2s_2B0EB2L_EB2q_EB2L_EB2L_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj64_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6N_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2v_ENtB2x_2B0EB2Q_EB2v_EB2Q_EB2Q_EB2Q_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApjc8_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6T_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2C_2B0EB2Q_EB2A_EB2Q_EB2A_EB2A_EB2Q_EB2Q_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj12c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6Z_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2A_ENtB2C_2B0EB2V_EB2A_EB2V_EB2V_EB2V_EB2V_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj190_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss75_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2A_EB2A_EB2A_EB2A_ENtB2C_2B0EB2A_EB3a_EB3a_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj1f4_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7b_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2x_2B0EB2L_EB2L_EB2L_EB2L_EB2L_EB2L_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj80_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7h_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2C_2B0EB2Q_EB2Q_EB2Q_EB2Q_EB2Q_EB2Q_EB2Q_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj100_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7n_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2H_2B0EB2V_EB2V_EB2V_EB2V_EB2V_EB2V_EB2V_EB2V_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj200_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7t_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2F_EB2F_EB2F_EB2F_ENtB2H_2B0EB2F_EB3f_EB3f_EB3f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj3e8_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7z_0pERINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2M_2B0EB30_EB30_EB30_EB30_EB30_EB30_EB30_EB30_EB30_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRApj400_E4fromB7_
149
            }
150
151
            impl<'a, T> From<&'a mut [T; $n]> for &'a mut GenericArray<T, $ty> {
152
                #[inline]
153
0
                fn from(slice: &mut [T; $n]) -> &mut GenericArray<T, $ty> {
154
0
                    unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray<T, $ty>) }
155
0
                }
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implsse_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntNtB1b_5UTermNtNtB1d_3bit2B1EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj1_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssk_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB22_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj2_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssq_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_NtB1b_5UTermNtNtB1d_3bit2B1EB20_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj3_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssw_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB27_2B0EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj4_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssC_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB27_2B0EB25_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj5_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssI_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB25_ENtB27_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj6_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssO_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB25_EB25_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj7_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssU_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2c_2B0EB2q_EB2q_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj8_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss10_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2d_2B0EB2r_EB2b_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj9_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss16_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2d_2B0EB2b_EB2r_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApja_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1c_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2d_2B0EB2b_EB2b_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApjb_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1i_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2b_ENtB2d_2B0EB2w_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApjc_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1o_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2b_ENtB2d_2B0EB2b_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApjd_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1u_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2b_EB2b_ENtB2d_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApje_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1A_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2b_EB2b_EB2b_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApjf_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1G_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2w_EB2w_EB2w_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj10_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1M_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2w_EB2w_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj11_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1S_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2w_EB2g_EB2w_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj12_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1Y_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2w_EB2g_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj13_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss24_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2g_EB2w_EB2w_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj14_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2a_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2g_EB2w_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj15_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2g_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2g_EB2g_EB2w_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj16_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2m_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2i_2B0EB2g_EB2g_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj17_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2s_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_ENtB2i_2B0EB2B_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj18_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2y_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_ENtB2i_2B0EB2B_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj19_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2E_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_ENtB2i_2B0EB2g_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj1a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2K_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_ENtB2i_2B0EB2g_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj1b_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2Q_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_EB2g_ENtB2i_2B0EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj1c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2W_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_EB2g_ENtB2i_2B0EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj1d_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss32_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_EB2g_EB2g_ENtB2i_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj1e_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss38_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2g_EB2g_EB2g_EB2g_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj1f_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3e_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2B_EB2B_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj20_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3k_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2B_EB2B_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj21_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3q_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2B_EB2l_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj22_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3w_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2B_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj23_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3C_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2l_EB2B_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj24_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3I_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2l_EB2B_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj25_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3O_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2l_EB2l_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj26_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3U_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2B_EB2l_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj27_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss40_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2B_EB2B_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj28_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss46_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2B_EB2B_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj29_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4c_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2B_EB2l_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj2a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4i_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2B_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj2b_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4o_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2l_EB2B_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj2c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4u_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2l_EB2B_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj2d_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4A_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2l_EB2l_EB2B_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj2e_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4G_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2n_2B0EB2l_EB2l_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj2f_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4M_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2G_EB2G_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj30_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4S_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2G_EB2G_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj31_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4Y_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2G_EB2l_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj32_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss54_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2G_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj33_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5a_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2l_EB2G_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj34_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5g_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2l_EB2G_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj35_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5m_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2l_EB2l_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj36_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5s_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_ENtB2n_2B0EB2l_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj37_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5y_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_ENtB2n_2B0EB2L_EB2L_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj38_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5E_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_ENtB2n_2B0EB2L_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj39_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5K_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_ENtB2n_2B0EB2l_EB2L_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj3a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5Q_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_ENtB2n_2B0EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj3b_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5W_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_EB2l_ENtB2n_2B0EB2Q_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj3c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss62_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_EB2l_ENtB2n_2B0EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj3d_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss68_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_EB2l_EB2l_ENtB2n_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj3e_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6e_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2l_EB2l_EB2l_EB2l_EB2l_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj3f_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6k_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2s_2B0EB2G_EB2G_EB2G_EB2G_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj40_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6q_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2s_2B0EB2G_EB2G_EB2q_EB2q_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj46_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6w_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2s_2B0EB2q_EB2G_EB2G_EB2G_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj50_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6C_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2s_2B0EB2q_EB2q_EB2G_EB2q_EB2G_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj5a_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6I_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2q_ENtB2s_2B0EB2L_EB2q_EB2L_EB2L_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj64_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6O_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2v_ENtB2x_2B0EB2Q_EB2v_EB2Q_EB2Q_EB2Q_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApjc8_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6U_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2C_2B0EB2Q_EB2A_EB2Q_EB2A_EB2A_EB2Q_EB2Q_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj12c_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss70_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2A_ENtB2C_2B0EB2V_EB2A_EB2V_EB2V_EB2V_EB2V_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj190_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss76_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2A_EB2A_EB2A_EB2A_ENtB2C_2B0EB2A_EB3a_EB3a_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj1f4_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7c_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2x_2B0EB2L_EB2L_EB2L_EB2L_EB2L_EB2L_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj80_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7i_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2C_2B0EB2Q_EB2Q_EB2Q_EB2Q_EB2Q_EB2Q_EB2Q_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj100_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7o_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2H_2B0EB2V_EB2V_EB2V_EB2V_EB2V_EB2V_EB2V_EB2V_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj200_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7u_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1EB2F_EB2F_EB2F_EB2F_ENtB2H_2B0EB2F_EB3f_EB3f_EB3f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj3e8_E4fromB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7A_0pEQINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_IB1a_NtB1c_5UTermNtNtB1e_3bit2B1ENtB2M_2B0EB30_EB30_EB30_EB30_EB30_EB30_EB30_EB30_EB30_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromQApj400_E4fromB7_
156
            }
157
158
            #[cfg(not(relaxed_coherence))]
159
            impl<T> Into<[T; $n]> for GenericArray<T, $ty> {
160
                #[inline(always)]
161
                fn into(self) -> [T; $n] {
162
                    unsafe { $crate::transmute(self) }
163
                }
164
            }
165
166
            impl<T> AsRef<[T; $n]> for GenericArray<T, $ty> {
167
                #[inline]
168
1.79k
                fn as_ref(&self) -> &[T; $n] {
169
1.79k
                    unsafe { $crate::transmute(self) }
170
1.79k
                }
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssf_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntNtB1a_5UTermNtNtB1c_3bit2B1EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj1_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssl_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB21_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj2_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssr_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_NtB1a_5UTermNtNtB1c_3bit2B1EB1Z_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj3_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssx_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB26_2B0EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj4_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssD_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB26_2B0EB24_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj5_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssJ_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1EB24_ENtB26_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj6_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssP_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1EB24_EB24_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj7_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssV_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB2b_2B0EB2p_EB2p_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj8_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss11_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2c_2B0EB2q_EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj9_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss17_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2c_2B0EB2a_EB2q_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApja_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1d_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2c_2B0EB2a_EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApjb_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1j_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_ENtB2c_2B0EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApjc_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1p_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_ENtB2c_2B0EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApjd_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1v_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_EB2a_ENtB2c_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApje_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1B_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_EB2a_EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApjf_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1H_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2v_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj10_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1N_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2v_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj11_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1T_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2f_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj12_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1Z_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj13_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss25_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2v_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj14_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2b_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2v_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj15_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2h_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2f_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj16_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2n_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj17_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2t_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj18_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2z_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2A_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj19_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2F_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2f_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj1a_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2L_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj1b_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2R_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_ENtB2h_2B0EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj1c_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2X_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_ENtB2h_2B0EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj1d_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss33_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_EB2f_ENtB2h_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj1e_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss39_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj1f_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3f_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj20_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3l_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj21_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3r_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj22_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3x_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj23_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3D_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj24_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3J_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj25_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3P_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj26_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3V_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj27_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss41_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj28_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss47_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj29_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4d_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj2a_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4j_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj2b_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4p_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj2c_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4v_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj2d_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4B_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj2e_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4H_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj2f_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4N_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj30_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4T_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2F_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj31_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4Z_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2k_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj32_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss55_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj33_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5b_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj34_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5h_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2F_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj35_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5n_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2k_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj36_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5t_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj37_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5z_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2K_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj38_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5F_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2K_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj39_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5L_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2k_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj3a_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5R_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj3b_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5X_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_ENtB2m_2B0EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj3c_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss63_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_ENtB2m_2B0EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj3d_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss69_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_EB2k_ENtB2m_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj3e_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6f_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj3f_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6l_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2F_EB2F_EB2F_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj40_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6r_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2F_EB2F_EB2p_EB2p_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj46_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6x_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2p_EB2F_EB2F_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj50_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6D_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2p_EB2p_EB2F_EB2p_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj5a_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6J_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2p_ENtB2r_2B0EB2K_EB2p_EB2K_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj64_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6P_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2u_ENtB2w_2B0EB2P_EB2u_EB2P_EB2P_EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApjc8_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6V_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2B_2B0EB2P_EB2z_EB2P_EB2z_EB2z_EB2P_EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj12c_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss71_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2z_ENtB2B_2B0EB2U_EB2z_EB2U_EB2U_EB2U_EB2U_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj190_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss77_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2z_EB2z_EB2z_EB2z_ENtB2B_2B0EB2z_EB39_EB39_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj1f4_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7d_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2w_2B0EB2K_EB2K_EB2K_EB2K_EB2K_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj80_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7j_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2B_2B0EB2P_EB2P_EB2P_EB2P_EB2P_EB2P_EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj100_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7p_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2G_2B0EB2U_EB2U_EB2U_EB2U_EB2U_EB2U_EB2U_EB2U_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj200_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7v_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2E_EB2E_EB2E_EB2E_ENtB2G_2B0EB2E_EB3e_EB3e_EB3e_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj3e8_E6as_refB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7B_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2L_2B0EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefApj400_E6as_refB7_
_RNvXs3f_NtCskVr04X3DebC_13generic_array5implsINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB13_IB13_IB13_IB13_IB13_NtB15_5UTermNtNtB17_3bit2B1ENtB2g_2B0EB2u_EB2u_EB2u_EB2u_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsRefAhj20_E6as_refCsjewTDwKBbyD_4k256
Line
Count
Source
168
1.79k
                fn as_ref(&self) -> &[T; $n] {
169
1.79k
                    unsafe { $crate::transmute(self) }
170
1.79k
                }
171
            }
172
173
            impl<T> AsMut<[T; $n]> for GenericArray<T, $ty> {
174
                #[inline]
175
0
                fn as_mut(&mut self) -> &mut [T; $n] {
176
0
                    unsafe { $crate::transmute(self) }
177
0
                }
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssg_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntNtB1a_5UTermNtNtB1c_3bit2B1EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj1_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssm_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB21_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj2_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implsss_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_NtB1a_5UTermNtNtB1c_3bit2B1EB1Z_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj3_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssy_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB26_2B0EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj4_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssE_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB26_2B0EB24_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj5_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssK_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1EB24_ENtB26_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj6_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssQ_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1EB24_EB24_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj7_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implssW_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB18_IB18_IB18_NtB1a_5UTermNtNtB1c_3bit2B1ENtB2b_2B0EB2p_EB2p_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj8_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss12_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2c_2B0EB2q_EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj9_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss18_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2c_2B0EB2a_EB2q_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApja_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1e_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2c_2B0EB2a_EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApjb_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1k_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_ENtB2c_2B0EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApjc_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1q_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_ENtB2c_2B0EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApjd_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1w_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_EB2a_ENtB2c_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApje_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1C_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2a_EB2a_EB2a_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApjf_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1I_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2v_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj10_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1O_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2v_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj11_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss1U_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2f_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj12_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss20_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2v_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj13_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss26_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2v_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj14_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2c_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2v_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj15_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2i_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2f_EB2v_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj16_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2o_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2h_2B0EB2f_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj17_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2u_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj18_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2A_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2A_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj19_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2G_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2f_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj1a_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2M_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_ENtB2h_2B0EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj1b_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2S_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_ENtB2h_2B0EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj1c_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss2Y_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_ENtB2h_2B0EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj1d_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss34_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_EB2f_ENtB2h_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj1e_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3a_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2f_EB2f_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj1f_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3g_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj20_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3m_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj21_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3s_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj22_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3y_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2A_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj23_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3E_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj24_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3K_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj25_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3Q_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj26_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss3W_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2A_EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj27_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss42_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj28_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss48_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj29_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4e_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj2a_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4k_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2A_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj2b_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4q_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2A_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj2c_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4w_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2A_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj2d_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4C_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2k_EB2A_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj2e_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4I_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2m_2B0EB2k_EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj2f_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4O_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj30_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss4U_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2F_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj31_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss50_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2k_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj32_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss56_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2F_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj33_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5c_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj34_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5i_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2F_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj35_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5o_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2k_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj36_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5u_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_ENtB2m_2B0EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj37_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5A_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2K_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj38_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5G_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2K_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj39_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5M_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2k_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj3a_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5S_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_ENtB2m_2B0EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj3b_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss5Y_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_ENtB2m_2B0EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj3c_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss64_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_ENtB2m_2B0EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj3d_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6a_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_EB2k_ENtB2m_2B0EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj3e_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6g_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2k_EB2k_EB2k_EB2k_EB2k_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj3f_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6m_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2F_EB2F_EB2F_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj40_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6s_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2F_EB2F_EB2p_EB2p_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj46_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6y_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2p_EB2F_EB2F_EB2F_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj50_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6E_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2r_2B0EB2p_EB2p_EB2F_EB2p_EB2F_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj5a_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6K_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2p_ENtB2r_2B0EB2K_EB2p_EB2K_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj64_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6Q_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2u_ENtB2w_2B0EB2P_EB2u_EB2P_EB2P_EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApjc8_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss6W_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2B_2B0EB2P_EB2z_EB2P_EB2z_EB2z_EB2P_EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj12c_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss72_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2z_ENtB2B_2B0EB2U_EB2z_EB2U_EB2U_EB2U_EB2U_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj190_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss78_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2z_EB2z_EB2z_EB2z_ENtB2B_2B0EB2z_EB39_EB39_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj1f4_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7e_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2w_2B0EB2K_EB2K_EB2K_EB2K_EB2K_EB2K_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj80_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7k_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2B_2B0EB2P_EB2P_EB2P_EB2P_EB2P_EB2P_EB2P_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj100_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7q_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2G_2B0EB2U_EB2U_EB2U_EB2U_EB2U_EB2U_EB2U_EB2U_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj200_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7w_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1EB2E_EB2E_EB2E_EB2E_ENtB2G_2B0EB2E_EB3e_EB3e_EB3e_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj3e8_E6as_mutB7_
Unexecuted instantiation: _RNvXININtCskVr04X3DebC_13generic_array5implss7C_0pEINtB7_12GenericArraypINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_IB19_NtB1b_5UTermNtNtB1d_3bit2B1ENtB2L_2B0EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EB2Z_EEINtNtCsbQ8arDwx5Xq_4core7convert5AsMutApj400_E6as_mutB7_
178
            }
179
        )*
180
    }
181
}
182
183
impl_from! {
184
    1  => ::typenum::U1,
185
    2  => ::typenum::U2,
186
    3  => ::typenum::U3,
187
    4  => ::typenum::U4,
188
    5  => ::typenum::U5,
189
    6  => ::typenum::U6,
190
    7  => ::typenum::U7,
191
    8  => ::typenum::U8,
192
    9  => ::typenum::U9,
193
    10 => ::typenum::U10,
194
    11 => ::typenum::U11,
195
    12 => ::typenum::U12,
196
    13 => ::typenum::U13,
197
    14 => ::typenum::U14,
198
    15 => ::typenum::U15,
199
    16 => ::typenum::U16,
200
    17 => ::typenum::U17,
201
    18 => ::typenum::U18,
202
    19 => ::typenum::U19,
203
    20 => ::typenum::U20,
204
    21 => ::typenum::U21,
205
    22 => ::typenum::U22,
206
    23 => ::typenum::U23,
207
    24 => ::typenum::U24,
208
    25 => ::typenum::U25,
209
    26 => ::typenum::U26,
210
    27 => ::typenum::U27,
211
    28 => ::typenum::U28,
212
    29 => ::typenum::U29,
213
    30 => ::typenum::U30,
214
    31 => ::typenum::U31,
215
    32 => ::typenum::U32
216
}
217
218
#[cfg(feature = "more_lengths")]
219
impl_from! {
220
    33 => ::typenum::U33,
221
    34 => ::typenum::U34,
222
    35 => ::typenum::U35,
223
    36 => ::typenum::U36,
224
    37 => ::typenum::U37,
225
    38 => ::typenum::U38,
226
    39 => ::typenum::U39,
227
    40 => ::typenum::U40,
228
    41 => ::typenum::U41,
229
    42 => ::typenum::U42,
230
    43 => ::typenum::U43,
231
    44 => ::typenum::U44,
232
    45 => ::typenum::U45,
233
    46 => ::typenum::U46,
234
    47 => ::typenum::U47,
235
    48 => ::typenum::U48,
236
    49 => ::typenum::U49,
237
    50 => ::typenum::U50,
238
    51 => ::typenum::U51,
239
    52 => ::typenum::U52,
240
    53 => ::typenum::U53,
241
    54 => ::typenum::U54,
242
    55 => ::typenum::U55,
243
    56 => ::typenum::U56,
244
    57 => ::typenum::U57,
245
    58 => ::typenum::U58,
246
    59 => ::typenum::U59,
247
    60 => ::typenum::U60,
248
    61 => ::typenum::U61,
249
    62 => ::typenum::U62,
250
    63 => ::typenum::U63,
251
    64 => ::typenum::U64,
252
253
    70 => ::typenum::U70,
254
    80 => ::typenum::U80,
255
    90 => ::typenum::U90,
256
257
    100 => ::typenum::U100,
258
    200 => ::typenum::U200,
259
    300 => ::typenum::U300,
260
    400 => ::typenum::U400,
261
    500 => ::typenum::U500,
262
263
    128 => ::typenum::U128,
264
    256 => ::typenum::U256,
265
    512 => ::typenum::U512,
266
267
    1000 => ::typenum::U1000,
268
    1024 => ::typenum::U1024
269
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/generic-array-0.14.7/src/iter.rs
Line
Count
Source
1
//! `GenericArray` iterator implementation.
2
3
use super::{ArrayLength, GenericArray};
4
use core::iter::FusedIterator;
5
use core::mem::ManuallyDrop;
6
use core::{cmp, fmt, mem, ptr};
7
8
/// An iterator that moves out of a `GenericArray`
9
pub struct GenericArrayIter<T, N: ArrayLength<T>> {
10
    // Invariants: index <= index_back <= N
11
    // Only values in array[index..index_back] are alive at any given time.
12
    // Values from array[..index] and array[index_back..] are already moved/dropped.
13
    array: ManuallyDrop<GenericArray<T, N>>,
14
    index: usize,
15
    index_back: usize,
16
}
17
18
#[cfg(test)]
19
mod test {
20
    use super::*;
21
22
    fn send<I: Send>(_iter: I) {}
23
24
    #[test]
25
    fn test_send_iter() {
26
        send(GenericArray::from([1, 2, 3, 4]).into_iter());
27
    }
28
}
29
30
impl<T, N> GenericArrayIter<T, N>
31
where
32
    N: ArrayLength<T>,
33
{
34
    /// Returns the remaining items of this iterator as a slice
35
    #[inline]
36
0
    pub fn as_slice(&self) -> &[T] {
37
0
        &self.array.as_slice()[self.index..self.index_back]
38
0
    }
39
40
    /// Returns the remaining items of this iterator as a mutable slice
41
    #[inline]
42
0
    pub fn as_mut_slice(&mut self) -> &mut [T] {
43
0
        &mut self.array.as_mut_slice()[self.index..self.index_back]
44
0
    }
45
}
46
47
impl<T, N> IntoIterator for GenericArray<T, N>
48
where
49
    N: ArrayLength<T>,
50
{
51
    type Item = T;
52
    type IntoIter = GenericArrayIter<T, N>;
53
54
0
    fn into_iter(self) -> Self::IntoIter {
55
0
        GenericArrayIter {
56
0
            array: ManuallyDrop::new(self),
57
0
            index: 0,
58
0
            index_back: N::USIZE,
59
0
        }
60
0
    }
61
}
62
63
// Based on work in rust-lang/rust#49000
64
impl<T: fmt::Debug, N> fmt::Debug for GenericArrayIter<T, N>
65
where
66
    N: ArrayLength<T>,
67
{
68
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69
0
        f.debug_tuple("GenericArrayIter")
70
0
            .field(&self.as_slice())
71
0
            .finish()
72
0
    }
73
}
74
75
impl<T, N> Drop for GenericArrayIter<T, N>
76
where
77
    N: ArrayLength<T>,
78
{
79
    #[inline]
80
0
    fn drop(&mut self) {
81
0
        if mem::needs_drop::<T>() {
82
            // Drop values that are still alive.
83
0
            for p in self.as_mut_slice() {
84
0
                unsafe {
85
0
                    ptr::drop_in_place(p);
86
0
                }
87
            }
88
0
        }
89
0
    }
90
}
91
92
// Based on work in rust-lang/rust#49000
93
impl<T: Clone, N> Clone for GenericArrayIter<T, N>
94
where
95
    N: ArrayLength<T>,
96
{
97
0
    fn clone(&self) -> Self {
98
0
        // This places all cloned elements at the start of the new array iterator,
99
0
        // not at their original indices.
100
0
101
0
        let mut array = unsafe { ptr::read(&self.array) };
102
0
        let mut index_back = 0;
103
104
0
        for (dst, src) in array.as_mut_slice().into_iter().zip(self.as_slice()) {
105
0
            unsafe { ptr::write(dst, src.clone()) };
106
0
            index_back += 1;
107
0
        }
108
109
0
        GenericArrayIter {
110
0
            array,
111
0
            index: 0,
112
0
            index_back,
113
0
        }
114
0
    }
115
}
116
117
impl<T, N> Iterator for GenericArrayIter<T, N>
118
where
119
    N: ArrayLength<T>,
120
{
121
    type Item = T;
122
123
    #[inline]
124
0
    fn next(&mut self) -> Option<T> {
125
0
        if self.index < self.index_back {
126
0
            let p = unsafe { Some(ptr::read(self.array.get_unchecked(self.index))) };
127
0
128
0
            self.index += 1;
129
0
130
0
            p
131
        } else {
132
0
            None
133
        }
134
0
    }
135
136
0
    fn fold<B, F>(mut self, init: B, mut f: F) -> B
137
0
    where
138
0
        F: FnMut(B, Self::Item) -> B,
139
0
    {
140
0
        let ret = unsafe {
141
0
            let GenericArrayIter {
142
0
                ref array,
143
0
                ref mut index,
144
0
                index_back,
145
0
            } = self;
146
0
147
0
            let remaining = &array[*index..index_back];
148
0
149
0
            remaining.iter().fold(init, |acc, src| {
150
0
                let value = ptr::read(src);
151
0
152
0
                *index += 1;
153
0
154
0
                f(acc, value)
155
0
            })
156
0
        };
157
0
158
0
        // ensure the drop happens here after iteration
159
0
        drop(self);
160
0
161
0
        ret
162
0
    }
163
164
    #[inline]
165
0
    fn size_hint(&self) -> (usize, Option<usize>) {
166
0
        let len = self.len();
167
0
        (len, Some(len))
168
0
    }
169
170
    #[inline]
171
0
    fn count(self) -> usize {
172
0
        self.len()
173
0
    }
174
175
0
    fn nth(&mut self, n: usize) -> Option<T> {
176
0
        // First consume values prior to the nth.
177
0
        let ndrop = cmp::min(n, self.len());
178
179
0
        for p in &mut self.array[self.index..self.index + ndrop] {
180
0
            self.index += 1;
181
0
182
0
            unsafe {
183
0
                ptr::drop_in_place(p);
184
0
            }
185
        }
186
187
0
        self.next()
188
0
    }
189
190
    #[inline]
191
0
    fn last(mut self) -> Option<T> {
192
0
        // Note, everything else will correctly drop first as `self` leaves scope.
193
0
        self.next_back()
194
0
    }
195
}
196
197
impl<T, N> DoubleEndedIterator for GenericArrayIter<T, N>
198
where
199
    N: ArrayLength<T>,
200
{
201
0
    fn next_back(&mut self) -> Option<T> {
202
0
        if self.index < self.index_back {
203
0
            self.index_back -= 1;
204
0
205
0
            unsafe { Some(ptr::read(self.array.get_unchecked(self.index_back))) }
206
        } else {
207
0
            None
208
        }
209
0
    }
210
211
0
    fn rfold<B, F>(mut self, init: B, mut f: F) -> B
212
0
    where
213
0
        F: FnMut(B, Self::Item) -> B,
214
0
    {
215
0
        let ret = unsafe {
216
0
            let GenericArrayIter {
217
0
                ref array,
218
0
                index,
219
0
                ref mut index_back,
220
0
            } = self;
221
0
222
0
            let remaining = &array[index..*index_back];
223
0
224
0
            remaining.iter().rfold(init, |acc, src| {
225
0
                let value = ptr::read(src);
226
0
227
0
                *index_back -= 1;
228
0
229
0
                f(acc, value)
230
0
            })
231
0
        };
232
0
233
0
        // ensure the drop happens here after iteration
234
0
        drop(self);
235
0
236
0
        ret
237
0
    }
238
}
239
240
impl<T, N> ExactSizeIterator for GenericArrayIter<T, N>
241
where
242
    N: ArrayLength<T>,
243
{
244
0
    fn len(&self) -> usize {
245
0
        self.index_back - self.index
246
0
    }
247
}
248
249
impl<T, N> FusedIterator for GenericArrayIter<T, N> where N: ArrayLength<T> {}
250
251
// TODO: Implement `TrustedLen` when stabilized
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/generic-array-0.14.7/src/lib.rs
Line
Count
Source
1
//! This crate implements a structure that can be used as a generic array type.
2
//! Core Rust array types `[T; N]` can't be used generically with
3
//! respect to `N`, so for example this:
4
//!
5
//! ```rust{compile_fail}
6
//! struct Foo<T, N> {
7
//!     data: [T; N]
8
//! }
9
//! ```
10
//!
11
//! won't work.
12
//!
13
//! **generic-array** exports a `GenericArray<T,N>` type, which lets
14
//! the above be implemented as:
15
//!
16
//! ```rust
17
//! use generic_array::{ArrayLength, GenericArray};
18
//!
19
//! struct Foo<T, N: ArrayLength<T>> {
20
//!     data: GenericArray<T,N>
21
//! }
22
//! ```
23
//!
24
//! The `ArrayLength<T>` trait is implemented by default for
25
//! [unsigned integer types](../typenum/uint/index.html) from
26
//! [typenum](../typenum/index.html):
27
//!
28
//! ```rust
29
//! # use generic_array::{ArrayLength, GenericArray};
30
//! use generic_array::typenum::U5;
31
//!
32
//! struct Foo<N: ArrayLength<i32>> {
33
//!     data: GenericArray<i32, N>
34
//! }
35
//!
36
//! # fn main() {
37
//! let foo = Foo::<U5>{data: GenericArray::default()};
38
//! # }
39
//! ```
40
//!
41
//! For example, `GenericArray<T, U5>` would work almost like `[T; 5]`:
42
//!
43
//! ```rust
44
//! # use generic_array::{ArrayLength, GenericArray};
45
//! use generic_array::typenum::U5;
46
//!
47
//! struct Foo<T, N: ArrayLength<T>> {
48
//!     data: GenericArray<T, N>
49
//! }
50
//!
51
//! # fn main() {
52
//! let foo = Foo::<i32, U5>{data: GenericArray::default()};
53
//! # }
54
//! ```
55
//!
56
//! For ease of use, an `arr!` macro is provided - example below:
57
//!
58
//! ```
59
//! # #[macro_use]
60
//! # extern crate generic_array;
61
//! # extern crate typenum;
62
//! # fn main() {
63
//! let array = arr![u32; 1, 2, 3];
64
//! assert_eq!(array[2], 3);
65
//! # }
66
//! ```
67
68
#![deny(missing_docs)]
69
#![deny(meta_variable_misuse)]
70
#![no_std]
71
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
72
73
#[cfg(feature = "serde")]
74
extern crate serde;
75
76
#[cfg(feature = "zeroize")]
77
extern crate zeroize;
78
79
#[cfg(test)]
80
extern crate bincode;
81
82
pub extern crate typenum;
83
84
mod hex;
85
mod impls;
86
87
#[cfg(feature = "serde")]
88
mod impl_serde;
89
90
#[cfg(feature = "zeroize")]
91
mod impl_zeroize;
92
93
use core::iter::FromIterator;
94
use core::marker::PhantomData;
95
use core::mem::{MaybeUninit, ManuallyDrop};
96
use core::ops::{Deref, DerefMut};
97
use core::{mem, ptr, slice};
98
use typenum::bit::{B0, B1};
99
use typenum::uint::{UInt, UTerm, Unsigned};
100
101
#[cfg_attr(test, macro_use)]
102
pub mod arr;
103
pub mod functional;
104
pub mod iter;
105
pub mod sequence;
106
107
use self::functional::*;
108
pub use self::iter::GenericArrayIter;
109
use self::sequence::*;
110
111
/// Trait making `GenericArray` work, marking types to be used as length of an array
112
pub unsafe trait ArrayLength<T>: Unsigned {
113
    /// Associated type representing the array type for the number
114
    type ArrayType;
115
}
116
117
unsafe impl<T> ArrayLength<T> for UTerm {
118
    #[doc(hidden)]
119
    type ArrayType = [T; 0];
120
}
121
122
/// Internal type used to generate a struct of appropriate size
123
#[allow(dead_code)]
124
#[repr(C)]
125
#[doc(hidden)]
126
pub struct GenericArrayImplEven<T, U> {
127
    parent1: U,
128
    parent2: U,
129
    _marker: PhantomData<T>,
130
}
131
132
impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
133
0
    fn clone(&self) -> GenericArrayImplEven<T, U> {
134
0
        GenericArrayImplEven {
135
0
            parent1: self.parent1.clone(),
136
0
            parent2: self.parent2.clone(),
137
0
            _marker: PhantomData,
138
0
        }
139
0
    }
140
}
141
142
impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}
143
144
/// Internal type used to generate a struct of appropriate size
145
#[allow(dead_code)]
146
#[repr(C)]
147
#[doc(hidden)]
148
pub struct GenericArrayImplOdd<T, U> {
149
    parent1: U,
150
    parent2: U,
151
    data: T,
152
}
153
154
impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
155
0
    fn clone(&self) -> GenericArrayImplOdd<T, U> {
156
0
        GenericArrayImplOdd {
157
0
            parent1: self.parent1.clone(),
158
0
            parent2: self.parent2.clone(),
159
0
            data: self.data.clone(),
160
0
        }
161
0
    }
162
}
163
164
impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}
165
166
unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
167
    #[doc(hidden)]
168
    type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
169
}
170
171
unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
172
    #[doc(hidden)]
173
    type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
174
}
175
176
/// Struct representing a generic array - `GenericArray<T, N>` works like [T; N]
177
#[allow(dead_code)]
178
#[repr(transparent)]
179
pub struct GenericArray<T, U: ArrayLength<T>> {
180
    data: U::ArrayType,
181
}
182
183
unsafe impl<T: Send, N: ArrayLength<T>> Send for GenericArray<T, N> {}
184
unsafe impl<T: Sync, N: ArrayLength<T>> Sync for GenericArray<T, N> {}
185
186
impl<T, N> Deref for GenericArray<T, N>
187
where
188
    N: ArrayLength<T>,
189
{
190
    type Target = [T];
191
192
    #[inline(always)]
193
226k
    fn deref(&self) -> &[T] {
194
226k
        unsafe { slice::from_raw_parts(self as *const Self as *const T, N::USIZE) }
195
226k
    }
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCs2IvCg5PL8uK_11chia_traits
_RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCs4RkbDk9WRL5_5clvmr
Line
Count
Source
193
138k
    fn deref(&self) -> &[T] {
194
138k
        unsafe { slice::from_raw_parts(self as *const Self as *const T, N::USIZE) }
195
138k
    }
_RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCs4RkbDk9WRL5_5clvmr
Line
Count
Source
193
1.42k
    fn deref(&self) -> &[T] {
194
1.42k
        unsafe { slice::from_raw_parts(self as *const Self as *const T, N::USIZE) }
195
1.42k
    }
_RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCs4RkbDk9WRL5_5clvmr
Line
Count
Source
193
7.14k
    fn deref(&self) -> &[T] {
194
7.14k
        unsafe { slice::from_raw_parts(self as *const Self as *const T, N::USIZE) }
195
7.14k
    }
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1T_2B0EB26_EB26_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1X_2B0EB2a_EB2a_EB2a_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1V_ENtB1X_2B0EB2f_EB2f_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_ENtB21_2B0EB2j_EB2j_EB2j_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_EB1Z_ENtB21_2B0EB2o_EB2o_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB23_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB2n_EB2n_EB2n_EB2n_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB23_EB2n_EB2n_EB2n_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_EB23_ENtB25_2B0EB2s_EB2s_EB2s_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB29_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EB2m_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_ENtB29_2B0EB2r_EB2r_EB2r_EB2r_EB2r_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_EB27_ENtB29_2B0EB2w_EB2w_EB2w_EB2w_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2d_2B0EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_ENtB2d_2B0EB2v_EB2v_EB2v_EB2v_EB2v_EB2v_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_EB2b_ENtB2d_2B0EB2A_EB2A_EB2A_EB2A_EB2A_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2h_2B0EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2f_ENtB2h_2B0EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2l_2B0EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXINICskVr04X3DebC_13generic_arrays7_0ppEINtB5_12GenericArrayppENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefB5_
_RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCsjewTDwKBbyD_4k256
Line
Count
Source
193
5.06k
    fn deref(&self) -> &[T] {
194
5.06k
        unsafe { slice::from_raw_parts(self as *const Self as *const T, N::USIZE) }
195
5.06k
    }
_RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCsjewTDwKBbyD_4k256
Line
Count
Source
193
69.1k
    fn deref(&self) -> &[T] {
194
69.1k
        unsafe { slice::from_raw_parts(self as *const Self as *const T, N::USIZE) }
195
69.1k
    }
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB1Z_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCsjewTDwKBbyD_4k256
_RNvXs7_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCsaHRNXv1Y9Bq_4p256
Line
Count
Source
193
5.16k
    fn deref(&self) -> &[T] {
194
5.16k
        unsafe { slice::from_raw_parts(self as *const Self as *const T, N::USIZE) }
195
5.16k
    }
196
}
197
198
impl<T, N> DerefMut for GenericArray<T, N>
199
where
200
    N: ArrayLength<T>,
201
{
202
    #[inline(always)]
203
149k
    fn deref_mut(&mut self) -> &mut [T] {
204
149k
        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::USIZE) }
205
149k
    }
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs2IvCg5PL8uK_11chia_traits
_RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs4RkbDk9WRL5_5clvmr
Line
Count
Source
203
4.90k
    fn deref_mut(&mut self) -> &mut [T] {
204
4.90k
        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::USIZE) }
205
4.90k
    }
_RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs4RkbDk9WRL5_5clvmr
Line
Count
Source
203
74.3k
    fn deref_mut(&mut self) -> &mut [T] {
204
74.3k
        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::USIZE) }
205
74.3k
    }
_RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs4RkbDk9WRL5_5clvmr
Line
Count
Source
203
47.3k
    fn deref_mut(&mut self) -> &mut [T] {
204
47.3k
        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::USIZE) }
205
47.3k
    }
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2l_2B0EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2f_ENtB2h_2B0EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2h_2B0EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_EB2b_ENtB2d_2B0EB2A_EB2A_EB2A_EB2A_EB2A_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_ENtB2d_2B0EB2v_EB2v_EB2v_EB2v_EB2v_EB2v_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2d_2B0EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_EB27_ENtB29_2B0EB2w_EB2w_EB2w_EB2w_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_ENtB29_2B0EB2r_EB2r_EB2r_EB2r_EB2r_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB29_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EB2m_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_EB23_ENtB25_2B0EB2s_EB2s_EB2s_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB23_EB2n_EB2n_EB2n_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB2n_EB2n_EB2n_EB2n_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB23_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_EB1Z_ENtB21_2B0EB2o_EB2o_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_ENtB21_2B0EB2j_EB2j_EB2j_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1V_ENtB1X_2B0EB2f_EB2f_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1X_2B0EB2a_EB2a_EB2a_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1T_2B0EB26_EB26_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXINICskVr04X3DebC_13generic_arrays8_0ppEINtB5_12GenericArrayppENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutB5_
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCsjewTDwKBbyD_4k256
_RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCsjewTDwKBbyD_4k256
Line
Count
Source
203
21.4k
    fn deref_mut(&mut self) -> &mut [T] {
204
21.4k
        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::USIZE) }
205
21.4k
    }
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB1Z_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCsjewTDwKBbyD_4k256
_RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCsaHRNXv1Y9Bq_4p256
Line
Count
Source
203
1.73k
    fn deref_mut(&mut self) -> &mut [T] {
204
1.73k
        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::USIZE) }
205
1.73k
    }
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB29_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EB2m_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNvXs8_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs23lnNM1woOA_4sha2
206
}
207
208
/// Creates an array one element at a time using a mutable iterator
209
/// you can write to with `ptr::write`.
210
///
211
/// Increment the position while iterating to mark off created elements,
212
/// which will be dropped if `into_inner` is not called.
213
#[doc(hidden)]
214
pub struct ArrayBuilder<T, N: ArrayLength<T>> {
215
    array: MaybeUninit<GenericArray<T, N>>,
216
    position: usize,
217
}
218
219
impl<T, N: ArrayLength<T>> ArrayBuilder<T, N> {
220
    #[doc(hidden)]
221
    #[inline]
222
41.0k
    pub unsafe fn new() -> ArrayBuilder<T, N> {
223
41.0k
        ArrayBuilder {
224
41.0k
            array: MaybeUninit::uninit(),
225
41.0k
            position: 0,
226
41.0k
        }
227
41.0k
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE3newCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE3newCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE3newCs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE3newCs2IvCg5PL8uK_11chia_traits
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
222
25.1k
    pub unsafe fn new() -> ArrayBuilder<T, N> {
223
25.1k
        ArrayBuilder {
224
25.1k
            array: MaybeUninit::uninit(),
225
25.1k
            position: 0,
226
25.1k
        }
227
25.1k
    }
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
222
9.97k
    pub unsafe fn new() -> ArrayBuilder<T, N> {
223
9.97k
        ArrayBuilder {
224
9.97k
            array: MaybeUninit::uninit(),
225
9.97k
            position: 0,
226
9.97k
        }
227
9.97k
    }
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EE3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
222
2.45k
    pub unsafe fn new() -> ArrayBuilder<T, N> {
223
2.45k
        ArrayBuilder {
224
2.45k
            array: MaybeUninit::uninit(),
225
2.45k
            position: 0,
226
2.45k
        }
227
2.45k
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2l_2B0EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2f_ENtB2h_2B0EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2h_2B0EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_EB2b_ENtB2d_2B0EB2A_EB2A_EB2A_EB2A_EB2A_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_ENtB2d_2B0EB2v_EB2v_EB2v_EB2v_EB2v_EB2v_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2d_2B0EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_EB27_ENtB29_2B0EB2w_EB2w_EB2w_EB2w_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_ENtB29_2B0EB2r_EB2r_EB2r_EB2r_EB2r_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB29_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EB2m_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_EB23_ENtB25_2B0EB2s_EB2s_EB2s_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB23_EB2n_EB2n_EB2n_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB2n_EB2n_EB2n_EB2n_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB23_EB2i_EB2i_EB2i_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_EB1Z_ENtB21_2B0EB2o_EB2o_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_ENtB21_2B0EB2j_EB2j_EB2j_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1V_ENtB1X_2B0EB2f_EB2f_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1X_2B0EB2a_EB2a_EB2a_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1T_2B0EB26_EB26_EE3newCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderppE3newB5_
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE3newCsjewTDwKBbyD_4k256
Line
Count
Source
222
2.61k
    pub unsafe fn new() -> ArrayBuilder<T, N> {
223
2.61k
        ArrayBuilder {
224
2.61k
            array: MaybeUninit::uninit(),
225
2.61k
            position: 0,
226
2.61k
        }
227
2.61k
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EE3newCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE3newCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB1Z_EE3newCsjewTDwKBbyD_4k256
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE3newCsaHRNXv1Y9Bq_4p256
Line
Count
Source
222
866
    pub unsafe fn new() -> ArrayBuilder<T, N> {
223
866
        ArrayBuilder {
224
866
            array: MaybeUninit::uninit(),
225
866
            position: 0,
226
866
        }
227
866
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB29_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EB2m_EE3newCs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE3newCs23lnNM1woOA_4sha2
228
229
    /// Creates a mutable iterator for writing to the array using `ptr::write`.
230
    ///
231
    /// Increment the position value given as a mutable reference as you iterate
232
    /// to mark how many elements have been created.
233
    #[doc(hidden)]
234
    #[inline]
235
41.0k
    pub unsafe fn iter_position(&mut self) -> (slice::IterMut<T>, &mut usize) {
236
41.0k
        ((&mut *self.array.as_mut_ptr()).iter_mut(), &mut self.position)
237
41.0k
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE13iter_positionCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE13iter_positionCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE13iter_positionCs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE13iter_positionCs2IvCg5PL8uK_11chia_traits
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE13iter_positionCs4RkbDk9WRL5_5clvmr
Line
Count
Source
235
25.1k
    pub unsafe fn iter_position(&mut self) -> (slice::IterMut<T>, &mut usize) {
236
25.1k
        ((&mut *self.array.as_mut_ptr()).iter_mut(), &mut self.position)
237
25.1k
    }
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE13iter_positionCs4RkbDk9WRL5_5clvmr
Line
Count
Source
235
9.97k
    pub unsafe fn iter_position(&mut self) -> (slice::IterMut<T>, &mut usize) {
236
9.97k
        ((&mut *self.array.as_mut_ptr()).iter_mut(), &mut self.position)
237
9.97k
    }
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EE13iter_positionCs4RkbDk9WRL5_5clvmr
Line
Count
Source
235
2.45k
    pub unsafe fn iter_position(&mut self) -> (slice::IterMut<T>, &mut usize) {
236
2.45k
        ((&mut *self.array.as_mut_ptr()).iter_mut(), &mut self.position)
237
2.45k
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2l_2B0EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2f_ENtB2h_2B0EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2h_2B0EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_EB2b_ENtB2d_2B0EB2A_EB2A_EB2A_EB2A_EB2A_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_ENtB2d_2B0EB2v_EB2v_EB2v_EB2v_EB2v_EB2v_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2d_2B0EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_EB27_ENtB29_2B0EB2w_EB2w_EB2w_EB2w_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_ENtB29_2B0EB2r_EB2r_EB2r_EB2r_EB2r_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB29_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EB2m_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_EB23_ENtB25_2B0EB2s_EB2s_EB2s_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB23_EB2n_EB2n_EB2n_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB2n_EB2n_EB2n_EB2n_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB23_EB2i_EB2i_EB2i_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_EB1Z_ENtB21_2B0EB2o_EB2o_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_ENtB21_2B0EB2j_EB2j_EB2j_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1V_ENtB1X_2B0EB2f_EB2f_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1X_2B0EB2a_EB2a_EB2a_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1T_2B0EB26_EB26_EE13iter_positionCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderppE13iter_positionB5_
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE13iter_positionCsjewTDwKBbyD_4k256
Line
Count
Source
235
2.61k
    pub unsafe fn iter_position(&mut self) -> (slice::IterMut<T>, &mut usize) {
236
2.61k
        ((&mut *self.array.as_mut_ptr()).iter_mut(), &mut self.position)
237
2.61k
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EE13iter_positionCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE13iter_positionCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB1Z_EE13iter_positionCsjewTDwKBbyD_4k256
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE13iter_positionCsaHRNXv1Y9Bq_4p256
Line
Count
Source
235
866
    pub unsafe fn iter_position(&mut self) -> (slice::IterMut<T>, &mut usize) {
236
866
        ((&mut *self.array.as_mut_ptr()).iter_mut(), &mut self.position)
237
866
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB29_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EB2m_EE13iter_positionCs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE13iter_positionCs23lnNM1woOA_4sha2
238
239
    /// When done writing (assuming all elements have been written to),
240
    /// get the inner array.
241
    #[doc(hidden)]
242
    #[inline]
243
41.0k
    pub unsafe fn into_inner(self) -> GenericArray<T, N> {
244
41.0k
        let array = ptr::read(&self.array);
245
41.0k
246
41.0k
        mem::forget(self);
247
41.0k
248
41.0k
        array.assume_init()
249
41.0k
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE10into_innerCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE10into_innerCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE10into_innerCs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE10into_innerCs2IvCg5PL8uK_11chia_traits
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE10into_innerCs4RkbDk9WRL5_5clvmr
Line
Count
Source
243
25.1k
    pub unsafe fn into_inner(self) -> GenericArray<T, N> {
244
25.1k
        let array = ptr::read(&self.array);
245
25.1k
246
25.1k
        mem::forget(self);
247
25.1k
248
25.1k
        array.assume_init()
249
25.1k
    }
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE10into_innerCs4RkbDk9WRL5_5clvmr
Line
Count
Source
243
9.97k
    pub unsafe fn into_inner(self) -> GenericArray<T, N> {
244
9.97k
        let array = ptr::read(&self.array);
245
9.97k
246
9.97k
        mem::forget(self);
247
9.97k
248
9.97k
        array.assume_init()
249
9.97k
    }
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EE10into_innerCs4RkbDk9WRL5_5clvmr
Line
Count
Source
243
2.45k
    pub unsafe fn into_inner(self) -> GenericArray<T, N> {
244
2.45k
        let array = ptr::read(&self.array);
245
2.45k
246
2.45k
        mem::forget(self);
247
2.45k
248
2.45k
        array.assume_init()
249
2.45k
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2l_2B0EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2f_ENtB2h_2B0EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2h_2B0EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_EB2b_ENtB2d_2B0EB2A_EB2A_EB2A_EB2A_EB2A_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_ENtB2d_2B0EB2v_EB2v_EB2v_EB2v_EB2v_EB2v_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2d_2B0EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_EB27_ENtB29_2B0EB2w_EB2w_EB2w_EB2w_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_ENtB29_2B0EB2r_EB2r_EB2r_EB2r_EB2r_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB29_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EB2m_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_EB23_ENtB25_2B0EB2s_EB2s_EB2s_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB23_EB2n_EB2n_EB2n_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB2n_EB2n_EB2n_EB2n_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB23_EB2i_EB2i_EB2i_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_EB1Z_ENtB21_2B0EB2o_EB2o_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_ENtB21_2B0EB2j_EB2j_EB2j_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1V_ENtB1X_2B0EB2f_EB2f_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1X_2B0EB2a_EB2a_EB2a_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1T_2B0EB26_EB26_EE10into_innerCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderppE10into_innerB5_
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE10into_innerCsjewTDwKBbyD_4k256
Line
Count
Source
243
2.61k
    pub unsafe fn into_inner(self) -> GenericArray<T, N> {
244
2.61k
        let array = ptr::read(&self.array);
245
2.61k
246
2.61k
        mem::forget(self);
247
2.61k
248
2.61k
        array.assume_init()
249
2.61k
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EE10into_innerCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE10into_innerCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB1Z_EE10into_innerCsjewTDwKBbyD_4k256
_RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE10into_innerCsaHRNXv1Y9Bq_4p256
Line
Count
Source
243
866
    pub unsafe fn into_inner(self) -> GenericArray<T, N> {
244
866
        let array = ptr::read(&self.array);
245
866
246
866
        mem::forget(self);
247
866
248
866
        array.assume_init()
249
866
    }
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB29_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EB2m_EE10into_innerCs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNvMs9_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE10into_innerCs23lnNM1woOA_4sha2
250
}
251
252
impl<T, N: ArrayLength<T>> Drop for ArrayBuilder<T, N> {
253
0
    fn drop(&mut self) {
254
0
        if mem::needs_drop::<T>() {
255
            unsafe {
256
0
                for value in &mut (&mut *self.array.as_mut_ptr())[..self.position] {
257
0
                    ptr::drop_in_place(value);
258
0
                }
259
            }
260
0
        }
261
0
    }
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCs4RkbDk9WRL5_5clvmr
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCs4RkbDk9WRL5_5clvmr
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCs4RkbDk9WRL5_5clvmr
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2l_2B0EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2f_ENtB2h_2B0EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2h_2B0EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_EB2b_ENtB2d_2B0EB2A_EB2A_EB2A_EB2A_EB2A_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB2b_ENtB2d_2B0EB2v_EB2v_EB2v_EB2v_EB2v_EB2v_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB2d_2B0EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_EB27_ENtB29_2B0EB2w_EB2w_EB2w_EB2w_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB27_ENtB29_2B0EB2r_EB2r_EB2r_EB2r_EB2r_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB29_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EB2m_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_EB23_ENtB25_2B0EB2s_EB2s_EB2s_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB23_EB2n_EB2n_EB2n_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB23_ENtB25_2B0EB2n_EB2n_EB2n_EB2n_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB23_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_EB1Z_ENtB21_2B0EB2o_EB2o_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1Z_ENtB21_2B0EB2j_EB2j_EB2j_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1EB1V_ENtB1X_2B0EB2f_EB2f_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1X_2B0EB2a_EB2a_EB2a_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB1T_2B0EB26_EB26_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXINICskVr04X3DebC_13generic_arraysa_0ppEINtB5_12ArrayBuilderppENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropB5_
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB23_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB1Z_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCsaHRNXv1Y9Bq_4p256
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB29_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EB2m_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNvXsa_CskVr04X3DebC_13generic_arrayINtB5_12ArrayBuilderhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCs23lnNM1woOA_4sha2
262
}
263
264
/// Consumes an array.
265
///
266
/// Increment the position while iterating and any leftover elements
267
/// will be dropped if position does not go to N
268
#[doc(hidden)]
269
pub struct ArrayConsumer<T, N: ArrayLength<T>> {
270
    array: ManuallyDrop<GenericArray<T, N>>,
271
    position: usize,
272
}
273
274
impl<T, N: ArrayLength<T>> ArrayConsumer<T, N> {
275
    #[doc(hidden)]
276
    #[inline]
277
0
    pub unsafe fn new(array: GenericArray<T, N>) -> ArrayConsumer<T, N> {
278
0
        ArrayConsumer {
279
0
            array: ManuallyDrop::new(array),
280
0
            position: 0,
281
0
        }
282
0
    }
283
284
    /// Creates an iterator and mutable reference to the internal position
285
    /// to keep track of consumed elements.
286
    ///
287
    /// Increment the position as you iterate to mark off consumed elements
288
    #[doc(hidden)]
289
    #[inline]
290
0
    pub unsafe fn iter_position(&mut self) -> (slice::Iter<T>, &mut usize) {
291
0
        (self.array.iter(), &mut self.position)
292
0
    }
293
}
294
295
impl<T, N: ArrayLength<T>> Drop for ArrayConsumer<T, N> {
296
0
    fn drop(&mut self) {
297
0
        if mem::needs_drop::<T>() {
298
0
            for value in &mut self.array[self.position..N::USIZE] {
299
0
                unsafe {
300
0
                    ptr::drop_in_place(value);
301
0
                }
302
            }
303
0
        }
304
0
    }
305
}
306
307
impl<'a, T: 'a, N> IntoIterator for &'a GenericArray<T, N>
308
where
309
    N: ArrayLength<T>,
310
{
311
    type IntoIter = slice::Iter<'a, T>;
312
    type Item = &'a T;
313
314
0
    fn into_iter(self: &'a GenericArray<T, N>) -> Self::IntoIter {
315
0
        self.as_slice().iter()
316
0
    }
Unexecuted instantiation: _RNvXsd_CskVr04X3DebC_13generic_arrayRINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EENtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits7collect12IntoIterator9into_iterCs4RkbDk9WRL5_5clvmr
Unexecuted instantiation: _RNvXINICskVr04X3DebC_13generic_arraysd_0ppERINtB5_12GenericArrayppENtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits7collect12IntoIterator9into_iterB5_
317
}
318
319
impl<'a, T: 'a, N> IntoIterator for &'a mut GenericArray<T, N>
320
where
321
    N: ArrayLength<T>,
322
{
323
    type IntoIter = slice::IterMut<'a, T>;
324
    type Item = &'a mut T;
325
326
0
    fn into_iter(self: &'a mut GenericArray<T, N>) -> Self::IntoIter {
327
0
        self.as_mut_slice().iter_mut()
328
0
    }
329
}
330
331
impl<T, N> FromIterator<T> for GenericArray<T, N>
332
where
333
    N: ArrayLength<T>,
334
{
335
0
    fn from_iter<I>(iter: I) -> GenericArray<T, N>
336
0
    where
337
0
        I: IntoIterator<Item = T>,
338
0
    {
339
0
        unsafe {
340
0
            let mut destination = ArrayBuilder::new();
341
0
342
0
            {
343
0
                let (destination_iter, position) = destination.iter_position();
344
0
345
0
                iter.into_iter()
346
0
                    .zip(destination_iter)
347
0
                    .for_each(|(src, dst)| {
348
0
                        ptr::write(dst, src);
349
0
350
0
                        *position += 1;
351
0
                    });
Unexecuted instantiation: _RNCINvXsf_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB28_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EEINtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits7collect12FromIteratorhE9from_iterINtNtNtB33_8adapters3map3MapINtNtNtB35_5slice4iter4IterhENvYhNtNtB35_5clone5Clone5cloneEE0Cs4RkbDk9WRL5_5clvmr
Unexecuted instantiation: _RNCINvXINICskVr04X3DebC_13generic_arraysf_0ppEINtB8_12GenericArrayppEINtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits7collect12FromIteratorpE9from_iterpE0B8_
352
0
            }
353
0
354
0
            if destination.position < N::USIZE {
355
0
                from_iter_length_fail(destination.position, N::USIZE);
356
0
            }
357
0
358
0
            destination.into_inner()
359
0
        }
360
0
    }
Unexecuted instantiation: _RINvXsf_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EEINtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits7collect12FromIteratorhE9from_iterINtNtNtB30_8adapters3map3MapINtNtNtB32_5slice4iter4IterhENvYhNtNtB32_5clone5Clone5cloneEECs4RkbDk9WRL5_5clvmr
Unexecuted instantiation: _RINvXINICskVr04X3DebC_13generic_arraysf_0ppEINtB6_12GenericArrayppEINtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits7collect12FromIteratorpE9from_iterpEB6_
361
}
362
363
#[inline(never)]
364
#[cold]
365
0
fn from_iter_length_fail(length: usize, expected: usize) -> ! {
366
0
    panic!(
367
0
        "GenericArray::from_iter received {} elements but expected {}",
368
0
        length, expected
369
0
    );
370
}
371
372
unsafe impl<T, N> GenericSequence<T> for GenericArray<T, N>
373
where
374
    N: ArrayLength<T>,
375
    Self: IntoIterator<Item = T>,
376
{
377
    type Length = N;
378
    type Sequence = Self;
379
380
38.1k
    fn generate<F>(mut f: F) -> GenericArray<T, N>
381
38.1k
    where
382
38.1k
        F: FnMut(usize) -> T,
383
38.1k
    {
384
38.1k
        unsafe {
385
38.1k
            let mut destination = ArrayBuilder::new();
386
38.1k
387
38.1k
            {
388
38.1k
                let (destination_iter, position) = destination.iter_position();
389
38.1k
390
1.62M
                destination_iter.enumerate().for_each(|(i, dst)| {
391
1.62M
                    ptr::write(dst, f(i));
392
1.62M
393
1.62M
                    *position += 1;
394
1.62M
                });
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB28_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB24_2B0EB2i_EB2i_EB2i_EB2i_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB28_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0Cs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB24_2B0EB2i_EB2i_EB2i_EB2i_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0Cs2IvCg5PL8uK_11chia_traits
_RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB28_2B0EB2m_EB2m_EB2m_EB2m_EB26_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
390
159k
                destination_iter.enumerate().for_each(|(i, dst)| {
391
159k
                    ptr::write(dst, f(i));
392
159k
393
159k
                    *position += 1;
394
159k
                });
_RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB28_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
390
638k
                destination_iter.enumerate().for_each(|(i, dst)| {
391
638k
                    ptr::write(dst, f(i));
392
638k
393
638k
                    *position += 1;
394
638k
                });
_RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB24_2B0EB2i_EB2i_EB2i_EB2i_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
390
712k
                destination_iter.enumerate().for_each(|(i, dst)| {
391
712k
                    ptr::write(dst, f(i));
392
712k
393
712k
                    *position += 1;
394
712k
                });
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB2o_2B0EB2C_EB2C_EB2C_EB2C_EB2C_EB2C_EB2C_EB2C_EB2C_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1EB2i_ENtB2k_2B0EB2D_EB2D_EB2D_EB2D_EB2D_EB2D_EB2D_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB2k_2B0EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EB2y_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1EB2e_EB2e_ENtB2g_2B0EB2E_EB2E_EB2E_EB2E_EB2E_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1EB2e_ENtB2g_2B0EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB2g_2B0EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EB2u_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1EB2a_EB2a_ENtB2c_2B0EB2A_EB2A_EB2A_EB2A_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1EB2a_ENtB2c_2B0EB2v_EB2v_EB2v_EB2v_EB2v_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB2c_2B0EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1EB26_EB26_ENtB28_2B0EB2w_EB2w_EB2w_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1EB26_ENtB28_2B0EB26_EB2r_EB2r_EB2r_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1EB26_ENtB28_2B0EB2r_EB2r_EB2r_EB2r_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB28_2B0EB2m_EB26_EB2m_EB2m_EB2m_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB28_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1EB22_EB22_ENtB24_2B0EB2s_EB2s_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1EB22_ENtB24_2B0EB2n_EB2n_EB2n_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB24_2B0EB2i_EB2i_EB2i_EB2i_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1EB1Y_ENtB20_2B0EB2j_EB2j_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB20_2B0EB2e_EB2e_EB2e_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB1W_2B0EB2a_EB2a_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNCINvXINICskVr04X3DebC_13generic_arraysg_0ppEINtB8_12GenericArrayppEINtNtB8_8sequence15GenericSequencepE8generatepE0B8_
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB28_2B0EB2m_EB2m_EB2m_EB2m_EB26_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB28_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB24_2B0EB2i_EB2i_EB2i_EB22_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CsjewTDwKBbyD_4k256
_RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB24_2B0EB2i_EB2i_EB2i_EB2i_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CsjewTDwKBbyD_4k256
Line
Count
Source
390
83.6k
                destination_iter.enumerate().for_each(|(i, dst)| {
391
83.6k
                    ptr::write(dst, f(i));
392
83.6k
393
83.6k
                    *position += 1;
394
83.6k
                });
_RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB24_2B0EB2i_EB2i_EB2i_EB2i_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0CsaHRNXv1Y9Bq_4p256
Line
Count
Source
390
27.7k
                destination_iter.enumerate().for_each(|(i, dst)| {
391
27.7k
                    ptr::write(dst, f(i));
392
27.7k
393
27.7k
                    *position += 1;
394
27.7k
                });
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB2c_2B0EB2q_EB2q_EB2q_EB2q_EB2q_EB2q_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0Cs23lnNM1woOA_4sha2
Unexecuted instantiation: _RNCINvXsg_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB28_2B0EB2m_EB2m_EB2m_EB2m_EB2m_EEINtNtB8_8sequence15GenericSequencehE8generateNCNvXNtB8_5implsBB_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0E0Cs23lnNM1woOA_4sha2
395
38.1k
            }
396
38.1k
397
38.1k
            destination.into_inner()
398
38.1k
        }
399
38.1k
    }
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECs2IvCg5PL8uK_11chia_traits
_RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB24_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
380
2.45k
    fn generate<F>(mut f: F) -> GenericArray<T, N>
381
2.45k
    where
382
2.45k
        F: FnMut(usize) -> T,
383
2.45k
    {
384
2.45k
        unsafe {
385
2.45k
            let mut destination = ArrayBuilder::new();
386
2.45k
387
2.45k
            {
388
2.45k
                let (destination_iter, position) = destination.iter_position();
389
2.45k
390
2.45k
                destination_iter.enumerate().for_each(|(i, dst)| {
391
                    ptr::write(dst, f(i));
392
393
                    *position += 1;
394
2.45k
                });
395
2.45k
            }
396
2.45k
397
2.45k
            destination.into_inner()
398
2.45k
        }
399
2.45k
    }
_RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
380
9.97k
    fn generate<F>(mut f: F) -> GenericArray<T, N>
381
9.97k
    where
382
9.97k
        F: FnMut(usize) -> T,
383
9.97k
    {
384
9.97k
        unsafe {
385
9.97k
            let mut destination = ArrayBuilder::new();
386
9.97k
387
9.97k
            {
388
9.97k
                let (destination_iter, position) = destination.iter_position();
389
9.97k
390
9.97k
                destination_iter.enumerate().for_each(|(i, dst)| {
391
                    ptr::write(dst, f(i));
392
393
                    *position += 1;
394
9.97k
                });
395
9.97k
            }
396
9.97k
397
9.97k
            destination.into_inner()
398
9.97k
        }
399
9.97k
    }
_RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
380
22.2k
    fn generate<F>(mut f: F) -> GenericArray<T, N>
381
22.2k
    where
382
22.2k
        F: FnMut(usize) -> T,
383
22.2k
    {
384
22.2k
        unsafe {
385
22.2k
            let mut destination = ArrayBuilder::new();
386
22.2k
387
22.2k
            {
388
22.2k
                let (destination_iter, position) = destination.iter_position();
389
22.2k
390
22.2k
                destination_iter.enumerate().for_each(|(i, dst)| {
391
                    ptr::write(dst, f(i));
392
393
                    *position += 1;
394
22.2k
                });
395
22.2k
            }
396
22.2k
397
22.2k
            destination.into_inner()
398
22.2k
        }
399
22.2k
    }
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB2m_2B0EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EB2z_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1EB2g_ENtB2i_2B0EB2A_EB2A_EB2A_EB2A_EB2A_EB2A_EB2A_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB2i_2B0EB2v_EB2v_EB2v_EB2v_EB2v_EB2v_EB2v_EB2v_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1EB2c_EB2c_ENtB2e_2B0EB2B_EB2B_EB2B_EB2B_EB2B_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1EB2c_ENtB2e_2B0EB2w_EB2w_EB2w_EB2w_EB2w_EB2w_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB2e_2B0EB2r_EB2r_EB2r_EB2r_EB2r_EB2r_EB2r_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1EB28_EB28_ENtB2a_2B0EB2x_EB2x_EB2x_EB2x_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1EB28_ENtB2a_2B0EB2s_EB2s_EB2s_EB2s_EB2s_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB2a_2B0EB2n_EB2n_EB2n_EB2n_EB2n_EB2n_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1EB24_EB24_ENtB26_2B0EB2t_EB2t_EB2t_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1EB24_ENtB26_2B0EB24_EB2o_EB2o_EB2o_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1EB24_ENtB26_2B0EB2o_EB2o_EB2o_EB2o_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB24_EB2j_EB2j_EB2j_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1EB20_EB20_ENtB22_2B0EB2p_EB2p_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1EB20_ENtB22_2B0EB2k_EB2k_EB2k_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1EB1W_ENtB1Y_2B0EB2g_EB2g_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB1Y_2B0EB2b_EB2b_EB2b_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB1U_2B0EB27_EB27_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RINvXINICskVr04X3DebC_13generic_arraysg_0ppEINtB6_12GenericArrayppEINtNtB6_8sequence15GenericSequencepE8generatepEB6_
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB24_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECsjewTDwKBbyD_4k256
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECsjewTDwKBbyD_4k256
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB20_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECsjewTDwKBbyD_4k256
_RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECsjewTDwKBbyD_4k256
Line
Count
Source
380
2.61k
    fn generate<F>(mut f: F) -> GenericArray<T, N>
381
2.61k
    where
382
2.61k
        F: FnMut(usize) -> T,
383
2.61k
    {
384
2.61k
        unsafe {
385
2.61k
            let mut destination = ArrayBuilder::new();
386
2.61k
387
2.61k
            {
388
2.61k
                let (destination_iter, position) = destination.iter_position();
389
2.61k
390
2.61k
                destination_iter.enumerate().for_each(|(i, dst)| {
391
                    ptr::write(dst, f(i));
392
393
                    *position += 1;
394
2.61k
                });
395
2.61k
            }
396
2.61k
397
2.61k
            destination.into_inner()
398
2.61k
        }
399
2.61k
    }
_RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECsaHRNXv1Y9Bq_4p256
Line
Count
Source
380
866
    fn generate<F>(mut f: F) -> GenericArray<T, N>
381
866
    where
382
866
        F: FnMut(usize) -> T,
383
866
    {
384
866
        unsafe {
385
866
            let mut destination = ArrayBuilder::new();
386
866
387
866
            {
388
866
                let (destination_iter, position) = destination.iter_position();
389
866
390
866
                destination_iter.enumerate().for_each(|(i, dst)| {
391
                    ptr::write(dst, f(i));
392
393
                    *position += 1;
394
866
                });
395
866
            }
396
866
397
866
            destination.into_inner()
398
866
        }
399
866
    }
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB2a_2B0EB2n_EB2n_EB2n_EB2n_EB2n_EB2n_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECs23lnNM1woOA_4sha2
Unexecuted instantiation: _RINvXsg_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EEINtNtB6_8sequence15GenericSequencehE8generateNCNvXNtB6_5implsBz_NtNtCsbQ8arDwx5Xq_4core7default7Default7default0ECs23lnNM1woOA_4sha2
400
401
    #[doc(hidden)]
402
0
    fn inverted_zip<B, U, F>(
403
0
        self,
404
0
        lhs: GenericArray<B, Self::Length>,
405
0
        mut f: F,
406
0
    ) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
407
0
    where
408
0
        GenericArray<B, Self::Length>:
409
0
            GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
410
0
        Self: MappedGenericSequence<T, U>,
411
0
        Self::Length: ArrayLength<B> + ArrayLength<U>,
412
0
        F: FnMut(B, Self::Item) -> U,
413
0
    {
414
0
        unsafe {
415
0
            let mut left = ArrayConsumer::new(lhs);
416
0
            let mut right = ArrayConsumer::new(self);
417
0
418
0
            let (left_array_iter, left_position) = left.iter_position();
419
0
            let (right_array_iter, right_position) = right.iter_position();
420
0
421
0
            FromIterator::from_iter(left_array_iter.zip(right_array_iter).map(|(l, r)| {
422
0
                let left_value = ptr::read(l);
423
0
                let right_value = ptr::read(r);
424
0
425
0
                *left_position += 1;
426
0
                *right_position += 1;
427
0
428
0
                f(left_value, right_value)
429
0
            }))
430
0
        }
431
0
    }
432
433
    #[doc(hidden)]
434
0
    fn inverted_zip2<B, Lhs, U, F>(self, lhs: Lhs, mut f: F) -> MappedSequence<Lhs, B, U>
435
0
    where
436
0
        Lhs: GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
437
0
        Self: MappedGenericSequence<T, U>,
438
0
        Self::Length: ArrayLength<B> + ArrayLength<U>,
439
0
        F: FnMut(Lhs::Item, Self::Item) -> U,
440
0
    {
441
0
        unsafe {
442
0
            let mut right = ArrayConsumer::new(self);
443
0
444
0
            let (right_array_iter, right_position) = right.iter_position();
445
0
446
0
            FromIterator::from_iter(
447
0
                lhs.into_iter()
448
0
                    .zip(right_array_iter)
449
0
                    .map(|(left_value, r)| {
450
0
                        let right_value = ptr::read(r);
451
0
452
0
                        *right_position += 1;
453
0
454
0
                        f(left_value, right_value)
455
0
                    }),
456
0
            )
457
0
        }
458
0
    }
459
}
460
461
unsafe impl<T, U, N> MappedGenericSequence<T, U> for GenericArray<T, N>
462
where
463
    N: ArrayLength<T> + ArrayLength<U>,
464
    GenericArray<U, N>: GenericSequence<U, Length = N>,
465
{
466
    type Mapped = GenericArray<U, N>;
467
}
468
469
unsafe impl<T, N> FunctionalSequence<T> for GenericArray<T, N>
470
where
471
    N: ArrayLength<T>,
472
    Self: GenericSequence<T, Item = T, Length = N>,
473
{
474
0
    fn map<U, F>(self, mut f: F) -> MappedSequence<Self, T, U>
475
0
    where
476
0
        Self::Length: ArrayLength<U>,
477
0
        Self: MappedGenericSequence<T, U>,
478
0
        F: FnMut(T) -> U,
479
0
    {
480
0
        unsafe {
481
0
            let mut source = ArrayConsumer::new(self);
482
0
483
0
            let (array_iter, position) = source.iter_position();
484
0
485
0
            FromIterator::from_iter(array_iter.map(|src| {
486
0
                let value = ptr::read(src);
487
0
488
0
                *position += 1;
489
0
490
0
                f(value)
491
0
            }))
492
0
        }
493
0
    }
494
495
    #[inline]
496
0
    fn zip<B, Rhs, U, F>(self, rhs: Rhs, f: F) -> MappedSequence<Self, T, U>
497
0
    where
498
0
        Self: MappedGenericSequence<T, U>,
499
0
        Rhs: MappedGenericSequence<B, U, Mapped = MappedSequence<Self, T, U>>,
500
0
        Self::Length: ArrayLength<B> + ArrayLength<U>,
501
0
        Rhs: GenericSequence<B, Length = Self::Length>,
502
0
        F: FnMut(T, Rhs::Item) -> U,
503
0
    {
504
0
        rhs.inverted_zip(self, f)
505
0
    }
506
507
0
    fn fold<U, F>(self, init: U, mut f: F) -> U
508
0
    where
509
0
        F: FnMut(U, T) -> U,
510
0
    {
511
0
        unsafe {
512
0
            let mut source = ArrayConsumer::new(self);
513
0
514
0
            let (array_iter, position) = source.iter_position();
515
0
516
0
            array_iter.fold(init, |acc, src| {
517
0
                let value = ptr::read(src);
518
0
519
0
                *position += 1;
520
0
521
0
                f(acc, value)
522
0
            })
523
0
        }
524
0
    }
525
}
526
527
impl<T, N> GenericArray<T, N>
528
where
529
    N: ArrayLength<T>,
530
{
531
    /// Extracts a slice containing the entire array.
532
    #[inline]
533
0
    pub fn as_slice(&self) -> &[T] {
534
0
        self.deref()
535
0
    }
Unexecuted instantiation: _RNvMsj_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE8as_sliceCs4RkbDk9WRL5_5clvmr
Unexecuted instantiation: _RNvMsj_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayppE8as_sliceB5_
Unexecuted instantiation: _RNvMsj_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE8as_sliceCsjewTDwKBbyD_4k256
536
537
    /// Extracts a mutable slice containing the entire array.
538
    #[inline]
539
0
    pub fn as_mut_slice(&mut self) -> &mut [T] {
540
0
        self.deref_mut()
541
0
    }
542
543
    /// Converts slice to a generic array reference with inferred length;
544
    ///
545
    /// # Panics
546
    ///
547
    /// Panics if the slice is not equal to the length of the array.
548
    #[inline]
549
4.27k
    pub fn from_slice(slice: &[T]) -> &GenericArray<T, N> {
550
4.27k
        slice.into()
551
4.27k
    }
_RNvMsj_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB25_2B0EB2i_EB2i_EB2i_EB2i_EB2i_EE10from_sliceCs4RkbDk9WRL5_5clvmr
Line
Count
Source
549
1.42k
    pub fn from_slice(slice: &[T]) -> &GenericArray<T, N> {
550
1.42k
        slice.into()
551
1.42k
    }
_RNvMsj_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE10from_sliceCs4RkbDk9WRL5_5clvmr
Line
Count
Source
549
2.84k
    pub fn from_slice(slice: &[T]) -> &GenericArray<T, N> {
550
2.84k
        slice.into()
551
2.84k
    }
Unexecuted instantiation: _RNvMsj_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayppE10from_sliceB5_
Unexecuted instantiation: _RNvMsj_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE10from_sliceCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMsj_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE10from_sliceCsaHRNXv1Y9Bq_4p256
552
553
    /// Converts mutable slice to a mutable generic array reference
554
    ///
555
    /// # Panics
556
    ///
557
    /// Panics if the slice is not equal to the length of the array.
558
    #[inline]
559
0
    pub fn from_mut_slice(slice: &mut [T]) -> &mut GenericArray<T, N> {
560
0
        slice.into()
561
0
    }
562
}
563
564
impl<'a, T, N: ArrayLength<T>> From<&'a [T]> for &'a GenericArray<T, N> {
565
    /// Converts slice to a generic array reference with inferred length;
566
    ///
567
    /// # Panics
568
    ///
569
    /// Panics if the slice is not equal to the length of the array.
570
    #[inline]
571
7.79k
    fn from(slice: &[T]) -> &GenericArray<T, N> {
572
7.79k
        assert_eq!(slice.len(), N::USIZE);
573
574
7.79k
        unsafe { &*(slice.as_ptr() as *const GenericArray<T, N>) }
575
7.79k
    }
_RNvXsk_CskVr04X3DebC_13generic_arrayRINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB26_2B0EB2j_EB2j_EB2j_EB2j_EB2j_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRShE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
571
1.42k
    fn from(slice: &[T]) -> &GenericArray<T, N> {
572
1.42k
        assert_eq!(slice.len(), N::USIZE);
573
574
1.42k
        unsafe { &*(slice.as_ptr() as *const GenericArray<T, N>) }
575
1.42k
    }
_RNvXsk_CskVr04X3DebC_13generic_arrayRINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRShE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
571
4.57k
    fn from(slice: &[T]) -> &GenericArray<T, N> {
572
4.57k
        assert_eq!(slice.len(), N::USIZE);
573
574
4.57k
        unsafe { &*(slice.as_ptr() as *const GenericArray<T, N>) }
575
4.57k
    }
Unexecuted instantiation: _RNvXINICskVr04X3DebC_13generic_arraysk_0ppERINtB5_12GenericArrayppEINtNtCsbQ8arDwx5Xq_4core7convert4FromRSpE4fromB5_
_RNvXsk_CskVr04X3DebC_13generic_arrayRINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRShE4fromCsjewTDwKBbyD_4k256
Line
Count
Source
571
1.79k
    fn from(slice: &[T]) -> &GenericArray<T, N> {
572
1.79k
        assert_eq!(slice.len(), N::USIZE);
573
574
1.79k
        unsafe { &*(slice.as_ptr() as *const GenericArray<T, N>) }
575
1.79k
    }
Unexecuted instantiation: _RNvXsk_CskVr04X3DebC_13generic_arrayRINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EEINtNtCsbQ8arDwx5Xq_4core7convert4FromRShE4fromCsaHRNXv1Y9Bq_4p256
576
}
577
578
impl<'a, T, N: ArrayLength<T>> From<&'a mut [T]> for &'a mut GenericArray<T, N> {
579
    /// Converts mutable slice to a mutable generic array reference
580
    ///
581
    /// # Panics
582
    ///
583
    /// Panics if the slice is not equal to the length of the array.
584
    #[inline]
585
0
    fn from(slice: &mut [T]) -> &mut GenericArray<T, N> {
586
0
        assert_eq!(slice.len(), N::USIZE);
587
588
0
        unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray<T, N>) }
589
0
    }
590
}
591
592
impl<T: Clone, N> GenericArray<T, N>
593
where
594
    N: ArrayLength<T>,
595
{
596
    /// Construct a `GenericArray` from a slice by cloning its content
597
    ///
598
    /// # Panics
599
    ///
600
    /// Panics if the slice is not equal to the length of the array.
601
    #[inline]
602
2.85k
    pub fn clone_from_slice(list: &[T]) -> GenericArray<T, N> {
603
2.85k
        Self::from_exact_iter(list.iter().cloned())
604
2.85k
            .expect("Slice must be the same length as the array")
605
2.85k
    }
Unexecuted instantiation: _RNvMsm_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE16clone_from_sliceCs568wuOlRYFZ_8chia_bls
_RNvMsm_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE16clone_from_sliceCs4RkbDk9WRL5_5clvmr
Line
Count
Source
602
2.85k
    pub fn clone_from_slice(list: &[T]) -> GenericArray<T, N> {
603
2.85k
        Self::from_exact_iter(list.iter().cloned())
604
2.85k
            .expect("Slice must be the same length as the array")
605
2.85k
    }
Unexecuted instantiation: _RNvMsm_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayppE16clone_from_sliceB5_
Unexecuted instantiation: _RNvMsm_CskVr04X3DebC_13generic_arrayINtB5_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBU_IBU_IBU_IBU_IBU_NtBW_5UTermNtNtBY_3bit2B1ENtB21_2B0EB2e_EB2e_EB2e_EB2e_EE16clone_from_sliceCsjewTDwKBbyD_4k256
606
}
607
608
impl<T, N> GenericArray<T, N>
609
where
610
    N: ArrayLength<T>,
611
{
612
    /// Creates a new `GenericArray` instance from an iterator with a specific size.
613
    ///
614
    /// Returns `None` if the size is not equal to the number of elements in the `GenericArray`.
615
2.85k
    pub fn from_exact_iter<I>(iter: I) -> Option<Self>
616
2.85k
    where
617
2.85k
        I: IntoIterator<Item = T>,
618
2.85k
    {
619
2.85k
        let mut iter = iter.into_iter();
620
2.85k
621
2.85k
        unsafe {
622
2.85k
            let mut destination = ArrayBuilder::new();
623
2.85k
624
2.85k
            {
625
2.85k
                let (destination_iter, position) = destination.iter_position();
626
2.85k
627
91.4k
                destination_iter.zip(&mut iter).for_each(|(dst, src)| {
628
91.4k
                    ptr::write(dst, src);
629
91.4k
630
91.4k
                    *position += 1;
631
91.4k
                });
Unexecuted instantiation: _RNCINvMsn_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB24_2B0EB2i_EB2i_EB2i_EB2i_EE15from_exact_iterINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6cloned6ClonedINtNtNtB3d_5slice4iter4IterhEEE0Cs568wuOlRYFZ_8chia_bls
_RNCINvMsn_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB24_2B0EB2i_EB2i_EB2i_EB2i_EE15from_exact_iterINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6cloned6ClonedINtNtNtB3d_5slice4iter4IterhEEE0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
627
91.4k
                destination_iter.zip(&mut iter).for_each(|(dst, src)| {
628
91.4k
                    ptr::write(dst, src);
629
91.4k
630
91.4k
                    *position += 1;
631
91.4k
                });
Unexecuted instantiation: _RNCINvMsn_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayppE15from_exact_iterpE0B8_
Unexecuted instantiation: _RNCINvMsn_CskVr04X3DebC_13generic_arrayINtB8_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBX_IBX_IBX_IBX_IBX_NtBZ_5UTermNtNtB11_3bit2B1ENtB24_2B0EB2i_EB2i_EB2i_EB2i_EE15from_exact_iterINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6cloned6ClonedINtNtNtB3d_5slice4iter4IterhEEE0CsjewTDwKBbyD_4k256
632
2.85k
633
2.85k
                // The iterator produced fewer than `N` elements.
634
2.85k
                if *position != N::USIZE {
635
0
                    return None;
636
2.85k
                }
637
2.85k
638
2.85k
                // The iterator produced more than `N` elements.
639
2.85k
                if iter.next().is_some() {
640
0
                    return None;
641
2.85k
                }
642
2.85k
            }
643
2.85k
644
2.85k
            Some(destination.into_inner())
645
        }
646
2.85k
    }
Unexecuted instantiation: _RINvMsn_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EE15from_exact_iterINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6cloned6ClonedINtNtNtB3a_5slice4iter4IterhEEECs568wuOlRYFZ_8chia_bls
_RINvMsn_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EE15from_exact_iterINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6cloned6ClonedINtNtNtB3a_5slice4iter4IterhEEECs4RkbDk9WRL5_5clvmr
Line
Count
Source
615
2.85k
    pub fn from_exact_iter<I>(iter: I) -> Option<Self>
616
2.85k
    where
617
2.85k
        I: IntoIterator<Item = T>,
618
2.85k
    {
619
2.85k
        let mut iter = iter.into_iter();
620
2.85k
621
2.85k
        unsafe {
622
2.85k
            let mut destination = ArrayBuilder::new();
623
2.85k
624
2.85k
            {
625
2.85k
                let (destination_iter, position) = destination.iter_position();
626
2.85k
627
2.85k
                destination_iter.zip(&mut iter).for_each(|(dst, src)| {
628
                    ptr::write(dst, src);
629
630
                    *position += 1;
631
2.85k
                });
632
2.85k
633
2.85k
                // The iterator produced fewer than `N` elements.
634
2.85k
                if *position != N::USIZE {
635
0
                    return None;
636
2.85k
                }
637
2.85k
638
2.85k
                // The iterator produced more than `N` elements.
639
2.85k
                if iter.next().is_some() {
640
0
                    return None;
641
2.85k
                }
642
2.85k
            }
643
2.85k
644
2.85k
            Some(destination.into_inner())
645
        }
646
2.85k
    }
Unexecuted instantiation: _RINvMsn_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayppE15from_exact_iterpEB6_
Unexecuted instantiation: _RINvMsn_CskVr04X3DebC_13generic_arrayINtB6_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBV_IBV_IBV_IBV_IBV_NtBX_5UTermNtNtBZ_3bit2B1ENtB22_2B0EB2f_EB2f_EB2f_EB2f_EE15from_exact_iterINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters6cloned6ClonedINtNtNtB3a_5slice4iter4IterhEEECsjewTDwKBbyD_4k256
647
}
648
649
/// A reimplementation of the `transmute` function, avoiding problems
650
/// when the compiler can't prove equal sizes.
651
#[inline]
652
#[doc(hidden)]
653
11.3k
pub unsafe fn transmute<A, B>(a: A) -> B {
654
11.3k
    let a = ManuallyDrop::new(a);
655
11.3k
    ::core::ptr::read(&*a as *const A as *const B)
656
11.3k
}
Unexecuted instantiation: _RINvCskVr04X3DebC_13generic_array9transmuteINtB2_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2e_2B0EB2s_EB2s_EB2s_EB2s_EEAhj20_ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvCskVr04X3DebC_13generic_array9transmuteINtB2_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2e_2B0EB2s_EB2s_EB2s_EB2s_EEAhj20_ECs2IvCg5PL8uK_11chia_traits
_RINvCskVr04X3DebC_13generic_array9transmuteINtB2_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2e_2B0EB2s_EB2s_EB2s_EB2s_EEAhj20_ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
653
9.60k
pub unsafe fn transmute<A, B>(a: A) -> B {
654
9.60k
    let a = ManuallyDrop::new(a);
655
9.60k
    ::core::ptr::read(&*a as *const A as *const B)
656
9.60k
}
Unexecuted instantiation: _RINvCskVr04X3DebC_13generic_array9transmuteppEB2_
Unexecuted instantiation: _RINvCskVr04X3DebC_13generic_array9transmuteINtB2_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB11_IB11_IB11_IB11_IB11_NtB13_5UTermNtNtB15_3bit2B1ENtB2e_2B0EB2s_EB2s_EB2s_EB2s_EEAhj20_ECsjewTDwKBbyD_4k256
_RINvCskVr04X3DebC_13generic_array9transmuteRINtB2_12GenericArrayhINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB12_IB12_IB12_IB12_IB12_NtB14_5UTermNtNtB16_3bit2B1ENtB2f_2B0EB2t_EB2t_EB2t_EB2t_EERAhj20_ECsjewTDwKBbyD_4k256
Line
Count
Source
653
1.79k
pub unsafe fn transmute<A, B>(a: A) -> B {
654
1.79k
    let a = ManuallyDrop::new(a);
655
1.79k
    ::core::ptr::read(&*a as *const A as *const B)
656
1.79k
}
657
658
#[cfg(test)]
659
mod test {
660
    // Compile with:
661
    // cargo rustc --lib --profile test --release --
662
    //      -C target-cpu=native -C opt-level=3 --emit asm
663
    // and view the assembly to make sure test_assembly generates
664
    // SIMD instructions instead of a naive loop.
665
666
    #[inline(never)]
667
    pub fn black_box<T>(val: T) -> T {
668
        use core::{mem, ptr};
669
670
        let ret = unsafe { ptr::read_volatile(&val) };
671
        mem::forget(val);
672
        ret
673
    }
674
675
    #[test]
676
    fn test_assembly() {
677
        use crate::functional::*;
678
679
        let a = black_box(arr![i32; 1, 3, 5, 7]);
680
        let b = black_box(arr![i32; 2, 4, 6, 8]);
681
682
        let c = (&a).zip(b, |l, r| l + r);
683
684
        let d = a.fold(0, |a, x| a + x);
685
686
        assert_eq!(c, arr![i32; 3, 7, 11, 15]);
687
688
        assert_eq!(d, 16);
689
    }
690
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/generic-array-0.14.7/src/sequence.rs
Line
Count
Source
1
//! Useful traits for manipulating sequences of data stored in `GenericArray`s
2
3
use super::*;
4
use core::ops::{Add, Sub};
5
use core::mem::MaybeUninit;
6
use core::ptr;
7
use typenum::operator_aliases::*;
8
9
/// Defines some sequence with an associated length and iteration capabilities.
10
///
11
/// This is useful for passing N-length generic arrays as generics.
12
pub unsafe trait GenericSequence<T>: Sized + IntoIterator {
13
    /// `GenericArray` associated length
14
    type Length: ArrayLength<T>;
15
16
    /// Concrete sequence type used in conjuction with reference implementations of `GenericSequence`
17
    type Sequence: GenericSequence<T, Length = Self::Length> + FromIterator<T>;
18
19
    /// Initializes a new sequence instance using the given function.
20
    ///
21
    /// If the generator function panics while initializing the sequence,
22
    /// any already initialized elements will be dropped.
23
    fn generate<F>(f: F) -> Self::Sequence
24
    where
25
        F: FnMut(usize) -> T;
26
27
    #[doc(hidden)]
28
0
    fn inverted_zip<B, U, F>(
29
0
        self,
30
0
        lhs: GenericArray<B, Self::Length>,
31
0
        mut f: F,
32
0
    ) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
33
0
    where
34
0
        GenericArray<B, Self::Length>: GenericSequence<B, Length = Self::Length>
35
0
            + MappedGenericSequence<B, U>,
36
0
        Self: MappedGenericSequence<T, U>,
37
0
        Self::Length: ArrayLength<B> + ArrayLength<U>,
38
0
        F: FnMut(B, Self::Item) -> U,
39
0
    {
40
0
        unsafe {
41
0
            let mut left = ArrayConsumer::new(lhs);
42
0
43
0
            let (left_array_iter, left_position) = left.iter_position();
44
0
45
0
            FromIterator::from_iter(left_array_iter.zip(self.into_iter()).map(
46
0
                |(l, right_value)| {
47
0
                        let left_value = ptr::read(l);
48
0
49
0
                        *left_position += 1;
50
0
51
0
                        f(left_value, right_value)
52
0
                },
53
0
            ))
54
0
        }
55
0
    }
56
57
    #[doc(hidden)]
58
0
    fn inverted_zip2<B, Lhs, U, F>(self, lhs: Lhs, mut f: F) -> MappedSequence<Lhs, B, U>
59
0
    where
60
0
        Lhs: GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
61
0
        Self: MappedGenericSequence<T, U>,
62
0
        Self::Length: ArrayLength<B> + ArrayLength<U>,
63
0
        F: FnMut(Lhs::Item, Self::Item) -> U,
64
0
    {
65
0
        FromIterator::from_iter(lhs.into_iter().zip(self.into_iter()).map(|(l, r)| f(l, r)))
66
0
    }
67
}
68
69
/// Accessor for `GenericSequence` item type, which is really `IntoIterator::Item`
70
///
71
/// For deeply nested generic mapped sequence types, like shown in `tests/generics.rs`,
72
/// this can be useful for keeping things organized.
73
pub type SequenceItem<T> = <T as IntoIterator>::Item;
74
75
unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a S
76
where
77
    &'a S: IntoIterator,
78
{
79
    type Length = S::Length;
80
    type Sequence = S::Sequence;
81
82
    #[inline]
83
0
    fn generate<F>(f: F) -> Self::Sequence
84
0
    where
85
0
        F: FnMut(usize) -> T,
86
0
    {
87
0
        S::generate(f)
88
0
    }
89
}
90
91
unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a mut S
92
where
93
    &'a mut S: IntoIterator,
94
{
95
    type Length = S::Length;
96
    type Sequence = S::Sequence;
97
98
    #[inline]
99
0
    fn generate<F>(f: F) -> Self::Sequence
100
0
    where
101
0
        F: FnMut(usize) -> T,
102
0
    {
103
0
        S::generate(f)
104
0
    }
105
}
106
107
/// Defines any `GenericSequence` which can be lengthened or extended by appending
108
/// or prepending an element to it.
109
///
110
/// Any lengthened sequence can be shortened back to the original using `pop_front` or `pop_back`
111
pub unsafe trait Lengthen<T>: Sized + GenericSequence<T> {
112
    /// `GenericSequence` that has one more element than `Self`
113
    type Longer: Shorten<T, Shorter = Self>;
114
115
    /// Returns a new array with the given element appended to the end of it.
116
    ///
117
    /// Example:
118
    ///
119
    /// ```rust
120
    /// # use generic_array::{arr, sequence::Lengthen};
121
    /// # fn main() {
122
    /// let a = arr![i32; 1, 2, 3];
123
    ///
124
    /// let b = a.append(4);
125
    ///
126
    /// assert_eq!(b, arr![i32; 1, 2, 3, 4]);
127
    /// # }
128
    /// ```
129
    fn append(self, last: T) -> Self::Longer;
130
131
    /// Returns a new array with the given element prepended to the front of it.
132
    ///
133
    /// Example:
134
    ///
135
    /// ```rust
136
    /// # use generic_array::{arr, sequence::Lengthen};
137
    /// # fn main() {
138
    /// let a = arr![i32; 1, 2, 3];
139
    ///
140
    /// let b = a.prepend(4);
141
    ///
142
    /// assert_eq!(b, arr![i32; 4, 1, 2, 3]);
143
    /// # }
144
    /// ```
145
    fn prepend(self, first: T) -> Self::Longer;
146
}
147
148
/// Defines a `GenericSequence` which can be shortened by removing the first or last element from it.
149
///
150
/// Additionally, any shortened sequence can be lengthened by
151
/// appending or prepending an element to it.
152
pub unsafe trait Shorten<T>: Sized + GenericSequence<T> {
153
    /// `GenericSequence` that has one less element than `Self`
154
    type Shorter: Lengthen<T, Longer = Self>;
155
156
    /// Returns a new array without the last element, and the last element.
157
    ///
158
    /// Example:
159
    ///
160
    /// ```rust
161
    /// # use generic_array::{arr, sequence::Shorten};
162
    /// # fn main() {
163
    /// let a = arr![i32; 1, 2, 3, 4];
164
    ///
165
    /// let (init, last) = a.pop_back();
166
    ///
167
    /// assert_eq!(init, arr![i32; 1, 2, 3]);
168
    /// assert_eq!(last, 4);
169
    /// # }
170
    /// ```
171
    fn pop_back(self) -> (Self::Shorter, T);
172
173
    /// Returns a new array without the first element, and the first element.
174
    /// Example:
175
    ///
176
    /// ```rust
177
    /// # use generic_array::{arr, sequence::Shorten};
178
    /// # fn main() {
179
    /// let a = arr![i32; 1, 2, 3, 4];
180
    ///
181
    /// let (head, tail) = a.pop_front();
182
    ///
183
    /// assert_eq!(head, 1);
184
    /// assert_eq!(tail, arr![i32; 2, 3, 4]);
185
    /// # }
186
    /// ```
187
    fn pop_front(self) -> (T, Self::Shorter);
188
}
189
190
unsafe impl<T, N: ArrayLength<T>> Lengthen<T> for GenericArray<T, N>
191
where
192
    N: Add<B1>,
193
    Add1<N>: ArrayLength<T>,
194
    Add1<N>: Sub<B1, Output = N>,
195
    Sub1<Add1<N>>: ArrayLength<T>,
196
{
197
    type Longer = GenericArray<T, Add1<N>>;
198
199
0
    fn append(self, last: T) -> Self::Longer {
200
0
        let mut longer: MaybeUninit<Self::Longer> = MaybeUninit::uninit();
201
0
202
0
        // Note this is *mut Self, so add(1) increments by the whole array
203
0
        let out_ptr = longer.as_mut_ptr() as *mut Self;
204
0
205
0
        unsafe {
206
0
            // write self first
207
0
            ptr::write(out_ptr, self);
208
0
            // increment past self, then write the last
209
0
            ptr::write(out_ptr.add(1) as *mut T, last);
210
0
211
0
            longer.assume_init()
212
0
        }
213
0
    }
214
215
0
    fn prepend(self, first: T) -> Self::Longer {
216
0
        let mut longer: MaybeUninit<Self::Longer> = MaybeUninit::uninit();
217
0
218
0
        // Note this is *mut T, so add(1) increments by a single T
219
0
        let out_ptr = longer.as_mut_ptr() as *mut T;
220
0
221
0
        unsafe {
222
0
            // write the first at the start
223
0
            ptr::write(out_ptr, first);
224
0
            // increment past the first, then write self
225
0
            ptr::write(out_ptr.add(1) as *mut Self, self);
226
0
227
0
            longer.assume_init()
228
0
        }
229
0
    }
230
}
231
232
unsafe impl<T, N: ArrayLength<T>> Shorten<T> for GenericArray<T, N>
233
where
234
    N: Sub<B1>,
235
    Sub1<N>: ArrayLength<T>,
236
    Sub1<N>: Add<B1, Output = N>,
237
    Add1<Sub1<N>>: ArrayLength<T>,
238
{
239
    type Shorter = GenericArray<T, Sub1<N>>;
240
241
0
    fn pop_back(self) -> (Self::Shorter, T) {
242
0
        let whole = ManuallyDrop::new(self);
243
0
244
0
        unsafe {
245
0
            let init = ptr::read(whole.as_ptr() as _);
246
0
            let last = ptr::read(whole.as_ptr().add(Sub1::<N>::USIZE) as _);
247
0
248
0
            (init, last)
249
0
        }
250
0
    }
251
252
0
    fn pop_front(self) -> (T, Self::Shorter) {
253
0
        // ensure this doesn't get dropped
254
0
        let whole = ManuallyDrop::new(self);
255
0
256
0
        unsafe {
257
0
            let head = ptr::read(whole.as_ptr() as _);
258
0
            let tail = ptr::read(whole.as_ptr().offset(1) as _);
259
0
260
0
            (head, tail)
261
0
        }
262
0
    }
263
}
264
265
/// Defines a `GenericSequence` that can be split into two parts at a given pivot index.
266
pub unsafe trait Split<T, K>: GenericSequence<T>
267
where
268
    K: ArrayLength<T>,
269
{
270
    /// First part of the resulting split array
271
    type First: GenericSequence<T>;
272
    /// Second part of the resulting split array
273
    type Second: GenericSequence<T>;
274
275
    /// Splits an array at the given index, returning the separate parts of the array.
276
    fn split(self) -> (Self::First, Self::Second);
277
}
278
279
unsafe impl<T, N, K> Split<T, K> for GenericArray<T, N>
280
where
281
    N: ArrayLength<T>,
282
    K: ArrayLength<T>,
283
    N: Sub<K>,
284
    Diff<N, K>: ArrayLength<T>,
285
{
286
    type First = GenericArray<T, K>;
287
    type Second = GenericArray<T, Diff<N, K>>;
288
289
0
    fn split(self) -> (Self::First, Self::Second) {
290
0
        unsafe {
291
0
            // ensure this doesn't get dropped
292
0
            let whole = ManuallyDrop::new(self);
293
0
294
0
            let head = ptr::read(whole.as_ptr() as *const _);
295
0
            let tail = ptr::read(whole.as_ptr().add(K::USIZE) as *const _);
296
0
297
0
            (head, tail)
298
0
        }
299
0
    }
300
}
301
302
unsafe impl<'a, T, N, K> Split<T, K> for &'a GenericArray<T, N>
303
where
304
    N: ArrayLength<T>,
305
    K: ArrayLength<T> + 'static,
306
    N: Sub<K>,
307
    Diff<N, K>: ArrayLength<T>,
308
{
309
    type First = &'a GenericArray<T, K>;
310
    type Second = &'a GenericArray<T, Diff<N, K>>;
311
312
0
    fn split(self) -> (Self::First, Self::Second) {
313
0
        unsafe {
314
0
            let ptr_to_first: *const T = self.as_ptr();
315
0
            let head = &*(ptr_to_first as *const _);
316
0
            let tail = &*(ptr_to_first.add(K::USIZE) as *const _);
317
0
            (head, tail)
318
0
        }
319
0
    }
320
}
321
322
unsafe impl<'a, T, N, K> Split<T, K> for &'a mut GenericArray<T, N>
323
where
324
    N: ArrayLength<T>,
325
    K: ArrayLength<T> + 'static,
326
    N: Sub<K>,
327
    Diff<N, K>: ArrayLength<T>,
328
{
329
    type First = &'a mut GenericArray<T, K>;
330
    type Second = &'a mut GenericArray<T, Diff<N, K>>;
331
332
0
    fn split(self) -> (Self::First, Self::Second) {
333
0
        unsafe {
334
0
            let ptr_to_first: *mut T = self.as_mut_ptr();
335
0
            let head = &mut *(ptr_to_first as *mut _);
336
0
            let tail = &mut *(ptr_to_first.add(K::USIZE) as *mut _);
337
0
            (head, tail)
338
0
        }
339
0
    }
340
}
341
342
/// Defines `GenericSequence`s which can be joined together, forming a larger array.
343
pub unsafe trait Concat<T, M>: GenericSequence<T>
344
where
345
    M: ArrayLength<T>,
346
{
347
    /// Sequence to be concatenated with `self`
348
    type Rest: GenericSequence<T, Length = M>;
349
350
    /// Resulting sequence formed by the concatenation.
351
    type Output: GenericSequence<T>;
352
353
    /// Concatenate, or join, two sequences.
354
    fn concat(self, rest: Self::Rest) -> Self::Output;
355
}
356
357
unsafe impl<T, N, M> Concat<T, M> for GenericArray<T, N>
358
where
359
    N: ArrayLength<T> + Add<M>,
360
    M: ArrayLength<T>,
361
    Sum<N, M>: ArrayLength<T>,
362
{
363
    type Rest = GenericArray<T, M>;
364
    type Output = GenericArray<T, Sum<N, M>>;
365
366
0
    fn concat(self, rest: Self::Rest) -> Self::Output {
367
0
        let mut output: MaybeUninit<Self::Output> = MaybeUninit::uninit();
368
0
369
0
        let out_ptr = output.as_mut_ptr() as *mut Self;
370
0
371
0
        unsafe {
372
0
            // write all of self to the pointer
373
0
            ptr::write(out_ptr, self);
374
0
            // increment past self, then write the rest
375
0
            ptr::write(out_ptr.add(1) as *mut _, rest);
376
0
377
0
            output.assume_init()
378
0
        }
379
0
    }
380
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.15/src/error.rs
Line
Count
Source
1
use core::{fmt, num::NonZeroU32};
2
3
/// A small and `no_std` compatible error type
4
///
5
/// The [`Error::raw_os_error()`] will indicate if the error is from the OS, and
6
/// if so, which error code the OS gave the application. If such an error is
7
/// encountered, please consult with your system documentation.
8
///
9
/// Internally this type is a NonZeroU32, with certain values reserved for
10
/// certain purposes, see [`Error::INTERNAL_START`] and [`Error::CUSTOM_START`].
11
///
12
/// *If this crate's `"std"` Cargo feature is enabled*, then:
13
/// - [`getrandom::Error`][Error] implements
14
///   [`std::error::Error`](https://doc.rust-lang.org/std/error/trait.Error.html)
15
/// - [`std::io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html) implements
16
///   [`From<getrandom::Error>`](https://doc.rust-lang.org/std/convert/trait.From.html).
17
#[derive(Copy, Clone, Eq, PartialEq)]
18
pub struct Error(NonZeroU32);
19
20
0
const fn internal_error(n: u16) -> Error {
21
0
    // SAFETY: code > 0 as INTERNAL_START > 0 and adding n won't overflow a u32.
22
0
    let code = Error::INTERNAL_START + (n as u32);
23
0
    Error(unsafe { NonZeroU32::new_unchecked(code) })
24
0
}
25
26
impl Error {
27
    /// This target/platform is not supported by `getrandom`.
28
    pub const UNSUPPORTED: Error = internal_error(0);
29
    /// The platform-specific `errno` returned a non-positive value.
30
    pub const ERRNO_NOT_POSITIVE: Error = internal_error(1);
31
    /// Encountered an unexpected situation which should not happen in practice.
32
    pub const UNEXPECTED: Error = internal_error(2);
33
    /// Call to [`CCRandomGenerateBytes`](https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html) failed
34
    /// on iOS, tvOS, or waatchOS.
35
    // TODO: Update this constant name in the next breaking release.
36
    pub const IOS_SEC_RANDOM: Error = internal_error(3);
37
    /// Call to Windows [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom) failed.
38
    pub const WINDOWS_RTL_GEN_RANDOM: Error = internal_error(4);
39
    /// RDRAND instruction failed due to a hardware issue.
40
    pub const FAILED_RDRAND: Error = internal_error(5);
41
    /// RDRAND instruction unsupported on this target.
42
    pub const NO_RDRAND: Error = internal_error(6);
43
    /// The environment does not support the Web Crypto API.
44
    pub const WEB_CRYPTO: Error = internal_error(7);
45
    /// Calling Web Crypto API `crypto.getRandomValues` failed.
46
    pub const WEB_GET_RANDOM_VALUES: Error = internal_error(8);
47
    /// On VxWorks, call to `randSecure` failed (random number generator is not yet initialized).
48
    pub const VXWORKS_RAND_SECURE: Error = internal_error(11);
49
    /// Node.js does not have the `crypto` CommonJS module.
50
    pub const NODE_CRYPTO: Error = internal_error(12);
51
    /// Calling Node.js function `crypto.randomFillSync` failed.
52
    pub const NODE_RANDOM_FILL_SYNC: Error = internal_error(13);
53
    /// Called from an ES module on Node.js. This is unsupported, see:
54
    /// <https://docs.rs/getrandom#nodejs-es-module-support>.
55
    pub const NODE_ES_MODULE: Error = internal_error(14);
56
57
    /// Codes below this point represent OS Errors (i.e. positive i32 values).
58
    /// Codes at or above this point, but below [`Error::CUSTOM_START`] are
59
    /// reserved for use by the `rand` and `getrandom` crates.
60
    pub const INTERNAL_START: u32 = 1 << 31;
61
62
    /// Codes at or above this point can be used by users to define their own
63
    /// custom errors.
64
    pub const CUSTOM_START: u32 = (1 << 31) + (1 << 30);
65
66
    /// Extract the raw OS error code (if this error came from the OS)
67
    ///
68
    /// This method is identical to [`std::io::Error::raw_os_error()`][1], except
69
    /// that it works in `no_std` contexts. If this method returns `None`, the
70
    /// error value can still be formatted via the `Display` implementation.
71
    ///
72
    /// [1]: https://doc.rust-lang.org/std/io/struct.Error.html#method.raw_os_error
73
    #[inline]
74
0
    pub fn raw_os_error(self) -> Option<i32> {
75
0
        if self.0.get() < Self::INTERNAL_START {
76
0
            match () {
77
0
                #[cfg(target_os = "solid_asp3")]
78
0
                // On SOLID, negate the error code again to obtain the original
79
0
                // error code.
80
0
                () => Some(-(self.0.get() as i32)),
81
0
                #[cfg(not(target_os = "solid_asp3"))]
82
0
                () => Some(self.0.get() as i32),
83
            }
84
        } else {
85
0
            None
86
        }
87
0
    }
88
89
    /// Extract the bare error code.
90
    ///
91
    /// This code can either come from the underlying OS, or be a custom error.
92
    /// Use [`Error::raw_os_error()`] to disambiguate.
93
    #[inline]
94
0
    pub const fn code(self) -> NonZeroU32 {
95
0
        self.0
96
0
    }
97
}
98
99
cfg_if! {
100
    if #[cfg(unix)] {
101
0
        fn os_err(errno: i32, buf: &mut [u8]) -> Option<&str> {
102
0
            let buf_ptr = buf.as_mut_ptr() as *mut libc::c_char;
103
0
            if unsafe { libc::strerror_r(errno, buf_ptr, buf.len()) } != 0 {
104
0
                return None;
105
0
            }
106
0
107
0
            // Take up to trailing null byte
108
0
            let n = buf.len();
109
0
            let idx = buf.iter().position(|&b| b == 0).unwrap_or(n);
110
0
            core::str::from_utf8(&buf[..idx]).ok()
111
0
        }
112
    } else {
113
        fn os_err(_errno: i32, _buf: &mut [u8]) -> Option<&str> {
114
            None
115
        }
116
    }
117
}
118
119
impl fmt::Debug for Error {
120
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121
0
        let mut dbg = f.debug_struct("Error");
122
0
        if let Some(errno) = self.raw_os_error() {
123
0
            dbg.field("os_error", &errno);
124
0
            let mut buf = [0u8; 128];
125
0
            if let Some(err) = os_err(errno, &mut buf) {
126
0
                dbg.field("description", &err);
127
0
            }
128
0
        } else if let Some(desc) = internal_desc(*self) {
129
0
            dbg.field("internal_code", &self.0.get());
130
0
            dbg.field("description", &desc);
131
0
        } else {
132
0
            dbg.field("unknown_code", &self.0.get());
133
0
        }
134
0
        dbg.finish()
135
0
    }
136
}
137
138
impl fmt::Display for Error {
139
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140
0
        if let Some(errno) = self.raw_os_error() {
141
0
            let mut buf = [0u8; 128];
142
0
            match os_err(errno, &mut buf) {
143
0
                Some(err) => err.fmt(f),
144
0
                None => write!(f, "OS Error: {}", errno),
145
            }
146
0
        } else if let Some(desc) = internal_desc(*self) {
147
0
            f.write_str(desc)
148
        } else {
149
0
            write!(f, "Unknown Error: {}", self.0.get())
150
        }
151
0
    }
152
}
153
154
impl From<NonZeroU32> for Error {
155
0
    fn from(code: NonZeroU32) -> Self {
156
0
        Self(code)
157
0
    }
158
}
159
160
0
fn internal_desc(error: Error) -> Option<&'static str> {
161
0
    match error {
162
0
        Error::UNSUPPORTED => Some("getrandom: this target is not supported"),
163
0
        Error::ERRNO_NOT_POSITIVE => Some("errno: did not return a positive value"),
164
0
        Error::UNEXPECTED => Some("unexpected situation"),
165
0
        Error::IOS_SEC_RANDOM => Some("SecRandomCopyBytes: iOS Security framework failure"),
166
0
        Error::WINDOWS_RTL_GEN_RANDOM => Some("RtlGenRandom: Windows system function failure"),
167
0
        Error::FAILED_RDRAND => Some("RDRAND: failed multiple times: CPU issue likely"),
168
0
        Error::NO_RDRAND => Some("RDRAND: instruction not supported"),
169
0
        Error::WEB_CRYPTO => Some("Web Crypto API is unavailable"),
170
0
        Error::WEB_GET_RANDOM_VALUES => Some("Calling Web API crypto.getRandomValues failed"),
171
0
        Error::VXWORKS_RAND_SECURE => Some("randSecure: VxWorks RNG module is not initialized"),
172
0
        Error::NODE_CRYPTO => Some("Node.js crypto CommonJS module is unavailable"),
173
0
        Error::NODE_RANDOM_FILL_SYNC => Some("Calling Node.js API crypto.randomFillSync failed"),
174
0
        Error::NODE_ES_MODULE => Some("Node.js ES modules are not directly supported, see https://docs.rs/getrandom#nodejs-es-module-support"),
175
0
        _ => None,
176
    }
177
0
}
178
179
#[cfg(test)]
180
mod tests {
181
    use super::Error;
182
    use core::mem::size_of;
183
184
    #[test]
185
    fn test_size() {
186
        assert_eq!(size_of::<Error>(), 4);
187
        assert_eq!(size_of::<Result<(), Error>>(), 4);
188
    }
189
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.15/src/error_impls.rs
Line
Count
Source
1
extern crate std;
2
3
use crate::Error;
4
use std::io;
5
6
impl From<Error> for io::Error {
7
0
    fn from(err: Error) -> Self {
8
0
        match err.raw_os_error() {
9
0
            Some(errno) => io::Error::from_raw_os_error(errno),
10
0
            None => io::Error::new(io::ErrorKind::Other, err),
11
        }
12
0
    }
13
}
14
15
impl std::error::Error for Error {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.15/src/lazy.rs
Line
Count
Source
1
use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
2
3
// This structure represents a lazily initialized static usize value. Useful
4
// when it is preferable to just rerun initialization instead of locking.
5
// unsync_init will invoke an init() function until it succeeds, then return the
6
// cached value for future calls.
7
//
8
// unsync_init supports init() "failing". If the init() method returns UNINIT,
9
// that value will be returned as normal, but will not be cached.
10
//
11
// Users should only depend on the _value_ returned by init() functions.
12
// Specifically, for the following init() function:
13
//      fn init() -> usize {
14
//          a();
15
//          let v = b();
16
//          c();
17
//          v
18
//      }
19
// the effects of c() or writes to shared memory will not necessarily be
20
// observed and additional synchronization methods may be needed.
21
pub(crate) struct LazyUsize(AtomicUsize);
22
23
impl LazyUsize {
24
0
    pub const fn new() -> Self {
25
0
        Self(AtomicUsize::new(Self::UNINIT))
26
0
    }
27
28
    // The initialization is not completed.
29
    pub const UNINIT: usize = usize::max_value();
30
31
    // Runs the init() function at most once, returning the value of some run of
32
    // init(). Multiple callers can run their init() functions in parallel.
33
    // init() should always return the same value, if it succeeds.
34
0
    pub fn unsync_init(&self, init: impl FnOnce() -> usize) -> usize {
35
0
        // Relaxed ordering is fine, as we only have a single atomic variable.
36
0
        let mut val = self.0.load(Relaxed);
37
0
        if val == Self::UNINIT {
38
0
            val = init();
39
0
            self.0.store(val, Relaxed);
40
0
        }
41
0
        val
42
0
    }
43
}
44
45
// Identical to LazyUsize except with bool instead of usize.
46
pub(crate) struct LazyBool(LazyUsize);
47
48
impl LazyBool {
49
0
    pub const fn new() -> Self {
50
0
        Self(LazyUsize::new())
51
0
    }
52
53
0
    pub fn unsync_init(&self, init: impl FnOnce() -> bool) -> bool {
54
0
        self.0.unsync_init(|| init() as usize) != 0
55
0
    }
56
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.15/src/lib.rs
Line
Count
Source
1
//! Interface to the operating system's random number generator.
2
//!
3
//! # Supported targets
4
//!
5
//! | Target            | Target Triple      | Implementation
6
//! | ----------------- | ------------------ | --------------
7
//! | Linux, Android    | `*‑linux‑*`        | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random`
8
//! | Windows           | `*‑windows‑*`      | [`BCryptGenRandom`]
9
//! | macOS             | `*‑apple‑darwin`   | [`getentropy`][3]
10
//! | iOS, tvOS, watchOS | `*‑apple‑ios`, `*-apple-tvos`, `*-apple-watchos` | [`CCRandomGenerateBytes`]
11
//! | FreeBSD           | `*‑freebsd`        | [`getrandom`][5]
12
//! | OpenBSD           | `*‑openbsd`        | [`getentropy`][7]
13
//! | NetBSD            | `*‑netbsd`         | [`getrandom`][16] if available, otherwise [`kern.arandom`][8]
14
//! | Dragonfly BSD     | `*‑dragonfly`      | [`getrandom`][9]
15
//! | Solaris           | `*‑solaris`        | [`getrandom`][11] (with `GRND_RANDOM`)
16
//! | illumos           | `*‑illumos`        | [`getrandom`][12]
17
//! | Fuchsia OS        | `*‑fuchsia`        | [`cprng_draw`]
18
//! | Redox             | `*‑redox`          | `/dev/urandom`
19
//! | Haiku             | `*‑haiku`          | `/dev/urandom` (identical to `/dev/random`)
20
//! | Hermit            | `*-hermit`         | [`sys_read_entropy`]
21
//! | Hurd              | `*-hurd-*`         | [`getrandom`][17]
22
//! | SGX               | `x86_64‑*‑sgx`     | [`RDRAND`]
23
//! | VxWorks           | `*‑wrs‑vxworks‑*`  | `randABytes` after checking entropy pool initialization with `randSecure`
24
//! | ESP-IDF           | `*‑espidf`         | [`esp_fill_random`]
25
//! | Emscripten        | `*‑emscripten`     | [`getentropy`][13]
26
//! | WASI              | `wasm32‑wasi`      | [`random_get`]
27
//! | Web Browser and Node.js | `wasm*‑*‑unknown` | [`Crypto.getRandomValues`] if available, then [`crypto.randomFillSync`] if on Node.js, see [WebAssembly support]
28
//! | SOLID             | `*-kmc-solid_*`    | `SOLID_RNG_SampleRandomBytes`
29
//! | Nintendo 3DS      | `*-nintendo-3ds`   | [`getrandom`][18]
30
//! | PS Vita           | `*-vita-*`         | [`getentropy`][13]
31
//! | QNX Neutrino      | `*‑nto-qnx*`       | [`/dev/urandom`][14] (identical to `/dev/random`)
32
//! | AIX               | `*-ibm-aix`        | [`/dev/urandom`][15]
33
//!
34
//! Pull Requests that add support for new targets to `getrandom` are always welcome.
35
//!
36
//! ## Unsupported targets
37
//!
38
//! By default, `getrandom` will not compile on unsupported targets, but certain
39
//! features allow a user to select a "fallback" implementation if no supported
40
//! implementation exists.
41
//!
42
//! All of the below mechanisms only affect unsupported
43
//! targets. Supported targets will _always_ use their supported implementations.
44
//! This prevents a crate from overriding a secure source of randomness
45
//! (either accidentally or intentionally).
46
//!
47
//! ## `/dev/urandom` fallback on Linux and Android
48
//!
49
//! On Linux targets the fallback is present only if either `target_env` is `musl`,
50
//! or `target_arch` is one of the following: `aarch64`, `arm`, `powerpc`, `powerpc64`,
51
//! `s390x`, `x86`, `x86_64`. Other supported targets [require][platform-support]
52
//! kernel versions which support `getrandom` system call, so fallback is not needed.
53
//!
54
//! On Android targets the fallback is present only for the following `target_arch`es:
55
//! `aarch64`, `arm`, `x86`, `x86_64`. Other `target_arch`es (e.g. RISC-V) require
56
//! sufficiently high API levels.
57
//!
58
//! The fallback can be disabled by enabling the `linux_disable_fallback` crate feature.
59
//! Note that doing so will bump minimum supported Linux kernel version to 3.17 and
60
//! Android API level to 23 (Marshmallow).
61
//!
62
//! ### RDRAND on x86
63
//!
64
//! *If the `rdrand` Cargo feature is enabled*, `getrandom` will fallback to using
65
//! the [`RDRAND`] instruction to get randomness on `no_std` `x86`/`x86_64`
66
//! targets. This feature has no effect on other CPU architectures.
67
//!
68
//! ### WebAssembly support
69
//!
70
//! This crate fully supports the
71
//! [`wasm32-wasi`](https://github.com/CraneStation/wasi) and
72
//! [`wasm32-unknown-emscripten`](https://www.hellorust.com/setup/emscripten/)
73
//! targets. However, the `wasm32-unknown-unknown` target (i.e. the target used
74
//! by `wasm-pack`) is not automatically
75
//! supported since, from the target name alone, we cannot deduce which
76
//! JavaScript interface is in use (or if JavaScript is available at all).
77
//!
78
//! Instead, *if the `js` Cargo feature is enabled*, this crate will assume
79
//! that you are building for an environment containing JavaScript, and will
80
//! call the appropriate methods. Both web browser (main window and Web Workers)
81
//! and Node.js environments are supported, invoking the methods
82
//! [described above](#supported-targets) using the [`wasm-bindgen`] toolchain.
83
//!
84
//! To enable the `js` Cargo feature, add the following to the `dependencies`
85
//! section in your `Cargo.toml` file:
86
//! ```toml
87
//! [dependencies]
88
//! getrandom = { version = "0.2", features = ["js"] }
89
//! ```
90
//!
91
//! This can be done even if `getrandom` is not a direct dependency. Cargo
92
//! allows crates to enable features for indirect dependencies.
93
//!
94
//! This feature should only be enabled for binary, test, or benchmark crates.
95
//! Library crates should generally not enable this feature, leaving such a
96
//! decision to *users* of their library. Also, libraries should not introduce
97
//! their own `js` features *just* to enable `getrandom`'s `js` feature.
98
//!
99
//! This feature has no effect on targets other than `wasm32-unknown-unknown`.
100
//!
101
//! #### Node.js ES module support
102
//!
103
//! Node.js supports both [CommonJS modules] and [ES modules]. Due to
104
//! limitations in wasm-bindgen's [`module`] support, we cannot directly
105
//! support ES Modules running on Node.js. However, on Node v15 and later, the
106
//! module author can add a simple shim to support the Web Cryptography API:
107
//! ```js
108
//! import { webcrypto } from 'node:crypto'
109
//! globalThis.crypto = webcrypto
110
//! ```
111
//! This crate will then use the provided `webcrypto` implementation.
112
//!
113
//! ### Platform Support
114
//! This crate generally supports the same operating system and platform versions
115
//! that the Rust standard library does. Additional targets may be supported using
116
//! pluggable custom implementations.
117
//!
118
//! This means that as Rust drops support for old versions of operating systems
119
//! (such as old Linux kernel versions, Android API levels, etc) in stable releases,
120
//! `getrandom` may create new patch releases (`0.N.x`) that remove support for
121
//! outdated platform versions.
122
//!
123
//! ### Custom implementations
124
//!
125
//! The [`register_custom_getrandom!`] macro allows a user to mark their own
126
//! function as the backing implementation for [`getrandom`]. See the macro's
127
//! documentation for more information about writing and registering your own
128
//! custom implementations.
129
//!
130
//! Note that registering a custom implementation only has an effect on targets
131
//! that would otherwise not compile. Any supported targets (including those
132
//! using `rdrand` and `js` Cargo features) continue using their normal
133
//! implementations even if a function is registered.
134
//!
135
//! ## Early boot
136
//!
137
//! Sometimes, early in the boot process, the OS has not collected enough
138
//! entropy to securely seed its RNG. This is especially common on virtual
139
//! machines, where standard "random" events are hard to come by.
140
//!
141
//! Some operating system interfaces always block until the RNG is securely
142
//! seeded. This can take anywhere from a few seconds to more than a minute.
143
//! A few (Linux, NetBSD and Solaris) offer a choice between blocking and
144
//! getting an error; in these cases, we always choose to block.
145
//!
146
//! On Linux (when the `getrandom` system call is not available), reading from
147
//! `/dev/urandom` never blocks, even when the OS hasn't collected enough
148
//! entropy yet. To avoid returning low-entropy bytes, we first poll
149
//! `/dev/random` and only switch to `/dev/urandom` once this has succeeded.
150
//!
151
//! On OpenBSD, this kind of entropy accounting isn't available, and on
152
//! NetBSD, blocking on it is discouraged. On these platforms, nonblocking
153
//! interfaces are used, even when reliable entropy may not be available.
154
//! On the platforms where it is used, the reliability of entropy accounting
155
//! itself isn't free from controversy. This library provides randomness
156
//! sourced according to the platform's best practices, but each platform has
157
//! its own limits on the grade of randomness it can promise in environments
158
//! with few sources of entropy.
159
//!
160
//! ## Error handling
161
//!
162
//! We always choose failure over returning known insecure "random" bytes. In
163
//! general, on supported platforms, failure is highly unlikely, though not
164
//! impossible. If an error does occur, then it is likely that it will occur
165
//! on every call to `getrandom`, hence after the first successful call one
166
//! can be reasonably confident that no errors will occur.
167
//!
168
//! [1]: https://manned.org/getrandom.2
169
//! [2]: https://manned.org/urandom.4
170
//! [3]: https://www.unix.com/man-page/mojave/2/getentropy/
171
//! [4]: https://www.unix.com/man-page/mojave/4/urandom/
172
//! [5]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable
173
//! [7]: https://man.openbsd.org/getentropy.2
174
//! [8]: https://man.netbsd.org/sysctl.7
175
//! [9]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom
176
//! [11]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
177
//! [12]: https://illumos.org/man/2/getrandom
178
//! [13]: https://github.com/emscripten-core/emscripten/pull/12240
179
//! [14]: https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.utilities/topic/r/random.html
180
//! [15]: https://www.ibm.com/docs/en/aix/7.3?topic=files-random-urandom-devices
181
//! [16]: https://man.netbsd.org/getrandom.2
182
//! [17]: https://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getrandom
183
//! [18]: https://github.com/rust3ds/shim-3ds/commit/b01d2568836dea2a65d05d662f8e5f805c64389d
184
//!
185
//! [`BCryptGenRandom`]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
186
//! [`Crypto.getRandomValues`]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
187
//! [`RDRAND`]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
188
//! [`CCRandomGenerateBytes`]: https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html
189
//! [`cprng_draw`]: https://fuchsia.dev/fuchsia-src/zircon/syscalls/cprng_draw
190
//! [`crypto.randomFillSync`]: https://nodejs.org/api/crypto.html#cryptorandomfillsyncbuffer-offset-size
191
//! [`esp_fill_random`]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html#_CPPv415esp_fill_randomPv6size_t
192
//! [`random_get`]: https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-random_getbuf-pointeru8-buf_len-size---errno
193
//! [WebAssembly support]: #webassembly-support
194
//! [`wasm-bindgen`]: https://github.com/rustwasm/wasm-bindgen
195
//! [`module`]: https://rustwasm.github.io/wasm-bindgen/reference/attributes/on-js-imports/module.html
196
//! [CommonJS modules]: https://nodejs.org/api/modules.html
197
//! [ES modules]: https://nodejs.org/api/esm.html
198
//! [`sys_read_entropy`]: https://github.com/hermit-os/kernel/blob/315f58ff5efc81d9bf0618af85a59963ff55f8b1/src/syscalls/entropy.rs#L47-L55
199
//! [platform-support]: https://doc.rust-lang.org/stable/rustc/platform-support.html
200
201
#![doc(
202
    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
203
    html_favicon_url = "https://www.rust-lang.org/favicon.ico",
204
    html_root_url = "https://docs.rs/getrandom/0.2.15"
205
)]
206
#![no_std]
207
#![warn(rust_2018_idioms, unused_lifetimes, missing_docs)]
208
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
209
210
#[macro_use]
211
extern crate cfg_if;
212
213
use crate::util::{slice_as_uninit_mut, slice_assume_init_mut};
214
use core::mem::MaybeUninit;
215
216
mod error;
217
mod util;
218
// To prevent a breaking change when targets are added, we always export the
219
// register_custom_getrandom macro, so old Custom RNG crates continue to build.
220
#[cfg(feature = "custom")]
221
mod custom;
222
#[cfg(feature = "std")]
223
mod error_impls;
224
225
pub use crate::error::Error;
226
227
// System-specific implementations.
228
//
229
// These should all provide getrandom_inner with the signature
230
// `fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error>`.
231
// The function MUST fully initialize `dest` when `Ok(())` is returned.
232
// The function MUST NOT ever write uninitialized bytes into `dest`,
233
// regardless of what value it returns.
234
cfg_if! {
235
    if #[cfg(any(target_os = "haiku", target_os = "redox", target_os = "nto", target_os = "aix"))] {
236
        mod util_libc;
237
        #[path = "use_file.rs"] mod imp;
238
    } else if #[cfg(any(
239
        target_os = "macos",
240
        target_os = "openbsd",
241
        target_os = "vita",
242
        target_os = "emscripten",
243
    ))] {
244
        mod util_libc;
245
        #[path = "getentropy.rs"] mod imp;
246
    } else if #[cfg(any(
247
        target_os = "dragonfly",
248
        target_os = "freebsd",
249
        target_os = "hurd",
250
        target_os = "illumos",
251
        // Check for target_arch = "arm" to only include the 3DS. Does not
252
        // include the Nintendo Switch (which is target_arch = "aarch64").
253
        all(target_os = "horizon", target_arch = "arm"),
254
    ))] {
255
        mod util_libc;
256
        #[path = "getrandom.rs"] mod imp;
257
    } else if #[cfg(all(
258
        not(feature = "linux_disable_fallback"),
259
        any(
260
            // Rust supports Android API level 19 (KitKat) [0] and the next upgrade targets
261
            // level 21 (Lollipop) [1], while `getrandom(2)` was added only in
262
            // level 23 (Marshmallow). Note that it applies only to the "old" `target_arch`es,
263
            // RISC-V Android targets sufficiently new API level, same will apply for potential
264
            // new Android `target_arch`es.
265
            // [0]: https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25.html
266
            // [1]: https://github.com/rust-lang/rust/pull/120593
267
            all(
268
                target_os = "android",
269
                any(
270
                    target_arch = "aarch64",
271
                    target_arch = "arm",
272
                    target_arch = "x86",
273
                    target_arch = "x86_64",
274
                ),
275
            ),
276
            // Only on these `target_arch`es Rust supports Linux kernel versions (3.2+)
277
            // that precede the version (3.17) in which `getrandom(2)` was added:
278
            // https://doc.rust-lang.org/stable/rustc/platform-support.html
279
            all(
280
                target_os = "linux",
281
                any(
282
                    target_arch = "aarch64",
283
                    target_arch = "arm",
284
                    target_arch = "powerpc",
285
                    target_arch = "powerpc64",
286
                    target_arch = "s390x",
287
                    target_arch = "x86",
288
                    target_arch = "x86_64",
289
                    // Minimum supported Linux kernel version for MUSL targets
290
                    // is not specified explicitly (as of Rust 1.77) and they
291
                    // are used in practice to target pre-3.17 kernels.
292
                    target_env = "musl",
293
                ),
294
            )
295
        ),
296
    ))] {
297
        mod util_libc;
298
        mod use_file;
299
        mod lazy;
300
        #[path = "linux_android_with_fallback.rs"] mod imp;
301
    } else if #[cfg(any(target_os = "android", target_os = "linux"))] {
302
        mod util_libc;
303
        #[path = "linux_android.rs"] mod imp;
304
    } else if #[cfg(target_os = "solaris")] {
305
        mod util_libc;
306
        #[path = "solaris.rs"] mod imp;
307
    } else if #[cfg(target_os = "netbsd")] {
308
        mod util_libc;
309
        #[path = "netbsd.rs"] mod imp;
310
    } else if #[cfg(target_os = "fuchsia")] {
311
        #[path = "fuchsia.rs"] mod imp;
312
    } else if #[cfg(any(target_os = "ios", target_os = "visionos", target_os = "watchos", target_os = "tvos"))] {
313
        #[path = "apple-other.rs"] mod imp;
314
    } else if #[cfg(all(target_arch = "wasm32", target_os = "wasi"))] {
315
        #[path = "wasi.rs"] mod imp;
316
    } else if #[cfg(target_os = "hermit")] {
317
        #[path = "hermit.rs"] mod imp;
318
    } else if #[cfg(target_os = "vxworks")] {
319
        mod util_libc;
320
        #[path = "vxworks.rs"] mod imp;
321
    } else if #[cfg(target_os = "solid_asp3")] {
322
        #[path = "solid.rs"] mod imp;
323
    } else if #[cfg(target_os = "espidf")] {
324
        #[path = "espidf.rs"] mod imp;
325
    } else if #[cfg(windows)] {
326
        #[path = "windows.rs"] mod imp;
327
    } else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] {
328
        mod lazy;
329
        #[path = "rdrand.rs"] mod imp;
330
    } else if #[cfg(all(feature = "rdrand",
331
                        any(target_arch = "x86_64", target_arch = "x86")))] {
332
        mod lazy;
333
        #[path = "rdrand.rs"] mod imp;
334
    } else if #[cfg(all(feature = "js",
335
                        any(target_arch = "wasm32", target_arch = "wasm64"),
336
                        target_os = "unknown"))] {
337
        #[path = "js.rs"] mod imp;
338
    } else if #[cfg(feature = "custom")] {
339
        use custom as imp;
340
    } else if #[cfg(all(any(target_arch = "wasm32", target_arch = "wasm64"),
341
                        target_os = "unknown"))] {
342
        compile_error!("the wasm*-unknown-unknown targets are not supported by \
343
                        default, you may need to enable the \"js\" feature. \
344
                        For more information see: \
345
                        https://docs.rs/getrandom/#webassembly-support");
346
    } else {
347
        compile_error!("target is not supported, for more information see: \
348
                        https://docs.rs/getrandom/#unsupported-targets");
349
    }
350
}
351
352
/// Fill `dest` with random bytes from the system's preferred random number
353
/// source.
354
///
355
/// This function returns an error on any failure, including partial reads. We
356
/// make no guarantees regarding the contents of `dest` on error. If `dest` is
357
/// empty, `getrandom` immediately returns success, making no calls to the
358
/// underlying operating system.
359
///
360
/// Blocking is possible, at least during early boot; see module documentation.
361
///
362
/// In general, `getrandom` will be fast enough for interactive usage, though
363
/// significantly slower than a user-space CSPRNG; for the latter consider
364
/// [`rand::thread_rng`](https://docs.rs/rand/*/rand/fn.thread_rng.html).
365
#[inline]
366
0
pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
367
0
    // SAFETY: The `&mut MaybeUninit<_>` reference doesn't escape, and
368
0
    // `getrandom_uninit` guarantees it will never de-initialize any part of
369
0
    // `dest`.
370
0
    getrandom_uninit(unsafe { slice_as_uninit_mut(dest) })?;
371
0
    Ok(())
372
0
}
Unexecuted instantiation: _RNvCs8QsUovYF45t_9getrandom9getrandomB1_
Unexecuted instantiation: _RNvCs8QsUovYF45t_9getrandom9getrandomCs7cRyI6h3MOh_9rand_core
373
374
/// Version of the `getrandom` function which fills `dest` with random bytes
375
/// returns a mutable reference to those bytes.
376
///
377
/// On successful completion this function is guaranteed to return a slice
378
/// which points to the same memory as `dest` and has the same length.
379
/// In other words, it's safe to assume that `dest` is initialized after
380
/// this function has returned `Ok`.
381
///
382
/// No part of `dest` will ever be de-initialized at any point, regardless
383
/// of what is returned.
384
///
385
/// # Examples
386
///
387
/// ```ignore
388
/// # // We ignore this test since `uninit_array` is unstable.
389
/// #![feature(maybe_uninit_uninit_array)]
390
/// # fn main() -> Result<(), getrandom::Error> {
391
/// let mut buf = core::mem::MaybeUninit::uninit_array::<1024>();
392
/// let buf: &mut [u8] = getrandom::getrandom_uninit(&mut buf)?;
393
/// # Ok(()) }
394
/// ```
395
#[inline]
396
0
pub fn getrandom_uninit(dest: &mut [MaybeUninit<u8>]) -> Result<&mut [u8], Error> {
397
0
    if !dest.is_empty() {
398
0
        imp::getrandom_inner(dest)?;
399
0
    }
400
    // SAFETY: `dest` has been fully initialized by `imp::getrandom_inner`
401
    // since it returned `Ok`.
402
0
    Ok(unsafe { slice_assume_init_mut(dest) })
403
0
}
Unexecuted instantiation: _RNvCs8QsUovYF45t_9getrandom16getrandom_uninitB1_
Unexecuted instantiation: _RNvCs8QsUovYF45t_9getrandom16getrandom_uninitCs7cRyI6h3MOh_9rand_core
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.15/src/linux_android_with_fallback.rs
Line
Count
Source
1
//! Implementation for Linux / Android with `/dev/urandom` fallback
2
use crate::{
3
    lazy::LazyBool,
4
    util_libc::{getrandom_syscall, last_os_error, sys_fill_exact},
5
    {use_file, Error},
6
};
7
use core::mem::MaybeUninit;
8
9
0
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
10
    // getrandom(2) was introduced in Linux 3.17
11
    static HAS_GETRANDOM: LazyBool = LazyBool::new();
12
0
    if HAS_GETRANDOM.unsync_init(is_getrandom_available) {
13
0
        sys_fill_exact(dest, getrandom_syscall)
14
    } else {
15
0
        use_file::getrandom_inner(dest)
16
    }
17
0
}
18
19
0
fn is_getrandom_available() -> bool {
20
0
    if getrandom_syscall(&mut []) < 0 {
21
0
        match last_os_error().raw_os_error() {
22
0
            Some(libc::ENOSYS) => false, // No kernel support
23
            // The fallback on EPERM is intentionally not done on Android since this workaround
24
            // seems to be needed only for specific Linux-based products that aren't based
25
            // on Android. See https://github.com/rust-random/getrandom/issues/229.
26
            #[cfg(target_os = "linux")]
27
0
            Some(libc::EPERM) => false, // Blocked by seccomp
28
0
            _ => true,
29
        }
30
    } else {
31
0
        true
32
    }
33
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.15/src/use_file.rs
Line
Count
Source
1
//! Implementations that just need to read from a file
2
use crate::{
3
    util_libc::{open_readonly, sys_fill_exact},
4
    Error,
5
};
6
use core::{
7
    cell::UnsafeCell,
8
    mem::MaybeUninit,
9
    sync::atomic::{AtomicUsize, Ordering::Relaxed},
10
};
11
12
/// For all platforms, we use `/dev/urandom` rather than `/dev/random`.
13
/// For more information see the linked man pages in lib.rs.
14
///   - On Linux, "/dev/urandom is preferred and sufficient in all use cases".
15
///   - On Redox, only /dev/urandom is provided.
16
///   - On AIX, /dev/urandom will "provide cryptographically secure output".
17
///   - On Haiku and QNX Neutrino they are identical.
18
const FILE_PATH: &str = "/dev/urandom\0";
19
const FD_UNINIT: usize = usize::max_value();
20
21
0
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
22
0
    let fd = get_rng_fd()?;
23
0
    sys_fill_exact(dest, |buf| unsafe {
24
0
        libc::read(fd, buf.as_mut_ptr() as *mut libc::c_void, buf.len())
25
0
    })
26
0
}
27
28
// Returns the file descriptor for the device file used to retrieve random
29
// bytes. The file will be opened exactly once. All subsequent calls will
30
// return the same file descriptor. This file descriptor is never closed.
31
0
fn get_rng_fd() -> Result<libc::c_int, Error> {
32
    static FD: AtomicUsize = AtomicUsize::new(FD_UNINIT);
33
0
    fn get_fd() -> Option<libc::c_int> {
34
0
        match FD.load(Relaxed) {
35
0
            FD_UNINIT => None,
36
0
            val => Some(val as libc::c_int),
37
        }
38
0
    }
39
40
    // Use double-checked locking to avoid acquiring the lock if possible.
41
0
    if let Some(fd) = get_fd() {
42
0
        return Ok(fd);
43
0
    }
44
45
    // SAFETY: We use the mutex only in this method, and we always unlock it
46
    // before returning, making sure we don't violate the pthread_mutex_t API.
47
    static MUTEX: Mutex = Mutex::new();
48
0
    unsafe { MUTEX.lock() };
49
0
    let _guard = DropGuard(|| unsafe { MUTEX.unlock() });
50
51
0
    if let Some(fd) = get_fd() {
52
0
        return Ok(fd);
53
0
    }
54
0
55
0
    // On Linux, /dev/urandom might return insecure values.
56
0
    #[cfg(any(target_os = "android", target_os = "linux"))]
57
0
    wait_until_rng_ready()?;
58
59
0
    let fd = unsafe { open_readonly(FILE_PATH)? };
60
    // The fd always fits in a usize without conflicting with FD_UNINIT.
61
0
    debug_assert!(fd >= 0 && (fd as usize) < FD_UNINIT);
62
0
    FD.store(fd as usize, Relaxed);
63
0
64
0
    Ok(fd)
65
0
}
66
67
// Succeeds once /dev/urandom is safe to read from
68
#[cfg(any(target_os = "android", target_os = "linux"))]
69
0
fn wait_until_rng_ready() -> Result<(), Error> {
70
    // Poll /dev/random to make sure it is ok to read from /dev/urandom.
71
0
    let fd = unsafe { open_readonly("/dev/random\0")? };
72
0
    let mut pfd = libc::pollfd {
73
0
        fd,
74
0
        events: libc::POLLIN,
75
0
        revents: 0,
76
0
    };
77
0
    let _guard = DropGuard(|| unsafe {
78
0
        libc::close(fd);
79
0
    });
80
81
    loop {
82
        // A negative timeout means an infinite timeout.
83
0
        let res = unsafe { libc::poll(&mut pfd, 1, -1) };
84
0
        if res >= 0 {
85
0
            debug_assert_eq!(res, 1); // We only used one fd, and cannot timeout.
86
0
            return Ok(());
87
0
        }
88
0
        let err = crate::util_libc::last_os_error();
89
0
        match err.raw_os_error() {
90
0
            Some(libc::EINTR) | Some(libc::EAGAIN) => continue,
91
0
            _ => return Err(err),
92
        }
93
    }
94
0
}
95
96
struct Mutex(UnsafeCell<libc::pthread_mutex_t>);
97
98
impl Mutex {
99
0
    const fn new() -> Self {
100
0
        Self(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER))
101
0
    }
102
0
    unsafe fn lock(&self) {
103
0
        let r = libc::pthread_mutex_lock(self.0.get());
104
0
        debug_assert_eq!(r, 0);
105
0
    }
106
0
    unsafe fn unlock(&self) {
107
0
        let r = libc::pthread_mutex_unlock(self.0.get());
108
0
        debug_assert_eq!(r, 0);
109
0
    }
110
}
111
112
unsafe impl Sync for Mutex {}
113
114
struct DropGuard<F: FnMut()>(F);
115
116
impl<F: FnMut()> Drop for DropGuard<F> {
117
0
    fn drop(&mut self) {
118
0
        self.0()
119
0
    }
Unexecuted instantiation: _RNvXs0_NtCs8QsUovYF45t_9getrandom8use_fileINtB5_9DropGuardNCNvB5_10get_rng_fd0ENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropB7_
Unexecuted instantiation: _RNvXs0_NtCs8QsUovYF45t_9getrandom8use_fileINtB5_9DropGuardNCNvB5_20wait_until_rng_ready0ENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropB7_
120
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.15/src/util.rs
Line
Count
Source
1
#![allow(dead_code)]
2
use core::{mem::MaybeUninit, ptr};
3
4
/// Polyfill for `maybe_uninit_slice` feature's
5
/// `MaybeUninit::slice_assume_init_mut`. Every element of `slice` must have
6
/// been initialized.
7
#[inline(always)]
8
0
pub unsafe fn slice_assume_init_mut<T>(slice: &mut [MaybeUninit<T>]) -> &mut [T] {
9
0
    // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
10
0
    &mut *(slice as *mut [MaybeUninit<T>] as *mut [T])
11
0
}
Unexecuted instantiation: _RINvNtCs8QsUovYF45t_9getrandom4util21slice_assume_init_muthEB4_
Unexecuted instantiation: _RINvNtCs8QsUovYF45t_9getrandom4util21slice_assume_init_muthECs7cRyI6h3MOh_9rand_core
12
13
#[inline]
14
0
pub fn uninit_slice_fill_zero(slice: &mut [MaybeUninit<u8>]) -> &mut [u8] {
15
0
    unsafe { ptr::write_bytes(slice.as_mut_ptr(), 0, slice.len()) };
16
0
    unsafe { slice_assume_init_mut(slice) }
17
0
}
18
19
#[inline(always)]
20
0
pub fn slice_as_uninit<T>(slice: &[T]) -> &[MaybeUninit<T>] {
21
0
    // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
22
0
    // There is no risk of writing a `MaybeUninit<T>` into the result since
23
0
    // the result isn't mutable.
24
0
    unsafe { &*(slice as *const [T] as *const [MaybeUninit<T>]) }
25
0
}
26
27
/// View an mutable initialized array as potentially-uninitialized.
28
///
29
/// This is unsafe because it allows assigning uninitialized values into
30
/// `slice`, which would be undefined behavior.
31
#[inline(always)]
32
0
pub unsafe fn slice_as_uninit_mut<T>(slice: &mut [T]) -> &mut [MaybeUninit<T>] {
33
0
    // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
34
0
    &mut *(slice as *mut [T] as *mut [MaybeUninit<T>])
35
0
}
Unexecuted instantiation: _RINvNtCs8QsUovYF45t_9getrandom4util19slice_as_uninit_muthEB4_
Unexecuted instantiation: _RINvNtCs8QsUovYF45t_9getrandom4util19slice_as_uninit_muthECs7cRyI6h3MOh_9rand_core
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.15/src/util_libc.rs
Line
Count
Source
1
#![allow(dead_code)]
2
use crate::Error;
3
use core::{
4
    mem::MaybeUninit,
5
    num::NonZeroU32,
6
    ptr::NonNull,
7
    sync::atomic::{fence, AtomicPtr, Ordering},
8
};
9
use libc::c_void;
10
11
cfg_if! {
12
    if #[cfg(any(target_os = "netbsd", target_os = "openbsd", target_os = "android"))] {
13
        use libc::__errno as errno_location;
14
    } else if #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "hurd", target_os = "redox", target_os = "dragonfly"))] {
15
        use libc::__errno_location as errno_location;
16
    } else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] {
17
        use libc::___errno as errno_location;
18
    } else if #[cfg(any(target_os = "macos", target_os = "freebsd"))] {
19
        use libc::__error as errno_location;
20
    } else if #[cfg(target_os = "haiku")] {
21
        use libc::_errnop as errno_location;
22
    } else if #[cfg(target_os = "nto")] {
23
        use libc::__get_errno_ptr as errno_location;
24
    } else if #[cfg(any(all(target_os = "horizon", target_arch = "arm"), target_os = "vita"))] {
25
        extern "C" {
26
            // Not provided by libc: https://github.com/rust-lang/libc/issues/1995
27
            fn __errno() -> *mut libc::c_int;
28
        }
29
        use __errno as errno_location;
30
    } else if #[cfg(target_os = "aix")] {
31
        use libc::_Errno as errno_location;
32
    }
33
}
34
35
cfg_if! {
36
    if #[cfg(target_os = "vxworks")] {
37
        use libc::errnoGet as get_errno;
38
    } else {
39
0
        unsafe fn get_errno() -> libc::c_int { *errno_location() }
40
    }
41
}
42
43
0
pub fn last_os_error() -> Error {
44
0
    let errno = unsafe { get_errno() };
45
0
    if errno > 0 {
46
0
        Error::from(NonZeroU32::new(errno as u32).unwrap())
47
    } else {
48
0
        Error::ERRNO_NOT_POSITIVE
49
    }
50
0
}
51
52
// Fill a buffer by repeatedly invoking a system call. The `sys_fill` function:
53
//   - should return -1 and set errno on failure
54
//   - should return the number of bytes written on success
55
0
pub fn sys_fill_exact(
56
0
    mut buf: &mut [MaybeUninit<u8>],
57
0
    sys_fill: impl Fn(&mut [MaybeUninit<u8>]) -> libc::ssize_t,
58
0
) -> Result<(), Error> {
59
0
    while !buf.is_empty() {
60
0
        let res = sys_fill(buf);
61
0
        match res {
62
0
            res if res > 0 => buf = buf.get_mut(res as usize..).ok_or(Error::UNEXPECTED)?,
63
            -1 => {
64
0
                let err = last_os_error();
65
0
                // We should try again if the call was interrupted.
66
0
                if err.raw_os_error() != Some(libc::EINTR) {
67
0
                    return Err(err);
68
0
                }
69
            }
70
            // Negative return codes not equal to -1 should be impossible.
71
            // EOF (ret = 0) should be impossible, as the data we are reading
72
            // should be an infinite stream of random bytes.
73
0
            _ => return Err(Error::UNEXPECTED),
74
        }
75
    }
76
0
    Ok(())
77
0
}
Unexecuted instantiation: _RINvNtCs8QsUovYF45t_9getrandom9util_libc14sys_fill_exactNCNvNtB4_8use_file15getrandom_inner0EB4_
Unexecuted instantiation: _RINvNtCs8QsUovYF45t_9getrandom9util_libc14sys_fill_exactNvB2_17getrandom_syscallEB4_
78
79
// A "weak" binding to a C function that may or may not be present at runtime.
80
// Used for supporting newer OS features while still building on older systems.
81
// Based off of the DlsymWeak struct in libstd:
82
// https://github.com/rust-lang/rust/blob/1.61.0/library/std/src/sys/unix/weak.rs#L84
83
// except that the caller must manually cast self.ptr() to a function pointer.
84
pub struct Weak {
85
    name: &'static str,
86
    addr: AtomicPtr<c_void>,
87
}
88
89
impl Weak {
90
    // A non-null pointer value which indicates we are uninitialized. This
91
    // constant should ideally not be a valid address of a function pointer.
92
    // However, if by chance libc::dlsym does return UNINIT, there will not
93
    // be undefined behavior. libc::dlsym will just be called each time ptr()
94
    // is called. This would be inefficient, but correct.
95
    // TODO: Replace with core::ptr::invalid_mut(1) when that is stable.
96
    const UNINIT: *mut c_void = 1 as *mut c_void;
97
98
    // Construct a binding to a C function with a given name. This function is
99
    // unsafe because `name` _must_ be null terminated.
100
0
    pub const unsafe fn new(name: &'static str) -> Self {
101
0
        Self {
102
0
            name,
103
0
            addr: AtomicPtr::new(Self::UNINIT),
104
0
        }
105
0
    }
106
107
    // Return the address of a function if present at runtime. Otherwise,
108
    // return None. Multiple callers can call ptr() concurrently. It will
109
    // always return _some_ value returned by libc::dlsym. However, the
110
    // dlsym function may be called multiple times.
111
0
    pub fn ptr(&self) -> Option<NonNull<c_void>> {
112
0
        // Despite having only a single atomic variable (self.addr), we still
113
0
        // cannot always use Ordering::Relaxed, as we need to make sure a
114
0
        // successful call to dlsym() is "ordered before" any data read through
115
0
        // the returned pointer (which occurs when the function is called).
116
0
        // Our implementation mirrors that of the one in libstd, meaning that
117
0
        // the use of non-Relaxed operations is probably unnecessary.
118
0
        match self.addr.load(Ordering::Relaxed) {
119
0
            Self::UNINIT => {
120
0
                let symbol = self.name.as_ptr() as *const _;
121
0
                let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, symbol) };
122
0
                // Synchronizes with the Acquire fence below
123
0
                self.addr.store(addr, Ordering::Release);
124
0
                NonNull::new(addr)
125
            }
126
0
            addr => {
127
0
                let func = NonNull::new(addr)?;
128
0
                fence(Ordering::Acquire);
129
0
                Some(func)
130
            }
131
        }
132
0
    }
133
}
134
135
// SAFETY: path must be null terminated, FD must be manually closed.
136
0
pub unsafe fn open_readonly(path: &str) -> Result<libc::c_int, Error> {
137
0
    debug_assert_eq!(path.as_bytes().last(), Some(&0));
138
    loop {
139
0
        let fd = libc::open(path.as_ptr() as *const _, libc::O_RDONLY | libc::O_CLOEXEC);
140
0
        if fd >= 0 {
141
0
            return Ok(fd);
142
0
        }
143
0
        let err = last_os_error();
144
0
        // We should try again if open() was interrupted.
145
0
        if err.raw_os_error() != Some(libc::EINTR) {
146
0
            return Err(err);
147
0
        }
148
    }
149
0
}
150
151
/// Thin wrapper around the `getrandom()` Linux system call
152
#[cfg(any(target_os = "android", target_os = "linux"))]
153
0
pub fn getrandom_syscall(buf: &mut [MaybeUninit<u8>]) -> libc::ssize_t {
154
0
    unsafe {
155
0
        libc::syscall(
156
0
            libc::SYS_getrandom,
157
0
            buf.as_mut_ptr() as *mut libc::c_void,
158
0
            buf.len(),
159
0
            0,
160
0
        ) as libc::ssize_t
161
0
    }
162
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/group-0.13.0/src/cofactor.rs
Line
Count
Source
1
use core::fmt;
2
use core::ops::{Mul, Neg};
3
use ff::PrimeField;
4
use subtle::{Choice, CtOption};
5
6
use crate::{prime::PrimeGroup, Curve, Group, GroupEncoding, GroupOps, GroupOpsOwned};
7
8
/// This trait represents an element of a cryptographic group with a large prime-order
9
/// subgroup and a comparatively-small cofactor.
10
pub trait CofactorGroup:
11
    Group
12
    + GroupEncoding
13
    + GroupOps<<Self as CofactorGroup>::Subgroup>
14
    + GroupOpsOwned<<Self as CofactorGroup>::Subgroup>
15
{
16
    /// The large prime-order subgroup in which cryptographic operations are performed.
17
    /// If `Self` implements `PrimeGroup`, then `Self::Subgroup` may be `Self`.
18
    type Subgroup: PrimeGroup<Scalar = Self::Scalar> + Into<Self>;
19
20
    /// Maps `self` to the prime-order subgroup by multiplying this element by some
21
    /// `k`-multiple of the cofactor.
22
    ///
23
    /// The value `k` does not vary between inputs for a given implementation, but may
24
    /// vary between different implementations of `CofactorGroup` because some groups have
25
    /// more efficient methods of clearing the cofactor when `k` is allowed to be
26
    /// different than `1`.
27
    ///
28
    /// If `Self` implements [`PrimeGroup`], this returns `self`.
29
    fn clear_cofactor(&self) -> Self::Subgroup;
30
31
    /// Returns `self` if it is contained in the prime-order subgroup.
32
    ///
33
    /// If `Self` implements [`PrimeGroup`], this returns `Some(self)`.
34
    fn into_subgroup(self) -> CtOption<Self::Subgroup>;
35
36
    /// Determines if this element is of small order.
37
    ///
38
    /// Returns:
39
    /// - `true` if `self` is in the torsion subgroup.
40
    /// - `false` if `self` is not in the torsion subgroup.
41
0
    fn is_small_order(&self) -> Choice {
42
0
        self.clear_cofactor().is_identity()
43
0
    }
44
45
    /// Determines if this element is "torsion free", i.e., is contained in the
46
    /// prime-order subgroup.
47
    ///
48
    /// Returns:
49
    /// - `true` if `self` has trivial torsion and is in the prime-order subgroup.
50
    /// - `false` if `self` has non-zero torsion component and is not in the prime-order
51
    ///   subgroup.
52
    fn is_torsion_free(&self) -> Choice;
53
}
54
55
/// Efficient representation of an elliptic curve point guaranteed to be
56
/// in the correct prime order subgroup.
57
pub trait CofactorCurve:
58
    Curve<AffineRepr = <Self as CofactorCurve>::Affine> + CofactorGroup
59
{
60
    type Affine: CofactorCurveAffine<Curve = Self, Scalar = Self::Scalar>
61
        + Mul<Self::Scalar, Output = Self>
62
        + for<'r> Mul<&'r Self::Scalar, Output = Self>;
63
}
64
65
/// Affine representation of an elliptic curve point guaranteed to be
66
/// in the correct prime order subgroup.
67
pub trait CofactorCurveAffine:
68
    GroupEncoding
69
    + Copy
70
    + Clone
71
    + Sized
72
    + Send
73
    + Sync
74
    + fmt::Debug
75
    + PartialEq
76
    + Eq
77
    + 'static
78
    + Neg<Output = Self>
79
    + Mul<<Self as CofactorCurveAffine>::Scalar, Output = <Self as CofactorCurveAffine>::Curve>
80
    + for<'r> Mul<
81
        &'r <Self as CofactorCurveAffine>::Scalar,
82
        Output = <Self as CofactorCurveAffine>::Curve,
83
    >
84
{
85
    type Scalar: PrimeField;
86
    type Curve: CofactorCurve<Affine = Self, Scalar = Self::Scalar>;
87
88
    /// Returns the additive identity.
89
    fn identity() -> Self;
90
91
    /// Returns a fixed generator of unknown exponent.
92
    fn generator() -> Self;
93
94
    /// Determines if this point represents the point at infinity; the
95
    /// additive identity.
96
    fn is_identity(&self) -> Choice;
97
98
    /// Converts this element to its curve representation.
99
    fn to_curve(&self) -> Self::Curve;
100
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/group-0.13.0/src/lib.rs
Line
Count
Source
1
#![no_std]
2
// Catch documentation errors caused by code changes.
3
#![deny(rustdoc::broken_intra_doc_links)]
4
5
#[cfg(feature = "alloc")]
6
#[macro_use]
7
extern crate alloc;
8
9
// Re-export ff to make version-matching easier.
10
pub use ff;
11
12
use core::fmt;
13
use core::iter::Sum;
14
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
15
use ff::PrimeField;
16
use rand_core::RngCore;
17
use subtle::{Choice, CtOption};
18
19
pub mod cofactor;
20
pub mod prime;
21
#[cfg(feature = "tests")]
22
pub mod tests;
23
24
#[cfg(feature = "alloc")]
25
mod wnaf;
26
#[cfg(feature = "alloc")]
27
pub use self::wnaf::{Wnaf, WnafBase, WnafGroup, WnafScalar};
28
29
/// A helper trait for types with a group operation.
30
pub trait GroupOps<Rhs = Self, Output = Self>:
31
    Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
32
{
33
}
34
35
impl<T, Rhs, Output> GroupOps<Rhs, Output> for T where
36
    T: Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
37
{
38
}
39
40
/// A helper trait for references with a group operation.
41
pub trait GroupOpsOwned<Rhs = Self, Output = Self>: for<'r> GroupOps<&'r Rhs, Output> {}
42
impl<T, Rhs, Output> GroupOpsOwned<Rhs, Output> for T where T: for<'r> GroupOps<&'r Rhs, Output> {}
43
44
/// A helper trait for types implementing group scalar multiplication.
45
pub trait ScalarMul<Rhs, Output = Self>: Mul<Rhs, Output = Output> + MulAssign<Rhs> {}
46
47
impl<T, Rhs, Output> ScalarMul<Rhs, Output> for T where T: Mul<Rhs, Output = Output> + MulAssign<Rhs>
48
{}
49
50
/// A helper trait for references implementing group scalar multiplication.
51
pub trait ScalarMulOwned<Rhs, Output = Self>: for<'r> ScalarMul<&'r Rhs, Output> {}
52
impl<T, Rhs, Output> ScalarMulOwned<Rhs, Output> for T where T: for<'r> ScalarMul<&'r Rhs, Output> {}
53
54
/// This trait represents an element of a cryptographic group.
55
pub trait Group:
56
    Clone
57
    + Copy
58
    + fmt::Debug
59
    + Eq
60
    + Sized
61
    + Send
62
    + Sync
63
    + 'static
64
    + Sum
65
    + for<'a> Sum<&'a Self>
66
    + Neg<Output = Self>
67
    + GroupOps
68
    + GroupOpsOwned
69
    + ScalarMul<<Self as Group>::Scalar>
70
    + ScalarMulOwned<<Self as Group>::Scalar>
71
{
72
    /// Scalars modulo the order of this group's scalar field.
73
    type Scalar: PrimeField;
74
75
    /// Returns an element chosen uniformly at random from the non-identity elements of
76
    /// this group.
77
    ///
78
    /// This function is non-deterministic, and samples from the user-provided RNG.
79
    fn random(rng: impl RngCore) -> Self;
80
81
    /// Returns the additive identity, also known as the "neutral element".
82
    fn identity() -> Self;
83
84
    /// Returns a fixed generator of the prime-order subgroup.
85
    fn generator() -> Self;
86
87
    /// Determines if this point is the identity.
88
    fn is_identity(&self) -> Choice;
89
90
    /// Doubles this element.
91
    #[must_use]
92
    fn double(&self) -> Self;
93
}
94
95
/// Efficient representation of an elliptic curve point guaranteed.
96
pub trait Curve:
97
    Group + GroupOps<<Self as Curve>::AffineRepr> + GroupOpsOwned<<Self as Curve>::AffineRepr>
98
{
99
    /// The affine representation for this elliptic curve.
100
    type AffineRepr;
101
102
    /// Converts a batch of projective elements into affine elements. This function will
103
    /// panic if `p.len() != q.len()`.
104
0
    fn batch_normalize(p: &[Self], q: &mut [Self::AffineRepr]) {
105
0
        assert_eq!(p.len(), q.len());
106
107
0
        for (p, q) in p.iter().zip(q.iter_mut()) {
108
0
            *q = p.to_affine();
109
0
        }
110
0
    }
111
112
    /// Converts this element into its affine representation.
113
    fn to_affine(&self) -> Self::AffineRepr;
114
}
115
116
pub trait GroupEncoding: Sized {
117
    /// The encoding of group elements.
118
    ///
119
    /// The `Default` implementation is not required to return a valid point encoding. The
120
    /// bound is present to enable encodings to be constructed generically:
121
    /// ```
122
    /// # use group::GroupEncoding;
123
    /// # use subtle::CtOption;
124
    /// # struct G;
125
    /// # impl GroupEncoding for G {
126
    /// #     type Repr = [u8; 0];
127
    /// #     fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> { unimplemented!() }
128
    /// #     fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> { unimplemented!() }
129
    /// #     fn to_bytes(&self) -> Self::Repr { unimplemented!() }
130
    /// # }
131
    /// # let buf = &[0u8; 0][..];
132
    /// let mut encoding = <G as GroupEncoding>::Repr::default();
133
    /// encoding.as_mut().copy_from_slice(buf);
134
    /// ```
135
    ///
136
    /// It is recommended that the default should be the all-zeroes encoding.
137
    type Repr: Copy + Default + Send + Sync + 'static + AsRef<[u8]> + AsMut<[u8]>;
138
139
    /// Attempts to deserialize a group element from its encoding.
140
    fn from_bytes(bytes: &Self::Repr) -> CtOption<Self>;
141
142
    /// Attempts to deserialize a group element, not checking if the element is valid.
143
    ///
144
    /// **This is dangerous to call unless you trust the bytes you are reading; otherwise,
145
    /// API invariants may be broken.** Please consider using
146
    /// [`GroupEncoding::from_bytes`] instead.
147
    fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self>;
148
149
    /// Converts this element into its byte encoding. This may or may not support
150
    /// encoding the identity.
151
    // TODO: Figure out how to handle identity encoding generically.
152
    fn to_bytes(&self) -> Self::Repr;
153
}
154
155
/// Affine representation of a point on an elliptic curve that has a defined uncompressed
156
/// encoding.
157
pub trait UncompressedEncoding: Sized {
158
    type Uncompressed: Default + AsRef<[u8]> + AsMut<[u8]>;
159
160
    /// Attempts to deserialize an element from its uncompressed encoding.
161
    fn from_uncompressed(bytes: &Self::Uncompressed) -> CtOption<Self>;
162
163
    /// Attempts to deserialize an uncompressed element, not checking if the element is in
164
    /// the correct subgroup.
165
    ///
166
    /// **This is dangerous to call unless you trust the bytes you are reading; otherwise,
167
    /// API invariants may be broken.** Please consider using
168
    /// [`UncompressedEncoding::from_uncompressed`] instead.
169
    fn from_uncompressed_unchecked(bytes: &Self::Uncompressed) -> CtOption<Self>;
170
171
    /// Converts this element into its uncompressed encoding, so long as it's not
172
    /// the point at infinity.
173
    fn to_uncompressed(&self) -> Self::Uncompressed;
174
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/group-0.13.0/src/wnaf.rs
Line
Count
Source
1
use alloc::vec::Vec;
2
use core::iter;
3
use core::marker::PhantomData;
4
use core::ops::Mul;
5
6
use ff::PrimeField;
7
8
use super::Group;
9
10
/// Extension trait on a [`Group`] that provides helpers used by [`Wnaf`].
11
pub trait WnafGroup: Group {
12
    /// Recommends a wNAF window size given the number of scalars you intend to multiply
13
    /// a base by. Always returns a number between 2 and 22, inclusive.
14
    fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize;
15
}
16
17
/// Replaces the contents of `table` with a w-NAF window table for the given window size.
18
0
pub(crate) fn wnaf_table<G: Group>(table: &mut Vec<G>, mut base: G, window: usize) {
19
0
    table.truncate(0);
20
0
    table.reserve(1 << (window - 1));
21
0
22
0
    let dbl = base.double();
23
0
24
0
    for _ in 0..(1 << (window - 1)) {
25
0
        table.push(base);
26
0
        base.add_assign(&dbl);
27
0
    }
28
0
}
29
30
/// This struct represents a view of a sequence of bytes as a sequence of
31
/// `u64` limbs in little-endian byte order. It maintains a current index, and
32
/// allows access to the limb at that index and the one following it. Bytes
33
/// beyond the end of the original buffer are treated as zero.
34
struct LimbBuffer<'a> {
35
    buf: &'a [u8],
36
    cur_idx: usize,
37
    cur_limb: u64,
38
    next_limb: u64,
39
}
40
41
impl<'a> LimbBuffer<'a> {
42
0
    fn new(buf: &'a [u8]) -> Self {
43
0
        let mut ret = Self {
44
0
            buf,
45
0
            cur_idx: 0,
46
0
            cur_limb: 0,
47
0
            next_limb: 0,
48
0
        };
49
0
50
0
        // Initialise the limb buffers.
51
0
        ret.increment_limb();
52
0
        ret.increment_limb();
53
0
        ret.cur_idx = 0usize;
54
0
55
0
        ret
56
0
    }
57
58
0
    fn increment_limb(&mut self) {
59
0
        self.cur_idx += 1;
60
0
        self.cur_limb = self.next_limb;
61
0
        match self.buf.len() {
62
            // There are no more bytes in the buffer; zero-extend.
63
0
            0 => self.next_limb = 0,
64
65
            // There are fewer bytes in the buffer than a u64 limb; zero-extend.
66
0
            x @ 1..=7 => {
67
0
                let mut next_limb = [0; 8];
68
0
                next_limb[..x].copy_from_slice(self.buf);
69
0
                self.next_limb = u64::from_le_bytes(next_limb);
70
0
                self.buf = &[];
71
0
            }
72
73
            // There are at least eight bytes in the buffer; read the next u64 limb.
74
0
            _ => {
75
0
                let (next_limb, rest) = self.buf.split_at(8);
76
0
                self.next_limb = u64::from_le_bytes(next_limb.try_into().unwrap());
77
0
                self.buf = rest;
78
0
            }
79
        }
80
0
    }
81
82
0
    fn get(&mut self, idx: usize) -> (u64, u64) {
83
0
        assert!([self.cur_idx, self.cur_idx + 1].contains(&idx));
84
0
        if idx > self.cur_idx {
85
0
            self.increment_limb();
86
0
        }
87
0
        (self.cur_limb, self.next_limb)
88
0
    }
89
}
90
91
/// Replaces the contents of `wnaf` with the w-NAF representation of a little-endian
92
/// scalar.
93
0
pub(crate) fn wnaf_form<S: AsRef<[u8]>>(wnaf: &mut Vec<i64>, c: S, window: usize) {
94
0
    // Required by the NAF definition
95
0
    debug_assert!(window >= 2);
96
    // Required so that the NAF digits fit in i64
97
0
    debug_assert!(window <= 64);
98
99
0
    let bit_len = c.as_ref().len() * 8;
100
0
101
0
    wnaf.truncate(0);
102
0
    wnaf.reserve(bit_len);
103
0
104
0
    // Initialise the current and next limb buffers.
105
0
    let mut limbs = LimbBuffer::new(c.as_ref());
106
0
107
0
    let width = 1u64 << window;
108
0
    let window_mask = width - 1;
109
0
110
0
    let mut pos = 0;
111
0
    let mut carry = 0;
112
0
    while pos < bit_len {
113
        // Construct a buffer of bits of the scalar, starting at bit `pos`
114
0
        let u64_idx = pos / 64;
115
0
        let bit_idx = pos % 64;
116
0
        let (cur_u64, next_u64) = limbs.get(u64_idx);
117
0
        let bit_buf = if bit_idx + window < 64 {
118
            // This window's bits are contained in a single u64
119
0
            cur_u64 >> bit_idx
120
        } else {
121
            // Combine the current u64's bits with the bits from the next u64
122
0
            (cur_u64 >> bit_idx) | (next_u64 << (64 - bit_idx))
123
        };
124
125
        // Add the carry into the current window
126
0
        let window_val = carry + (bit_buf & window_mask);
127
0
128
0
        if window_val & 1 == 0 {
129
0
            // If the window value is even, preserve the carry and emit 0.
130
0
            // Why is the carry preserved?
131
0
            // If carry == 0 and window_val & 1 == 0, then the next carry should be 0
132
0
            // If carry == 1 and window_val & 1 == 0, then bit_buf & 1 == 1 so the next carry should be 1
133
0
            wnaf.push(0);
134
0
            pos += 1;
135
0
        } else {
136
0
            wnaf.push(if window_val < width / 2 {
137
0
                carry = 0;
138
0
                window_val as i64
139
            } else {
140
0
                carry = 1;
141
0
                (window_val as i64).wrapping_sub(width as i64)
142
            });
143
0
            wnaf.extend(iter::repeat(0).take(window - 1));
144
0
            pos += window;
145
        }
146
    }
147
0
}
148
149
/// Performs w-NAF exponentiation with the provided window table and w-NAF form scalar.
150
///
151
/// This function must be provided a `table` and `wnaf` that were constructed with
152
/// the same window size; otherwise, it may panic or produce invalid results.
153
0
pub(crate) fn wnaf_exp<G: Group>(table: &[G], wnaf: &[i64]) -> G {
154
0
    let mut result = G::identity();
155
0
156
0
    let mut found_one = false;
157
158
0
    for n in wnaf.iter().rev() {
159
0
        if found_one {
160
0
            result = result.double();
161
0
        }
162
163
0
        if *n != 0 {
164
0
            found_one = true;
165
0
166
0
            if *n > 0 {
167
0
                result += &table[(n / 2) as usize];
168
0
            } else {
169
0
                result -= &table[((-n) / 2) as usize];
170
0
            }
171
0
        }
172
    }
173
174
0
    result
175
0
}
176
177
/// A "w-ary non-adjacent form" scalar multiplication (also known as exponentiation)
178
/// context.
179
///
180
/// # Examples
181
///
182
/// This struct can be used to implement several patterns:
183
///
184
/// ## One base, one scalar
185
///
186
/// For this pattern, you can use a transient `Wnaf` context:
187
///
188
/// ```ignore
189
/// use group::Wnaf;
190
///
191
/// let result = Wnaf::new().scalar(&scalar).base(base);
192
/// ```
193
///
194
/// ## Many bases, one scalar
195
///
196
/// For this pattern, you create a `Wnaf` context, load the scalar into it, and then
197
/// process each base in turn:
198
///
199
/// ```ignore
200
/// use group::Wnaf;
201
///
202
/// let mut wnaf = Wnaf::new();
203
/// let mut wnaf_scalar = wnaf.scalar(&scalar);
204
/// let results: Vec<_> = bases
205
///     .into_iter()
206
///     .map(|base| wnaf_scalar.base(base))
207
///     .collect();
208
/// ```
209
///
210
/// ## One base, many scalars
211
///
212
/// For this pattern, you create a `Wnaf` context, load the base into it, and then process
213
/// each scalar in turn:
214
///
215
/// ```ignore
216
/// use group::Wnaf;
217
///
218
/// let mut wnaf = Wnaf::new();
219
/// let mut wnaf_base = wnaf.base(base, scalars.len());
220
/// let results: Vec<_> = scalars
221
///     .iter()
222
///     .map(|scalar| wnaf_base.scalar(scalar))
223
///     .collect();
224
/// ```
225
///
226
/// ## Many bases, many scalars
227
///
228
/// Say you have `n` bases and `m` scalars, and want to produce `n * m` results. For this
229
/// pattern, you need to cache the w-NAF tables for the bases and then compute the w-NAF
230
/// form of the scalars on the fly for every base, or vice versa:
231
///
232
/// ```ignore
233
/// use group::Wnaf;
234
///
235
/// let mut wnaf_contexts: Vec<_> = (0..bases.len()).map(|_| Wnaf::new()).collect();
236
/// let mut wnaf_bases: Vec<_> = wnaf_contexts
237
///     .iter_mut()
238
///     .zip(bases)
239
///     .map(|(wnaf, base)| wnaf.base(base, scalars.len()))
240
///     .collect();
241
/// let results: Vec<_> = wnaf_bases
242
///     .iter()
243
///     .flat_map(|wnaf_base| scalars.iter().map(|scalar| wnaf_base.scalar(scalar)))
244
///     .collect();
245
/// ```
246
///
247
/// Alternatively, use the [`WnafBase`] and [`WnafScalar`] types, which enable the various
248
/// tables and w-NAF forms to be cached individually per base and scalar. These types can
249
/// then be directly multiplied without any additional runtime work, at the cost of fixing
250
/// a specific window size (rather than choosing the window size dynamically).
251
#[derive(Debug)]
252
pub struct Wnaf<W, B, S> {
253
    base: B,
254
    scalar: S,
255
    window_size: W,
256
}
257
258
impl<G: Group> Wnaf<(), Vec<G>, Vec<i64>> {
259
    /// Construct a new wNAF context without allocating.
260
0
    pub fn new() -> Self {
261
0
        Wnaf {
262
0
            base: vec![],
263
0
            scalar: vec![],
264
0
            window_size: (),
265
0
        }
266
0
    }
267
}
268
269
#[cfg(feature = "wnaf-memuse")]
270
impl<G: Group + memuse::DynamicUsage> memuse::DynamicUsage for Wnaf<(), Vec<G>, Vec<i64>> {
271
    fn dynamic_usage(&self) -> usize {
272
        self.base.dynamic_usage() + self.scalar.dynamic_usage()
273
    }
274
275
    fn dynamic_usage_bounds(&self) -> (usize, Option<usize>) {
276
        let (base_lower, base_upper) = self.base.dynamic_usage_bounds();
277
        let (scalar_lower, scalar_upper) = self.scalar.dynamic_usage_bounds();
278
279
        (
280
            base_lower + scalar_lower,
281
            base_upper.zip(scalar_upper).map(|(a, b)| a + b),
282
        )
283
    }
284
}
285
286
impl<G: WnafGroup> Wnaf<(), Vec<G>, Vec<i64>> {
287
    /// Given a base and a number of scalars, compute a window table and return a `Wnaf` object that
288
    /// can perform exponentiations with `.scalar(..)`.
289
0
    pub fn base(&mut self, base: G, num_scalars: usize) -> Wnaf<usize, &[G], &mut Vec<i64>> {
290
0
        // Compute the appropriate window size based on the number of scalars.
291
0
        let window_size = G::recommended_wnaf_for_num_scalars(num_scalars);
292
0
293
0
        // Compute a wNAF table for the provided base and window size.
294
0
        wnaf_table(&mut self.base, base, window_size);
295
0
296
0
        // Return a Wnaf object that immutably borrows the computed base storage location,
297
0
        // but mutably borrows the scalar storage location.
298
0
        Wnaf {
299
0
            base: &self.base[..],
300
0
            scalar: &mut self.scalar,
301
0
            window_size,
302
0
        }
303
0
    }
304
305
    /// Given a scalar, compute its wNAF representation and return a `Wnaf` object that can perform
306
    /// exponentiations with `.base(..)`.
307
0
    pub fn scalar(&mut self, scalar: &<G as Group>::Scalar) -> Wnaf<usize, &mut Vec<G>, &[i64]> {
308
0
        // We hard-code a window size of 4.
309
0
        let window_size = 4;
310
0
311
0
        // Compute the wNAF form of the scalar.
312
0
        wnaf_form(&mut self.scalar, scalar.to_repr(), window_size);
313
0
314
0
        // Return a Wnaf object that mutably borrows the base storage location, but
315
0
        // immutably borrows the computed wNAF form scalar location.
316
0
        Wnaf {
317
0
            base: &mut self.base,
318
0
            scalar: &self.scalar[..],
319
0
            window_size,
320
0
        }
321
0
    }
322
}
323
324
impl<'a, G: Group> Wnaf<usize, &'a [G], &'a mut Vec<i64>> {
325
    /// Constructs new space for the scalar representation while borrowing
326
    /// the computed window table, for sending the window table across threads.
327
0
    pub fn shared(&self) -> Wnaf<usize, &'a [G], Vec<i64>> {
328
0
        Wnaf {
329
0
            base: self.base,
330
0
            scalar: vec![],
331
0
            window_size: self.window_size,
332
0
        }
333
0
    }
334
}
335
336
#[cfg(feature = "wnaf-memuse")]
337
impl<'a, G: Group> memuse::DynamicUsage for Wnaf<usize, &'a [G], Vec<i64>> {
338
    fn dynamic_usage(&self) -> usize {
339
        // The heap memory for the window table is counted in the parent `Wnaf`.
340
        self.scalar.dynamic_usage()
341
    }
342
343
    fn dynamic_usage_bounds(&self) -> (usize, Option<usize>) {
344
        self.scalar.dynamic_usage_bounds()
345
    }
346
}
347
348
impl<'a, G: Group> Wnaf<usize, &'a mut Vec<G>, &'a [i64]> {
349
    /// Constructs new space for the window table while borrowing
350
    /// the computed scalar representation, for sending the scalar representation
351
    /// across threads.
352
0
    pub fn shared(&self) -> Wnaf<usize, Vec<G>, &'a [i64]> {
353
0
        Wnaf {
354
0
            base: vec![],
355
0
            scalar: self.scalar,
356
0
            window_size: self.window_size,
357
0
        }
358
0
    }
359
}
360
361
#[cfg(feature = "wnaf-memuse")]
362
impl<'a, G: Group + memuse::DynamicUsage> memuse::DynamicUsage for Wnaf<usize, Vec<G>, &'a [i64]> {
363
    fn dynamic_usage(&self) -> usize {
364
        // The heap memory for the scalar representation is counted in the parent `Wnaf`.
365
        self.base.dynamic_usage()
366
    }
367
368
    fn dynamic_usage_bounds(&self) -> (usize, Option<usize>) {
369
        self.base.dynamic_usage_bounds()
370
    }
371
}
372
373
impl<B, S: AsRef<[i64]>> Wnaf<usize, B, S> {
374
    /// Performs exponentiation given a base.
375
0
    pub fn base<G: Group>(&mut self, base: G) -> G
376
0
    where
377
0
        B: AsMut<Vec<G>>,
378
0
    {
379
0
        wnaf_table(self.base.as_mut(), base, self.window_size);
380
0
        wnaf_exp(self.base.as_mut(), self.scalar.as_ref())
381
0
    }
382
}
383
384
impl<B, S: AsMut<Vec<i64>>> Wnaf<usize, B, S> {
385
    /// Performs exponentiation given a scalar.
386
0
    pub fn scalar<G: Group>(&mut self, scalar: &<G as Group>::Scalar) -> G
387
0
    where
388
0
        B: AsRef<[G]>,
389
0
    {
390
0
        wnaf_form(self.scalar.as_mut(), scalar.to_repr(), self.window_size);
391
0
        wnaf_exp(self.base.as_ref(), self.scalar.as_mut())
392
0
    }
393
}
394
395
/// A "w-ary non-adjacent form" scalar, that uses precomputation to improve the speed of
396
/// scalar multiplication.
397
///
398
/// # Examples
399
///
400
/// See [`WnafBase`] for usage examples.
401
#[derive(Clone, Debug)]
402
pub struct WnafScalar<F: PrimeField, const WINDOW_SIZE: usize> {
403
    wnaf: Vec<i64>,
404
    field: PhantomData<F>,
405
}
406
407
#[cfg(feature = "wnaf-memuse")]
408
impl<F: PrimeField, const WINDOW_SIZE: usize> memuse::DynamicUsage for WnafScalar<F, WINDOW_SIZE> {
409
    fn dynamic_usage(&self) -> usize {
410
        self.wnaf.dynamic_usage()
411
    }
412
413
    fn dynamic_usage_bounds(&self) -> (usize, Option<usize>) {
414
        self.wnaf.dynamic_usage_bounds()
415
    }
416
}
417
418
impl<F: PrimeField, const WINDOW_SIZE: usize> WnafScalar<F, WINDOW_SIZE> {
419
    /// Computes the w-NAF representation of the given scalar with the specified
420
    /// `WINDOW_SIZE`.
421
0
    pub fn new(scalar: &F) -> Self {
422
0
        let mut wnaf = vec![];
423
0
424
0
        // Compute the w-NAF form of the scalar.
425
0
        wnaf_form(&mut wnaf, scalar.to_repr(), WINDOW_SIZE);
426
0
427
0
        WnafScalar {
428
0
            wnaf,
429
0
            field: PhantomData::default(),
430
0
        }
431
0
    }
432
}
433
434
/// A fixed window table for a group element, precomputed to improve the speed of scalar
435
/// multiplication.
436
///
437
/// This struct is designed for usage patterns that have long-term cached bases and/or
438
/// scalars, or [Cartesian products] of bases and scalars. The [`Wnaf`] API enables one or
439
/// the other to be cached, but requires either the base window tables or the scalar w-NAF
440
/// forms to be computed repeatedly on the fly, which can become a significant performance
441
/// issue for some use cases.
442
///
443
/// `WnafBase` and [`WnafScalar`] enable an alternative trade-off: by fixing the window
444
/// size at compile time, the precomputations are guaranteed to only occur once per base
445
/// and once per scalar. Users should select their window size based on how long the bases
446
/// are expected to live; a larger window size will consume more memory and take longer to
447
/// precompute, but result in faster scalar multiplications.
448
///
449
/// [Cartesian products]: https://en.wikipedia.org/wiki/Cartesian_product
450
///
451
/// # Examples
452
///
453
/// ```ignore
454
/// use group::{WnafBase, WnafScalar};
455
///
456
/// let wnaf_bases: Vec<_> = bases.into_iter().map(WnafBase::<_, 4>::new).collect();
457
/// let wnaf_scalars: Vec<_> = scalars.iter().map(WnafScalar::new).collect();
458
/// let results: Vec<_> = wnaf_bases
459
///     .iter()
460
///     .flat_map(|base| wnaf_scalars.iter().map(|scalar| base * scalar))
461
///     .collect();
462
/// ```
463
///
464
/// Note that this pattern requires specifying a fixed window size (unlike previous
465
/// patterns that picked a suitable window size internally). This is necessary to ensure
466
/// in the type system that the base and scalar `Wnaf`s were computed with the same window
467
/// size, allowing the result to be computed infallibly.
468
#[derive(Clone, Debug)]
469
pub struct WnafBase<G: Group, const WINDOW_SIZE: usize> {
470
    table: Vec<G>,
471
}
472
473
#[cfg(feature = "wnaf-memuse")]
474
impl<G: Group + memuse::DynamicUsage, const WINDOW_SIZE: usize> memuse::DynamicUsage
475
    for WnafBase<G, WINDOW_SIZE>
476
{
477
    fn dynamic_usage(&self) -> usize {
478
        self.table.dynamic_usage()
479
    }
480
481
    fn dynamic_usage_bounds(&self) -> (usize, Option<usize>) {
482
        self.table.dynamic_usage_bounds()
483
    }
484
}
485
486
impl<G: Group, const WINDOW_SIZE: usize> WnafBase<G, WINDOW_SIZE> {
487
    /// Computes a window table for the given base with the specified `WINDOW_SIZE`.
488
0
    pub fn new(base: G) -> Self {
489
0
        let mut table = vec![];
490
0
491
0
        // Compute a window table for the provided base and window size.
492
0
        wnaf_table(&mut table, base, WINDOW_SIZE);
493
0
494
0
        WnafBase { table }
495
0
    }
496
}
497
498
impl<G: Group, const WINDOW_SIZE: usize> Mul<&WnafScalar<G::Scalar, WINDOW_SIZE>>
499
    for &WnafBase<G, WINDOW_SIZE>
500
{
501
    type Output = G;
502
503
0
    fn mul(self, rhs: &WnafScalar<G::Scalar, WINDOW_SIZE>) -> Self::Output {
504
0
        wnaf_exp(&self.table, &rhs.wnaf)
505
0
    }
506
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/lib.rs
Line
Count
Source
1
//! This crate is a Rust port of Google's high-performance [SwissTable] hash
2
//! map, adapted to make it a drop-in replacement for Rust's standard `HashMap`
3
//! and `HashSet` types.
4
//!
5
//! The original C++ version of [SwissTable] can be found [here], and this
6
//! [CppCon talk] gives an overview of how the algorithm works.
7
//!
8
//! [SwissTable]: https://abseil.io/blog/20180927-swisstables
9
//! [here]: https://github.com/abseil/abseil-cpp/blob/master/absl/container/internal/raw_hash_set.h
10
//! [CppCon talk]: https://www.youtube.com/watch?v=ncHmEUmJZf4
11
12
#![no_std]
13
#![cfg_attr(
14
    feature = "nightly",
15
    feature(
16
        test,
17
        core_intrinsics,
18
        dropck_eyepatch,
19
        min_specialization,
20
        extend_one,
21
        allocator_api,
22
        slice_ptr_get,
23
        maybe_uninit_array_assume_init,
24
        strict_provenance
25
    )
26
)]
27
#![allow(
28
    clippy::doc_markdown,
29
    clippy::module_name_repetitions,
30
    clippy::must_use_candidate,
31
    clippy::option_if_let_else,
32
    clippy::redundant_else,
33
    clippy::manual_map,
34
    clippy::missing_safety_doc,
35
    clippy::missing_errors_doc
36
)]
37
#![warn(missing_docs)]
38
#![warn(rust_2018_idioms)]
39
#![cfg_attr(feature = "nightly", warn(fuzzy_provenance_casts))]
40
#![cfg_attr(feature = "nightly", allow(internal_features))]
41
42
#[cfg(test)]
43
#[macro_use]
44
extern crate std;
45
46
#[cfg_attr(test, macro_use)]
47
extern crate alloc;
48
49
#[cfg(feature = "nightly")]
50
#[cfg(doctest)]
51
doc_comment::doctest!("../README.md");
52
53
#[macro_use]
54
mod macros;
55
56
#[cfg(feature = "raw")]
57
/// Experimental and unsafe `RawTable` API. This module is only available if the
58
/// `raw` feature is enabled.
59
pub mod raw {
60
    // The RawTable API is still experimental and is not properly documented yet.
61
    #[allow(missing_docs)]
62
    #[path = "mod.rs"]
63
    mod inner;
64
    pub use inner::*;
65
66
    #[cfg(feature = "rayon")]
67
    /// [rayon]-based parallel iterator types for hash maps.
68
    /// You will rarely need to interact with it directly unless you have need
69
    /// to name one of the iterator types.
70
    ///
71
    /// [rayon]: https://docs.rs/rayon/1.0/rayon
72
    pub mod rayon {
73
        pub use crate::external_trait_impls::rayon::raw::*;
74
    }
75
}
76
#[cfg(not(feature = "raw"))]
77
mod raw;
78
79
mod external_trait_impls;
80
mod map;
81
#[cfg(feature = "rustc-internal-api")]
82
mod rustc_entry;
83
mod scopeguard;
84
mod set;
85
mod table;
86
87
pub mod hash_map {
88
    //! A hash map implemented with quadratic probing and SIMD lookup.
89
    pub use crate::map::*;
90
91
    #[cfg(feature = "rustc-internal-api")]
92
    pub use crate::rustc_entry::*;
93
94
    #[cfg(feature = "rayon")]
95
    /// [rayon]-based parallel iterator types for hash maps.
96
    /// You will rarely need to interact with it directly unless you have need
97
    /// to name one of the iterator types.
98
    ///
99
    /// [rayon]: https://docs.rs/rayon/1.0/rayon
100
    pub mod rayon {
101
        pub use crate::external_trait_impls::rayon::map::*;
102
    }
103
}
104
pub mod hash_set {
105
    //! A hash set implemented as a `HashMap` where the value is `()`.
106
    pub use crate::set::*;
107
108
    #[cfg(feature = "rayon")]
109
    /// [rayon]-based parallel iterator types for hash sets.
110
    /// You will rarely need to interact with it directly unless you have need
111
    /// to name one of the iterator types.
112
    ///
113
    /// [rayon]: https://docs.rs/rayon/1.0/rayon
114
    pub mod rayon {
115
        pub use crate::external_trait_impls::rayon::set::*;
116
    }
117
}
118
pub mod hash_table {
119
    //! A hash table implemented with quadratic probing and SIMD lookup.
120
    pub use crate::table::*;
121
122
    #[cfg(feature = "rayon")]
123
    /// [rayon]-based parallel iterator types for hash tables.
124
    /// You will rarely need to interact with it directly unless you have need
125
    /// to name one of the iterator types.
126
    ///
127
    /// [rayon]: https://docs.rs/rayon/1.0/rayon
128
    pub mod rayon {
129
        pub use crate::external_trait_impls::rayon::table::*;
130
    }
131
}
132
133
pub use crate::map::HashMap;
134
pub use crate::set::HashSet;
135
pub use crate::table::HashTable;
136
137
#[cfg(feature = "equivalent")]
138
pub use equivalent::Equivalent;
139
140
// This is only used as a fallback when building as part of `std`.
141
#[cfg(not(feature = "equivalent"))]
142
/// Key equivalence trait.
143
///
144
/// This trait defines the function used to compare the input value with the
145
/// map keys (or set values) during a lookup operation such as [`HashMap::get`]
146
/// or [`HashSet::contains`].
147
/// It is provided with a blanket implementation based on the
148
/// [`Borrow`](core::borrow::Borrow) trait.
149
///
150
/// # Correctness
151
///
152
/// Equivalent values must hash to the same value.
153
pub trait Equivalent<K: ?Sized> {
154
    /// Checks if this value is equivalent to the given key.
155
    ///
156
    /// Returns `true` if both values are equivalent, and `false` otherwise.
157
    ///
158
    /// # Correctness
159
    ///
160
    /// When this function returns `true`, both `self` and `key` must hash to
161
    /// the same value.
162
    fn equivalent(&self, key: &K) -> bool;
163
}
164
165
#[cfg(not(feature = "equivalent"))]
166
impl<Q: ?Sized, K: ?Sized> Equivalent<K> for Q
167
where
168
    Q: Eq,
169
    K: core::borrow::Borrow<Q>,
170
{
171
0
    fn equivalent(&self, key: &K) -> bool {
172
0
        self == key.borrow()
173
0
    }
Unexecuted instantiation: _RNvXCsgkA6tlBCRmB_9hashbrownINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtB2_10EquivalentBq_E10equivalentCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXINICsgkA6tlBCRmB_9hashbrown0ppEpINtB5_10EquivalentpE10equivalentB5_
174
}
175
176
/// The error type for `try_reserve` methods.
177
#[derive(Clone, PartialEq, Eq, Debug)]
178
pub enum TryReserveError {
179
    /// Error due to the computed capacity exceeding the collection's maximum
180
    /// (usually `isize::MAX` bytes).
181
    CapacityOverflow,
182
183
    /// The memory allocator returned an error
184
    AllocError {
185
        /// The layout of the allocation request that failed.
186
        layout: alloc::alloc::Layout,
187
    },
188
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/map.rs
Line
Count
Source
1
use crate::raw::{
2
    Allocator, Bucket, Global, RawDrain, RawExtractIf, RawIntoIter, RawIter, RawTable,
3
};
4
use crate::{Equivalent, TryReserveError};
5
use core::borrow::Borrow;
6
use core::fmt::{self, Debug};
7
use core::hash::{BuildHasher, Hash};
8
use core::iter::FusedIterator;
9
use core::marker::PhantomData;
10
use core::mem;
11
use core::ops::Index;
12
13
/// Default hasher for `HashMap`.
14
#[cfg(feature = "ahash")]
15
pub type DefaultHashBuilder = core::hash::BuildHasherDefault<ahash::AHasher>;
16
17
/// Dummy default hasher for `HashMap`.
18
#[cfg(not(feature = "ahash"))]
19
pub enum DefaultHashBuilder {}
20
21
/// A hash map implemented with quadratic probing and SIMD lookup.
22
///
23
/// The default hashing algorithm is currently [`AHash`], though this is
24
/// subject to change at any point in the future. This hash function is very
25
/// fast for all types of keys, but this algorithm will typically *not* protect
26
/// against attacks such as HashDoS.
27
///
28
/// The hashing algorithm can be replaced on a per-`HashMap` basis using the
29
/// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. Many
30
/// alternative algorithms are available on crates.io, such as the [`fnv`] crate.
31
///
32
/// It is required that the keys implement the [`Eq`] and [`Hash`] traits, although
33
/// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`.
34
/// If you implement these yourself, it is important that the following
35
/// property holds:
36
///
37
/// ```text
38
/// k1 == k2 -> hash(k1) == hash(k2)
39
/// ```
40
///
41
/// In other words, if two keys are equal, their hashes must be equal.
42
///
43
/// It is a logic error for a key to be modified in such a way that the key's
44
/// hash, as determined by the [`Hash`] trait, or its equality, as determined by
45
/// the [`Eq`] trait, changes while it is in the map. This is normally only
46
/// possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
47
///
48
/// It is also a logic error for the [`Hash`] implementation of a key to panic.
49
/// This is generally only possible if the trait is implemented manually. If a
50
/// panic does occur then the contents of the `HashMap` may become corrupted and
51
/// some items may be dropped from the table.
52
///
53
/// # Examples
54
///
55
/// ```
56
/// use hashbrown::HashMap;
57
///
58
/// // Type inference lets us omit an explicit type signature (which
59
/// // would be `HashMap<String, String>` in this example).
60
/// let mut book_reviews = HashMap::new();
61
///
62
/// // Review some books.
63
/// book_reviews.insert(
64
///     "Adventures of Huckleberry Finn".to_string(),
65
///     "My favorite book.".to_string(),
66
/// );
67
/// book_reviews.insert(
68
///     "Grimms' Fairy Tales".to_string(),
69
///     "Masterpiece.".to_string(),
70
/// );
71
/// book_reviews.insert(
72
///     "Pride and Prejudice".to_string(),
73
///     "Very enjoyable.".to_string(),
74
/// );
75
/// book_reviews.insert(
76
///     "The Adventures of Sherlock Holmes".to_string(),
77
///     "Eye lyked it alot.".to_string(),
78
/// );
79
///
80
/// // Check for a specific one.
81
/// // When collections store owned values (String), they can still be
82
/// // queried using references (&str).
83
/// if !book_reviews.contains_key("Les Misérables") {
84
///     println!("We've got {} reviews, but Les Misérables ain't one.",
85
///              book_reviews.len());
86
/// }
87
///
88
/// // oops, this review has a lot of spelling mistakes, let's delete it.
89
/// book_reviews.remove("The Adventures of Sherlock Holmes");
90
///
91
/// // Look up the values associated with some keys.
92
/// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
93
/// for &book in &to_find {
94
///     match book_reviews.get(book) {
95
///         Some(review) => println!("{}: {}", book, review),
96
///         None => println!("{} is unreviewed.", book)
97
///     }
98
/// }
99
///
100
/// // Look up the value for a key (will panic if the key is not found).
101
/// println!("Review for Jane: {}", book_reviews["Pride and Prejudice"]);
102
///
103
/// // Iterate over everything.
104
/// for (book, review) in &book_reviews {
105
///     println!("{}: \"{}\"", book, review);
106
/// }
107
/// ```
108
///
109
/// `HashMap` also implements an [`Entry API`](#method.entry), which allows
110
/// for more complex methods of getting, setting, updating and removing keys and
111
/// their values:
112
///
113
/// ```
114
/// use hashbrown::HashMap;
115
///
116
/// // type inference lets us omit an explicit type signature (which
117
/// // would be `HashMap<&str, u8>` in this example).
118
/// let mut player_stats = HashMap::new();
119
///
120
/// fn random_stat_buff() -> u8 {
121
///     // could actually return some random value here - let's just return
122
///     // some fixed value for now
123
///     42
124
/// }
125
///
126
/// // insert a key only if it doesn't already exist
127
/// player_stats.entry("health").or_insert(100);
128
///
129
/// // insert a key using a function that provides a new value only if it
130
/// // doesn't already exist
131
/// player_stats.entry("defence").or_insert_with(random_stat_buff);
132
///
133
/// // update a key, guarding against the key possibly not being set
134
/// let stat = player_stats.entry("attack").or_insert(100);
135
/// *stat += random_stat_buff();
136
/// ```
137
///
138
/// The easiest way to use `HashMap` with a custom key type is to derive [`Eq`] and [`Hash`].
139
/// We must also derive [`PartialEq`].
140
///
141
/// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
142
/// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
143
/// [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
144
/// [`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
145
/// [`Cell`]: https://doc.rust-lang.org/std/cell/struct.Cell.html
146
/// [`default`]: #method.default
147
/// [`with_hasher`]: #method.with_hasher
148
/// [`with_capacity_and_hasher`]: #method.with_capacity_and_hasher
149
/// [`fnv`]: https://crates.io/crates/fnv
150
/// [`AHash`]: https://crates.io/crates/ahash
151
///
152
/// ```
153
/// use hashbrown::HashMap;
154
///
155
/// #[derive(Hash, Eq, PartialEq, Debug)]
156
/// struct Viking {
157
///     name: String,
158
///     country: String,
159
/// }
160
///
161
/// impl Viking {
162
///     /// Creates a new Viking.
163
///     fn new(name: &str, country: &str) -> Viking {
164
///         Viking { name: name.to_string(), country: country.to_string() }
165
///     }
166
/// }
167
///
168
/// // Use a HashMap to store the vikings' health points.
169
/// let mut vikings = HashMap::new();
170
///
171
/// vikings.insert(Viking::new("Einar", "Norway"), 25);
172
/// vikings.insert(Viking::new("Olaf", "Denmark"), 24);
173
/// vikings.insert(Viking::new("Harald", "Iceland"), 12);
174
///
175
/// // Use derived implementation to print the status of the vikings.
176
/// for (viking, health) in &vikings {
177
///     println!("{:?} has {} hp", viking, health);
178
/// }
179
/// ```
180
///
181
/// A `HashMap` with fixed list of elements can be initialized from an array:
182
///
183
/// ```
184
/// use hashbrown::HashMap;
185
///
186
/// let timber_resources: HashMap<&str, i32> = [("Norway", 100), ("Denmark", 50), ("Iceland", 10)]
187
///     .into_iter().collect();
188
/// // use the values stored in map
189
/// ```
190
pub struct HashMap<K, V, S = DefaultHashBuilder, A: Allocator = Global> {
191
    pub(crate) hash_builder: S,
192
    pub(crate) table: RawTable<(K, V), A>,
193
}
194
195
impl<K: Clone, V: Clone, S: Clone, A: Allocator + Clone> Clone for HashMap<K, V, S, A> {
196
0
    fn clone(&self) -> Self {
197
0
        HashMap {
198
0
            hash_builder: self.hash_builder.clone(),
199
0
            table: self.table.clone(),
200
0
        }
201
0
    }
202
203
0
    fn clone_from(&mut self, source: &Self) {
204
0
        self.table.clone_from(&source.table);
205
0
206
0
        // Update hash_builder only if we successfully cloned all elements.
207
0
        self.hash_builder.clone_from(&source.hash_builder);
208
0
    }
209
}
210
211
/// Ensures that a single closure type across uses of this which, in turn prevents multiple
212
/// instances of any functions like RawTable::reserve from being generated
213
#[cfg_attr(feature = "inline-more", inline)]
214
0
pub(crate) fn make_hasher<Q, V, S>(hash_builder: &S) -> impl Fn(&(Q, V)) -> u64 + '_
215
0
where
216
0
    Q: Hash,
217
0
    S: BuildHasher,
218
0
{
219
0
    move |val| make_hash::<Q, S>(hash_builder, &val.0)
Unexecuted instantiation: _RNCINvNtCsgkA6tlBCRmB_9hashbrown3map11make_hasherINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBO_8LruEntryB1d_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEINtNtB1r_4hash18BuildHasherDefaultNtNtCseb6QmliwlWD_5ahash13fallback_hash7AHasherEE0B2s_
Unexecuted instantiation: _RNCINvNtCsgkA6tlBCRmB_9hashbrown3map11make_hasherpppE0B6_
220
0
}
Unexecuted instantiation: _RINvNtCsgkA6tlBCRmB_9hashbrown3map11make_hasherINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBM_8LruEntryB1b_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEINtNtB1p_4hash18BuildHasherDefaultNtNtCseb6QmliwlWD_5ahash13fallback_hash7AHasherEEB2q_
Unexecuted instantiation: _RINvNtCsgkA6tlBCRmB_9hashbrown3map11make_hasherpppEB4_
221
222
/// Ensures that a single closure type across uses of this which, in turn prevents multiple
223
/// instances of any functions like RawTable::reserve from being generated
224
#[cfg_attr(feature = "inline-more", inline)]
225
0
fn equivalent_key<Q, K, V>(k: &Q) -> impl Fn(&(K, V)) -> bool + '_
226
0
where
227
0
    Q: ?Sized + Equivalent<K>,
228
0
{
229
0
    move |x| k.equivalent(&x.0)
Unexecuted instantiation: _RNCINvNtCsgkA6tlBCRmB_9hashbrown3map14equivalent_keyINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EBO_INtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBR_8LruEntryB1g_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEE0B2y_
Unexecuted instantiation: _RNCINvNtCsgkA6tlBCRmB_9hashbrown3map14equivalent_keypppE0B6_
230
0
}
Unexecuted instantiation: _RINvNtCsgkA6tlBCRmB_9hashbrown3map14equivalent_keyINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EBM_INtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBP_8LruEntryB1e_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEB2w_
Unexecuted instantiation: _RINvNtCsgkA6tlBCRmB_9hashbrown3map14equivalent_keypppEB4_
231
232
/// Ensures that a single closure type across uses of this which, in turn prevents multiple
233
/// instances of any functions like RawTable::reserve from being generated
234
#[cfg_attr(feature = "inline-more", inline)]
235
0
fn equivalent<Q, K>(k: &Q) -> impl Fn(&K) -> bool + '_
236
0
where
237
0
    Q: ?Sized + Equivalent<K>,
238
0
{
239
0
    move |x| k.equivalent(x)
240
0
}
241
242
#[cfg(not(feature = "nightly"))]
243
#[cfg_attr(feature = "inline-more", inline)]
244
0
pub(crate) fn make_hash<Q, S>(hash_builder: &S, val: &Q) -> u64
245
0
where
246
0
    Q: Hash + ?Sized,
247
0
    S: BuildHasher,
248
0
{
249
    use core::hash::Hasher;
250
0
    let mut state = hash_builder.build_hasher();
251
0
    val.hash(&mut state);
252
0
    state.finish()
253
0
}
Unexecuted instantiation: _RINvNtCsgkA6tlBCRmB_9hashbrown3map9make_hashINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtCsbQ8arDwx5Xq_4core4hash18BuildHasherDefaultNtNtCseb6QmliwlWD_5ahash13fallback_hash7AHasherEECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvNtCsgkA6tlBCRmB_9hashbrown3map9make_hashppEB4_
254
255
#[cfg(feature = "nightly")]
256
#[cfg_attr(feature = "inline-more", inline)]
257
pub(crate) fn make_hash<Q, S>(hash_builder: &S, val: &Q) -> u64
258
where
259
    Q: Hash + ?Sized,
260
    S: BuildHasher,
261
{
262
    hash_builder.hash_one(val)
263
}
264
265
#[cfg(feature = "ahash")]
266
impl<K, V> HashMap<K, V, DefaultHashBuilder> {
267
    /// Creates an empty `HashMap`.
268
    ///
269
    /// The hash map is initially created with a capacity of 0, so it will not allocate until it
270
    /// is first inserted into.
271
    ///
272
    /// # HashDoS resistance
273
    ///
274
    /// The `hash_builder` normally use a fixed key by default and that does
275
    /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
276
    /// Users who require HashDoS resistance should explicitly use
277
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
278
    /// as the hasher when creating a [`HashMap`], for example with
279
    /// [`with_hasher`](HashMap::with_hasher) method.
280
    ///
281
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
282
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
283
    ///
284
    /// # Examples
285
    ///
286
    /// ```
287
    /// use hashbrown::HashMap;
288
    /// let mut map: HashMap<&str, i32> = HashMap::new();
289
    /// assert_eq!(map.len(), 0);
290
    /// assert_eq!(map.capacity(), 0);
291
    /// ```
292
    #[cfg_attr(feature = "inline-more", inline)]
293
0
    pub fn new() -> Self {
294
0
        Self::default()
295
0
    }
296
297
    /// Creates an empty `HashMap` with the specified capacity.
298
    ///
299
    /// The hash map will be able to hold at least `capacity` elements without
300
    /// reallocating. If `capacity` is 0, the hash map will not allocate.
301
    ///
302
    /// # HashDoS resistance
303
    ///
304
    /// The `hash_builder` normally use a fixed key by default and that does
305
    /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
306
    /// Users who require HashDoS resistance should explicitly use
307
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
308
    /// as the hasher when creating a [`HashMap`], for example with
309
    /// [`with_capacity_and_hasher`](HashMap::with_capacity_and_hasher) method.
310
    ///
311
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
312
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
313
    ///
314
    /// # Examples
315
    ///
316
    /// ```
317
    /// use hashbrown::HashMap;
318
    /// let mut map: HashMap<&str, i32> = HashMap::with_capacity(10);
319
    /// assert_eq!(map.len(), 0);
320
    /// assert!(map.capacity() >= 10);
321
    /// ```
322
    #[cfg_attr(feature = "inline-more", inline)]
323
0
    pub fn with_capacity(capacity: usize) -> Self {
324
0
        Self::with_capacity_and_hasher(capacity, DefaultHashBuilder::default())
325
0
    }
Unexecuted instantiation: _RNvMs_NtCsgkA6tlBCRmB_9hashbrown3mapINtB4_7HashMapINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBP_8LruEntryB1e_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEE13with_capacityB2t_
Unexecuted instantiation: _RNvMs_NtCsgkA6tlBCRmB_9hashbrown3mapINtB4_7HashMapppE13with_capacityB6_
326
}
327
328
#[cfg(feature = "ahash")]
329
impl<K, V, A: Allocator> HashMap<K, V, DefaultHashBuilder, A> {
330
    /// Creates an empty `HashMap` using the given allocator.
331
    ///
332
    /// The hash map is initially created with a capacity of 0, so it will not allocate until it
333
    /// is first inserted into.
334
    ///
335
    /// # HashDoS resistance
336
    ///
337
    /// The `hash_builder` normally use a fixed key by default and that does
338
    /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
339
    /// Users who require HashDoS resistance should explicitly use
340
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
341
    /// as the hasher when creating a [`HashMap`], for example with
342
    /// [`with_hasher_in`](HashMap::with_hasher_in) method.
343
    ///
344
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
345
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
346
    ///
347
    /// # Examples
348
    ///
349
    /// ```
350
    /// use hashbrown::HashMap;
351
    /// use bumpalo::Bump;
352
    ///
353
    /// let bump = Bump::new();
354
    /// let mut map = HashMap::new_in(&bump);
355
    ///
356
    /// // The created HashMap holds none elements
357
    /// assert_eq!(map.len(), 0);
358
    ///
359
    /// // The created HashMap also doesn't allocate memory
360
    /// assert_eq!(map.capacity(), 0);
361
    ///
362
    /// // Now we insert element inside created HashMap
363
    /// map.insert("One", 1);
364
    /// // We can see that the HashMap holds 1 element
365
    /// assert_eq!(map.len(), 1);
366
    /// // And it also allocates some capacity
367
    /// assert!(map.capacity() > 1);
368
    /// ```
369
    #[cfg_attr(feature = "inline-more", inline)]
370
0
    pub fn new_in(alloc: A) -> Self {
371
0
        Self::with_hasher_in(DefaultHashBuilder::default(), alloc)
372
0
    }
373
374
    /// Creates an empty `HashMap` with the specified capacity using the given allocator.
375
    ///
376
    /// The hash map will be able to hold at least `capacity` elements without
377
    /// reallocating. If `capacity` is 0, the hash map will not allocate.
378
    ///
379
    /// # HashDoS resistance
380
    ///
381
    /// The `hash_builder` normally use a fixed key by default and that does
382
    /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
383
    /// Users who require HashDoS resistance should explicitly use
384
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
385
    /// as the hasher when creating a [`HashMap`], for example with
386
    /// [`with_capacity_and_hasher_in`](HashMap::with_capacity_and_hasher_in) method.
387
    ///
388
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
389
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
390
    ///
391
    /// # Examples
392
    ///
393
    /// ```
394
    /// use hashbrown::HashMap;
395
    /// use bumpalo::Bump;
396
    ///
397
    /// let bump = Bump::new();
398
    /// let mut map = HashMap::with_capacity_in(5, &bump);
399
    ///
400
    /// // The created HashMap holds none elements
401
    /// assert_eq!(map.len(), 0);
402
    /// // But it can hold at least 5 elements without reallocating
403
    /// let empty_map_capacity = map.capacity();
404
    /// assert!(empty_map_capacity >= 5);
405
    ///
406
    /// // Now we insert some 5 elements inside created HashMap
407
    /// map.insert("One",   1);
408
    /// map.insert("Two",   2);
409
    /// map.insert("Three", 3);
410
    /// map.insert("Four",  4);
411
    /// map.insert("Five",  5);
412
    ///
413
    /// // We can see that the HashMap holds 5 elements
414
    /// assert_eq!(map.len(), 5);
415
    /// // But its capacity isn't changed
416
    /// assert_eq!(map.capacity(), empty_map_capacity)
417
    /// ```
418
    #[cfg_attr(feature = "inline-more", inline)]
419
0
    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
420
0
        Self::with_capacity_and_hasher_in(capacity, DefaultHashBuilder::default(), alloc)
421
0
    }
422
}
423
424
impl<K, V, S> HashMap<K, V, S> {
425
    /// Creates an empty `HashMap` which will use the given hash builder to hash
426
    /// keys.
427
    ///
428
    /// The hash map is initially created with a capacity of 0, so it will not
429
    /// allocate until it is first inserted into.
430
    ///
431
    /// # HashDoS resistance
432
    ///
433
    /// The `hash_builder` normally use a fixed key by default and that does
434
    /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
435
    /// Users who require HashDoS resistance should explicitly use
436
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
437
    /// as the hasher when creating a [`HashMap`].
438
    ///
439
    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
440
    /// the HashMap to be useful, see its documentation for details.
441
    ///
442
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
443
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
444
    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
445
    ///
446
    /// # Examples
447
    ///
448
    /// ```
449
    /// use hashbrown::HashMap;
450
    /// use hashbrown::hash_map::DefaultHashBuilder;
451
    ///
452
    /// let s = DefaultHashBuilder::default();
453
    /// let mut map = HashMap::with_hasher(s);
454
    /// assert_eq!(map.len(), 0);
455
    /// assert_eq!(map.capacity(), 0);
456
    ///
457
    /// map.insert(1, 2);
458
    /// ```
459
    #[cfg_attr(feature = "inline-more", inline)]
460
0
    pub const fn with_hasher(hash_builder: S) -> Self {
461
0
        Self {
462
0
            hash_builder,
463
0
            table: RawTable::new(),
464
0
        }
465
0
    }
466
467
    /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
468
    /// to hash the keys.
469
    ///
470
    /// The hash map will be able to hold at least `capacity` elements without
471
    /// reallocating. If `capacity` is 0, the hash map will not allocate.
472
    ///
473
    /// # HashDoS resistance
474
    ///
475
    /// The `hash_builder` normally use a fixed key by default and that does
476
    /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
477
    /// Users who require HashDoS resistance should explicitly use
478
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
479
    /// as the hasher when creating a [`HashMap`].
480
    ///
481
    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
482
    /// the HashMap to be useful, see its documentation for details.
483
    ///
484
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
485
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
486
    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
487
    ///
488
    /// # Examples
489
    ///
490
    /// ```
491
    /// use hashbrown::HashMap;
492
    /// use hashbrown::hash_map::DefaultHashBuilder;
493
    ///
494
    /// let s = DefaultHashBuilder::default();
495
    /// let mut map = HashMap::with_capacity_and_hasher(10, s);
496
    /// assert_eq!(map.len(), 0);
497
    /// assert!(map.capacity() >= 10);
498
    ///
499
    /// map.insert(1, 2);
500
    /// ```
501
    #[cfg_attr(feature = "inline-more", inline)]
502
0
    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
503
0
        Self {
504
0
            hash_builder,
505
0
            table: RawTable::with_capacity(capacity),
506
0
        }
507
0
    }
Unexecuted instantiation: _RNvMs1_NtCsgkA6tlBCRmB_9hashbrown3mapINtB5_7HashMapINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEE24with_capacity_and_hasherB2u_
Unexecuted instantiation: _RNvMs1_NtCsgkA6tlBCRmB_9hashbrown3mapINtB5_7HashMappppE24with_capacity_and_hasherB7_
508
}
509
510
impl<K, V, S, A: Allocator> HashMap<K, V, S, A> {
511
    /// Returns a reference to the underlying allocator.
512
    #[inline]
513
0
    pub fn allocator(&self) -> &A {
514
0
        self.table.allocator()
515
0
    }
516
517
    /// Creates an empty `HashMap` which will use the given hash builder to hash
518
    /// keys. It will be allocated with the given allocator.
519
    ///
520
    /// The hash map is initially created with a capacity of 0, so it will not allocate until it
521
    /// is first inserted into.
522
    ///
523
    /// # HashDoS resistance
524
    ///
525
    /// The `hash_builder` normally use a fixed key by default and that does
526
    /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
527
    /// Users who require HashDoS resistance should explicitly use
528
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
529
    /// as the hasher when creating a [`HashMap`].
530
    ///
531
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
532
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
533
    ///
534
    /// # Examples
535
    ///
536
    /// ```
537
    /// use hashbrown::HashMap;
538
    /// use hashbrown::hash_map::DefaultHashBuilder;
539
    ///
540
    /// let s = DefaultHashBuilder::default();
541
    /// let mut map = HashMap::with_hasher(s);
542
    /// map.insert(1, 2);
543
    /// ```
544
    #[cfg_attr(feature = "inline-more", inline)]
545
0
    pub const fn with_hasher_in(hash_builder: S, alloc: A) -> Self {
546
0
        Self {
547
0
            hash_builder,
548
0
            table: RawTable::new_in(alloc),
549
0
        }
550
0
    }
551
552
    /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
553
    /// to hash the keys. It will be allocated with the given allocator.
554
    ///
555
    /// The hash map will be able to hold at least `capacity` elements without
556
    /// reallocating. If `capacity` is 0, the hash map will not allocate.
557
    ///
558
    /// # HashDoS resistance
559
    ///
560
    /// The `hash_builder` normally use a fixed key by default and that does
561
    /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
562
    /// Users who require HashDoS resistance should explicitly use
563
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
564
    /// as the hasher when creating a [`HashMap`].
565
    ///
566
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
567
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
568
    ///
569
    /// # Examples
570
    ///
571
    /// ```
572
    /// use hashbrown::HashMap;
573
    /// use hashbrown::hash_map::DefaultHashBuilder;
574
    ///
575
    /// let s = DefaultHashBuilder::default();
576
    /// let mut map = HashMap::with_capacity_and_hasher(10, s);
577
    /// map.insert(1, 2);
578
    /// ```
579
    #[cfg_attr(feature = "inline-more", inline)]
580
0
    pub fn with_capacity_and_hasher_in(capacity: usize, hash_builder: S, alloc: A) -> Self {
581
0
        Self {
582
0
            hash_builder,
583
0
            table: RawTable::with_capacity_in(capacity, alloc),
584
0
        }
585
0
    }
586
587
    /// Returns a reference to the map's [`BuildHasher`].
588
    ///
589
    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
590
    ///
591
    /// # Examples
592
    ///
593
    /// ```
594
    /// use hashbrown::HashMap;
595
    /// use hashbrown::hash_map::DefaultHashBuilder;
596
    ///
597
    /// let hasher = DefaultHashBuilder::default();
598
    /// let map: HashMap<i32, i32> = HashMap::with_hasher(hasher);
599
    /// let hasher: &DefaultHashBuilder = map.hasher();
600
    /// ```
601
    #[cfg_attr(feature = "inline-more", inline)]
602
0
    pub fn hasher(&self) -> &S {
603
0
        &self.hash_builder
604
0
    }
605
606
    /// Returns the number of elements the map can hold without reallocating.
607
    ///
608
    /// This number is a lower bound; the `HashMap<K, V>` might be able to hold
609
    /// more, but is guaranteed to be able to hold at least this many.
610
    ///
611
    /// # Examples
612
    ///
613
    /// ```
614
    /// use hashbrown::HashMap;
615
    /// let map: HashMap<i32, i32> = HashMap::with_capacity(100);
616
    /// assert_eq!(map.len(), 0);
617
    /// assert!(map.capacity() >= 100);
618
    /// ```
619
    #[cfg_attr(feature = "inline-more", inline)]
620
0
    pub fn capacity(&self) -> usize {
621
0
        self.table.capacity()
622
0
    }
623
624
    /// An iterator visiting all keys in arbitrary order.
625
    /// The iterator element type is `&'a K`.
626
    ///
627
    /// # Examples
628
    ///
629
    /// ```
630
    /// use hashbrown::HashMap;
631
    ///
632
    /// let mut map = HashMap::new();
633
    /// map.insert("a", 1);
634
    /// map.insert("b", 2);
635
    /// map.insert("c", 3);
636
    /// assert_eq!(map.len(), 3);
637
    /// let mut vec: Vec<&str> = Vec::new();
638
    ///
639
    /// for key in map.keys() {
640
    ///     println!("{}", key);
641
    ///     vec.push(*key);
642
    /// }
643
    ///
644
    /// // The `Keys` iterator produces keys in arbitrary order, so the
645
    /// // keys must be sorted to test them against a sorted array.
646
    /// vec.sort_unstable();
647
    /// assert_eq!(vec, ["a", "b", "c"]);
648
    ///
649
    /// assert_eq!(map.len(), 3);
650
    /// ```
651
    #[cfg_attr(feature = "inline-more", inline)]
652
0
    pub fn keys(&self) -> Keys<'_, K, V> {
653
0
        Keys { inner: self.iter() }
654
0
    }
655
656
    /// An iterator visiting all values in arbitrary order.
657
    /// The iterator element type is `&'a V`.
658
    ///
659
    /// # Examples
660
    ///
661
    /// ```
662
    /// use hashbrown::HashMap;
663
    ///
664
    /// let mut map = HashMap::new();
665
    /// map.insert("a", 1);
666
    /// map.insert("b", 2);
667
    /// map.insert("c", 3);
668
    /// assert_eq!(map.len(), 3);
669
    /// let mut vec: Vec<i32> = Vec::new();
670
    ///
671
    /// for val in map.values() {
672
    ///     println!("{}", val);
673
    ///     vec.push(*val);
674
    /// }
675
    ///
676
    /// // The `Values` iterator produces values in arbitrary order, so the
677
    /// // values must be sorted to test them against a sorted array.
678
    /// vec.sort_unstable();
679
    /// assert_eq!(vec, [1, 2, 3]);
680
    ///
681
    /// assert_eq!(map.len(), 3);
682
    /// ```
683
    #[cfg_attr(feature = "inline-more", inline)]
684
0
    pub fn values(&self) -> Values<'_, K, V> {
685
0
        Values { inner: self.iter() }
686
0
    }
687
688
    /// An iterator visiting all values mutably in arbitrary order.
689
    /// The iterator element type is `&'a mut V`.
690
    ///
691
    /// # Examples
692
    ///
693
    /// ```
694
    /// use hashbrown::HashMap;
695
    ///
696
    /// let mut map = HashMap::new();
697
    ///
698
    /// map.insert("a", 1);
699
    /// map.insert("b", 2);
700
    /// map.insert("c", 3);
701
    ///
702
    /// for val in map.values_mut() {
703
    ///     *val = *val + 10;
704
    /// }
705
    ///
706
    /// assert_eq!(map.len(), 3);
707
    /// let mut vec: Vec<i32> = Vec::new();
708
    ///
709
    /// for val in map.values() {
710
    ///     println!("{}", val);
711
    ///     vec.push(*val);
712
    /// }
713
    ///
714
    /// // The `Values` iterator produces values in arbitrary order, so the
715
    /// // values must be sorted to test them against a sorted array.
716
    /// vec.sort_unstable();
717
    /// assert_eq!(vec, [11, 12, 13]);
718
    ///
719
    /// assert_eq!(map.len(), 3);
720
    /// ```
721
    #[cfg_attr(feature = "inline-more", inline)]
722
0
    pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
723
0
        ValuesMut {
724
0
            inner: self.iter_mut(),
725
0
        }
726
0
    }
727
728
    /// An iterator visiting all key-value pairs in arbitrary order.
729
    /// The iterator element type is `(&'a K, &'a V)`.
730
    ///
731
    /// # Examples
732
    ///
733
    /// ```
734
    /// use hashbrown::HashMap;
735
    ///
736
    /// let mut map = HashMap::new();
737
    /// map.insert("a", 1);
738
    /// map.insert("b", 2);
739
    /// map.insert("c", 3);
740
    /// assert_eq!(map.len(), 3);
741
    /// let mut vec: Vec<(&str, i32)> = Vec::new();
742
    ///
743
    /// for (key, val) in map.iter() {
744
    ///     println!("key: {} val: {}", key, val);
745
    ///     vec.push((*key, *val));
746
    /// }
747
    ///
748
    /// // The `Iter` iterator produces items in arbitrary order, so the
749
    /// // items must be sorted to test them against a sorted array.
750
    /// vec.sort_unstable();
751
    /// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]);
752
    ///
753
    /// assert_eq!(map.len(), 3);
754
    /// ```
755
    #[cfg_attr(feature = "inline-more", inline)]
756
0
    pub fn iter(&self) -> Iter<'_, K, V> {
757
0
        // Here we tie the lifetime of self to the iter.
758
0
        unsafe {
759
0
            Iter {
760
0
                inner: self.table.iter(),
761
0
                marker: PhantomData,
762
0
            }
763
0
        }
764
0
    }
765
766
    /// An iterator visiting all key-value pairs in arbitrary order,
767
    /// with mutable references to the values.
768
    /// The iterator element type is `(&'a K, &'a mut V)`.
769
    ///
770
    /// # Examples
771
    ///
772
    /// ```
773
    /// use hashbrown::HashMap;
774
    ///
775
    /// let mut map = HashMap::new();
776
    /// map.insert("a", 1);
777
    /// map.insert("b", 2);
778
    /// map.insert("c", 3);
779
    ///
780
    /// // Update all values
781
    /// for (_, val) in map.iter_mut() {
782
    ///     *val *= 2;
783
    /// }
784
    ///
785
    /// assert_eq!(map.len(), 3);
786
    /// let mut vec: Vec<(&str, i32)> = Vec::new();
787
    ///
788
    /// for (key, val) in &map {
789
    ///     println!("key: {} val: {}", key, val);
790
    ///     vec.push((*key, *val));
791
    /// }
792
    ///
793
    /// // The `Iter` iterator produces items in arbitrary order, so the
794
    /// // items must be sorted to test them against a sorted array.
795
    /// vec.sort_unstable();
796
    /// assert_eq!(vec, [("a", 2), ("b", 4), ("c", 6)]);
797
    ///
798
    /// assert_eq!(map.len(), 3);
799
    /// ```
800
    #[cfg_attr(feature = "inline-more", inline)]
801
0
    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
802
0
        // Here we tie the lifetime of self to the iter.
803
0
        unsafe {
804
0
            IterMut {
805
0
                inner: self.table.iter(),
806
0
                marker: PhantomData,
807
0
            }
808
0
        }
809
0
    }
810
811
    #[cfg(test)]
812
    #[cfg_attr(feature = "inline-more", inline)]
813
    fn raw_capacity(&self) -> usize {
814
        self.table.buckets()
815
    }
816
817
    /// Returns the number of elements in the map.
818
    ///
819
    /// # Examples
820
    ///
821
    /// ```
822
    /// use hashbrown::HashMap;
823
    ///
824
    /// let mut a = HashMap::new();
825
    /// assert_eq!(a.len(), 0);
826
    /// a.insert(1, "a");
827
    /// assert_eq!(a.len(), 1);
828
    /// ```
829
    #[cfg_attr(feature = "inline-more", inline)]
830
0
    pub fn len(&self) -> usize {
831
0
        self.table.len()
832
0
    }
Unexecuted instantiation: _RNvMs2_NtCsgkA6tlBCRmB_9hashbrown3mapINtB5_7HashMapINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEE3lenB2u_
Unexecuted instantiation: _RNvMs2_NtCsgkA6tlBCRmB_9hashbrown3mapINtB5_7HashMapppppE3lenB7_
833
834
    /// Returns `true` if the map contains no elements.
835
    ///
836
    /// # Examples
837
    ///
838
    /// ```
839
    /// use hashbrown::HashMap;
840
    ///
841
    /// let mut a = HashMap::new();
842
    /// assert!(a.is_empty());
843
    /// a.insert(1, "a");
844
    /// assert!(!a.is_empty());
845
    /// ```
846
    #[cfg_attr(feature = "inline-more", inline)]
847
0
    pub fn is_empty(&self) -> bool {
848
0
        self.len() == 0
849
0
    }
850
851
    /// Clears the map, returning all key-value pairs as an iterator. Keeps the
852
    /// allocated memory for reuse.
853
    ///
854
    /// If the returned iterator is dropped before being fully consumed, it
855
    /// drops the remaining key-value pairs. The returned iterator keeps a
856
    /// mutable borrow on the vector to optimize its implementation.
857
    ///
858
    /// # Examples
859
    ///
860
    /// ```
861
    /// use hashbrown::HashMap;
862
    ///
863
    /// let mut a = HashMap::new();
864
    /// a.insert(1, "a");
865
    /// a.insert(2, "b");
866
    /// let capacity_before_drain = a.capacity();
867
    ///
868
    /// for (k, v) in a.drain().take(1) {
869
    ///     assert!(k == 1 || k == 2);
870
    ///     assert!(v == "a" || v == "b");
871
    /// }
872
    ///
873
    /// // As we can see, the map is empty and contains no element.
874
    /// assert!(a.is_empty() && a.len() == 0);
875
    /// // But map capacity is equal to old one.
876
    /// assert_eq!(a.capacity(), capacity_before_drain);
877
    ///
878
    /// let mut a = HashMap::new();
879
    /// a.insert(1, "a");
880
    /// a.insert(2, "b");
881
    ///
882
    /// {   // Iterator is dropped without being consumed.
883
    ///     let d = a.drain();
884
    /// }
885
    ///
886
    /// // But the map is empty even if we do not use Drain iterator.
887
    /// assert!(a.is_empty());
888
    /// ```
889
    #[cfg_attr(feature = "inline-more", inline)]
890
0
    pub fn drain(&mut self) -> Drain<'_, K, V, A> {
891
0
        Drain {
892
0
            inner: self.table.drain(),
893
0
        }
894
0
    }
Unexecuted instantiation: _RNvMs2_NtCsgkA6tlBCRmB_9hashbrown3mapINtB5_7HashMapINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEE5drainB2u_
Unexecuted instantiation: _RNvMs2_NtCsgkA6tlBCRmB_9hashbrown3mapINtB5_7HashMapppppE5drainB7_
895
896
    /// Retains only the elements specified by the predicate. Keeps the
897
    /// allocated memory for reuse.
898
    ///
899
    /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
900
    /// The elements are visited in unsorted (and unspecified) order.
901
    ///
902
    /// # Examples
903
    ///
904
    /// ```
905
    /// use hashbrown::HashMap;
906
    ///
907
    /// let mut map: HashMap<i32, i32> = (0..8).map(|x|(x, x*10)).collect();
908
    /// assert_eq!(map.len(), 8);
909
    ///
910
    /// map.retain(|&k, _| k % 2 == 0);
911
    ///
912
    /// // We can see, that the number of elements inside map is changed.
913
    /// assert_eq!(map.len(), 4);
914
    ///
915
    /// let mut vec: Vec<(i32, i32)> = map.iter().map(|(&k, &v)| (k, v)).collect();
916
    /// vec.sort_unstable();
917
    /// assert_eq!(vec, [(0, 0), (2, 20), (4, 40), (6, 60)]);
918
    /// ```
919
0
    pub fn retain<F>(&mut self, mut f: F)
920
0
    where
921
0
        F: FnMut(&K, &mut V) -> bool,
922
0
    {
923
        // Here we only use `iter` as a temporary, preventing use-after-free
924
        unsafe {
925
0
            for item in self.table.iter() {
926
0
                let &mut (ref key, ref mut value) = item.as_mut();
927
0
                if !f(key, value) {
928
0
                    self.table.erase(item);
929
0
                }
930
            }
931
        }
932
0
    }
933
934
    /// Drains elements which are true under the given predicate,
935
    /// and returns an iterator over the removed items.
936
    ///
937
    /// In other words, move all pairs `(k, v)` such that `f(&k, &mut v)` returns `true` out
938
    /// into another iterator.
939
    ///
940
    /// Note that `extract_if` lets you mutate every value in the filter closure, regardless of
941
    /// whether you choose to keep or remove it.
942
    ///
943
    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
944
    /// or the iteration short-circuits, then the remaining elements will be retained.
945
    /// Use [`retain()`] with a negated predicate if you do not need the returned iterator.
946
    ///
947
    /// Keeps the allocated memory for reuse.
948
    ///
949
    /// [`retain()`]: HashMap::retain
950
    ///
951
    /// # Examples
952
    ///
953
    /// ```
954
    /// use hashbrown::HashMap;
955
    ///
956
    /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
957
    ///
958
    /// let drained: HashMap<i32, i32> = map.extract_if(|k, _v| k % 2 == 0).collect();
959
    ///
960
    /// let mut evens = drained.keys().cloned().collect::<Vec<_>>();
961
    /// let mut odds = map.keys().cloned().collect::<Vec<_>>();
962
    /// evens.sort();
963
    /// odds.sort();
964
    ///
965
    /// assert_eq!(evens, vec![0, 2, 4, 6]);
966
    /// assert_eq!(odds, vec![1, 3, 5, 7]);
967
    ///
968
    /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
969
    ///
970
    /// {   // Iterator is dropped without being consumed.
971
    ///     let d = map.extract_if(|k, _v| k % 2 != 0);
972
    /// }
973
    ///
974
    /// // ExtractIf was not exhausted, therefore no elements were drained.
975
    /// assert_eq!(map.len(), 8);
976
    /// ```
977
    #[cfg_attr(feature = "inline-more", inline)]
978
0
    pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, K, V, F, A>
979
0
    where
980
0
        F: FnMut(&K, &mut V) -> bool,
981
0
    {
982
0
        ExtractIf {
983
0
            f,
984
0
            inner: RawExtractIf {
985
0
                iter: unsafe { self.table.iter() },
986
0
                table: &mut self.table,
987
0
            },
988
0
        }
989
0
    }
990
991
    /// Clears the map, removing all key-value pairs. Keeps the allocated memory
992
    /// for reuse.
993
    ///
994
    /// # Examples
995
    ///
996
    /// ```
997
    /// use hashbrown::HashMap;
998
    ///
999
    /// let mut a = HashMap::new();
1000
    /// a.insert(1, "a");
1001
    /// let capacity_before_clear = a.capacity();
1002
    ///
1003
    /// a.clear();
1004
    ///
1005
    /// // Map is empty.
1006
    /// assert!(a.is_empty());
1007
    /// // But map capacity is equal to old one.
1008
    /// assert_eq!(a.capacity(), capacity_before_clear);
1009
    /// ```
1010
    #[cfg_attr(feature = "inline-more", inline)]
1011
0
    pub fn clear(&mut self) {
1012
0
        self.table.clear();
1013
0
    }
1014
1015
    /// Creates a consuming iterator visiting all the keys in arbitrary order.
1016
    /// The map cannot be used after calling this.
1017
    /// The iterator element type is `K`.
1018
    ///
1019
    /// # Examples
1020
    ///
1021
    /// ```
1022
    /// use hashbrown::HashMap;
1023
    ///
1024
    /// let mut map = HashMap::new();
1025
    /// map.insert("a", 1);
1026
    /// map.insert("b", 2);
1027
    /// map.insert("c", 3);
1028
    ///
1029
    /// let mut vec: Vec<&str> = map.into_keys().collect();
1030
    ///
1031
    /// // The `IntoKeys` iterator produces keys in arbitrary order, so the
1032
    /// // keys must be sorted to test them against a sorted array.
1033
    /// vec.sort_unstable();
1034
    /// assert_eq!(vec, ["a", "b", "c"]);
1035
    /// ```
1036
    #[inline]
1037
0
    pub fn into_keys(self) -> IntoKeys<K, V, A> {
1038
0
        IntoKeys {
1039
0
            inner: self.into_iter(),
1040
0
        }
1041
0
    }
1042
1043
    /// Creates a consuming iterator visiting all the values in arbitrary order.
1044
    /// The map cannot be used after calling this.
1045
    /// The iterator element type is `V`.
1046
    ///
1047
    /// # Examples
1048
    ///
1049
    /// ```
1050
    /// use hashbrown::HashMap;
1051
    ///
1052
    /// let mut map = HashMap::new();
1053
    /// map.insert("a", 1);
1054
    /// map.insert("b", 2);
1055
    /// map.insert("c", 3);
1056
    ///
1057
    /// let mut vec: Vec<i32> = map.into_values().collect();
1058
    ///
1059
    /// // The `IntoValues` iterator produces values in arbitrary order, so
1060
    /// // the values must be sorted to test them against a sorted array.
1061
    /// vec.sort_unstable();
1062
    /// assert_eq!(vec, [1, 2, 3]);
1063
    /// ```
1064
    #[inline]
1065
0
    pub fn into_values(self) -> IntoValues<K, V, A> {
1066
0
        IntoValues {
1067
0
            inner: self.into_iter(),
1068
0
        }
1069
0
    }
1070
}
1071
1072
impl<K, V, S, A> HashMap<K, V, S, A>
1073
where
1074
    K: Eq + Hash,
1075
    S: BuildHasher,
1076
    A: Allocator,
1077
{
1078
    /// Reserves capacity for at least `additional` more elements to be inserted
1079
    /// in the `HashMap`. The collection may reserve more space to avoid
1080
    /// frequent reallocations.
1081
    ///
1082
    /// # Panics
1083
    ///
1084
    /// Panics if the new capacity exceeds [`isize::MAX`] bytes and [`abort`] the program
1085
    /// in case of allocation error. Use [`try_reserve`](HashMap::try_reserve) instead
1086
    /// if you want to handle memory allocation failure.
1087
    ///
1088
    /// [`isize::MAX`]: https://doc.rust-lang.org/std/primitive.isize.html
1089
    /// [`abort`]: https://doc.rust-lang.org/alloc/alloc/fn.handle_alloc_error.html
1090
    ///
1091
    /// # Examples
1092
    ///
1093
    /// ```
1094
    /// use hashbrown::HashMap;
1095
    /// let mut map: HashMap<&str, i32> = HashMap::new();
1096
    /// // Map is empty and doesn't allocate memory
1097
    /// assert_eq!(map.capacity(), 0);
1098
    ///
1099
    /// map.reserve(10);
1100
    ///
1101
    /// // And now map can hold at least 10 elements
1102
    /// assert!(map.capacity() >= 10);
1103
    /// ```
1104
    #[cfg_attr(feature = "inline-more", inline)]
1105
0
    pub fn reserve(&mut self, additional: usize) {
1106
0
        self.table
1107
0
            .reserve(additional, make_hasher::<_, V, S>(&self.hash_builder));
1108
0
    }
1109
1110
    /// Tries to reserve capacity for at least `additional` more elements to be inserted
1111
    /// in the given `HashMap<K,V>`. The collection may reserve more space to avoid
1112
    /// frequent reallocations.
1113
    ///
1114
    /// # Errors
1115
    ///
1116
    /// If the capacity overflows, or the allocator reports a failure, then an error
1117
    /// is returned.
1118
    ///
1119
    /// # Examples
1120
    ///
1121
    /// ```
1122
    /// use hashbrown::HashMap;
1123
    ///
1124
    /// let mut map: HashMap<&str, isize> = HashMap::new();
1125
    /// // Map is empty and doesn't allocate memory
1126
    /// assert_eq!(map.capacity(), 0);
1127
    ///
1128
    /// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
1129
    ///
1130
    /// // And now map can hold at least 10 elements
1131
    /// assert!(map.capacity() >= 10);
1132
    /// ```
1133
    /// If the capacity overflows, or the allocator reports a failure, then an error
1134
    /// is returned:
1135
    /// ```
1136
    /// # fn test() {
1137
    /// use hashbrown::HashMap;
1138
    /// use hashbrown::TryReserveError;
1139
    /// let mut map: HashMap<i32, i32> = HashMap::new();
1140
    ///
1141
    /// match map.try_reserve(usize::MAX) {
1142
    ///     Err(error) => match error {
1143
    ///         TryReserveError::CapacityOverflow => {}
1144
    ///         _ => panic!("TryReserveError::AllocError ?"),
1145
    ///     },
1146
    ///     _ => panic!(),
1147
    /// }
1148
    /// # }
1149
    /// # fn main() {
1150
    /// #     #[cfg(not(miri))]
1151
    /// #     test()
1152
    /// # }
1153
    /// ```
1154
    #[cfg_attr(feature = "inline-more", inline)]
1155
0
    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
1156
0
        self.table
1157
0
            .try_reserve(additional, make_hasher::<_, V, S>(&self.hash_builder))
1158
0
    }
1159
1160
    /// Shrinks the capacity of the map as much as possible. It will drop
1161
    /// down as much as possible while maintaining the internal rules
1162
    /// and possibly leaving some space in accordance with the resize policy.
1163
    ///
1164
    /// # Examples
1165
    ///
1166
    /// ```
1167
    /// use hashbrown::HashMap;
1168
    ///
1169
    /// let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
1170
    /// map.insert(1, 2);
1171
    /// map.insert(3, 4);
1172
    /// assert!(map.capacity() >= 100);
1173
    /// map.shrink_to_fit();
1174
    /// assert!(map.capacity() >= 2);
1175
    /// ```
1176
    #[cfg_attr(feature = "inline-more", inline)]
1177
0
    pub fn shrink_to_fit(&mut self) {
1178
0
        self.table
1179
0
            .shrink_to(0, make_hasher::<_, V, S>(&self.hash_builder));
1180
0
    }
1181
1182
    /// Shrinks the capacity of the map with a lower limit. It will drop
1183
    /// down no lower than the supplied limit while maintaining the internal rules
1184
    /// and possibly leaving some space in accordance with the resize policy.
1185
    ///
1186
    /// This function does nothing if the current capacity is smaller than the
1187
    /// supplied minimum capacity.
1188
    ///
1189
    /// # Examples
1190
    ///
1191
    /// ```
1192
    /// use hashbrown::HashMap;
1193
    ///
1194
    /// let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
1195
    /// map.insert(1, 2);
1196
    /// map.insert(3, 4);
1197
    /// assert!(map.capacity() >= 100);
1198
    /// map.shrink_to(10);
1199
    /// assert!(map.capacity() >= 10);
1200
    /// map.shrink_to(0);
1201
    /// assert!(map.capacity() >= 2);
1202
    /// map.shrink_to(10);
1203
    /// assert!(map.capacity() >= 2);
1204
    /// ```
1205
    #[cfg_attr(feature = "inline-more", inline)]
1206
0
    pub fn shrink_to(&mut self, min_capacity: usize) {
1207
0
        self.table
1208
0
            .shrink_to(min_capacity, make_hasher::<_, V, S>(&self.hash_builder));
1209
0
    }
1210
1211
    /// Gets the given key's corresponding entry in the map for in-place manipulation.
1212
    ///
1213
    /// # Examples
1214
    ///
1215
    /// ```
1216
    /// use hashbrown::HashMap;
1217
    ///
1218
    /// let mut letters = HashMap::new();
1219
    ///
1220
    /// for ch in "a short treatise on fungi".chars() {
1221
    ///     let counter = letters.entry(ch).or_insert(0);
1222
    ///     *counter += 1;
1223
    /// }
1224
    ///
1225
    /// assert_eq!(letters[&'s'], 2);
1226
    /// assert_eq!(letters[&'t'], 3);
1227
    /// assert_eq!(letters[&'u'], 1);
1228
    /// assert_eq!(letters.get(&'y'), None);
1229
    /// ```
1230
    #[cfg_attr(feature = "inline-more", inline)]
1231
0
    pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S, A> {
1232
0
        let hash = make_hash::<K, S>(&self.hash_builder, &key);
1233
0
        if let Some(elem) = self.table.find(hash, equivalent_key(&key)) {
1234
0
            Entry::Occupied(OccupiedEntry {
1235
0
                hash,
1236
0
                key: Some(key),
1237
0
                elem,
1238
0
                table: self,
1239
0
            })
1240
        } else {
1241
0
            Entry::Vacant(VacantEntry {
1242
0
                hash,
1243
0
                key,
1244
0
                table: self,
1245
0
            })
1246
        }
1247
0
    }
1248
1249
    /// Gets the given key's corresponding entry by reference in the map for in-place manipulation.
1250
    ///
1251
    /// # Examples
1252
    ///
1253
    /// ```
1254
    /// use hashbrown::HashMap;
1255
    ///
1256
    /// let mut words: HashMap<String, usize> = HashMap::new();
1257
    /// let source = ["poneyland", "horseyland", "poneyland", "poneyland"];
1258
    /// for (i, &s) in source.iter().enumerate() {
1259
    ///     let counter = words.entry_ref(s).or_insert(0);
1260
    ///     *counter += 1;
1261
    /// }
1262
    ///
1263
    /// assert_eq!(words["poneyland"], 3);
1264
    /// assert_eq!(words["horseyland"], 1);
1265
    /// ```
1266
    #[cfg_attr(feature = "inline-more", inline)]
1267
0
    pub fn entry_ref<'a, 'b, Q: ?Sized>(&'a mut self, key: &'b Q) -> EntryRef<'a, 'b, K, Q, V, S, A>
1268
0
    where
1269
0
        Q: Hash + Equivalent<K>,
1270
0
    {
1271
0
        let hash = make_hash::<Q, S>(&self.hash_builder, key);
1272
0
        if let Some(elem) = self.table.find(hash, equivalent_key(key)) {
1273
0
            EntryRef::Occupied(OccupiedEntryRef {
1274
0
                hash,
1275
0
                key: Some(KeyOrRef::Borrowed(key)),
1276
0
                elem,
1277
0
                table: self,
1278
0
            })
1279
        } else {
1280
0
            EntryRef::Vacant(VacantEntryRef {
1281
0
                hash,
1282
0
                key: KeyOrRef::Borrowed(key),
1283
0
                table: self,
1284
0
            })
1285
        }
1286
0
    }
1287
1288
    /// Returns a reference to the value corresponding to the key.
1289
    ///
1290
    /// The key may be any borrowed form of the map's key type, but
1291
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1292
    /// the key type.
1293
    ///
1294
    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1295
    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1296
    ///
1297
    /// # Examples
1298
    ///
1299
    /// ```
1300
    /// use hashbrown::HashMap;
1301
    ///
1302
    /// let mut map = HashMap::new();
1303
    /// map.insert(1, "a");
1304
    /// assert_eq!(map.get(&1), Some(&"a"));
1305
    /// assert_eq!(map.get(&2), None);
1306
    /// ```
1307
    #[inline]
1308
0
    pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
1309
0
    where
1310
0
        Q: Hash + Equivalent<K>,
1311
0
    {
1312
0
        // Avoid `Option::map` because it bloats LLVM IR.
1313
0
        match self.get_inner(k) {
1314
0
            Some((_, v)) => Some(v),
1315
0
            None => None,
1316
        }
1317
0
    }
1318
1319
    /// Returns the key-value pair corresponding to the supplied key.
1320
    ///
1321
    /// The supplied key may be any borrowed form of the map's key type, but
1322
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1323
    /// the key type.
1324
    ///
1325
    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1326
    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1327
    ///
1328
    /// # Examples
1329
    ///
1330
    /// ```
1331
    /// use hashbrown::HashMap;
1332
    ///
1333
    /// let mut map = HashMap::new();
1334
    /// map.insert(1, "a");
1335
    /// assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
1336
    /// assert_eq!(map.get_key_value(&2), None);
1337
    /// ```
1338
    #[inline]
1339
0
    pub fn get_key_value<Q: ?Sized>(&self, k: &Q) -> Option<(&K, &V)>
1340
0
    where
1341
0
        Q: Hash + Equivalent<K>,
1342
0
    {
1343
0
        // Avoid `Option::map` because it bloats LLVM IR.
1344
0
        match self.get_inner(k) {
1345
0
            Some((key, value)) => Some((key, value)),
1346
0
            None => None,
1347
        }
1348
0
    }
1349
1350
    #[inline]
1351
0
    fn get_inner<Q: ?Sized>(&self, k: &Q) -> Option<&(K, V)>
1352
0
    where
1353
0
        Q: Hash + Equivalent<K>,
1354
0
    {
1355
0
        if self.table.is_empty() {
1356
0
            None
1357
        } else {
1358
0
            let hash = make_hash::<Q, S>(&self.hash_builder, k);
1359
0
            self.table.get(hash, equivalent_key(k))
1360
        }
1361
0
    }
1362
1363
    /// Returns the key-value pair corresponding to the supplied key, with a mutable reference to value.
1364
    ///
1365
    /// The supplied key may be any borrowed form of the map's key type, but
1366
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1367
    /// the key type.
1368
    ///
1369
    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1370
    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1371
    ///
1372
    /// # Examples
1373
    ///
1374
    /// ```
1375
    /// use hashbrown::HashMap;
1376
    ///
1377
    /// let mut map = HashMap::new();
1378
    /// map.insert(1, "a");
1379
    /// let (k, v) = map.get_key_value_mut(&1).unwrap();
1380
    /// assert_eq!(k, &1);
1381
    /// assert_eq!(v, &mut "a");
1382
    /// *v = "b";
1383
    /// assert_eq!(map.get_key_value_mut(&1), Some((&1, &mut "b")));
1384
    /// assert_eq!(map.get_key_value_mut(&2), None);
1385
    /// ```
1386
    #[inline]
1387
0
    pub fn get_key_value_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<(&K, &mut V)>
1388
0
    where
1389
0
        Q: Hash + Equivalent<K>,
1390
0
    {
1391
0
        // Avoid `Option::map` because it bloats LLVM IR.
1392
0
        match self.get_inner_mut(k) {
1393
0
            Some(&mut (ref key, ref mut value)) => Some((key, value)),
1394
0
            None => None,
1395
        }
1396
0
    }
1397
1398
    /// Returns `true` if the map contains a value for the specified key.
1399
    ///
1400
    /// The key may be any borrowed form of the map's key type, but
1401
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1402
    /// the key type.
1403
    ///
1404
    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1405
    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1406
    ///
1407
    /// # Examples
1408
    ///
1409
    /// ```
1410
    /// use hashbrown::HashMap;
1411
    ///
1412
    /// let mut map = HashMap::new();
1413
    /// map.insert(1, "a");
1414
    /// assert_eq!(map.contains_key(&1), true);
1415
    /// assert_eq!(map.contains_key(&2), false);
1416
    /// ```
1417
    #[cfg_attr(feature = "inline-more", inline)]
1418
0
    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
1419
0
    where
1420
0
        Q: Hash + Equivalent<K>,
1421
0
    {
1422
0
        self.get_inner(k).is_some()
1423
0
    }
1424
1425
    /// Returns a mutable reference to the value corresponding to the key.
1426
    ///
1427
    /// The key may be any borrowed form of the map's key type, but
1428
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1429
    /// the key type.
1430
    ///
1431
    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1432
    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1433
    ///
1434
    /// # Examples
1435
    ///
1436
    /// ```
1437
    /// use hashbrown::HashMap;
1438
    ///
1439
    /// let mut map = HashMap::new();
1440
    /// map.insert(1, "a");
1441
    /// if let Some(x) = map.get_mut(&1) {
1442
    ///     *x = "b";
1443
    /// }
1444
    /// assert_eq!(map[&1], "b");
1445
    ///
1446
    /// assert_eq!(map.get_mut(&2), None);
1447
    /// ```
1448
    #[cfg_attr(feature = "inline-more", inline)]
1449
0
    pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
1450
0
    where
1451
0
        Q: Hash + Equivalent<K>,
1452
0
    {
1453
0
        // Avoid `Option::map` because it bloats LLVM IR.
1454
0
        match self.get_inner_mut(k) {
1455
0
            Some(&mut (_, ref mut v)) => Some(v),
1456
0
            None => None,
1457
        }
1458
0
    }
Unexecuted instantiation: _RINvMs3_NtCsgkA6tlBCRmB_9hashbrown3mapINtB6_7HashMapINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBR_8LruEntryB1g_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEE7get_mutBO_EB2v_
Unexecuted instantiation: _RINvMs3_NtCsgkA6tlBCRmB_9hashbrown3mapINtB6_7HashMapppppE7get_mutpEB8_
1459
1460
    #[inline]
1461
0
    fn get_inner_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut (K, V)>
1462
0
    where
1463
0
        Q: Hash + Equivalent<K>,
1464
0
    {
1465
0
        if self.table.is_empty() {
1466
0
            None
1467
        } else {
1468
0
            let hash = make_hash::<Q, S>(&self.hash_builder, k);
1469
0
            self.table.get_mut(hash, equivalent_key(k))
1470
        }
1471
0
    }
Unexecuted instantiation: _RINvMs3_NtCsgkA6tlBCRmB_9hashbrown3mapINtB6_7HashMapINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBR_8LruEntryB1g_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEE13get_inner_mutBO_EB2v_
Unexecuted instantiation: _RINvMs3_NtCsgkA6tlBCRmB_9hashbrown3mapINtB6_7HashMapppppE13get_inner_mutpEB8_
1472
1473
    /// Attempts to get mutable references to `N` values in the map at once.
1474
    ///
1475
    /// Returns an array of length `N` with the results of each query. For soundness, at most one
1476
    /// mutable reference will be returned to any value. `None` will be returned if any of the
1477
    /// keys are duplicates or missing.
1478
    ///
1479
    /// # Examples
1480
    ///
1481
    /// ```
1482
    /// use hashbrown::HashMap;
1483
    ///
1484
    /// let mut libraries = HashMap::new();
1485
    /// libraries.insert("Bodleian Library".to_string(), 1602);
1486
    /// libraries.insert("Athenæum".to_string(), 1807);
1487
    /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
1488
    /// libraries.insert("Library of Congress".to_string(), 1800);
1489
    ///
1490
    /// let got = libraries.get_many_mut([
1491
    ///     "Athenæum",
1492
    ///     "Library of Congress",
1493
    /// ]);
1494
    /// assert_eq!(
1495
    ///     got,
1496
    ///     Some([
1497
    ///         &mut 1807,
1498
    ///         &mut 1800,
1499
    ///     ]),
1500
    /// );
1501
    ///
1502
    /// // Missing keys result in None
1503
    /// let got = libraries.get_many_mut([
1504
    ///     "Athenæum",
1505
    ///     "New York Public Library",
1506
    /// ]);
1507
    /// assert_eq!(got, None);
1508
    ///
1509
    /// // Duplicate keys result in None
1510
    /// let got = libraries.get_many_mut([
1511
    ///     "Athenæum",
1512
    ///     "Athenæum",
1513
    /// ]);
1514
    /// assert_eq!(got, None);
1515
    /// ```
1516
0
    pub fn get_many_mut<Q: ?Sized, const N: usize>(&mut self, ks: [&Q; N]) -> Option<[&'_ mut V; N]>
1517
0
    where
1518
0
        Q: Hash + Equivalent<K>,
1519
0
    {
1520
0
        self.get_many_mut_inner(ks).map(|res| res.map(|(_, v)| v))
1521
0
    }
1522
1523
    /// Attempts to get mutable references to `N` values in the map at once, without validating that
1524
    /// the values are unique.
1525
    ///
1526
    /// Returns an array of length `N` with the results of each query. `None` will be returned if
1527
    /// any of the keys are missing.
1528
    ///
1529
    /// For a safe alternative see [`get_many_mut`](`HashMap::get_many_mut`).
1530
    ///
1531
    /// # Safety
1532
    ///
1533
    /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1534
    /// references are not used.
1535
    ///
1536
    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1537
    ///
1538
    /// # Examples
1539
    ///
1540
    /// ```
1541
    /// use hashbrown::HashMap;
1542
    ///
1543
    /// let mut libraries = HashMap::new();
1544
    /// libraries.insert("Bodleian Library".to_string(), 1602);
1545
    /// libraries.insert("Athenæum".to_string(), 1807);
1546
    /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
1547
    /// libraries.insert("Library of Congress".to_string(), 1800);
1548
    ///
1549
    /// let got = libraries.get_many_mut([
1550
    ///     "Athenæum",
1551
    ///     "Library of Congress",
1552
    /// ]);
1553
    /// assert_eq!(
1554
    ///     got,
1555
    ///     Some([
1556
    ///         &mut 1807,
1557
    ///         &mut 1800,
1558
    ///     ]),
1559
    /// );
1560
    ///
1561
    /// // Missing keys result in None
1562
    /// let got = libraries.get_many_mut([
1563
    ///     "Athenæum",
1564
    ///     "New York Public Library",
1565
    /// ]);
1566
    /// assert_eq!(got, None);
1567
    /// ```
1568
0
    pub unsafe fn get_many_unchecked_mut<Q: ?Sized, const N: usize>(
1569
0
        &mut self,
1570
0
        ks: [&Q; N],
1571
0
    ) -> Option<[&'_ mut V; N]>
1572
0
    where
1573
0
        Q: Hash + Equivalent<K>,
1574
0
    {
1575
0
        self.get_many_unchecked_mut_inner(ks)
1576
0
            .map(|res| res.map(|(_, v)| v))
1577
0
    }
1578
1579
    /// Attempts to get mutable references to `N` values in the map at once, with immutable
1580
    /// references to the corresponding keys.
1581
    ///
1582
    /// Returns an array of length `N` with the results of each query. For soundness, at most one
1583
    /// mutable reference will be returned to any value. `None` will be returned if any of the keys
1584
    /// are duplicates or missing.
1585
    ///
1586
    /// # Examples
1587
    ///
1588
    /// ```
1589
    /// use hashbrown::HashMap;
1590
    ///
1591
    /// let mut libraries = HashMap::new();
1592
    /// libraries.insert("Bodleian Library".to_string(), 1602);
1593
    /// libraries.insert("Athenæum".to_string(), 1807);
1594
    /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
1595
    /// libraries.insert("Library of Congress".to_string(), 1800);
1596
    ///
1597
    /// let got = libraries.get_many_key_value_mut([
1598
    ///     "Bodleian Library",
1599
    ///     "Herzogin-Anna-Amalia-Bibliothek",
1600
    /// ]);
1601
    /// assert_eq!(
1602
    ///     got,
1603
    ///     Some([
1604
    ///         (&"Bodleian Library".to_string(), &mut 1602),
1605
    ///         (&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691),
1606
    ///     ]),
1607
    /// );
1608
    /// // Missing keys result in None
1609
    /// let got = libraries.get_many_key_value_mut([
1610
    ///     "Bodleian Library",
1611
    ///     "Gewandhaus",
1612
    /// ]);
1613
    /// assert_eq!(got, None);
1614
    ///
1615
    /// // Duplicate keys result in None
1616
    /// let got = libraries.get_many_key_value_mut([
1617
    ///     "Bodleian Library",
1618
    ///     "Herzogin-Anna-Amalia-Bibliothek",
1619
    ///     "Herzogin-Anna-Amalia-Bibliothek",
1620
    /// ]);
1621
    /// assert_eq!(got, None);
1622
    /// ```
1623
0
    pub fn get_many_key_value_mut<Q: ?Sized, const N: usize>(
1624
0
        &mut self,
1625
0
        ks: [&Q; N],
1626
0
    ) -> Option<[(&'_ K, &'_ mut V); N]>
1627
0
    where
1628
0
        Q: Hash + Equivalent<K>,
1629
0
    {
1630
0
        self.get_many_mut_inner(ks)
1631
0
            .map(|res| res.map(|(k, v)| (&*k, v)))
1632
0
    }
1633
1634
    /// Attempts to get mutable references to `N` values in the map at once, with immutable
1635
    /// references to the corresponding keys, without validating that the values are unique.
1636
    ///
1637
    /// Returns an array of length `N` with the results of each query. `None` will be returned if
1638
    /// any of the keys are missing.
1639
    ///
1640
    /// For a safe alternative see [`get_many_key_value_mut`](`HashMap::get_many_key_value_mut`).
1641
    ///
1642
    /// # Safety
1643
    ///
1644
    /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1645
    /// references are not used.
1646
    ///
1647
    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1648
    ///
1649
    /// # Examples
1650
    ///
1651
    /// ```
1652
    /// use hashbrown::HashMap;
1653
    ///
1654
    /// let mut libraries = HashMap::new();
1655
    /// libraries.insert("Bodleian Library".to_string(), 1602);
1656
    /// libraries.insert("Athenæum".to_string(), 1807);
1657
    /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
1658
    /// libraries.insert("Library of Congress".to_string(), 1800);
1659
    ///
1660
    /// let got = libraries.get_many_key_value_mut([
1661
    ///     "Bodleian Library",
1662
    ///     "Herzogin-Anna-Amalia-Bibliothek",
1663
    /// ]);
1664
    /// assert_eq!(
1665
    ///     got,
1666
    ///     Some([
1667
    ///         (&"Bodleian Library".to_string(), &mut 1602),
1668
    ///         (&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691),
1669
    ///     ]),
1670
    /// );
1671
    /// // Missing keys result in None
1672
    /// let got = libraries.get_many_key_value_mut([
1673
    ///     "Bodleian Library",
1674
    ///     "Gewandhaus",
1675
    /// ]);
1676
    /// assert_eq!(got, None);
1677
    /// ```
1678
0
    pub unsafe fn get_many_key_value_unchecked_mut<Q: ?Sized, const N: usize>(
1679
0
        &mut self,
1680
0
        ks: [&Q; N],
1681
0
    ) -> Option<[(&'_ K, &'_ mut V); N]>
1682
0
    where
1683
0
        Q: Hash + Equivalent<K>,
1684
0
    {
1685
0
        self.get_many_unchecked_mut_inner(ks)
1686
0
            .map(|res| res.map(|(k, v)| (&*k, v)))
1687
0
    }
1688
1689
0
    fn get_many_mut_inner<Q: ?Sized, const N: usize>(
1690
0
        &mut self,
1691
0
        ks: [&Q; N],
1692
0
    ) -> Option<[&'_ mut (K, V); N]>
1693
0
    where
1694
0
        Q: Hash + Equivalent<K>,
1695
0
    {
1696
0
        let hashes = self.build_hashes_inner(ks);
1697
0
        self.table
1698
0
            .get_many_mut(hashes, |i, (k, _)| ks[i].equivalent(k))
1699
0
    }
1700
1701
0
    unsafe fn get_many_unchecked_mut_inner<Q: ?Sized, const N: usize>(
1702
0
        &mut self,
1703
0
        ks: [&Q; N],
1704
0
    ) -> Option<[&'_ mut (K, V); N]>
1705
0
    where
1706
0
        Q: Hash + Equivalent<K>,
1707
0
    {
1708
0
        let hashes = self.build_hashes_inner(ks);
1709
0
        self.table
1710
0
            .get_many_unchecked_mut(hashes, |i, (k, _)| ks[i].equivalent(k))
1711
0
    }
1712
1713
0
    fn build_hashes_inner<Q: ?Sized, const N: usize>(&self, ks: [&Q; N]) -> [u64; N]
1714
0
    where
1715
0
        Q: Hash + Equivalent<K>,
1716
0
    {
1717
0
        let mut hashes = [0_u64; N];
1718
0
        for i in 0..N {
1719
0
            hashes[i] = make_hash::<Q, S>(&self.hash_builder, ks[i]);
1720
0
        }
1721
0
        hashes
1722
0
    }
1723
1724
    /// Inserts a key-value pair into the map.
1725
    ///
1726
    /// If the map did not have this key present, [`None`] is returned.
1727
    ///
1728
    /// If the map did have this key present, the value is updated, and the old
1729
    /// value is returned. The key is not updated, though; this matters for
1730
    /// types that can be `==` without being identical. See the [`std::collections`]
1731
    /// [module-level documentation] for more.
1732
    ///
1733
    /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
1734
    /// [`std::collections`]: https://doc.rust-lang.org/std/collections/index.html
1735
    /// [module-level documentation]: https://doc.rust-lang.org/std/collections/index.html#insert-and-complex-keys
1736
    ///
1737
    /// # Examples
1738
    ///
1739
    /// ```
1740
    /// use hashbrown::HashMap;
1741
    ///
1742
    /// let mut map = HashMap::new();
1743
    /// assert_eq!(map.insert(37, "a"), None);
1744
    /// assert_eq!(map.is_empty(), false);
1745
    ///
1746
    /// map.insert(37, "b");
1747
    /// assert_eq!(map.insert(37, "c"), Some("b"));
1748
    /// assert_eq!(map[&37], "c");
1749
    /// ```
1750
    #[cfg_attr(feature = "inline-more", inline)]
1751
0
    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
1752
0
        let hash = make_hash::<K, S>(&self.hash_builder, &k);
1753
0
        let hasher = make_hasher::<_, V, S>(&self.hash_builder);
1754
0
        match self
1755
0
            .table
1756
0
            .find_or_find_insert_slot(hash, equivalent_key(&k), hasher)
1757
        {
1758
0
            Ok(bucket) => Some(mem::replace(unsafe { &mut bucket.as_mut().1 }, v)),
1759
0
            Err(slot) => {
1760
0
                unsafe {
1761
0
                    self.table.insert_in_slot(hash, slot, (k, v));
1762
0
                }
1763
0
                None
1764
            }
1765
        }
1766
0
    }
Unexecuted instantiation: _RNvMs3_NtCsgkA6tlBCRmB_9hashbrown3mapINtB5_7HashMapINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEE6insertB2u_
Unexecuted instantiation: _RNvMs3_NtCsgkA6tlBCRmB_9hashbrown3mapINtB5_7HashMapppppE6insertB7_
1767
1768
    /// Insert a key-value pair into the map without checking
1769
    /// if the key already exists in the map.
1770
    ///
1771
    /// Returns a reference to the key and value just inserted.
1772
    ///
1773
    /// This operation is safe if a key does not exist in the map.
1774
    ///
1775
    /// However, if a key exists in the map already, the behavior is unspecified:
1776
    /// this operation may panic, loop forever, or any following operation with the map
1777
    /// may panic, loop forever or return arbitrary result.
1778
    ///
1779
    /// That said, this operation (and following operations) are guaranteed to
1780
    /// not violate memory safety.
1781
    ///
1782
    /// This operation is faster than regular insert, because it does not perform
1783
    /// lookup before insertion.
1784
    ///
1785
    /// This operation is useful during initial population of the map.
1786
    /// For example, when constructing a map from another map, we know
1787
    /// that keys are unique.
1788
    ///
1789
    /// # Examples
1790
    ///
1791
    /// ```
1792
    /// use hashbrown::HashMap;
1793
    ///
1794
    /// let mut map1 = HashMap::new();
1795
    /// assert_eq!(map1.insert(1, "a"), None);
1796
    /// assert_eq!(map1.insert(2, "b"), None);
1797
    /// assert_eq!(map1.insert(3, "c"), None);
1798
    /// assert_eq!(map1.len(), 3);
1799
    ///
1800
    /// let mut map2 = HashMap::new();
1801
    ///
1802
    /// for (key, value) in map1.into_iter() {
1803
    ///     map2.insert_unique_unchecked(key, value);
1804
    /// }
1805
    ///
1806
    /// let (key, value) = map2.insert_unique_unchecked(4, "d");
1807
    /// assert_eq!(key, &4);
1808
    /// assert_eq!(value, &mut "d");
1809
    /// *value = "e";
1810
    ///
1811
    /// assert_eq!(map2[&1], "a");
1812
    /// assert_eq!(map2[&2], "b");
1813
    /// assert_eq!(map2[&3], "c");
1814
    /// assert_eq!(map2[&4], "e");
1815
    /// assert_eq!(map2.len(), 4);
1816
    /// ```
1817
    #[cfg_attr(feature = "inline-more", inline)]
1818
0
    pub fn insert_unique_unchecked(&mut self, k: K, v: V) -> (&K, &mut V) {
1819
0
        let hash = make_hash::<K, S>(&self.hash_builder, &k);
1820
0
        let bucket = self
1821
0
            .table
1822
0
            .insert(hash, (k, v), make_hasher::<_, V, S>(&self.hash_builder));
1823
0
        let (k_ref, v_ref) = unsafe { bucket.as_mut() };
1824
0
        (k_ref, v_ref)
1825
0
    }
1826
1827
    /// Tries to insert a key-value pair into the map, and returns
1828
    /// a mutable reference to the value in the entry.
1829
    ///
1830
    /// # Errors
1831
    ///
1832
    /// If the map already had this key present, nothing is updated, and
1833
    /// an error containing the occupied entry and the value is returned.
1834
    ///
1835
    /// # Examples
1836
    ///
1837
    /// Basic usage:
1838
    ///
1839
    /// ```
1840
    /// use hashbrown::HashMap;
1841
    /// use hashbrown::hash_map::OccupiedError;
1842
    ///
1843
    /// let mut map = HashMap::new();
1844
    /// assert_eq!(map.try_insert(37, "a").unwrap(), &"a");
1845
    ///
1846
    /// match map.try_insert(37, "b") {
1847
    ///     Err(OccupiedError { entry, value }) => {
1848
    ///         assert_eq!(entry.key(), &37);
1849
    ///         assert_eq!(entry.get(), &"a");
1850
    ///         assert_eq!(value, "b");
1851
    ///     }
1852
    ///     _ => panic!()
1853
    /// }
1854
    /// ```
1855
    #[cfg_attr(feature = "inline-more", inline)]
1856
0
    pub fn try_insert(
1857
0
        &mut self,
1858
0
        key: K,
1859
0
        value: V,
1860
0
    ) -> Result<&mut V, OccupiedError<'_, K, V, S, A>> {
1861
0
        match self.entry(key) {
1862
0
            Entry::Occupied(entry) => Err(OccupiedError { entry, value }),
1863
0
            Entry::Vacant(entry) => Ok(entry.insert(value)),
1864
        }
1865
0
    }
1866
1867
    /// Removes a key from the map, returning the value at the key if the key
1868
    /// was previously in the map. Keeps the allocated memory for reuse.
1869
    ///
1870
    /// The key may be any borrowed form of the map's key type, but
1871
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1872
    /// the key type.
1873
    ///
1874
    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1875
    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1876
    ///
1877
    /// # Examples
1878
    ///
1879
    /// ```
1880
    /// use hashbrown::HashMap;
1881
    ///
1882
    /// let mut map = HashMap::new();
1883
    /// // The map is empty
1884
    /// assert!(map.is_empty() && map.capacity() == 0);
1885
    ///
1886
    /// map.insert(1, "a");
1887
    ///
1888
    /// assert_eq!(map.remove(&1), Some("a"));
1889
    /// assert_eq!(map.remove(&1), None);
1890
    ///
1891
    /// // Now map holds none elements
1892
    /// assert!(map.is_empty());
1893
    /// ```
1894
    #[cfg_attr(feature = "inline-more", inline)]
1895
0
    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
1896
0
    where
1897
0
        Q: Hash + Equivalent<K>,
1898
0
    {
1899
0
        // Avoid `Option::map` because it bloats LLVM IR.
1900
0
        match self.remove_entry(k) {
1901
0
            Some((_, v)) => Some(v),
1902
0
            None => None,
1903
        }
1904
0
    }
Unexecuted instantiation: _RINvMs3_NtCsgkA6tlBCRmB_9hashbrown3mapINtB6_7HashMapINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBR_8LruEntryB1g_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEE6removeBO_EB2v_
Unexecuted instantiation: _RINvMs3_NtCsgkA6tlBCRmB_9hashbrown3mapINtB6_7HashMapppppE6removepEB8_
1905
1906
    /// Removes a key from the map, returning the stored key and value if the
1907
    /// key was previously in the map. Keeps the allocated memory for reuse.
1908
    ///
1909
    /// The key may be any borrowed form of the map's key type, but
1910
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1911
    /// the key type.
1912
    ///
1913
    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1914
    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1915
    ///
1916
    /// # Examples
1917
    ///
1918
    /// ```
1919
    /// use hashbrown::HashMap;
1920
    ///
1921
    /// let mut map = HashMap::new();
1922
    /// // The map is empty
1923
    /// assert!(map.is_empty() && map.capacity() == 0);
1924
    ///
1925
    /// map.insert(1, "a");
1926
    ///
1927
    /// assert_eq!(map.remove_entry(&1), Some((1, "a")));
1928
    /// assert_eq!(map.remove(&1), None);
1929
    ///
1930
    /// // Now map hold none elements
1931
    /// assert!(map.is_empty());
1932
    /// ```
1933
    #[cfg_attr(feature = "inline-more", inline)]
1934
0
    pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)>
1935
0
    where
1936
0
        Q: Hash + Equivalent<K>,
1937
0
    {
1938
0
        let hash = make_hash::<Q, S>(&self.hash_builder, k);
1939
0
        self.table.remove_entry(hash, equivalent_key(k))
1940
0
    }
Unexecuted instantiation: _RINvMs3_NtCsgkA6tlBCRmB_9hashbrown3mapINtB6_7HashMapINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBR_8LruEntryB1g_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEE12remove_entryBO_EB2v_
Unexecuted instantiation: _RINvMs3_NtCsgkA6tlBCRmB_9hashbrown3mapINtB6_7HashMapppppE12remove_entrypEB8_
1941
}
1942
1943
impl<K, V, S, A: Allocator> HashMap<K, V, S, A> {
1944
    /// Creates a raw entry builder for the HashMap.
1945
    ///
1946
    /// Raw entries provide the lowest level of control for searching and
1947
    /// manipulating a map. They must be manually initialized with a hash and
1948
    /// then manually searched. After this, insertions into a vacant entry
1949
    /// still require an owned key to be provided.
1950
    ///
1951
    /// Raw entries are useful for such exotic situations as:
1952
    ///
1953
    /// * Hash memoization
1954
    /// * Deferring the creation of an owned key until it is known to be required
1955
    /// * Using a search key that doesn't work with the Borrow trait
1956
    /// * Using custom comparison logic without newtype wrappers
1957
    ///
1958
    /// Because raw entries provide much more low-level control, it's much easier
1959
    /// to put the HashMap into an inconsistent state which, while memory-safe,
1960
    /// will cause the map to produce seemingly random results. Higher-level and
1961
    /// more foolproof APIs like `entry` should be preferred when possible.
1962
    ///
1963
    /// In particular, the hash used to initialized the raw entry must still be
1964
    /// consistent with the hash of the key that is ultimately stored in the entry.
1965
    /// This is because implementations of HashMap may need to recompute hashes
1966
    /// when resizing, at which point only the keys are available.
1967
    ///
1968
    /// Raw entries give mutable access to the keys. This must not be used
1969
    /// to modify how the key would compare or hash, as the map will not re-evaluate
1970
    /// where the key should go, meaning the keys may become "lost" if their
1971
    /// location does not reflect their state. For instance, if you change a key
1972
    /// so that the map now contains keys which compare equal, search may start
1973
    /// acting erratically, with two keys randomly masking each other. Implementations
1974
    /// are free to assume this doesn't happen (within the limits of memory-safety).
1975
    ///
1976
    /// # Examples
1977
    ///
1978
    /// ```
1979
    /// use core::hash::{BuildHasher, Hash};
1980
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
1981
    ///
1982
    /// let mut map = HashMap::new();
1983
    /// map.extend([("a", 100), ("b", 200), ("c", 300)]);
1984
    ///
1985
    /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
1986
    ///     use core::hash::Hasher;
1987
    ///     let mut state = hash_builder.build_hasher();
1988
    ///     key.hash(&mut state);
1989
    ///     state.finish()
1990
    /// }
1991
    ///
1992
    /// // Existing key (insert and update)
1993
    /// match map.raw_entry_mut().from_key(&"a") {
1994
    ///     RawEntryMut::Vacant(_) => unreachable!(),
1995
    ///     RawEntryMut::Occupied(mut view) => {
1996
    ///         assert_eq!(view.get(), &100);
1997
    ///         let v = view.get_mut();
1998
    ///         let new_v = (*v) * 10;
1999
    ///         *v = new_v;
2000
    ///         assert_eq!(view.insert(1111), 1000);
2001
    ///     }
2002
    /// }
2003
    ///
2004
    /// assert_eq!(map[&"a"], 1111);
2005
    /// assert_eq!(map.len(), 3);
2006
    ///
2007
    /// // Existing key (take)
2008
    /// let hash = compute_hash(map.hasher(), &"c");
2009
    /// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"c") {
2010
    ///     RawEntryMut::Vacant(_) => unreachable!(),
2011
    ///     RawEntryMut::Occupied(view) => {
2012
    ///         assert_eq!(view.remove_entry(), ("c", 300));
2013
    ///     }
2014
    /// }
2015
    /// assert_eq!(map.raw_entry().from_key(&"c"), None);
2016
    /// assert_eq!(map.len(), 2);
2017
    ///
2018
    /// // Nonexistent key (insert and update)
2019
    /// let key = "d";
2020
    /// let hash = compute_hash(map.hasher(), &key);
2021
    /// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
2022
    ///     RawEntryMut::Occupied(_) => unreachable!(),
2023
    ///     RawEntryMut::Vacant(view) => {
2024
    ///         let (k, value) = view.insert("d", 4000);
2025
    ///         assert_eq!((*k, *value), ("d", 4000));
2026
    ///         *value = 40000;
2027
    ///     }
2028
    /// }
2029
    /// assert_eq!(map[&"d"], 40000);
2030
    /// assert_eq!(map.len(), 3);
2031
    ///
2032
    /// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
2033
    ///     RawEntryMut::Vacant(_) => unreachable!(),
2034
    ///     RawEntryMut::Occupied(view) => {
2035
    ///         assert_eq!(view.remove_entry(), ("d", 40000));
2036
    ///     }
2037
    /// }
2038
    /// assert_eq!(map.get(&"d"), None);
2039
    /// assert_eq!(map.len(), 2);
2040
    /// ```
2041
    #[cfg_attr(feature = "inline-more", inline)]
2042
0
    pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S, A> {
2043
0
        RawEntryBuilderMut { map: self }
2044
0
    }
2045
2046
    /// Creates a raw immutable entry builder for the HashMap.
2047
    ///
2048
    /// Raw entries provide the lowest level of control for searching and
2049
    /// manipulating a map. They must be manually initialized with a hash and
2050
    /// then manually searched.
2051
    ///
2052
    /// This is useful for
2053
    /// * Hash memoization
2054
    /// * Using a search key that doesn't work with the Borrow trait
2055
    /// * Using custom comparison logic without newtype wrappers
2056
    ///
2057
    /// Unless you are in such a situation, higher-level and more foolproof APIs like
2058
    /// `get` should be preferred.
2059
    ///
2060
    /// Immutable raw entries have very limited use; you might instead want `raw_entry_mut`.
2061
    ///
2062
    /// # Examples
2063
    ///
2064
    /// ```
2065
    /// use core::hash::{BuildHasher, Hash};
2066
    /// use hashbrown::HashMap;
2067
    ///
2068
    /// let mut map = HashMap::new();
2069
    /// map.extend([("a", 100), ("b", 200), ("c", 300)]);
2070
    ///
2071
    /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
2072
    ///     use core::hash::Hasher;
2073
    ///     let mut state = hash_builder.build_hasher();
2074
    ///     key.hash(&mut state);
2075
    ///     state.finish()
2076
    /// }
2077
    ///
2078
    /// for k in ["a", "b", "c", "d", "e", "f"] {
2079
    ///     let hash = compute_hash(map.hasher(), k);
2080
    ///     let v = map.get(&k).cloned();
2081
    ///     let kv = v.as_ref().map(|v| (&k, v));
2082
    ///
2083
    ///     println!("Key: {} and value: {:?}", k, v);
2084
    ///
2085
    ///     assert_eq!(map.raw_entry().from_key(&k), kv);
2086
    ///     assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
2087
    ///     assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
2088
    /// }
2089
    /// ```
2090
    #[cfg_attr(feature = "inline-more", inline)]
2091
0
    pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S, A> {
2092
0
        RawEntryBuilder { map: self }
2093
0
    }
2094
2095
    /// Returns a reference to the [`RawTable`] used underneath [`HashMap`].
2096
    /// This function is only available if the `raw` feature of the crate is enabled.
2097
    ///
2098
    /// See [`raw_table_mut`] for more.
2099
    ///
2100
    /// [`raw_table_mut`]: Self::raw_table_mut
2101
    #[cfg(feature = "raw")]
2102
    #[cfg_attr(feature = "inline-more", inline)]
2103
    pub fn raw_table(&self) -> &RawTable<(K, V), A> {
2104
        &self.table
2105
    }
2106
2107
    /// Returns a mutable reference to the [`RawTable`] used underneath [`HashMap`].
2108
    /// This function is only available if the `raw` feature of the crate is enabled.
2109
    ///
2110
    /// # Note
2111
    ///
2112
    /// Calling this function is safe, but using the raw hash table API may require
2113
    /// unsafe functions or blocks.
2114
    ///
2115
    /// `RawTable` API gives the lowest level of control under the map that can be useful
2116
    /// for extending the HashMap's API, but may lead to *[undefined behavior]*.
2117
    ///
2118
    /// [`HashMap`]: struct.HashMap.html
2119
    /// [`RawTable`]: crate::raw::RawTable
2120
    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2121
    ///
2122
    /// # Examples
2123
    ///
2124
    /// ```
2125
    /// use core::hash::{BuildHasher, Hash};
2126
    /// use hashbrown::HashMap;
2127
    ///
2128
    /// let mut map = HashMap::new();
2129
    /// map.extend([("a", 10), ("b", 20), ("c", 30)]);
2130
    /// assert_eq!(map.len(), 3);
2131
    ///
2132
    /// // Let's imagine that we have a value and a hash of the key, but not the key itself.
2133
    /// // However, if you want to remove the value from the map by hash and value, and you
2134
    /// // know exactly that the value is unique, then you can create a function like this:
2135
    /// fn remove_by_hash<K, V, S, F>(
2136
    ///     map: &mut HashMap<K, V, S>,
2137
    ///     hash: u64,
2138
    ///     is_match: F,
2139
    /// ) -> Option<(K, V)>
2140
    /// where
2141
    ///     F: Fn(&(K, V)) -> bool,
2142
    /// {
2143
    ///     let raw_table = map.raw_table_mut();
2144
    ///     match raw_table.find(hash, is_match) {
2145
    ///         Some(bucket) => Some(unsafe { raw_table.remove(bucket).0 }),
2146
    ///         None => None,
2147
    ///     }
2148
    /// }
2149
    ///
2150
    /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
2151
    ///     use core::hash::Hasher;
2152
    ///     let mut state = hash_builder.build_hasher();
2153
    ///     key.hash(&mut state);
2154
    ///     state.finish()
2155
    /// }
2156
    ///
2157
    /// let hash = compute_hash(map.hasher(), "a");
2158
    /// assert_eq!(remove_by_hash(&mut map, hash, |(_, v)| *v == 10), Some(("a", 10)));
2159
    /// assert_eq!(map.get(&"a"), None);
2160
    /// assert_eq!(map.len(), 2);
2161
    /// ```
2162
    #[cfg(feature = "raw")]
2163
    #[cfg_attr(feature = "inline-more", inline)]
2164
    pub fn raw_table_mut(&mut self) -> &mut RawTable<(K, V), A> {
2165
        &mut self.table
2166
    }
2167
}
2168
2169
impl<K, V, S, A> PartialEq for HashMap<K, V, S, A>
2170
where
2171
    K: Eq + Hash,
2172
    V: PartialEq,
2173
    S: BuildHasher,
2174
    A: Allocator,
2175
{
2176
0
    fn eq(&self, other: &Self) -> bool {
2177
0
        if self.len() != other.len() {
2178
0
            return false;
2179
0
        }
2180
0
2181
0
        self.iter()
2182
0
            .all(|(key, value)| other.get(key).map_or(false, |v| *value == *v))
2183
0
    }
2184
}
2185
2186
impl<K, V, S, A> Eq for HashMap<K, V, S, A>
2187
where
2188
    K: Eq + Hash,
2189
    V: Eq,
2190
    S: BuildHasher,
2191
    A: Allocator,
2192
{
2193
}
2194
2195
impl<K, V, S, A> Debug for HashMap<K, V, S, A>
2196
where
2197
    K: Debug,
2198
    V: Debug,
2199
    A: Allocator,
2200
{
2201
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2202
0
        f.debug_map().entries(self.iter()).finish()
2203
0
    }
2204
}
2205
2206
impl<K, V, S, A> Default for HashMap<K, V, S, A>
2207
where
2208
    S: Default,
2209
    A: Default + Allocator,
2210
{
2211
    /// Creates an empty `HashMap<K, V, S, A>`, with the `Default` value for the hasher and allocator.
2212
    ///
2213
    /// # Examples
2214
    ///
2215
    /// ```
2216
    /// use hashbrown::HashMap;
2217
    /// use std::collections::hash_map::RandomState;
2218
    ///
2219
    /// // You can specify all types of HashMap, including hasher and allocator.
2220
    /// // Created map is empty and don't allocate memory
2221
    /// let map: HashMap<u32, String> = Default::default();
2222
    /// assert_eq!(map.capacity(), 0);
2223
    /// let map: HashMap<u32, String, RandomState> = HashMap::default();
2224
    /// assert_eq!(map.capacity(), 0);
2225
    /// ```
2226
    #[cfg_attr(feature = "inline-more", inline)]
2227
0
    fn default() -> Self {
2228
0
        Self::with_hasher_in(Default::default(), Default::default())
2229
0
    }
2230
}
2231
2232
impl<K, Q: ?Sized, V, S, A> Index<&Q> for HashMap<K, V, S, A>
2233
where
2234
    K: Eq + Hash,
2235
    Q: Hash + Equivalent<K>,
2236
    S: BuildHasher,
2237
    A: Allocator,
2238
{
2239
    type Output = V;
2240
2241
    /// Returns a reference to the value corresponding to the supplied key.
2242
    ///
2243
    /// # Panics
2244
    ///
2245
    /// Panics if the key is not present in the `HashMap`.
2246
    ///
2247
    /// # Examples
2248
    ///
2249
    /// ```
2250
    /// use hashbrown::HashMap;
2251
    ///
2252
    /// let map: HashMap<_, _> = [("a", "One"), ("b", "Two")].into();
2253
    ///
2254
    /// assert_eq!(map[&"a"], "One");
2255
    /// assert_eq!(map[&"b"], "Two");
2256
    /// ```
2257
    #[cfg_attr(feature = "inline-more", inline)]
2258
0
    fn index(&self, key: &Q) -> &V {
2259
0
        self.get(key).expect("no entry found for key")
2260
0
    }
2261
}
2262
2263
// The default hasher is used to match the std implementation signature
2264
#[cfg(feature = "ahash")]
2265
impl<K, V, A, const N: usize> From<[(K, V); N]> for HashMap<K, V, DefaultHashBuilder, A>
2266
where
2267
    K: Eq + Hash,
2268
    A: Default + Allocator,
2269
{
2270
    /// # Examples
2271
    ///
2272
    /// ```
2273
    /// use hashbrown::HashMap;
2274
    ///
2275
    /// let map1 = HashMap::from([(1, 2), (3, 4)]);
2276
    /// let map2: HashMap<_, _> = [(1, 2), (3, 4)].into();
2277
    /// assert_eq!(map1, map2);
2278
    /// ```
2279
0
    fn from(arr: [(K, V); N]) -> Self {
2280
0
        arr.into_iter().collect()
2281
0
    }
2282
}
2283
2284
/// An iterator over the entries of a `HashMap` in arbitrary order.
2285
/// The iterator element type is `(&'a K, &'a V)`.
2286
///
2287
/// This `struct` is created by the [`iter`] method on [`HashMap`]. See its
2288
/// documentation for more.
2289
///
2290
/// [`iter`]: struct.HashMap.html#method.iter
2291
/// [`HashMap`]: struct.HashMap.html
2292
///
2293
/// # Examples
2294
///
2295
/// ```
2296
/// use hashbrown::HashMap;
2297
///
2298
/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].into();
2299
///
2300
/// let mut iter = map.iter();
2301
/// let mut vec = vec![iter.next(), iter.next(), iter.next()];
2302
///
2303
/// // The `Iter` iterator produces items in arbitrary order, so the
2304
/// // items must be sorted to test them against a sorted array.
2305
/// vec.sort_unstable();
2306
/// assert_eq!(vec, [Some((&1, &"a")), Some((&2, &"b")), Some((&3, &"c"))]);
2307
///
2308
/// // It is fused iterator
2309
/// assert_eq!(iter.next(), None);
2310
/// assert_eq!(iter.next(), None);
2311
/// ```
2312
pub struct Iter<'a, K, V> {
2313
    inner: RawIter<(K, V)>,
2314
    marker: PhantomData<(&'a K, &'a V)>,
2315
}
2316
2317
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2318
impl<K, V> Clone for Iter<'_, K, V> {
2319
    #[cfg_attr(feature = "inline-more", inline)]
2320
0
    fn clone(&self) -> Self {
2321
0
        Iter {
2322
0
            inner: self.inner.clone(),
2323
0
            marker: PhantomData,
2324
0
        }
2325
0
    }
2326
}
2327
2328
impl<K: Debug, V: Debug> fmt::Debug for Iter<'_, K, V> {
2329
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2330
0
        f.debug_list().entries(self.clone()).finish()
2331
0
    }
2332
}
2333
2334
/// A mutable iterator over the entries of a `HashMap` in arbitrary order.
2335
/// The iterator element type is `(&'a K, &'a mut V)`.
2336
///
2337
/// This `struct` is created by the [`iter_mut`] method on [`HashMap`]. See its
2338
/// documentation for more.
2339
///
2340
/// [`iter_mut`]: struct.HashMap.html#method.iter_mut
2341
/// [`HashMap`]: struct.HashMap.html
2342
///
2343
/// # Examples
2344
///
2345
/// ```
2346
/// use hashbrown::HashMap;
2347
///
2348
/// let mut map: HashMap<_, _> = [(1, "One".to_owned()), (2, "Two".into())].into();
2349
///
2350
/// let mut iter = map.iter_mut();
2351
/// iter.next().map(|(_, v)| v.push_str(" Mississippi"));
2352
/// iter.next().map(|(_, v)| v.push_str(" Mississippi"));
2353
///
2354
/// // It is fused iterator
2355
/// assert_eq!(iter.next(), None);
2356
/// assert_eq!(iter.next(), None);
2357
///
2358
/// assert_eq!(map.get(&1).unwrap(), &"One Mississippi".to_owned());
2359
/// assert_eq!(map.get(&2).unwrap(), &"Two Mississippi".to_owned());
2360
/// ```
2361
pub struct IterMut<'a, K, V> {
2362
    inner: RawIter<(K, V)>,
2363
    // To ensure invariance with respect to V
2364
    marker: PhantomData<(&'a K, &'a mut V)>,
2365
}
2366
2367
// We override the default Send impl which has K: Sync instead of K: Send. Both
2368
// are correct, but this one is more general since it allows keys which
2369
// implement Send but not Sync.
2370
unsafe impl<K: Send, V: Send> Send for IterMut<'_, K, V> {}
2371
2372
impl<K, V> IterMut<'_, K, V> {
2373
    /// Returns a iterator of references over the remaining items.
2374
    #[cfg_attr(feature = "inline-more", inline)]
2375
0
    pub(super) fn iter(&self) -> Iter<'_, K, V> {
2376
0
        Iter {
2377
0
            inner: self.inner.clone(),
2378
0
            marker: PhantomData,
2379
0
        }
2380
0
    }
2381
}
2382
2383
/// An owning iterator over the entries of a `HashMap` in arbitrary order.
2384
/// The iterator element type is `(K, V)`.
2385
///
2386
/// This `struct` is created by the [`into_iter`] method on [`HashMap`]
2387
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
2388
/// The map cannot be used after calling that method.
2389
///
2390
/// [`into_iter`]: struct.HashMap.html#method.into_iter
2391
/// [`HashMap`]: struct.HashMap.html
2392
/// [`IntoIterator`]: https://doc.rust-lang.org/core/iter/trait.IntoIterator.html
2393
///
2394
/// # Examples
2395
///
2396
/// ```
2397
/// use hashbrown::HashMap;
2398
///
2399
/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].into();
2400
///
2401
/// let mut iter = map.into_iter();
2402
/// let mut vec = vec![iter.next(), iter.next(), iter.next()];
2403
///
2404
/// // The `IntoIter` iterator produces items in arbitrary order, so the
2405
/// // items must be sorted to test them against a sorted array.
2406
/// vec.sort_unstable();
2407
/// assert_eq!(vec, [Some((1, "a")), Some((2, "b")), Some((3, "c"))]);
2408
///
2409
/// // It is fused iterator
2410
/// assert_eq!(iter.next(), None);
2411
/// assert_eq!(iter.next(), None);
2412
/// ```
2413
pub struct IntoIter<K, V, A: Allocator = Global> {
2414
    inner: RawIntoIter<(K, V), A>,
2415
}
2416
2417
impl<K, V, A: Allocator> IntoIter<K, V, A> {
2418
    /// Returns a iterator of references over the remaining items.
2419
    #[cfg_attr(feature = "inline-more", inline)]
2420
0
    pub(super) fn iter(&self) -> Iter<'_, K, V> {
2421
0
        Iter {
2422
0
            inner: self.inner.iter(),
2423
0
            marker: PhantomData,
2424
0
        }
2425
0
    }
2426
}
2427
2428
/// An owning iterator over the keys of a `HashMap` in arbitrary order.
2429
/// The iterator element type is `K`.
2430
///
2431
/// This `struct` is created by the [`into_keys`] method on [`HashMap`].
2432
/// See its documentation for more.
2433
/// The map cannot be used after calling that method.
2434
///
2435
/// [`into_keys`]: struct.HashMap.html#method.into_keys
2436
/// [`HashMap`]: struct.HashMap.html
2437
///
2438
/// # Examples
2439
///
2440
/// ```
2441
/// use hashbrown::HashMap;
2442
///
2443
/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].into();
2444
///
2445
/// let mut keys = map.into_keys();
2446
/// let mut vec = vec![keys.next(), keys.next(), keys.next()];
2447
///
2448
/// // The `IntoKeys` iterator produces keys in arbitrary order, so the
2449
/// // keys must be sorted to test them against a sorted array.
2450
/// vec.sort_unstable();
2451
/// assert_eq!(vec, [Some(1), Some(2), Some(3)]);
2452
///
2453
/// // It is fused iterator
2454
/// assert_eq!(keys.next(), None);
2455
/// assert_eq!(keys.next(), None);
2456
/// ```
2457
pub struct IntoKeys<K, V, A: Allocator = Global> {
2458
    inner: IntoIter<K, V, A>,
2459
}
2460
2461
impl<K, V, A: Allocator> Iterator for IntoKeys<K, V, A> {
2462
    type Item = K;
2463
2464
    #[inline]
2465
0
    fn next(&mut self) -> Option<K> {
2466
0
        self.inner.next().map(|(k, _)| k)
2467
0
    }
2468
    #[inline]
2469
0
    fn size_hint(&self) -> (usize, Option<usize>) {
2470
0
        self.inner.size_hint()
2471
0
    }
2472
    #[inline]
2473
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
2474
0
    where
2475
0
        Self: Sized,
2476
0
        F: FnMut(B, Self::Item) -> B,
2477
0
    {
2478
0
        self.inner.fold(init, |acc, (k, _)| f(acc, k))
2479
0
    }
2480
}
2481
2482
impl<K, V, A: Allocator> ExactSizeIterator for IntoKeys<K, V, A> {
2483
    #[inline]
2484
0
    fn len(&self) -> usize {
2485
0
        self.inner.len()
2486
0
    }
2487
}
2488
2489
impl<K, V, A: Allocator> FusedIterator for IntoKeys<K, V, A> {}
2490
2491
impl<K: Debug, V: Debug, A: Allocator> fmt::Debug for IntoKeys<K, V, A> {
2492
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2493
0
        f.debug_list()
2494
0
            .entries(self.inner.iter().map(|(k, _)| k))
2495
0
            .finish()
2496
0
    }
2497
}
2498
2499
/// An owning iterator over the values of a `HashMap` in arbitrary order.
2500
/// The iterator element type is `V`.
2501
///
2502
/// This `struct` is created by the [`into_values`] method on [`HashMap`].
2503
/// See its documentation for more. The map cannot be used after calling that method.
2504
///
2505
/// [`into_values`]: struct.HashMap.html#method.into_values
2506
/// [`HashMap`]: struct.HashMap.html
2507
///
2508
/// # Examples
2509
///
2510
/// ```
2511
/// use hashbrown::HashMap;
2512
///
2513
/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].into();
2514
///
2515
/// let mut values = map.into_values();
2516
/// let mut vec = vec![values.next(), values.next(), values.next()];
2517
///
2518
/// // The `IntoValues` iterator produces values in arbitrary order, so
2519
/// // the values must be sorted to test them against a sorted array.
2520
/// vec.sort_unstable();
2521
/// assert_eq!(vec, [Some("a"), Some("b"), Some("c")]);
2522
///
2523
/// // It is fused iterator
2524
/// assert_eq!(values.next(), None);
2525
/// assert_eq!(values.next(), None);
2526
/// ```
2527
pub struct IntoValues<K, V, A: Allocator = Global> {
2528
    inner: IntoIter<K, V, A>,
2529
}
2530
2531
impl<K, V, A: Allocator> Iterator for IntoValues<K, V, A> {
2532
    type Item = V;
2533
2534
    #[inline]
2535
0
    fn next(&mut self) -> Option<V> {
2536
0
        self.inner.next().map(|(_, v)| v)
2537
0
    }
2538
    #[inline]
2539
0
    fn size_hint(&self) -> (usize, Option<usize>) {
2540
0
        self.inner.size_hint()
2541
0
    }
2542
    #[inline]
2543
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
2544
0
    where
2545
0
        Self: Sized,
2546
0
        F: FnMut(B, Self::Item) -> B,
2547
0
    {
2548
0
        self.inner.fold(init, |acc, (_, v)| f(acc, v))
2549
0
    }
2550
}
2551
2552
impl<K, V, A: Allocator> ExactSizeIterator for IntoValues<K, V, A> {
2553
    #[inline]
2554
0
    fn len(&self) -> usize {
2555
0
        self.inner.len()
2556
0
    }
2557
}
2558
2559
impl<K, V, A: Allocator> FusedIterator for IntoValues<K, V, A> {}
2560
2561
impl<K, V: Debug, A: Allocator> fmt::Debug for IntoValues<K, V, A> {
2562
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2563
0
        f.debug_list()
2564
0
            .entries(self.inner.iter().map(|(_, v)| v))
2565
0
            .finish()
2566
0
    }
2567
}
2568
2569
/// An iterator over the keys of a `HashMap` in arbitrary order.
2570
/// The iterator element type is `&'a K`.
2571
///
2572
/// This `struct` is created by the [`keys`] method on [`HashMap`]. See its
2573
/// documentation for more.
2574
///
2575
/// [`keys`]: struct.HashMap.html#method.keys
2576
/// [`HashMap`]: struct.HashMap.html
2577
///
2578
/// # Examples
2579
///
2580
/// ```
2581
/// use hashbrown::HashMap;
2582
///
2583
/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].into();
2584
///
2585
/// let mut keys = map.keys();
2586
/// let mut vec = vec![keys.next(), keys.next(), keys.next()];
2587
///
2588
/// // The `Keys` iterator produces keys in arbitrary order, so the
2589
/// // keys must be sorted to test them against a sorted array.
2590
/// vec.sort_unstable();
2591
/// assert_eq!(vec, [Some(&1), Some(&2), Some(&3)]);
2592
///
2593
/// // It is fused iterator
2594
/// assert_eq!(keys.next(), None);
2595
/// assert_eq!(keys.next(), None);
2596
/// ```
2597
pub struct Keys<'a, K, V> {
2598
    inner: Iter<'a, K, V>,
2599
}
2600
2601
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2602
impl<K, V> Clone for Keys<'_, K, V> {
2603
    #[cfg_attr(feature = "inline-more", inline)]
2604
0
    fn clone(&self) -> Self {
2605
0
        Keys {
2606
0
            inner: self.inner.clone(),
2607
0
        }
2608
0
    }
2609
}
2610
2611
impl<K: Debug, V> fmt::Debug for Keys<'_, K, V> {
2612
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2613
0
        f.debug_list().entries(self.clone()).finish()
2614
0
    }
2615
}
2616
2617
/// An iterator over the values of a `HashMap` in arbitrary order.
2618
/// The iterator element type is `&'a V`.
2619
///
2620
/// This `struct` is created by the [`values`] method on [`HashMap`]. See its
2621
/// documentation for more.
2622
///
2623
/// [`values`]: struct.HashMap.html#method.values
2624
/// [`HashMap`]: struct.HashMap.html
2625
///
2626
/// # Examples
2627
///
2628
/// ```
2629
/// use hashbrown::HashMap;
2630
///
2631
/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].into();
2632
///
2633
/// let mut values = map.values();
2634
/// let mut vec = vec![values.next(), values.next(), values.next()];
2635
///
2636
/// // The `Values` iterator produces values in arbitrary order, so the
2637
/// // values must be sorted to test them against a sorted array.
2638
/// vec.sort_unstable();
2639
/// assert_eq!(vec, [Some(&"a"), Some(&"b"), Some(&"c")]);
2640
///
2641
/// // It is fused iterator
2642
/// assert_eq!(values.next(), None);
2643
/// assert_eq!(values.next(), None);
2644
/// ```
2645
pub struct Values<'a, K, V> {
2646
    inner: Iter<'a, K, V>,
2647
}
2648
2649
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2650
impl<K, V> Clone for Values<'_, K, V> {
2651
    #[cfg_attr(feature = "inline-more", inline)]
2652
0
    fn clone(&self) -> Self {
2653
0
        Values {
2654
0
            inner: self.inner.clone(),
2655
0
        }
2656
0
    }
2657
}
2658
2659
impl<K, V: Debug> fmt::Debug for Values<'_, K, V> {
2660
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2661
0
        f.debug_list().entries(self.clone()).finish()
2662
0
    }
2663
}
2664
2665
/// A draining iterator over the entries of a `HashMap` in arbitrary
2666
/// order. The iterator element type is `(K, V)`.
2667
///
2668
/// This `struct` is created by the [`drain`] method on [`HashMap`]. See its
2669
/// documentation for more.
2670
///
2671
/// [`drain`]: struct.HashMap.html#method.drain
2672
/// [`HashMap`]: struct.HashMap.html
2673
///
2674
/// # Examples
2675
///
2676
/// ```
2677
/// use hashbrown::HashMap;
2678
///
2679
/// let mut map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].into();
2680
///
2681
/// let mut drain_iter = map.drain();
2682
/// let mut vec = vec![drain_iter.next(), drain_iter.next(), drain_iter.next()];
2683
///
2684
/// // The `Drain` iterator produces items in arbitrary order, so the
2685
/// // items must be sorted to test them against a sorted array.
2686
/// vec.sort_unstable();
2687
/// assert_eq!(vec, [Some((1, "a")), Some((2, "b")), Some((3, "c"))]);
2688
///
2689
/// // It is fused iterator
2690
/// assert_eq!(drain_iter.next(), None);
2691
/// assert_eq!(drain_iter.next(), None);
2692
/// ```
2693
pub struct Drain<'a, K, V, A: Allocator = Global> {
2694
    inner: RawDrain<'a, (K, V), A>,
2695
}
2696
2697
impl<K, V, A: Allocator> Drain<'_, K, V, A> {
2698
    /// Returns a iterator of references over the remaining items.
2699
    #[cfg_attr(feature = "inline-more", inline)]
2700
0
    pub(super) fn iter(&self) -> Iter<'_, K, V> {
2701
0
        Iter {
2702
0
            inner: self.inner.iter(),
2703
0
            marker: PhantomData,
2704
0
        }
2705
0
    }
2706
}
2707
2708
/// A draining iterator over entries of a `HashMap` which don't satisfy the predicate
2709
/// `f(&k, &mut v)` in arbitrary order. The iterator element type is `(K, V)`.
2710
///
2711
/// This `struct` is created by the [`extract_if`] method on [`HashMap`]. See its
2712
/// documentation for more.
2713
///
2714
/// [`extract_if`]: struct.HashMap.html#method.extract_if
2715
/// [`HashMap`]: struct.HashMap.html
2716
///
2717
/// # Examples
2718
///
2719
/// ```
2720
/// use hashbrown::HashMap;
2721
///
2722
/// let mut map: HashMap<i32, &str> = [(1, "a"), (2, "b"), (3, "c")].into();
2723
///
2724
/// let mut extract_if = map.extract_if(|k, _v| k % 2 != 0);
2725
/// let mut vec = vec![extract_if.next(), extract_if.next()];
2726
///
2727
/// // The `ExtractIf` iterator produces items in arbitrary order, so the
2728
/// // items must be sorted to test them against a sorted array.
2729
/// vec.sort_unstable();
2730
/// assert_eq!(vec, [Some((1, "a")),Some((3, "c"))]);
2731
///
2732
/// // It is fused iterator
2733
/// assert_eq!(extract_if.next(), None);
2734
/// assert_eq!(extract_if.next(), None);
2735
/// drop(extract_if);
2736
///
2737
/// assert_eq!(map.len(), 1);
2738
/// ```
2739
#[must_use = "Iterators are lazy unless consumed"]
2740
pub struct ExtractIf<'a, K, V, F, A: Allocator = Global>
2741
where
2742
    F: FnMut(&K, &mut V) -> bool,
2743
{
2744
    f: F,
2745
    inner: RawExtractIf<'a, (K, V), A>,
2746
}
2747
2748
impl<K, V, F, A> Iterator for ExtractIf<'_, K, V, F, A>
2749
where
2750
    F: FnMut(&K, &mut V) -> bool,
2751
    A: Allocator,
2752
{
2753
    type Item = (K, V);
2754
2755
    #[cfg_attr(feature = "inline-more", inline)]
2756
0
    fn next(&mut self) -> Option<Self::Item> {
2757
0
        self.inner.next(|&mut (ref k, ref mut v)| (self.f)(k, v))
2758
0
    }
2759
2760
    #[inline]
2761
0
    fn size_hint(&self) -> (usize, Option<usize>) {
2762
0
        (0, self.inner.iter.size_hint().1)
2763
0
    }
2764
}
2765
2766
impl<K, V, F> FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {}
2767
2768
/// A mutable iterator over the values of a `HashMap` in arbitrary order.
2769
/// The iterator element type is `&'a mut V`.
2770
///
2771
/// This `struct` is created by the [`values_mut`] method on [`HashMap`]. See its
2772
/// documentation for more.
2773
///
2774
/// [`values_mut`]: struct.HashMap.html#method.values_mut
2775
/// [`HashMap`]: struct.HashMap.html
2776
///
2777
/// # Examples
2778
///
2779
/// ```
2780
/// use hashbrown::HashMap;
2781
///
2782
/// let mut map: HashMap<_, _> = [(1, "One".to_owned()), (2, "Two".into())].into();
2783
///
2784
/// let mut values = map.values_mut();
2785
/// values.next().map(|v| v.push_str(" Mississippi"));
2786
/// values.next().map(|v| v.push_str(" Mississippi"));
2787
///
2788
/// // It is fused iterator
2789
/// assert_eq!(values.next(), None);
2790
/// assert_eq!(values.next(), None);
2791
///
2792
/// assert_eq!(map.get(&1).unwrap(), &"One Mississippi".to_owned());
2793
/// assert_eq!(map.get(&2).unwrap(), &"Two Mississippi".to_owned());
2794
/// ```
2795
pub struct ValuesMut<'a, K, V> {
2796
    inner: IterMut<'a, K, V>,
2797
}
2798
2799
/// A builder for computing where in a [`HashMap`] a key-value pair would be stored.
2800
///
2801
/// See the [`HashMap::raw_entry_mut`] docs for usage examples.
2802
///
2803
/// [`HashMap::raw_entry_mut`]: struct.HashMap.html#method.raw_entry_mut
2804
///
2805
/// # Examples
2806
///
2807
/// ```
2808
/// use hashbrown::hash_map::{RawEntryBuilderMut, RawEntryMut::Vacant, RawEntryMut::Occupied};
2809
/// use hashbrown::HashMap;
2810
/// use core::hash::{BuildHasher, Hash};
2811
///
2812
/// let mut map = HashMap::new();
2813
/// map.extend([(1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16)]);
2814
/// assert_eq!(map.len(), 6);
2815
///
2816
/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
2817
///     use core::hash::Hasher;
2818
///     let mut state = hash_builder.build_hasher();
2819
///     key.hash(&mut state);
2820
///     state.finish()
2821
/// }
2822
///
2823
/// let builder: RawEntryBuilderMut<_, _, _> = map.raw_entry_mut();
2824
///
2825
/// // Existing key
2826
/// match builder.from_key(&6) {
2827
///     Vacant(_) => unreachable!(),
2828
///     Occupied(view) => assert_eq!(view.get(), &16),
2829
/// }
2830
///
2831
/// for key in 0..12 {
2832
///     let hash = compute_hash(map.hasher(), &key);
2833
///     let value = map.get(&key).cloned();
2834
///     let key_value = value.as_ref().map(|v| (&key, v));
2835
///
2836
///     println!("Key: {} and value: {:?}", key, value);
2837
///
2838
///     match map.raw_entry_mut().from_key(&key) {
2839
///         Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
2840
///         Vacant(_) => assert_eq!(value, None),
2841
///     }
2842
///     match map.raw_entry_mut().from_key_hashed_nocheck(hash, &key) {
2843
///         Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
2844
///         Vacant(_) => assert_eq!(value, None),
2845
///     }
2846
///     match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
2847
///         Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
2848
///         Vacant(_) => assert_eq!(value, None),
2849
///     }
2850
/// }
2851
///
2852
/// assert_eq!(map.len(), 6);
2853
/// ```
2854
pub struct RawEntryBuilderMut<'a, K, V, S, A: Allocator = Global> {
2855
    map: &'a mut HashMap<K, V, S, A>,
2856
}
2857
2858
/// A view into a single entry in a map, which may either be vacant or occupied.
2859
///
2860
/// This is a lower-level version of [`Entry`].
2861
///
2862
/// This `enum` is constructed through the [`raw_entry_mut`] method on [`HashMap`],
2863
/// then calling one of the methods of that [`RawEntryBuilderMut`].
2864
///
2865
/// [`HashMap`]: struct.HashMap.html
2866
/// [`Entry`]: enum.Entry.html
2867
/// [`raw_entry_mut`]: struct.HashMap.html#method.raw_entry_mut
2868
/// [`RawEntryBuilderMut`]: struct.RawEntryBuilderMut.html
2869
///
2870
/// # Examples
2871
///
2872
/// ```
2873
/// use core::hash::{BuildHasher, Hash};
2874
/// use hashbrown::hash_map::{HashMap, RawEntryMut, RawOccupiedEntryMut};
2875
///
2876
/// let mut map = HashMap::new();
2877
/// map.extend([('a', 1), ('b', 2), ('c', 3)]);
2878
/// assert_eq!(map.len(), 3);
2879
///
2880
/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
2881
///     use core::hash::Hasher;
2882
///     let mut state = hash_builder.build_hasher();
2883
///     key.hash(&mut state);
2884
///     state.finish()
2885
/// }
2886
///
2887
/// // Existing key (insert)
2888
/// let raw: RawEntryMut<_, _, _> = map.raw_entry_mut().from_key(&'a');
2889
/// let _raw_o: RawOccupiedEntryMut<_, _, _> = raw.insert('a', 10);
2890
/// assert_eq!(map.len(), 3);
2891
///
2892
/// // Nonexistent key (insert)
2893
/// map.raw_entry_mut().from_key(&'d').insert('d', 40);
2894
/// assert_eq!(map.len(), 4);
2895
///
2896
/// // Existing key (or_insert)
2897
/// let hash = compute_hash(map.hasher(), &'b');
2898
/// let kv = map
2899
///     .raw_entry_mut()
2900
///     .from_key_hashed_nocheck(hash, &'b')
2901
///     .or_insert('b', 20);
2902
/// assert_eq!(kv, (&mut 'b', &mut 2));
2903
/// *kv.1 = 20;
2904
/// assert_eq!(map.len(), 4);
2905
///
2906
/// // Nonexistent key (or_insert)
2907
/// let hash = compute_hash(map.hasher(), &'e');
2908
/// let kv = map
2909
///     .raw_entry_mut()
2910
///     .from_key_hashed_nocheck(hash, &'e')
2911
///     .or_insert('e', 50);
2912
/// assert_eq!(kv, (&mut 'e', &mut 50));
2913
/// assert_eq!(map.len(), 5);
2914
///
2915
/// // Existing key (or_insert_with)
2916
/// let hash = compute_hash(map.hasher(), &'c');
2917
/// let kv = map
2918
///     .raw_entry_mut()
2919
///     .from_hash(hash, |q| q == &'c')
2920
///     .or_insert_with(|| ('c', 30));
2921
/// assert_eq!(kv, (&mut 'c', &mut 3));
2922
/// *kv.1 = 30;
2923
/// assert_eq!(map.len(), 5);
2924
///
2925
/// // Nonexistent key (or_insert_with)
2926
/// let hash = compute_hash(map.hasher(), &'f');
2927
/// let kv = map
2928
///     .raw_entry_mut()
2929
///     .from_hash(hash, |q| q == &'f')
2930
///     .or_insert_with(|| ('f', 60));
2931
/// assert_eq!(kv, (&mut 'f', &mut 60));
2932
/// assert_eq!(map.len(), 6);
2933
///
2934
/// println!("Our HashMap: {:?}", map);
2935
///
2936
/// let mut vec: Vec<_> = map.iter().map(|(&k, &v)| (k, v)).collect();
2937
/// // The `Iter` iterator produces items in arbitrary order, so the
2938
/// // items must be sorted to test them against a sorted array.
2939
/// vec.sort_unstable();
2940
/// assert_eq!(vec, [('a', 10), ('b', 20), ('c', 30), ('d', 40), ('e', 50), ('f', 60)]);
2941
/// ```
2942
pub enum RawEntryMut<'a, K, V, S, A: Allocator = Global> {
2943
    /// An occupied entry.
2944
    ///
2945
    /// # Examples
2946
    ///
2947
    /// ```
2948
    /// use hashbrown::{hash_map::RawEntryMut, HashMap};
2949
    /// let mut map: HashMap<_, _> = [("a", 100), ("b", 200)].into();
2950
    ///
2951
    /// match map.raw_entry_mut().from_key(&"a") {
2952
    ///     RawEntryMut::Vacant(_) => unreachable!(),
2953
    ///     RawEntryMut::Occupied(_) => { }
2954
    /// }
2955
    /// ```
2956
    Occupied(RawOccupiedEntryMut<'a, K, V, S, A>),
2957
    /// A vacant entry.
2958
    ///
2959
    /// # Examples
2960
    ///
2961
    /// ```
2962
    /// use hashbrown::{hash_map::RawEntryMut, HashMap};
2963
    /// let mut map: HashMap<&str, i32> = HashMap::new();
2964
    ///
2965
    /// match map.raw_entry_mut().from_key("a") {
2966
    ///     RawEntryMut::Occupied(_) => unreachable!(),
2967
    ///     RawEntryMut::Vacant(_) => { }
2968
    /// }
2969
    /// ```
2970
    Vacant(RawVacantEntryMut<'a, K, V, S, A>),
2971
}
2972
2973
/// A view into an occupied entry in a `HashMap`.
2974
/// It is part of the [`RawEntryMut`] enum.
2975
///
2976
/// [`RawEntryMut`]: enum.RawEntryMut.html
2977
///
2978
/// # Examples
2979
///
2980
/// ```
2981
/// use core::hash::{BuildHasher, Hash};
2982
/// use hashbrown::hash_map::{HashMap, RawEntryMut, RawOccupiedEntryMut};
2983
///
2984
/// let mut map = HashMap::new();
2985
/// map.extend([("a", 10), ("b", 20), ("c", 30)]);
2986
///
2987
/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
2988
///     use core::hash::Hasher;
2989
///     let mut state = hash_builder.build_hasher();
2990
///     key.hash(&mut state);
2991
///     state.finish()
2992
/// }
2993
///
2994
/// let _raw_o: RawOccupiedEntryMut<_, _, _> = map.raw_entry_mut().from_key(&"a").insert("a", 100);
2995
/// assert_eq!(map.len(), 3);
2996
///
2997
/// // Existing key (insert and update)
2998
/// match map.raw_entry_mut().from_key(&"a") {
2999
///     RawEntryMut::Vacant(_) => unreachable!(),
3000
///     RawEntryMut::Occupied(mut view) => {
3001
///         assert_eq!(view.get(), &100);
3002
///         let v = view.get_mut();
3003
///         let new_v = (*v) * 10;
3004
///         *v = new_v;
3005
///         assert_eq!(view.insert(1111), 1000);
3006
///     }
3007
/// }
3008
///
3009
/// assert_eq!(map[&"a"], 1111);
3010
/// assert_eq!(map.len(), 3);
3011
///
3012
/// // Existing key (take)
3013
/// let hash = compute_hash(map.hasher(), &"c");
3014
/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"c") {
3015
///     RawEntryMut::Vacant(_) => unreachable!(),
3016
///     RawEntryMut::Occupied(view) => {
3017
///         assert_eq!(view.remove_entry(), ("c", 30));
3018
///     }
3019
/// }
3020
/// assert_eq!(map.raw_entry().from_key(&"c"), None);
3021
/// assert_eq!(map.len(), 2);
3022
///
3023
/// let hash = compute_hash(map.hasher(), &"b");
3024
/// match map.raw_entry_mut().from_hash(hash, |q| *q == "b") {
3025
///     RawEntryMut::Vacant(_) => unreachable!(),
3026
///     RawEntryMut::Occupied(view) => {
3027
///         assert_eq!(view.remove_entry(), ("b", 20));
3028
///     }
3029
/// }
3030
/// assert_eq!(map.get(&"b"), None);
3031
/// assert_eq!(map.len(), 1);
3032
/// ```
3033
pub struct RawOccupiedEntryMut<'a, K, V, S, A: Allocator = Global> {
3034
    elem: Bucket<(K, V)>,
3035
    table: &'a mut RawTable<(K, V), A>,
3036
    hash_builder: &'a S,
3037
}
3038
3039
unsafe impl<K, V, S, A> Send for RawOccupiedEntryMut<'_, K, V, S, A>
3040
where
3041
    K: Send,
3042
    V: Send,
3043
    S: Send,
3044
    A: Send + Allocator,
3045
{
3046
}
3047
unsafe impl<K, V, S, A> Sync for RawOccupiedEntryMut<'_, K, V, S, A>
3048
where
3049
    K: Sync,
3050
    V: Sync,
3051
    S: Sync,
3052
    A: Sync + Allocator,
3053
{
3054
}
3055
3056
/// A view into a vacant entry in a `HashMap`.
3057
/// It is part of the [`RawEntryMut`] enum.
3058
///
3059
/// [`RawEntryMut`]: enum.RawEntryMut.html
3060
///
3061
/// # Examples
3062
///
3063
/// ```
3064
/// use core::hash::{BuildHasher, Hash};
3065
/// use hashbrown::hash_map::{HashMap, RawEntryMut, RawVacantEntryMut};
3066
///
3067
/// let mut map = HashMap::<&str, i32>::new();
3068
///
3069
/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3070
///     use core::hash::Hasher;
3071
///     let mut state = hash_builder.build_hasher();
3072
///     key.hash(&mut state);
3073
///     state.finish()
3074
/// }
3075
///
3076
/// let raw_v: RawVacantEntryMut<_, _, _> = match map.raw_entry_mut().from_key(&"a") {
3077
///     RawEntryMut::Vacant(view) => view,
3078
///     RawEntryMut::Occupied(_) => unreachable!(),
3079
/// };
3080
/// raw_v.insert("a", 10);
3081
/// assert!(map[&"a"] == 10 && map.len() == 1);
3082
///
3083
/// // Nonexistent key (insert and update)
3084
/// let hash = compute_hash(map.hasher(), &"b");
3085
/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"b") {
3086
///     RawEntryMut::Occupied(_) => unreachable!(),
3087
///     RawEntryMut::Vacant(view) => {
3088
///         let (k, value) = view.insert("b", 2);
3089
///         assert_eq!((*k, *value), ("b", 2));
3090
///         *value = 20;
3091
///     }
3092
/// }
3093
/// assert!(map[&"b"] == 20 && map.len() == 2);
3094
///
3095
/// let hash = compute_hash(map.hasher(), &"c");
3096
/// match map.raw_entry_mut().from_hash(hash, |q| *q == "c") {
3097
///     RawEntryMut::Occupied(_) => unreachable!(),
3098
///     RawEntryMut::Vacant(view) => {
3099
///         assert_eq!(view.insert("c", 30), (&mut "c", &mut 30));
3100
///     }
3101
/// }
3102
/// assert!(map[&"c"] == 30 && map.len() == 3);
3103
/// ```
3104
pub struct RawVacantEntryMut<'a, K, V, S, A: Allocator = Global> {
3105
    table: &'a mut RawTable<(K, V), A>,
3106
    hash_builder: &'a S,
3107
}
3108
3109
/// A builder for computing where in a [`HashMap`] a key-value pair would be stored.
3110
///
3111
/// See the [`HashMap::raw_entry`] docs for usage examples.
3112
///
3113
/// [`HashMap::raw_entry`]: struct.HashMap.html#method.raw_entry
3114
///
3115
/// # Examples
3116
///
3117
/// ```
3118
/// use hashbrown::hash_map::{HashMap, RawEntryBuilder};
3119
/// use core::hash::{BuildHasher, Hash};
3120
///
3121
/// let mut map = HashMap::new();
3122
/// map.extend([(1, 10), (2, 20), (3, 30)]);
3123
///
3124
/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3125
///     use core::hash::Hasher;
3126
///     let mut state = hash_builder.build_hasher();
3127
///     key.hash(&mut state);
3128
///     state.finish()
3129
/// }
3130
///
3131
/// for k in 0..6 {
3132
///     let hash = compute_hash(map.hasher(), &k);
3133
///     let v = map.get(&k).cloned();
3134
///     let kv = v.as_ref().map(|v| (&k, v));
3135
///
3136
///     println!("Key: {} and value: {:?}", k, v);
3137
///     let builder: RawEntryBuilder<_, _, _> = map.raw_entry();
3138
///     assert_eq!(builder.from_key(&k), kv);
3139
///     assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
3140
///     assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
3141
/// }
3142
/// ```
3143
pub struct RawEntryBuilder<'a, K, V, S, A: Allocator = Global> {
3144
    map: &'a HashMap<K, V, S, A>,
3145
}
3146
3147
impl<'a, K, V, S, A: Allocator> RawEntryBuilderMut<'a, K, V, S, A> {
3148
    /// Creates a `RawEntryMut` from the given key.
3149
    ///
3150
    /// # Examples
3151
    ///
3152
    /// ```
3153
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3154
    ///
3155
    /// let mut map: HashMap<&str, u32> = HashMap::new();
3156
    /// let key = "a";
3157
    /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_key(&key);
3158
    /// entry.insert(key, 100);
3159
    /// assert_eq!(map[&"a"], 100);
3160
    /// ```
3161
    #[cfg_attr(feature = "inline-more", inline)]
3162
    #[allow(clippy::wrong_self_convention)]
3163
0
    pub fn from_key<Q: ?Sized>(self, k: &Q) -> RawEntryMut<'a, K, V, S, A>
3164
0
    where
3165
0
        S: BuildHasher,
3166
0
        Q: Hash + Equivalent<K>,
3167
0
    {
3168
0
        let hash = make_hash::<Q, S>(&self.map.hash_builder, k);
3169
0
        self.from_key_hashed_nocheck(hash, k)
3170
0
    }
3171
3172
    /// Creates a `RawEntryMut` from the given key and its hash.
3173
    ///
3174
    /// # Examples
3175
    ///
3176
    /// ```
3177
    /// use core::hash::{BuildHasher, Hash};
3178
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3179
    ///
3180
    /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3181
    ///     use core::hash::Hasher;
3182
    ///     let mut state = hash_builder.build_hasher();
3183
    ///     key.hash(&mut state);
3184
    ///     state.finish()
3185
    /// }
3186
    ///
3187
    /// let mut map: HashMap<&str, u32> = HashMap::new();
3188
    /// let key = "a";
3189
    /// let hash = compute_hash(map.hasher(), &key);
3190
    /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_key_hashed_nocheck(hash, &key);
3191
    /// entry.insert(key, 100);
3192
    /// assert_eq!(map[&"a"], 100);
3193
    /// ```
3194
    #[inline]
3195
    #[allow(clippy::wrong_self_convention)]
3196
0
    pub fn from_key_hashed_nocheck<Q: ?Sized>(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S, A>
3197
0
    where
3198
0
        Q: Equivalent<K>,
3199
0
    {
3200
0
        self.from_hash(hash, equivalent(k))
3201
0
    }
3202
}
3203
3204
impl<'a, K, V, S, A: Allocator> RawEntryBuilderMut<'a, K, V, S, A> {
3205
    /// Creates a `RawEntryMut` from the given hash and matching function.
3206
    ///
3207
    /// # Examples
3208
    ///
3209
    /// ```
3210
    /// use core::hash::{BuildHasher, Hash};
3211
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3212
    ///
3213
    /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3214
    ///     use core::hash::Hasher;
3215
    ///     let mut state = hash_builder.build_hasher();
3216
    ///     key.hash(&mut state);
3217
    ///     state.finish()
3218
    /// }
3219
    ///
3220
    /// let mut map: HashMap<&str, u32> = HashMap::new();
3221
    /// let key = "a";
3222
    /// let hash = compute_hash(map.hasher(), &key);
3223
    /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_hash(hash, |k| k == &key);
3224
    /// entry.insert(key, 100);
3225
    /// assert_eq!(map[&"a"], 100);
3226
    /// ```
3227
    #[cfg_attr(feature = "inline-more", inline)]
3228
    #[allow(clippy::wrong_self_convention)]
3229
0
    pub fn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S, A>
3230
0
    where
3231
0
        for<'b> F: FnMut(&'b K) -> bool,
3232
0
    {
3233
0
        self.search(hash, is_match)
3234
0
    }
3235
3236
    #[cfg_attr(feature = "inline-more", inline)]
3237
0
    fn search<F>(self, hash: u64, mut is_match: F) -> RawEntryMut<'a, K, V, S, A>
3238
0
    where
3239
0
        for<'b> F: FnMut(&'b K) -> bool,
3240
0
    {
3241
0
        match self.map.table.find(hash, |(k, _)| is_match(k)) {
3242
0
            Some(elem) => RawEntryMut::Occupied(RawOccupiedEntryMut {
3243
0
                elem,
3244
0
                table: &mut self.map.table,
3245
0
                hash_builder: &self.map.hash_builder,
3246
0
            }),
3247
0
            None => RawEntryMut::Vacant(RawVacantEntryMut {
3248
0
                table: &mut self.map.table,
3249
0
                hash_builder: &self.map.hash_builder,
3250
0
            }),
3251
        }
3252
0
    }
3253
}
3254
3255
impl<'a, K, V, S, A: Allocator> RawEntryBuilder<'a, K, V, S, A> {
3256
    /// Access an immutable entry by key.
3257
    ///
3258
    /// # Examples
3259
    ///
3260
    /// ```
3261
    /// use hashbrown::HashMap;
3262
    ///
3263
    /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3264
    /// let key = "a";
3265
    /// assert_eq!(map.raw_entry().from_key(&key), Some((&"a", &100)));
3266
    /// ```
3267
    #[cfg_attr(feature = "inline-more", inline)]
3268
    #[allow(clippy::wrong_self_convention)]
3269
0
    pub fn from_key<Q: ?Sized>(self, k: &Q) -> Option<(&'a K, &'a V)>
3270
0
    where
3271
0
        S: BuildHasher,
3272
0
        Q: Hash + Equivalent<K>,
3273
0
    {
3274
0
        let hash = make_hash::<Q, S>(&self.map.hash_builder, k);
3275
0
        self.from_key_hashed_nocheck(hash, k)
3276
0
    }
3277
3278
    /// Access an immutable entry by a key and its hash.
3279
    ///
3280
    /// # Examples
3281
    ///
3282
    /// ```
3283
    /// use core::hash::{BuildHasher, Hash};
3284
    /// use hashbrown::HashMap;
3285
    ///
3286
    /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3287
    ///     use core::hash::Hasher;
3288
    ///     let mut state = hash_builder.build_hasher();
3289
    ///     key.hash(&mut state);
3290
    ///     state.finish()
3291
    /// }
3292
    ///
3293
    /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3294
    /// let key = "a";
3295
    /// let hash = compute_hash(map.hasher(), &key);
3296
    /// assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &key), Some((&"a", &100)));
3297
    /// ```
3298
    #[cfg_attr(feature = "inline-more", inline)]
3299
    #[allow(clippy::wrong_self_convention)]
3300
0
    pub fn from_key_hashed_nocheck<Q: ?Sized>(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)>
3301
0
    where
3302
0
        Q: Equivalent<K>,
3303
0
    {
3304
0
        self.from_hash(hash, equivalent(k))
3305
0
    }
3306
3307
    #[cfg_attr(feature = "inline-more", inline)]
3308
0
    fn search<F>(self, hash: u64, mut is_match: F) -> Option<(&'a K, &'a V)>
3309
0
    where
3310
0
        F: FnMut(&K) -> bool,
3311
0
    {
3312
0
        match self.map.table.get(hash, |(k, _)| is_match(k)) {
3313
0
            Some((key, value)) => Some((key, value)),
3314
0
            None => None,
3315
        }
3316
0
    }
3317
3318
    /// Access an immutable entry by hash and matching function.
3319
    ///
3320
    /// # Examples
3321
    ///
3322
    /// ```
3323
    /// use core::hash::{BuildHasher, Hash};
3324
    /// use hashbrown::HashMap;
3325
    ///
3326
    /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3327
    ///     use core::hash::Hasher;
3328
    ///     let mut state = hash_builder.build_hasher();
3329
    ///     key.hash(&mut state);
3330
    ///     state.finish()
3331
    /// }
3332
    ///
3333
    /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3334
    /// let key = "a";
3335
    /// let hash = compute_hash(map.hasher(), &key);
3336
    /// assert_eq!(map.raw_entry().from_hash(hash, |k| k == &key), Some((&"a", &100)));
3337
    /// ```
3338
    #[cfg_attr(feature = "inline-more", inline)]
3339
    #[allow(clippy::wrong_self_convention)]
3340
0
    pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
3341
0
    where
3342
0
        F: FnMut(&K) -> bool,
3343
0
    {
3344
0
        self.search(hash, is_match)
3345
0
    }
3346
}
3347
3348
impl<'a, K, V, S, A: Allocator> RawEntryMut<'a, K, V, S, A> {
3349
    /// Sets the value of the entry, and returns a RawOccupiedEntryMut.
3350
    ///
3351
    /// # Examples
3352
    ///
3353
    /// ```
3354
    /// use hashbrown::HashMap;
3355
    ///
3356
    /// let mut map: HashMap<&str, u32> = HashMap::new();
3357
    /// let entry = map.raw_entry_mut().from_key("horseyland").insert("horseyland", 37);
3358
    ///
3359
    /// assert_eq!(entry.remove_entry(), ("horseyland", 37));
3360
    /// ```
3361
    #[cfg_attr(feature = "inline-more", inline)]
3362
0
    pub fn insert(self, key: K, value: V) -> RawOccupiedEntryMut<'a, K, V, S, A>
3363
0
    where
3364
0
        K: Hash,
3365
0
        S: BuildHasher,
3366
0
    {
3367
0
        match self {
3368
0
            RawEntryMut::Occupied(mut entry) => {
3369
0
                entry.insert(value);
3370
0
                entry
3371
            }
3372
0
            RawEntryMut::Vacant(entry) => entry.insert_entry(key, value),
3373
        }
3374
0
    }
3375
3376
    /// Ensures a value is in the entry by inserting the default if empty, and returns
3377
    /// mutable references to the key and value in the entry.
3378
    ///
3379
    /// # Examples
3380
    ///
3381
    /// ```
3382
    /// use hashbrown::HashMap;
3383
    ///
3384
    /// let mut map: HashMap<&str, u32> = HashMap::new();
3385
    ///
3386
    /// map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 3);
3387
    /// assert_eq!(map["poneyland"], 3);
3388
    ///
3389
    /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2;
3390
    /// assert_eq!(map["poneyland"], 6);
3391
    /// ```
3392
    #[cfg_attr(feature = "inline-more", inline)]
3393
0
    pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V)
3394
0
    where
3395
0
        K: Hash,
3396
0
        S: BuildHasher,
3397
0
    {
3398
0
        match self {
3399
0
            RawEntryMut::Occupied(entry) => entry.into_key_value(),
3400
0
            RawEntryMut::Vacant(entry) => entry.insert(default_key, default_val),
3401
        }
3402
0
    }
3403
3404
    /// Ensures a value is in the entry by inserting the result of the default function if empty,
3405
    /// and returns mutable references to the key and value in the entry.
3406
    ///
3407
    /// # Examples
3408
    ///
3409
    /// ```
3410
    /// use hashbrown::HashMap;
3411
    ///
3412
    /// let mut map: HashMap<&str, String> = HashMap::new();
3413
    ///
3414
    /// map.raw_entry_mut().from_key("poneyland").or_insert_with(|| {
3415
    ///     ("poneyland", "hoho".to_string())
3416
    /// });
3417
    ///
3418
    /// assert_eq!(map["poneyland"], "hoho".to_string());
3419
    /// ```
3420
    #[cfg_attr(feature = "inline-more", inline)]
3421
0
    pub fn or_insert_with<F>(self, default: F) -> (&'a mut K, &'a mut V)
3422
0
    where
3423
0
        F: FnOnce() -> (K, V),
3424
0
        K: Hash,
3425
0
        S: BuildHasher,
3426
0
    {
3427
0
        match self {
3428
0
            RawEntryMut::Occupied(entry) => entry.into_key_value(),
3429
0
            RawEntryMut::Vacant(entry) => {
3430
0
                let (k, v) = default();
3431
0
                entry.insert(k, v)
3432
            }
3433
        }
3434
0
    }
3435
3436
    /// Provides in-place mutable access to an occupied entry before any
3437
    /// potential inserts into the map.
3438
    ///
3439
    /// # Examples
3440
    ///
3441
    /// ```
3442
    /// use hashbrown::HashMap;
3443
    ///
3444
    /// let mut map: HashMap<&str, u32> = HashMap::new();
3445
    ///
3446
    /// map.raw_entry_mut()
3447
    ///    .from_key("poneyland")
3448
    ///    .and_modify(|_k, v| { *v += 1 })
3449
    ///    .or_insert("poneyland", 42);
3450
    /// assert_eq!(map["poneyland"], 42);
3451
    ///
3452
    /// map.raw_entry_mut()
3453
    ///    .from_key("poneyland")
3454
    ///    .and_modify(|_k, v| { *v += 1 })
3455
    ///    .or_insert("poneyland", 0);
3456
    /// assert_eq!(map["poneyland"], 43);
3457
    /// ```
3458
    #[cfg_attr(feature = "inline-more", inline)]
3459
0
    pub fn and_modify<F>(self, f: F) -> Self
3460
0
    where
3461
0
        F: FnOnce(&mut K, &mut V),
3462
0
    {
3463
0
        match self {
3464
0
            RawEntryMut::Occupied(mut entry) => {
3465
0
                {
3466
0
                    let (k, v) = entry.get_key_value_mut();
3467
0
                    f(k, v);
3468
0
                }
3469
0
                RawEntryMut::Occupied(entry)
3470
            }
3471
0
            RawEntryMut::Vacant(entry) => RawEntryMut::Vacant(entry),
3472
        }
3473
0
    }
3474
3475
    /// Provides shared access to the key and owned access to the value of
3476
    /// an occupied entry and allows to replace or remove it based on the
3477
    /// value of the returned option.
3478
    ///
3479
    /// # Examples
3480
    ///
3481
    /// ```
3482
    /// use hashbrown::HashMap;
3483
    /// use hashbrown::hash_map::RawEntryMut;
3484
    ///
3485
    /// let mut map: HashMap<&str, u32> = HashMap::new();
3486
    ///
3487
    /// let entry = map
3488
    ///     .raw_entry_mut()
3489
    ///     .from_key("poneyland")
3490
    ///     .and_replace_entry_with(|_k, _v| panic!());
3491
    ///
3492
    /// match entry {
3493
    ///     RawEntryMut::Vacant(_) => {},
3494
    ///     RawEntryMut::Occupied(_) => panic!(),
3495
    /// }
3496
    ///
3497
    /// map.insert("poneyland", 42);
3498
    ///
3499
    /// let entry = map
3500
    ///     .raw_entry_mut()
3501
    ///     .from_key("poneyland")
3502
    ///     .and_replace_entry_with(|k, v| {
3503
    ///         assert_eq!(k, &"poneyland");
3504
    ///         assert_eq!(v, 42);
3505
    ///         Some(v + 1)
3506
    ///     });
3507
    ///
3508
    /// match entry {
3509
    ///     RawEntryMut::Occupied(e) => {
3510
    ///         assert_eq!(e.key(), &"poneyland");
3511
    ///         assert_eq!(e.get(), &43);
3512
    ///     },
3513
    ///     RawEntryMut::Vacant(_) => panic!(),
3514
    /// }
3515
    ///
3516
    /// assert_eq!(map["poneyland"], 43);
3517
    ///
3518
    /// let entry = map
3519
    ///     .raw_entry_mut()
3520
    ///     .from_key("poneyland")
3521
    ///     .and_replace_entry_with(|_k, _v| None);
3522
    ///
3523
    /// match entry {
3524
    ///     RawEntryMut::Vacant(_) => {},
3525
    ///     RawEntryMut::Occupied(_) => panic!(),
3526
    /// }
3527
    ///
3528
    /// assert!(!map.contains_key("poneyland"));
3529
    /// ```
3530
    #[cfg_attr(feature = "inline-more", inline)]
3531
0
    pub fn and_replace_entry_with<F>(self, f: F) -> Self
3532
0
    where
3533
0
        F: FnOnce(&K, V) -> Option<V>,
3534
0
    {
3535
0
        match self {
3536
0
            RawEntryMut::Occupied(entry) => entry.replace_entry_with(f),
3537
0
            RawEntryMut::Vacant(_) => self,
3538
        }
3539
0
    }
3540
}
3541
3542
impl<'a, K, V, S, A: Allocator> RawOccupiedEntryMut<'a, K, V, S, A> {
3543
    /// Gets a reference to the key in the entry.
3544
    ///
3545
    /// # Examples
3546
    ///
3547
    /// ```
3548
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3549
    ///
3550
    /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3551
    ///
3552
    /// match map.raw_entry_mut().from_key(&"a") {
3553
    ///     RawEntryMut::Vacant(_) => panic!(),
3554
    ///     RawEntryMut::Occupied(o) => assert_eq!(o.key(), &"a")
3555
    /// }
3556
    /// ```
3557
    #[cfg_attr(feature = "inline-more", inline)]
3558
0
    pub fn key(&self) -> &K {
3559
0
        unsafe { &self.elem.as_ref().0 }
3560
0
    }
3561
3562
    /// Gets a mutable reference to the key in the entry.
3563
    ///
3564
    /// # Examples
3565
    ///
3566
    /// ```
3567
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3568
    /// use std::rc::Rc;
3569
    ///
3570
    /// let key_one = Rc::new("a");
3571
    /// let key_two = Rc::new("a");
3572
    ///
3573
    /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
3574
    /// map.insert(key_one.clone(), 10);
3575
    ///
3576
    /// assert_eq!(map[&key_one], 10);
3577
    /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
3578
    ///
3579
    /// match map.raw_entry_mut().from_key(&key_one) {
3580
    ///     RawEntryMut::Vacant(_) => panic!(),
3581
    ///     RawEntryMut::Occupied(mut o) => {
3582
    ///         *o.key_mut() = key_two.clone();
3583
    ///     }
3584
    /// }
3585
    /// assert_eq!(map[&key_two], 10);
3586
    /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
3587
    /// ```
3588
    #[cfg_attr(feature = "inline-more", inline)]
3589
0
    pub fn key_mut(&mut self) -> &mut K {
3590
0
        unsafe { &mut self.elem.as_mut().0 }
3591
0
    }
3592
3593
    /// Converts the entry into a mutable reference to the key in the entry
3594
    /// with a lifetime bound to the map itself.
3595
    ///
3596
    /// # Examples
3597
    ///
3598
    /// ```
3599
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3600
    /// use std::rc::Rc;
3601
    ///
3602
    /// let key_one = Rc::new("a");
3603
    /// let key_two = Rc::new("a");
3604
    ///
3605
    /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
3606
    /// map.insert(key_one.clone(), 10);
3607
    ///
3608
    /// assert_eq!(map[&key_one], 10);
3609
    /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
3610
    ///
3611
    /// let inside_key: &mut Rc<&str>;
3612
    ///
3613
    /// match map.raw_entry_mut().from_key(&key_one) {
3614
    ///     RawEntryMut::Vacant(_) => panic!(),
3615
    ///     RawEntryMut::Occupied(o) => inside_key = o.into_key(),
3616
    /// }
3617
    /// *inside_key = key_two.clone();
3618
    ///
3619
    /// assert_eq!(map[&key_two], 10);
3620
    /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
3621
    /// ```
3622
    #[cfg_attr(feature = "inline-more", inline)]
3623
0
    pub fn into_key(self) -> &'a mut K {
3624
0
        unsafe { &mut self.elem.as_mut().0 }
3625
0
    }
3626
3627
    /// Gets a reference to the value in the entry.
3628
    ///
3629
    /// # Examples
3630
    ///
3631
    /// ```
3632
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3633
    ///
3634
    /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3635
    ///
3636
    /// match map.raw_entry_mut().from_key(&"a") {
3637
    ///     RawEntryMut::Vacant(_) => panic!(),
3638
    ///     RawEntryMut::Occupied(o) => assert_eq!(o.get(), &100),
3639
    /// }
3640
    /// ```
3641
    #[cfg_attr(feature = "inline-more", inline)]
3642
0
    pub fn get(&self) -> &V {
3643
0
        unsafe { &self.elem.as_ref().1 }
3644
0
    }
3645
3646
    /// Converts the OccupiedEntry into a mutable reference to the value in the entry
3647
    /// with a lifetime bound to the map itself.
3648
    ///
3649
    /// # Examples
3650
    ///
3651
    /// ```
3652
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3653
    ///
3654
    /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3655
    ///
3656
    /// let value: &mut u32;
3657
    ///
3658
    /// match map.raw_entry_mut().from_key(&"a") {
3659
    ///     RawEntryMut::Vacant(_) => panic!(),
3660
    ///     RawEntryMut::Occupied(o) => value = o.into_mut(),
3661
    /// }
3662
    /// *value += 900;
3663
    ///
3664
    /// assert_eq!(map[&"a"], 1000);
3665
    /// ```
3666
    #[cfg_attr(feature = "inline-more", inline)]
3667
0
    pub fn into_mut(self) -> &'a mut V {
3668
0
        unsafe { &mut self.elem.as_mut().1 }
3669
0
    }
3670
3671
    /// Gets a mutable reference to the value in the entry.
3672
    ///
3673
    /// # Examples
3674
    ///
3675
    /// ```
3676
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3677
    ///
3678
    /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3679
    ///
3680
    /// match map.raw_entry_mut().from_key(&"a") {
3681
    ///     RawEntryMut::Vacant(_) => panic!(),
3682
    ///     RawEntryMut::Occupied(mut o) => *o.get_mut() += 900,
3683
    /// }
3684
    ///
3685
    /// assert_eq!(map[&"a"], 1000);
3686
    /// ```
3687
    #[cfg_attr(feature = "inline-more", inline)]
3688
0
    pub fn get_mut(&mut self) -> &mut V {
3689
0
        unsafe { &mut self.elem.as_mut().1 }
3690
0
    }
3691
3692
    /// Gets a reference to the key and value in the entry.
3693
    ///
3694
    /// # Examples
3695
    ///
3696
    /// ```
3697
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3698
    ///
3699
    /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3700
    ///
3701
    /// match map.raw_entry_mut().from_key(&"a") {
3702
    ///     RawEntryMut::Vacant(_) => panic!(),
3703
    ///     RawEntryMut::Occupied(o) => assert_eq!(o.get_key_value(), (&"a", &100)),
3704
    /// }
3705
    /// ```
3706
    #[cfg_attr(feature = "inline-more", inline)]
3707
0
    pub fn get_key_value(&self) -> (&K, &V) {
3708
0
        unsafe {
3709
0
            let (key, value) = self.elem.as_ref();
3710
0
            (key, value)
3711
0
        }
3712
0
    }
3713
3714
    /// Gets a mutable reference to the key and value in the entry.
3715
    ///
3716
    /// # Examples
3717
    ///
3718
    /// ```
3719
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3720
    /// use std::rc::Rc;
3721
    ///
3722
    /// let key_one = Rc::new("a");
3723
    /// let key_two = Rc::new("a");
3724
    ///
3725
    /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
3726
    /// map.insert(key_one.clone(), 10);
3727
    ///
3728
    /// assert_eq!(map[&key_one], 10);
3729
    /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
3730
    ///
3731
    /// match map.raw_entry_mut().from_key(&key_one) {
3732
    ///     RawEntryMut::Vacant(_) => panic!(),
3733
    ///     RawEntryMut::Occupied(mut o) => {
3734
    ///         let (inside_key, inside_value) = o.get_key_value_mut();
3735
    ///         *inside_key = key_two.clone();
3736
    ///         *inside_value = 100;
3737
    ///     }
3738
    /// }
3739
    /// assert_eq!(map[&key_two], 100);
3740
    /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
3741
    /// ```
3742
    #[cfg_attr(feature = "inline-more", inline)]
3743
0
    pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
3744
0
        unsafe {
3745
0
            let &mut (ref mut key, ref mut value) = self.elem.as_mut();
3746
0
            (key, value)
3747
0
        }
3748
0
    }
3749
3750
    /// Converts the OccupiedEntry into a mutable reference to the key and value in the entry
3751
    /// with a lifetime bound to the map itself.
3752
    ///
3753
    /// # Examples
3754
    ///
3755
    /// ```
3756
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3757
    /// use std::rc::Rc;
3758
    ///
3759
    /// let key_one = Rc::new("a");
3760
    /// let key_two = Rc::new("a");
3761
    ///
3762
    /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
3763
    /// map.insert(key_one.clone(), 10);
3764
    ///
3765
    /// assert_eq!(map[&key_one], 10);
3766
    /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
3767
    ///
3768
    /// let inside_key: &mut Rc<&str>;
3769
    /// let inside_value: &mut u32;
3770
    /// match map.raw_entry_mut().from_key(&key_one) {
3771
    ///     RawEntryMut::Vacant(_) => panic!(),
3772
    ///     RawEntryMut::Occupied(o) => {
3773
    ///         let tuple = o.into_key_value();
3774
    ///         inside_key = tuple.0;
3775
    ///         inside_value = tuple.1;
3776
    ///     }
3777
    /// }
3778
    /// *inside_key = key_two.clone();
3779
    /// *inside_value = 100;
3780
    /// assert_eq!(map[&key_two], 100);
3781
    /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
3782
    /// ```
3783
    #[cfg_attr(feature = "inline-more", inline)]
3784
0
    pub fn into_key_value(self) -> (&'a mut K, &'a mut V) {
3785
0
        unsafe {
3786
0
            let &mut (ref mut key, ref mut value) = self.elem.as_mut();
3787
0
            (key, value)
3788
0
        }
3789
0
    }
3790
3791
    /// Sets the value of the entry, and returns the entry's old value.
3792
    ///
3793
    /// # Examples
3794
    ///
3795
    /// ```
3796
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3797
    ///
3798
    /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3799
    ///
3800
    /// match map.raw_entry_mut().from_key(&"a") {
3801
    ///     RawEntryMut::Vacant(_) => panic!(),
3802
    ///     RawEntryMut::Occupied(mut o) => assert_eq!(o.insert(1000), 100),
3803
    /// }
3804
    ///
3805
    /// assert_eq!(map[&"a"], 1000);
3806
    /// ```
3807
    #[cfg_attr(feature = "inline-more", inline)]
3808
0
    pub fn insert(&mut self, value: V) -> V {
3809
0
        mem::replace(self.get_mut(), value)
3810
0
    }
3811
3812
    /// Sets the value of the entry, and returns the entry's old value.
3813
    ///
3814
    /// # Examples
3815
    ///
3816
    /// ```
3817
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3818
    /// use std::rc::Rc;
3819
    ///
3820
    /// let key_one = Rc::new("a");
3821
    /// let key_two = Rc::new("a");
3822
    ///
3823
    /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
3824
    /// map.insert(key_one.clone(), 10);
3825
    ///
3826
    /// assert_eq!(map[&key_one], 10);
3827
    /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
3828
    ///
3829
    /// match map.raw_entry_mut().from_key(&key_one) {
3830
    ///     RawEntryMut::Vacant(_) => panic!(),
3831
    ///     RawEntryMut::Occupied(mut o) => {
3832
    ///         let old_key = o.insert_key(key_two.clone());
3833
    ///         assert!(Rc::ptr_eq(&old_key, &key_one));
3834
    ///     }
3835
    /// }
3836
    /// assert_eq!(map[&key_two], 10);
3837
    /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
3838
    /// ```
3839
    #[cfg_attr(feature = "inline-more", inline)]
3840
0
    pub fn insert_key(&mut self, key: K) -> K {
3841
0
        mem::replace(self.key_mut(), key)
3842
0
    }
3843
3844
    /// Takes the value out of the entry, and returns it.
3845
    ///
3846
    /// # Examples
3847
    ///
3848
    /// ```
3849
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3850
    ///
3851
    /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3852
    ///
3853
    /// match map.raw_entry_mut().from_key(&"a") {
3854
    ///     RawEntryMut::Vacant(_) => panic!(),
3855
    ///     RawEntryMut::Occupied(o) => assert_eq!(o.remove(), 100),
3856
    /// }
3857
    /// assert_eq!(map.get(&"a"), None);
3858
    /// ```
3859
    #[cfg_attr(feature = "inline-more", inline)]
3860
0
    pub fn remove(self) -> V {
3861
0
        self.remove_entry().1
3862
0
    }
3863
3864
    /// Take the ownership of the key and value from the map.
3865
    ///
3866
    /// # Examples
3867
    ///
3868
    /// ```
3869
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3870
    ///
3871
    /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3872
    ///
3873
    /// match map.raw_entry_mut().from_key(&"a") {
3874
    ///     RawEntryMut::Vacant(_) => panic!(),
3875
    ///     RawEntryMut::Occupied(o) => assert_eq!(o.remove_entry(), ("a", 100)),
3876
    /// }
3877
    /// assert_eq!(map.get(&"a"), None);
3878
    /// ```
3879
    #[cfg_attr(feature = "inline-more", inline)]
3880
0
    pub fn remove_entry(self) -> (K, V) {
3881
0
        unsafe { self.table.remove(self.elem).0 }
3882
0
    }
3883
3884
    /// Provides shared access to the key and owned access to the value of
3885
    /// the entry and allows to replace or remove it based on the
3886
    /// value of the returned option.
3887
    ///
3888
    /// # Examples
3889
    ///
3890
    /// ```
3891
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3892
    ///
3893
    /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3894
    ///
3895
    /// let raw_entry = match map.raw_entry_mut().from_key(&"a") {
3896
    ///     RawEntryMut::Vacant(_) => panic!(),
3897
    ///     RawEntryMut::Occupied(o) => o.replace_entry_with(|k, v| {
3898
    ///         assert_eq!(k, &"a");
3899
    ///         assert_eq!(v, 100);
3900
    ///         Some(v + 900)
3901
    ///     }),
3902
    /// };
3903
    /// let raw_entry = match raw_entry {
3904
    ///     RawEntryMut::Vacant(_) => panic!(),
3905
    ///     RawEntryMut::Occupied(o) => o.replace_entry_with(|k, v| {
3906
    ///         assert_eq!(k, &"a");
3907
    ///         assert_eq!(v, 1000);
3908
    ///         None
3909
    ///     }),
3910
    /// };
3911
    /// match raw_entry {
3912
    ///     RawEntryMut::Vacant(_) => { },
3913
    ///     RawEntryMut::Occupied(_) => panic!(),
3914
    /// };
3915
    /// assert_eq!(map.get(&"a"), None);
3916
    /// ```
3917
    #[cfg_attr(feature = "inline-more", inline)]
3918
0
    pub fn replace_entry_with<F>(self, f: F) -> RawEntryMut<'a, K, V, S, A>
3919
0
    where
3920
0
        F: FnOnce(&K, V) -> Option<V>,
3921
0
    {
3922
0
        unsafe {
3923
0
            let still_occupied = self
3924
0
                .table
3925
0
                .replace_bucket_with(self.elem.clone(), |(key, value)| {
3926
0
                    f(&key, value).map(|new_value| (key, new_value))
3927
0
                });
3928
0
3929
0
            if still_occupied {
3930
0
                RawEntryMut::Occupied(self)
3931
            } else {
3932
0
                RawEntryMut::Vacant(RawVacantEntryMut {
3933
0
                    table: self.table,
3934
0
                    hash_builder: self.hash_builder,
3935
0
                })
3936
            }
3937
        }
3938
0
    }
3939
}
3940
3941
impl<'a, K, V, S, A: Allocator> RawVacantEntryMut<'a, K, V, S, A> {
3942
    /// Sets the value of the entry with the VacantEntry's key,
3943
    /// and returns a mutable reference to it.
3944
    ///
3945
    /// # Examples
3946
    ///
3947
    /// ```
3948
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3949
    ///
3950
    /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3951
    ///
3952
    /// match map.raw_entry_mut().from_key(&"c") {
3953
    ///     RawEntryMut::Occupied(_) => panic!(),
3954
    ///     RawEntryMut::Vacant(v) => assert_eq!(v.insert("c", 300), (&mut "c", &mut 300)),
3955
    /// }
3956
    ///
3957
    /// assert_eq!(map[&"c"], 300);
3958
    /// ```
3959
    #[cfg_attr(feature = "inline-more", inline)]
3960
0
    pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
3961
0
    where
3962
0
        K: Hash,
3963
0
        S: BuildHasher,
3964
0
    {
3965
0
        let hash = make_hash::<K, S>(self.hash_builder, &key);
3966
0
        self.insert_hashed_nocheck(hash, key, value)
3967
0
    }
3968
3969
    /// Sets the value of the entry with the VacantEntry's key,
3970
    /// and returns a mutable reference to it.
3971
    ///
3972
    /// # Examples
3973
    ///
3974
    /// ```
3975
    /// use core::hash::{BuildHasher, Hash};
3976
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
3977
    ///
3978
    /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3979
    ///     use core::hash::Hasher;
3980
    ///     let mut state = hash_builder.build_hasher();
3981
    ///     key.hash(&mut state);
3982
    ///     state.finish()
3983
    /// }
3984
    ///
3985
    /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into();
3986
    /// let key = "c";
3987
    /// let hash = compute_hash(map.hasher(), &key);
3988
    ///
3989
    /// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &key) {
3990
    ///     RawEntryMut::Occupied(_) => panic!(),
3991
    ///     RawEntryMut::Vacant(v) => assert_eq!(
3992
    ///         v.insert_hashed_nocheck(hash, key, 300),
3993
    ///         (&mut "c", &mut 300)
3994
    ///     ),
3995
    /// }
3996
    ///
3997
    /// assert_eq!(map[&"c"], 300);
3998
    /// ```
3999
    #[cfg_attr(feature = "inline-more", inline)]
4000
    #[allow(clippy::shadow_unrelated)]
4001
0
    pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V)
4002
0
    where
4003
0
        K: Hash,
4004
0
        S: BuildHasher,
4005
0
    {
4006
0
        let &mut (ref mut k, ref mut v) = self.table.insert_entry(
4007
0
            hash,
4008
0
            (key, value),
4009
0
            make_hasher::<_, V, S>(self.hash_builder),
4010
0
        );
4011
0
        (k, v)
4012
0
    }
4013
4014
    /// Set the value of an entry with a custom hasher function.
4015
    ///
4016
    /// # Examples
4017
    ///
4018
    /// ```
4019
    /// use core::hash::{BuildHasher, Hash};
4020
    /// use hashbrown::hash_map::{HashMap, RawEntryMut};
4021
    ///
4022
    /// fn make_hasher<K, S>(hash_builder: &S) -> impl Fn(&K) -> u64 + '_
4023
    /// where
4024
    ///     K: Hash + ?Sized,
4025
    ///     S: BuildHasher,
4026
    /// {
4027
    ///     move |key: &K| {
4028
    ///         use core::hash::Hasher;
4029
    ///         let mut state = hash_builder.build_hasher();
4030
    ///         key.hash(&mut state);
4031
    ///         state.finish()
4032
    ///     }
4033
    /// }
4034
    ///
4035
    /// let mut map: HashMap<&str, u32> = HashMap::new();
4036
    /// let key = "a";
4037
    /// let hash_builder = map.hasher().clone();
4038
    /// let hash = make_hasher(&hash_builder)(&key);
4039
    ///
4040
    /// match map.raw_entry_mut().from_hash(hash, |q| q == &key) {
4041
    ///     RawEntryMut::Occupied(_) => panic!(),
4042
    ///     RawEntryMut::Vacant(v) => assert_eq!(
4043
    ///         v.insert_with_hasher(hash, key, 100, make_hasher(&hash_builder)),
4044
    ///         (&mut "a", &mut 100)
4045
    ///     ),
4046
    /// }
4047
    /// map.extend([("b", 200), ("c", 300), ("d", 400), ("e", 500), ("f", 600)]);
4048
    /// assert_eq!(map[&"a"], 100);
4049
    /// ```
4050
    #[cfg_attr(feature = "inline-more", inline)]
4051
0
    pub fn insert_with_hasher<H>(
4052
0
        self,
4053
0
        hash: u64,
4054
0
        key: K,
4055
0
        value: V,
4056
0
        hasher: H,
4057
0
    ) -> (&'a mut K, &'a mut V)
4058
0
    where
4059
0
        H: Fn(&K) -> u64,
4060
0
    {
4061
0
        let &mut (ref mut k, ref mut v) = self
4062
0
            .table
4063
0
            .insert_entry(hash, (key, value), |x| hasher(&x.0));
4064
0
        (k, v)
4065
0
    }
4066
4067
    #[cfg_attr(feature = "inline-more", inline)]
4068
0
    fn insert_entry(self, key: K, value: V) -> RawOccupiedEntryMut<'a, K, V, S, A>
4069
0
    where
4070
0
        K: Hash,
4071
0
        S: BuildHasher,
4072
0
    {
4073
0
        let hash = make_hash::<K, S>(self.hash_builder, &key);
4074
0
        let elem = self.table.insert(
4075
0
            hash,
4076
0
            (key, value),
4077
0
            make_hasher::<_, V, S>(self.hash_builder),
4078
0
        );
4079
0
        RawOccupiedEntryMut {
4080
0
            elem,
4081
0
            table: self.table,
4082
0
            hash_builder: self.hash_builder,
4083
0
        }
4084
0
    }
4085
}
4086
4087
impl<K, V, S, A: Allocator> Debug for RawEntryBuilderMut<'_, K, V, S, A> {
4088
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4089
0
        f.debug_struct("RawEntryBuilder").finish()
4090
0
    }
4091
}
4092
4093
impl<K: Debug, V: Debug, S, A: Allocator> Debug for RawEntryMut<'_, K, V, S, A> {
4094
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4095
0
        match *self {
4096
0
            RawEntryMut::Vacant(ref v) => f.debug_tuple("RawEntry").field(v).finish(),
4097
0
            RawEntryMut::Occupied(ref o) => f.debug_tuple("RawEntry").field(o).finish(),
4098
        }
4099
0
    }
4100
}
4101
4102
impl<K: Debug, V: Debug, S, A: Allocator> Debug for RawOccupiedEntryMut<'_, K, V, S, A> {
4103
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4104
0
        f.debug_struct("RawOccupiedEntryMut")
4105
0
            .field("key", self.key())
4106
0
            .field("value", self.get())
4107
0
            .finish()
4108
0
    }
4109
}
4110
4111
impl<K, V, S, A: Allocator> Debug for RawVacantEntryMut<'_, K, V, S, A> {
4112
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4113
0
        f.debug_struct("RawVacantEntryMut").finish()
4114
0
    }
4115
}
4116
4117
impl<K, V, S, A: Allocator> Debug for RawEntryBuilder<'_, K, V, S, A> {
4118
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4119
0
        f.debug_struct("RawEntryBuilder").finish()
4120
0
    }
4121
}
4122
4123
/// A view into a single entry in a map, which may either be vacant or occupied.
4124
///
4125
/// This `enum` is constructed from the [`entry`] method on [`HashMap`].
4126
///
4127
/// [`HashMap`]: struct.HashMap.html
4128
/// [`entry`]: struct.HashMap.html#method.entry
4129
///
4130
/// # Examples
4131
///
4132
/// ```
4133
/// use hashbrown::hash_map::{Entry, HashMap, OccupiedEntry};
4134
///
4135
/// let mut map = HashMap::new();
4136
/// map.extend([("a", 10), ("b", 20), ("c", 30)]);
4137
/// assert_eq!(map.len(), 3);
4138
///
4139
/// // Existing key (insert)
4140
/// let entry: Entry<_, _, _> = map.entry("a");
4141
/// let _raw_o: OccupiedEntry<_, _, _> = entry.insert(1);
4142
/// assert_eq!(map.len(), 3);
4143
/// // Nonexistent key (insert)
4144
/// map.entry("d").insert(4);
4145
///
4146
/// // Existing key (or_insert)
4147
/// let v = map.entry("b").or_insert(2);
4148
/// assert_eq!(std::mem::replace(v, 2), 20);
4149
/// // Nonexistent key (or_insert)
4150
/// map.entry("e").or_insert(5);
4151
///
4152
/// // Existing key (or_insert_with)
4153
/// let v = map.entry("c").or_insert_with(|| 3);
4154
/// assert_eq!(std::mem::replace(v, 3), 30);
4155
/// // Nonexistent key (or_insert_with)
4156
/// map.entry("f").or_insert_with(|| 6);
4157
///
4158
/// println!("Our HashMap: {:?}", map);
4159
///
4160
/// let mut vec: Vec<_> = map.iter().map(|(&k, &v)| (k, v)).collect();
4161
/// // The `Iter` iterator produces items in arbitrary order, so the
4162
/// // items must be sorted to test them against a sorted array.
4163
/// vec.sort_unstable();
4164
/// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3), ("d", 4), ("e", 5), ("f", 6)]);
4165
/// ```
4166
pub enum Entry<'a, K, V, S, A = Global>
4167
where
4168
    A: Allocator,
4169
{
4170
    /// An occupied entry.
4171
    ///
4172
    /// # Examples
4173
    ///
4174
    /// ```
4175
    /// use hashbrown::hash_map::{Entry, HashMap};
4176
    /// let mut map: HashMap<_, _> = [("a", 100), ("b", 200)].into();
4177
    ///
4178
    /// match map.entry("a") {
4179
    ///     Entry::Vacant(_) => unreachable!(),
4180
    ///     Entry::Occupied(_) => { }
4181
    /// }
4182
    /// ```
4183
    Occupied(OccupiedEntry<'a, K, V, S, A>),
4184
4185
    /// A vacant entry.
4186
    ///
4187
    /// # Examples
4188
    ///
4189
    /// ```
4190
    /// use hashbrown::hash_map::{Entry, HashMap};
4191
    /// let mut map: HashMap<&str, i32> = HashMap::new();
4192
    ///
4193
    /// match map.entry("a") {
4194
    ///     Entry::Occupied(_) => unreachable!(),
4195
    ///     Entry::Vacant(_) => { }
4196
    /// }
4197
    /// ```
4198
    Vacant(VacantEntry<'a, K, V, S, A>),
4199
}
4200
4201
impl<K: Debug, V: Debug, S, A: Allocator> Debug for Entry<'_, K, V, S, A> {
4202
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4203
0
        match *self {
4204
0
            Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
4205
0
            Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
4206
        }
4207
0
    }
4208
}
4209
4210
/// A view into an occupied entry in a `HashMap`.
4211
/// It is part of the [`Entry`] enum.
4212
///
4213
/// [`Entry`]: enum.Entry.html
4214
///
4215
/// # Examples
4216
///
4217
/// ```
4218
/// use hashbrown::hash_map::{Entry, HashMap, OccupiedEntry};
4219
///
4220
/// let mut map = HashMap::new();
4221
/// map.extend([("a", 10), ("b", 20), ("c", 30)]);
4222
///
4223
/// let _entry_o: OccupiedEntry<_, _, _> = map.entry("a").insert(100);
4224
/// assert_eq!(map.len(), 3);
4225
///
4226
/// // Existing key (insert and update)
4227
/// match map.entry("a") {
4228
///     Entry::Vacant(_) => unreachable!(),
4229
///     Entry::Occupied(mut view) => {
4230
///         assert_eq!(view.get(), &100);
4231
///         let v = view.get_mut();
4232
///         *v *= 10;
4233
///         assert_eq!(view.insert(1111), 1000);
4234
///     }
4235
/// }
4236
///
4237
/// assert_eq!(map[&"a"], 1111);
4238
/// assert_eq!(map.len(), 3);
4239
///
4240
/// // Existing key (take)
4241
/// match map.entry("c") {
4242
///     Entry::Vacant(_) => unreachable!(),
4243
///     Entry::Occupied(view) => {
4244
///         assert_eq!(view.remove_entry(), ("c", 30));
4245
///     }
4246
/// }
4247
/// assert_eq!(map.get(&"c"), None);
4248
/// assert_eq!(map.len(), 2);
4249
/// ```
4250
pub struct OccupiedEntry<'a, K, V, S = DefaultHashBuilder, A: Allocator = Global> {
4251
    hash: u64,
4252
    key: Option<K>,
4253
    elem: Bucket<(K, V)>,
4254
    table: &'a mut HashMap<K, V, S, A>,
4255
}
4256
4257
unsafe impl<K, V, S, A> Send for OccupiedEntry<'_, K, V, S, A>
4258
where
4259
    K: Send,
4260
    V: Send,
4261
    S: Send,
4262
    A: Send + Allocator,
4263
{
4264
}
4265
unsafe impl<K, V, S, A> Sync for OccupiedEntry<'_, K, V, S, A>
4266
where
4267
    K: Sync,
4268
    V: Sync,
4269
    S: Sync,
4270
    A: Sync + Allocator,
4271
{
4272
}
4273
4274
impl<K: Debug, V: Debug, S, A: Allocator> Debug for OccupiedEntry<'_, K, V, S, A> {
4275
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4276
0
        f.debug_struct("OccupiedEntry")
4277
0
            .field("key", self.key())
4278
0
            .field("value", self.get())
4279
0
            .finish()
4280
0
    }
4281
}
4282
4283
/// A view into a vacant entry in a `HashMap`.
4284
/// It is part of the [`Entry`] enum.
4285
///
4286
/// [`Entry`]: enum.Entry.html
4287
///
4288
/// # Examples
4289
///
4290
/// ```
4291
/// use hashbrown::hash_map::{Entry, HashMap, VacantEntry};
4292
///
4293
/// let mut map = HashMap::<&str, i32>::new();
4294
///
4295
/// let entry_v: VacantEntry<_, _, _> = match map.entry("a") {
4296
///     Entry::Vacant(view) => view,
4297
///     Entry::Occupied(_) => unreachable!(),
4298
/// };
4299
/// entry_v.insert(10);
4300
/// assert!(map[&"a"] == 10 && map.len() == 1);
4301
///
4302
/// // Nonexistent key (insert and update)
4303
/// match map.entry("b") {
4304
///     Entry::Occupied(_) => unreachable!(),
4305
///     Entry::Vacant(view) => {
4306
///         let value = view.insert(2);
4307
///         assert_eq!(*value, 2);
4308
///         *value = 20;
4309
///     }
4310
/// }
4311
/// assert!(map[&"b"] == 20 && map.len() == 2);
4312
/// ```
4313
pub struct VacantEntry<'a, K, V, S = DefaultHashBuilder, A: Allocator = Global> {
4314
    hash: u64,
4315
    key: K,
4316
    table: &'a mut HashMap<K, V, S, A>,
4317
}
4318
4319
impl<K: Debug, V, S, A: Allocator> Debug for VacantEntry<'_, K, V, S, A> {
4320
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4321
0
        f.debug_tuple("VacantEntry").field(self.key()).finish()
4322
0
    }
4323
}
4324
4325
/// A view into a single entry in a map, which may either be vacant or occupied,
4326
/// with any borrowed form of the map's key type.
4327
///
4328
///
4329
/// This `enum` is constructed from the [`entry_ref`] method on [`HashMap`].
4330
///
4331
/// [`Hash`] and [`Eq`] on the borrowed form of the map's key type *must* match those
4332
/// for the key type. It also require that key may be constructed from the borrowed
4333
/// form through the [`From`] trait.
4334
///
4335
/// [`HashMap`]: struct.HashMap.html
4336
/// [`entry_ref`]: struct.HashMap.html#method.entry_ref
4337
/// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
4338
/// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
4339
/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
4340
///
4341
/// # Examples
4342
///
4343
/// ```
4344
/// use hashbrown::hash_map::{EntryRef, HashMap, OccupiedEntryRef};
4345
///
4346
/// let mut map = HashMap::new();
4347
/// map.extend([("a".to_owned(), 10), ("b".into(), 20), ("c".into(), 30)]);
4348
/// assert_eq!(map.len(), 3);
4349
///
4350
/// // Existing key (insert)
4351
/// let key = String::from("a");
4352
/// let entry: EntryRef<_, _, _, _> = map.entry_ref(&key);
4353
/// let _raw_o: OccupiedEntryRef<_, _, _, _> = entry.insert(1);
4354
/// assert_eq!(map.len(), 3);
4355
/// // Nonexistent key (insert)
4356
/// map.entry_ref("d").insert(4);
4357
///
4358
/// // Existing key (or_insert)
4359
/// let v = map.entry_ref("b").or_insert(2);
4360
/// assert_eq!(std::mem::replace(v, 2), 20);
4361
/// // Nonexistent key (or_insert)
4362
/// map.entry_ref("e").or_insert(5);
4363
///
4364
/// // Existing key (or_insert_with)
4365
/// let v = map.entry_ref("c").or_insert_with(|| 3);
4366
/// assert_eq!(std::mem::replace(v, 3), 30);
4367
/// // Nonexistent key (or_insert_with)
4368
/// map.entry_ref("f").or_insert_with(|| 6);
4369
///
4370
/// println!("Our HashMap: {:?}", map);
4371
///
4372
/// for (key, value) in ["a", "b", "c", "d", "e", "f"].into_iter().zip(1..=6) {
4373
///     assert_eq!(map[key], value)
4374
/// }
4375
/// assert_eq!(map.len(), 6);
4376
/// ```
4377
pub enum EntryRef<'a, 'b, K, Q: ?Sized, V, S, A = Global>
4378
where
4379
    A: Allocator,
4380
{
4381
    /// An occupied entry.
4382
    ///
4383
    /// # Examples
4384
    ///
4385
    /// ```
4386
    /// use hashbrown::hash_map::{EntryRef, HashMap};
4387
    /// let mut map: HashMap<_, _> = [("a".to_owned(), 100), ("b".into(), 200)].into();
4388
    ///
4389
    /// match map.entry_ref("a") {
4390
    ///     EntryRef::Vacant(_) => unreachable!(),
4391
    ///     EntryRef::Occupied(_) => { }
4392
    /// }
4393
    /// ```
4394
    Occupied(OccupiedEntryRef<'a, 'b, K, Q, V, S, A>),
4395
4396
    /// A vacant entry.
4397
    ///
4398
    /// # Examples
4399
    ///
4400
    /// ```
4401
    /// use hashbrown::hash_map::{EntryRef, HashMap};
4402
    /// let mut map: HashMap<String, i32> = HashMap::new();
4403
    ///
4404
    /// match map.entry_ref("a") {
4405
    ///     EntryRef::Occupied(_) => unreachable!(),
4406
    ///     EntryRef::Vacant(_) => { }
4407
    /// }
4408
    /// ```
4409
    Vacant(VacantEntryRef<'a, 'b, K, Q, V, S, A>),
4410
}
4411
4412
impl<K: Borrow<Q>, Q: ?Sized + Debug, V: Debug, S, A: Allocator> Debug
4413
    for EntryRef<'_, '_, K, Q, V, S, A>
4414
{
4415
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4416
0
        match *self {
4417
0
            EntryRef::Vacant(ref v) => f.debug_tuple("EntryRef").field(v).finish(),
4418
0
            EntryRef::Occupied(ref o) => f.debug_tuple("EntryRef").field(o).finish(),
4419
        }
4420
0
    }
4421
}
4422
4423
enum KeyOrRef<'a, K, Q: ?Sized> {
4424
    Borrowed(&'a Q),
4425
    Owned(K),
4426
}
4427
4428
impl<'a, K, Q: ?Sized> KeyOrRef<'a, K, Q> {
4429
0
    fn into_owned(self) -> K
4430
0
    where
4431
0
        K: From<&'a Q>,
4432
0
    {
4433
0
        match self {
4434
0
            Self::Borrowed(borrowed) => borrowed.into(),
4435
0
            Self::Owned(owned) => owned,
4436
        }
4437
0
    }
4438
}
4439
4440
impl<'a, K: Borrow<Q>, Q: ?Sized> AsRef<Q> for KeyOrRef<'a, K, Q> {
4441
0
    fn as_ref(&self) -> &Q {
4442
0
        match self {
4443
0
            Self::Borrowed(borrowed) => borrowed,
4444
0
            Self::Owned(owned) => owned.borrow(),
4445
        }
4446
0
    }
4447
}
4448
4449
/// A view into an occupied entry in a `HashMap`.
4450
/// It is part of the [`EntryRef`] enum.
4451
///
4452
/// [`EntryRef`]: enum.EntryRef.html
4453
///
4454
/// # Examples
4455
///
4456
/// ```
4457
/// use hashbrown::hash_map::{EntryRef, HashMap, OccupiedEntryRef};
4458
///
4459
/// let mut map = HashMap::new();
4460
/// map.extend([("a".to_owned(), 10), ("b".into(), 20), ("c".into(), 30)]);
4461
///
4462
/// let key = String::from("a");
4463
/// let _entry_o: OccupiedEntryRef<_, _, _, _> = map.entry_ref(&key).insert(100);
4464
/// assert_eq!(map.len(), 3);
4465
///
4466
/// // Existing key (insert and update)
4467
/// match map.entry_ref("a") {
4468
///     EntryRef::Vacant(_) => unreachable!(),
4469
///     EntryRef::Occupied(mut view) => {
4470
///         assert_eq!(view.get(), &100);
4471
///         let v = view.get_mut();
4472
///         *v *= 10;
4473
///         assert_eq!(view.insert(1111), 1000);
4474
///     }
4475
/// }
4476
///
4477
/// assert_eq!(map["a"], 1111);
4478
/// assert_eq!(map.len(), 3);
4479
///
4480
/// // Existing key (take)
4481
/// match map.entry_ref("c") {
4482
///     EntryRef::Vacant(_) => unreachable!(),
4483
///     EntryRef::Occupied(view) => {
4484
///         assert_eq!(view.remove_entry(), ("c".to_owned(), 30));
4485
///     }
4486
/// }
4487
/// assert_eq!(map.get("c"), None);
4488
/// assert_eq!(map.len(), 2);
4489
/// ```
4490
pub struct OccupiedEntryRef<'a, 'b, K, Q: ?Sized, V, S, A: Allocator = Global> {
4491
    hash: u64,
4492
    key: Option<KeyOrRef<'b, K, Q>>,
4493
    elem: Bucket<(K, V)>,
4494
    table: &'a mut HashMap<K, V, S, A>,
4495
}
4496
4497
unsafe impl<'a, 'b, K, Q, V, S, A> Send for OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
4498
where
4499
    K: Send,
4500
    Q: Sync + ?Sized,
4501
    V: Send,
4502
    S: Send,
4503
    A: Send + Allocator,
4504
{
4505
}
4506
unsafe impl<'a, 'b, K, Q, V, S, A> Sync for OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
4507
where
4508
    K: Sync,
4509
    Q: Sync + ?Sized,
4510
    V: Sync,
4511
    S: Sync,
4512
    A: Sync + Allocator,
4513
{
4514
}
4515
4516
impl<K: Borrow<Q>, Q: ?Sized + Debug, V: Debug, S, A: Allocator> Debug
4517
    for OccupiedEntryRef<'_, '_, K, Q, V, S, A>
4518
{
4519
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4520
0
        f.debug_struct("OccupiedEntryRef")
4521
0
            .field("key", &self.key().borrow())
4522
0
            .field("value", &self.get())
4523
0
            .finish()
4524
0
    }
4525
}
4526
4527
/// A view into a vacant entry in a `HashMap`.
4528
/// It is part of the [`EntryRef`] enum.
4529
///
4530
/// [`EntryRef`]: enum.EntryRef.html
4531
///
4532
/// # Examples
4533
///
4534
/// ```
4535
/// use hashbrown::hash_map::{EntryRef, HashMap, VacantEntryRef};
4536
///
4537
/// let mut map = HashMap::<String, i32>::new();
4538
///
4539
/// let entry_v: VacantEntryRef<_, _, _, _> = match map.entry_ref("a") {
4540
///     EntryRef::Vacant(view) => view,
4541
///     EntryRef::Occupied(_) => unreachable!(),
4542
/// };
4543
/// entry_v.insert(10);
4544
/// assert!(map["a"] == 10 && map.len() == 1);
4545
///
4546
/// // Nonexistent key (insert and update)
4547
/// match map.entry_ref("b") {
4548
///     EntryRef::Occupied(_) => unreachable!(),
4549
///     EntryRef::Vacant(view) => {
4550
///         let value = view.insert(2);
4551
///         assert_eq!(*value, 2);
4552
///         *value = 20;
4553
///     }
4554
/// }
4555
/// assert!(map["b"] == 20 && map.len() == 2);
4556
/// ```
4557
pub struct VacantEntryRef<'a, 'b, K, Q: ?Sized, V, S, A: Allocator = Global> {
4558
    hash: u64,
4559
    key: KeyOrRef<'b, K, Q>,
4560
    table: &'a mut HashMap<K, V, S, A>,
4561
}
4562
4563
impl<K: Borrow<Q>, Q: ?Sized + Debug, V, S, A: Allocator> Debug
4564
    for VacantEntryRef<'_, '_, K, Q, V, S, A>
4565
{
4566
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4567
0
        f.debug_tuple("VacantEntryRef").field(&self.key()).finish()
4568
0
    }
4569
}
4570
4571
/// The error returned by [`try_insert`](HashMap::try_insert) when the key already exists.
4572
///
4573
/// Contains the occupied entry, and the value that was not inserted.
4574
///
4575
/// # Examples
4576
///
4577
/// ```
4578
/// use hashbrown::hash_map::{HashMap, OccupiedError};
4579
///
4580
/// let mut map: HashMap<_, _> = [("a", 10), ("b", 20)].into();
4581
///
4582
/// // try_insert method returns mutable reference to the value if keys are vacant,
4583
/// // but if the map did have key present, nothing is updated, and the provided
4584
/// // value is returned inside `Err(_)` variant
4585
/// match map.try_insert("a", 100) {
4586
///     Err(OccupiedError { mut entry, value }) => {
4587
///         assert_eq!(entry.key(), &"a");
4588
///         assert_eq!(value, 100);
4589
///         assert_eq!(entry.insert(100), 10)
4590
///     }
4591
///     _ => unreachable!(),
4592
/// }
4593
/// assert_eq!(map[&"a"], 100);
4594
/// ```
4595
pub struct OccupiedError<'a, K, V, S, A: Allocator = Global> {
4596
    /// The entry in the map that was already occupied.
4597
    pub entry: OccupiedEntry<'a, K, V, S, A>,
4598
    /// The value which was not inserted, because the entry was already occupied.
4599
    pub value: V,
4600
}
4601
4602
impl<K: Debug, V: Debug, S, A: Allocator> Debug for OccupiedError<'_, K, V, S, A> {
4603
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4604
0
        f.debug_struct("OccupiedError")
4605
0
            .field("key", self.entry.key())
4606
0
            .field("old_value", self.entry.get())
4607
0
            .field("new_value", &self.value)
4608
0
            .finish()
4609
0
    }
4610
}
4611
4612
impl<'a, K: Debug, V: Debug, S, A: Allocator> fmt::Display for OccupiedError<'a, K, V, S, A> {
4613
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4614
0
        write!(
4615
0
            f,
4616
0
            "failed to insert {:?}, key {:?} already exists with value {:?}",
4617
0
            self.value,
4618
0
            self.entry.key(),
4619
0
            self.entry.get(),
4620
0
        )
4621
0
    }
4622
}
4623
4624
impl<'a, K, V, S, A: Allocator> IntoIterator for &'a HashMap<K, V, S, A> {
4625
    type Item = (&'a K, &'a V);
4626
    type IntoIter = Iter<'a, K, V>;
4627
4628
    /// Creates an iterator over the entries of a `HashMap` in arbitrary order.
4629
    /// The iterator element type is `(&'a K, &'a V)`.
4630
    ///
4631
    /// Return the same `Iter` struct as by the [`iter`] method on [`HashMap`].
4632
    ///
4633
    /// [`iter`]: struct.HashMap.html#method.iter
4634
    /// [`HashMap`]: struct.HashMap.html
4635
    ///
4636
    /// # Examples
4637
    ///
4638
    /// ```
4639
    /// use hashbrown::HashMap;
4640
    /// let map_one: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].into();
4641
    /// let mut map_two = HashMap::new();
4642
    ///
4643
    /// for (key, value) in &map_one {
4644
    ///     println!("Key: {}, Value: {}", key, value);
4645
    ///     map_two.insert_unique_unchecked(*key, *value);
4646
    /// }
4647
    ///
4648
    /// assert_eq!(map_one, map_two);
4649
    /// ```
4650
    #[cfg_attr(feature = "inline-more", inline)]
4651
0
    fn into_iter(self) -> Iter<'a, K, V> {
4652
0
        self.iter()
4653
0
    }
4654
}
4655
4656
impl<'a, K, V, S, A: Allocator> IntoIterator for &'a mut HashMap<K, V, S, A> {
4657
    type Item = (&'a K, &'a mut V);
4658
    type IntoIter = IterMut<'a, K, V>;
4659
4660
    /// Creates an iterator over the entries of a `HashMap` in arbitrary order
4661
    /// with mutable references to the values. The iterator element type is
4662
    /// `(&'a K, &'a mut V)`.
4663
    ///
4664
    /// Return the same `IterMut` struct as by the [`iter_mut`] method on
4665
    /// [`HashMap`].
4666
    ///
4667
    /// [`iter_mut`]: struct.HashMap.html#method.iter_mut
4668
    /// [`HashMap`]: struct.HashMap.html
4669
    ///
4670
    /// # Examples
4671
    ///
4672
    /// ```
4673
    /// use hashbrown::HashMap;
4674
    /// let mut map: HashMap<_, _> = [("a", 1), ("b", 2), ("c", 3)].into();
4675
    ///
4676
    /// for (key, value) in &mut map {
4677
    ///     println!("Key: {}, Value: {}", key, value);
4678
    ///     *value *= 2;
4679
    /// }
4680
    ///
4681
    /// let mut vec = map.iter().collect::<Vec<_>>();
4682
    /// // The `Iter` iterator produces items in arbitrary order, so the
4683
    /// // items must be sorted to test them against a sorted array.
4684
    /// vec.sort_unstable();
4685
    /// assert_eq!(vec, [(&"a", &2), (&"b", &4), (&"c", &6)]);
4686
    /// ```
4687
    #[cfg_attr(feature = "inline-more", inline)]
4688
0
    fn into_iter(self) -> IterMut<'a, K, V> {
4689
0
        self.iter_mut()
4690
0
    }
4691
}
4692
4693
impl<K, V, S, A: Allocator> IntoIterator for HashMap<K, V, S, A> {
4694
    type Item = (K, V);
4695
    type IntoIter = IntoIter<K, V, A>;
4696
4697
    /// Creates a consuming iterator, that is, one that moves each key-value
4698
    /// pair out of the map in arbitrary order. The map cannot be used after
4699
    /// calling this.
4700
    ///
4701
    /// # Examples
4702
    ///
4703
    /// ```
4704
    /// use hashbrown::HashMap;
4705
    ///
4706
    /// let map: HashMap<_, _> = [("a", 1), ("b", 2), ("c", 3)].into();
4707
    ///
4708
    /// // Not possible with .iter()
4709
    /// let mut vec: Vec<(&str, i32)> = map.into_iter().collect();
4710
    /// // The `IntoIter` iterator produces items in arbitrary order, so
4711
    /// // the items must be sorted to test them against a sorted array.
4712
    /// vec.sort_unstable();
4713
    /// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]);
4714
    /// ```
4715
    #[cfg_attr(feature = "inline-more", inline)]
4716
0
    fn into_iter(self) -> IntoIter<K, V, A> {
4717
0
        IntoIter {
4718
0
            inner: self.table.into_iter(),
4719
0
        }
4720
0
    }
4721
}
4722
4723
impl<'a, K, V> Iterator for Iter<'a, K, V> {
4724
    type Item = (&'a K, &'a V);
4725
4726
    #[cfg_attr(feature = "inline-more", inline)]
4727
0
    fn next(&mut self) -> Option<(&'a K, &'a V)> {
4728
0
        // Avoid `Option::map` because it bloats LLVM IR.
4729
0
        match self.inner.next() {
4730
0
            Some(x) => unsafe {
4731
0
                let r = x.as_ref();
4732
0
                Some((&r.0, &r.1))
4733
            },
4734
0
            None => None,
4735
        }
4736
0
    }
4737
    #[cfg_attr(feature = "inline-more", inline)]
4738
0
    fn size_hint(&self) -> (usize, Option<usize>) {
4739
0
        self.inner.size_hint()
4740
0
    }
4741
    #[cfg_attr(feature = "inline-more", inline)]
4742
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
4743
0
    where
4744
0
        Self: Sized,
4745
0
        F: FnMut(B, Self::Item) -> B,
4746
0
    {
4747
0
        self.inner.fold(init, |acc, x| unsafe {
4748
0
            let (k, v) = x.as_ref();
4749
0
            f(acc, (k, v))
4750
0
        })
4751
0
    }
4752
}
4753
impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
4754
    #[cfg_attr(feature = "inline-more", inline)]
4755
0
    fn len(&self) -> usize {
4756
0
        self.inner.len()
4757
0
    }
4758
}
4759
4760
impl<K, V> FusedIterator for Iter<'_, K, V> {}
4761
4762
impl<'a, K, V> Iterator for IterMut<'a, K, V> {
4763
    type Item = (&'a K, &'a mut V);
4764
4765
    #[cfg_attr(feature = "inline-more", inline)]
4766
0
    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
4767
0
        // Avoid `Option::map` because it bloats LLVM IR.
4768
0
        match self.inner.next() {
4769
0
            Some(x) => unsafe {
4770
0
                let r = x.as_mut();
4771
0
                Some((&r.0, &mut r.1))
4772
            },
4773
0
            None => None,
4774
        }
4775
0
    }
4776
    #[cfg_attr(feature = "inline-more", inline)]
4777
0
    fn size_hint(&self) -> (usize, Option<usize>) {
4778
0
        self.inner.size_hint()
4779
0
    }
4780
    #[cfg_attr(feature = "inline-more", inline)]
4781
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
4782
0
    where
4783
0
        Self: Sized,
4784
0
        F: FnMut(B, Self::Item) -> B,
4785
0
    {
4786
0
        self.inner.fold(init, |acc, x| unsafe {
4787
0
            let (k, v) = x.as_mut();
4788
0
            f(acc, (k, v))
4789
0
        })
4790
0
    }
4791
}
4792
impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
4793
    #[cfg_attr(feature = "inline-more", inline)]
4794
0
    fn len(&self) -> usize {
4795
0
        self.inner.len()
4796
0
    }
4797
}
4798
impl<K, V> FusedIterator for IterMut<'_, K, V> {}
4799
4800
impl<K, V> fmt::Debug for IterMut<'_, K, V>
4801
where
4802
    K: fmt::Debug,
4803
    V: fmt::Debug,
4804
{
4805
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4806
0
        f.debug_list().entries(self.iter()).finish()
4807
0
    }
4808
}
4809
4810
impl<K, V, A: Allocator> Iterator for IntoIter<K, V, A> {
4811
    type Item = (K, V);
4812
4813
    #[cfg_attr(feature = "inline-more", inline)]
4814
0
    fn next(&mut self) -> Option<(K, V)> {
4815
0
        self.inner.next()
4816
0
    }
4817
    #[cfg_attr(feature = "inline-more", inline)]
4818
0
    fn size_hint(&self) -> (usize, Option<usize>) {
4819
0
        self.inner.size_hint()
4820
0
    }
4821
    #[cfg_attr(feature = "inline-more", inline)]
4822
0
    fn fold<B, F>(self, init: B, f: F) -> B
4823
0
    where
4824
0
        Self: Sized,
4825
0
        F: FnMut(B, Self::Item) -> B,
4826
0
    {
4827
0
        self.inner.fold(init, f)
4828
0
    }
4829
}
4830
impl<K, V, A: Allocator> ExactSizeIterator for IntoIter<K, V, A> {
4831
    #[cfg_attr(feature = "inline-more", inline)]
4832
0
    fn len(&self) -> usize {
4833
0
        self.inner.len()
4834
0
    }
4835
}
4836
impl<K, V, A: Allocator> FusedIterator for IntoIter<K, V, A> {}
4837
4838
impl<K: Debug, V: Debug, A: Allocator> fmt::Debug for IntoIter<K, V, A> {
4839
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4840
0
        f.debug_list().entries(self.iter()).finish()
4841
0
    }
4842
}
4843
4844
impl<'a, K, V> Iterator for Keys<'a, K, V> {
4845
    type Item = &'a K;
4846
4847
    #[cfg_attr(feature = "inline-more", inline)]
4848
0
    fn next(&mut self) -> Option<&'a K> {
4849
0
        // Avoid `Option::map` because it bloats LLVM IR.
4850
0
        match self.inner.next() {
4851
0
            Some((k, _)) => Some(k),
4852
0
            None => None,
4853
        }
4854
0
    }
4855
    #[cfg_attr(feature = "inline-more", inline)]
4856
0
    fn size_hint(&self) -> (usize, Option<usize>) {
4857
0
        self.inner.size_hint()
4858
0
    }
4859
    #[cfg_attr(feature = "inline-more", inline)]
4860
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
4861
0
    where
4862
0
        Self: Sized,
4863
0
        F: FnMut(B, Self::Item) -> B,
4864
0
    {
4865
0
        self.inner.fold(init, |acc, (k, _)| f(acc, k))
4866
0
    }
4867
}
4868
impl<K, V> ExactSizeIterator for Keys<'_, K, V> {
4869
    #[cfg_attr(feature = "inline-more", inline)]
4870
0
    fn len(&self) -> usize {
4871
0
        self.inner.len()
4872
0
    }
4873
}
4874
impl<K, V> FusedIterator for Keys<'_, K, V> {}
4875
4876
impl<'a, K, V> Iterator for Values<'a, K, V> {
4877
    type Item = &'a V;
4878
4879
    #[cfg_attr(feature = "inline-more", inline)]
4880
0
    fn next(&mut self) -> Option<&'a V> {
4881
0
        // Avoid `Option::map` because it bloats LLVM IR.
4882
0
        match self.inner.next() {
4883
0
            Some((_, v)) => Some(v),
4884
0
            None => None,
4885
        }
4886
0
    }
4887
    #[cfg_attr(feature = "inline-more", inline)]
4888
0
    fn size_hint(&self) -> (usize, Option<usize>) {
4889
0
        self.inner.size_hint()
4890
0
    }
4891
    #[cfg_attr(feature = "inline-more", inline)]
4892
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
4893
0
    where
4894
0
        Self: Sized,
4895
0
        F: FnMut(B, Self::Item) -> B,
4896
0
    {
4897
0
        self.inner.fold(init, |acc, (_, v)| f(acc, v))
4898
0
    }
4899
}
4900
impl<K, V> ExactSizeIterator for Values<'_, K, V> {
4901
    #[cfg_attr(feature = "inline-more", inline)]
4902
0
    fn len(&self) -> usize {
4903
0
        self.inner.len()
4904
0
    }
4905
}
4906
impl<K, V> FusedIterator for Values<'_, K, V> {}
4907
4908
impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
4909
    type Item = &'a mut V;
4910
4911
    #[cfg_attr(feature = "inline-more", inline)]
4912
0
    fn next(&mut self) -> Option<&'a mut V> {
4913
0
        // Avoid `Option::map` because it bloats LLVM IR.
4914
0
        match self.inner.next() {
4915
0
            Some((_, v)) => Some(v),
4916
0
            None => None,
4917
        }
4918
0
    }
4919
    #[cfg_attr(feature = "inline-more", inline)]
4920
0
    fn size_hint(&self) -> (usize, Option<usize>) {
4921
0
        self.inner.size_hint()
4922
0
    }
4923
    #[cfg_attr(feature = "inline-more", inline)]
4924
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
4925
0
    where
4926
0
        Self: Sized,
4927
0
        F: FnMut(B, Self::Item) -> B,
4928
0
    {
4929
0
        self.inner.fold(init, |acc, (_, v)| f(acc, v))
4930
0
    }
4931
}
4932
impl<K, V> ExactSizeIterator for ValuesMut<'_, K, V> {
4933
    #[cfg_attr(feature = "inline-more", inline)]
4934
0
    fn len(&self) -> usize {
4935
0
        self.inner.len()
4936
0
    }
4937
}
4938
impl<K, V> FusedIterator for ValuesMut<'_, K, V> {}
4939
4940
impl<K, V: Debug> fmt::Debug for ValuesMut<'_, K, V> {
4941
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4942
0
        f.debug_list()
4943
0
            .entries(self.inner.iter().map(|(_, val)| val))
4944
0
            .finish()
4945
0
    }
4946
}
4947
4948
impl<'a, K, V, A: Allocator> Iterator for Drain<'a, K, V, A> {
4949
    type Item = (K, V);
4950
4951
    #[cfg_attr(feature = "inline-more", inline)]
4952
0
    fn next(&mut self) -> Option<(K, V)> {
4953
0
        self.inner.next()
4954
0
    }
4955
    #[cfg_attr(feature = "inline-more", inline)]
4956
0
    fn size_hint(&self) -> (usize, Option<usize>) {
4957
0
        self.inner.size_hint()
4958
0
    }
4959
    #[cfg_attr(feature = "inline-more", inline)]
4960
0
    fn fold<B, F>(self, init: B, f: F) -> B
4961
0
    where
4962
0
        Self: Sized,
4963
0
        F: FnMut(B, Self::Item) -> B,
4964
0
    {
4965
0
        self.inner.fold(init, f)
4966
0
    }
Unexecuted instantiation: _RINvXs1k_NtCsgkA6tlBCRmB_9hashbrown3mapINtB7_5DrainINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEENtNtNtNtB1t_4iter6traits8iterator8Iterator4folduNCINvNvB3e_8for_each4callTBN_B1m_ENCNvXsa_BQ_INtBQ_8LruCacheB1f_B2q_ENtNtNtB1t_3ops4drop4Drop4drop0E0EB2u_
Unexecuted instantiation: _RINvXININtCsgkA6tlBCRmB_9hashbrown3maps1k_0pppEINtB6_5DrainpppENtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits8iterator8Iterator4foldppEB8_
4967
}
4968
impl<K, V, A: Allocator> ExactSizeIterator for Drain<'_, K, V, A> {
4969
    #[cfg_attr(feature = "inline-more", inline)]
4970
0
    fn len(&self) -> usize {
4971
0
        self.inner.len()
4972
0
    }
4973
}
4974
impl<K, V, A: Allocator> FusedIterator for Drain<'_, K, V, A> {}
4975
4976
impl<K, V, A> fmt::Debug for Drain<'_, K, V, A>
4977
where
4978
    K: fmt::Debug,
4979
    V: fmt::Debug,
4980
    A: Allocator,
4981
{
4982
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4983
0
        f.debug_list().entries(self.iter()).finish()
4984
0
    }
4985
}
4986
4987
impl<'a, K, V, S, A: Allocator> Entry<'a, K, V, S, A> {
4988
    /// Sets the value of the entry, and returns an OccupiedEntry.
4989
    ///
4990
    /// # Examples
4991
    ///
4992
    /// ```
4993
    /// use hashbrown::HashMap;
4994
    ///
4995
    /// let mut map: HashMap<&str, u32> = HashMap::new();
4996
    /// let entry = map.entry("horseyland").insert(37);
4997
    ///
4998
    /// assert_eq!(entry.key(), &"horseyland");
4999
    /// ```
5000
    #[cfg_attr(feature = "inline-more", inline)]
5001
0
    pub fn insert(self, value: V) -> OccupiedEntry<'a, K, V, S, A>
5002
0
    where
5003
0
        K: Hash,
5004
0
        S: BuildHasher,
5005
0
    {
5006
0
        match self {
5007
0
            Entry::Occupied(mut entry) => {
5008
0
                entry.insert(value);
5009
0
                entry
5010
            }
5011
0
            Entry::Vacant(entry) => entry.insert_entry(value),
5012
        }
5013
0
    }
5014
5015
    /// Ensures a value is in the entry by inserting the default if empty, and returns
5016
    /// a mutable reference to the value in the entry.
5017
    ///
5018
    /// # Examples
5019
    ///
5020
    /// ```
5021
    /// use hashbrown::HashMap;
5022
    ///
5023
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5024
    ///
5025
    /// // nonexistent key
5026
    /// map.entry("poneyland").or_insert(3);
5027
    /// assert_eq!(map["poneyland"], 3);
5028
    ///
5029
    /// // existing key
5030
    /// *map.entry("poneyland").or_insert(10) *= 2;
5031
    /// assert_eq!(map["poneyland"], 6);
5032
    /// ```
5033
    #[cfg_attr(feature = "inline-more", inline)]
5034
0
    pub fn or_insert(self, default: V) -> &'a mut V
5035
0
    where
5036
0
        K: Hash,
5037
0
        S: BuildHasher,
5038
0
    {
5039
0
        match self {
5040
0
            Entry::Occupied(entry) => entry.into_mut(),
5041
0
            Entry::Vacant(entry) => entry.insert(default),
5042
        }
5043
0
    }
5044
5045
    /// Ensures a value is in the entry by inserting the result of the default function if empty,
5046
    /// and returns a mutable reference to the value in the entry.
5047
    ///
5048
    /// # Examples
5049
    ///
5050
    /// ```
5051
    /// use hashbrown::HashMap;
5052
    ///
5053
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5054
    ///
5055
    /// // nonexistent key
5056
    /// map.entry("poneyland").or_insert_with(|| 3);
5057
    /// assert_eq!(map["poneyland"], 3);
5058
    ///
5059
    /// // existing key
5060
    /// *map.entry("poneyland").or_insert_with(|| 10) *= 2;
5061
    /// assert_eq!(map["poneyland"], 6);
5062
    /// ```
5063
    #[cfg_attr(feature = "inline-more", inline)]
5064
0
    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V
5065
0
    where
5066
0
        K: Hash,
5067
0
        S: BuildHasher,
5068
0
    {
5069
0
        match self {
5070
0
            Entry::Occupied(entry) => entry.into_mut(),
5071
0
            Entry::Vacant(entry) => entry.insert(default()),
5072
        }
5073
0
    }
5074
5075
    /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
5076
    /// This method allows for generating key-derived values for insertion by providing the default
5077
    /// function a reference to the key that was moved during the `.entry(key)` method call.
5078
    ///
5079
    /// The reference to the moved key is provided so that cloning or copying the key is
5080
    /// unnecessary, unlike with `.or_insert_with(|| ... )`.
5081
    ///
5082
    /// # Examples
5083
    ///
5084
    /// ```
5085
    /// use hashbrown::HashMap;
5086
    ///
5087
    /// let mut map: HashMap<&str, usize> = HashMap::new();
5088
    ///
5089
    /// // nonexistent key
5090
    /// map.entry("poneyland").or_insert_with_key(|key| key.chars().count());
5091
    /// assert_eq!(map["poneyland"], 9);
5092
    ///
5093
    /// // existing key
5094
    /// *map.entry("poneyland").or_insert_with_key(|key| key.chars().count() * 10) *= 2;
5095
    /// assert_eq!(map["poneyland"], 18);
5096
    /// ```
5097
    #[cfg_attr(feature = "inline-more", inline)]
5098
0
    pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V
5099
0
    where
5100
0
        K: Hash,
5101
0
        S: BuildHasher,
5102
0
    {
5103
0
        match self {
5104
0
            Entry::Occupied(entry) => entry.into_mut(),
5105
0
            Entry::Vacant(entry) => {
5106
0
                let value = default(entry.key());
5107
0
                entry.insert(value)
5108
            }
5109
        }
5110
0
    }
5111
5112
    /// Returns a reference to this entry's key.
5113
    ///
5114
    /// # Examples
5115
    ///
5116
    /// ```
5117
    /// use hashbrown::HashMap;
5118
    ///
5119
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5120
    /// map.entry("poneyland").or_insert(3);
5121
    /// // existing key
5122
    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
5123
    /// // nonexistent key
5124
    /// assert_eq!(map.entry("horseland").key(), &"horseland");
5125
    /// ```
5126
    #[cfg_attr(feature = "inline-more", inline)]
5127
0
    pub fn key(&self) -> &K {
5128
0
        match *self {
5129
0
            Entry::Occupied(ref entry) => entry.key(),
5130
0
            Entry::Vacant(ref entry) => entry.key(),
5131
        }
5132
0
    }
5133
5134
    /// Provides in-place mutable access to an occupied entry before any
5135
    /// potential inserts into the map.
5136
    ///
5137
    /// # Examples
5138
    ///
5139
    /// ```
5140
    /// use hashbrown::HashMap;
5141
    ///
5142
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5143
    ///
5144
    /// map.entry("poneyland")
5145
    ///    .and_modify(|e| { *e += 1 })
5146
    ///    .or_insert(42);
5147
    /// assert_eq!(map["poneyland"], 42);
5148
    ///
5149
    /// map.entry("poneyland")
5150
    ///    .and_modify(|e| { *e += 1 })
5151
    ///    .or_insert(42);
5152
    /// assert_eq!(map["poneyland"], 43);
5153
    /// ```
5154
    #[cfg_attr(feature = "inline-more", inline)]
5155
0
    pub fn and_modify<F>(self, f: F) -> Self
5156
0
    where
5157
0
        F: FnOnce(&mut V),
5158
0
    {
5159
0
        match self {
5160
0
            Entry::Occupied(mut entry) => {
5161
0
                f(entry.get_mut());
5162
0
                Entry::Occupied(entry)
5163
            }
5164
0
            Entry::Vacant(entry) => Entry::Vacant(entry),
5165
        }
5166
0
    }
5167
5168
    /// Provides shared access to the key and owned access to the value of
5169
    /// an occupied entry and allows to replace or remove it based on the
5170
    /// value of the returned option.
5171
    ///
5172
    /// # Examples
5173
    ///
5174
    /// ```
5175
    /// use hashbrown::HashMap;
5176
    /// use hashbrown::hash_map::Entry;
5177
    ///
5178
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5179
    ///
5180
    /// let entry = map
5181
    ///     .entry("poneyland")
5182
    ///     .and_replace_entry_with(|_k, _v| panic!());
5183
    ///
5184
    /// match entry {
5185
    ///     Entry::Vacant(e) => {
5186
    ///         assert_eq!(e.key(), &"poneyland");
5187
    ///     }
5188
    ///     Entry::Occupied(_) => panic!(),
5189
    /// }
5190
    ///
5191
    /// map.insert("poneyland", 42);
5192
    ///
5193
    /// let entry = map
5194
    ///     .entry("poneyland")
5195
    ///     .and_replace_entry_with(|k, v| {
5196
    ///         assert_eq!(k, &"poneyland");
5197
    ///         assert_eq!(v, 42);
5198
    ///         Some(v + 1)
5199
    ///     });
5200
    ///
5201
    /// match entry {
5202
    ///     Entry::Occupied(e) => {
5203
    ///         assert_eq!(e.key(), &"poneyland");
5204
    ///         assert_eq!(e.get(), &43);
5205
    ///     }
5206
    ///     Entry::Vacant(_) => panic!(),
5207
    /// }
5208
    ///
5209
    /// assert_eq!(map["poneyland"], 43);
5210
    ///
5211
    /// let entry = map
5212
    ///     .entry("poneyland")
5213
    ///     .and_replace_entry_with(|_k, _v| None);
5214
    ///
5215
    /// match entry {
5216
    ///     Entry::Vacant(e) => assert_eq!(e.key(), &"poneyland"),
5217
    ///     Entry::Occupied(_) => panic!(),
5218
    /// }
5219
    ///
5220
    /// assert!(!map.contains_key("poneyland"));
5221
    /// ```
5222
    #[cfg_attr(feature = "inline-more", inline)]
5223
0
    pub fn and_replace_entry_with<F>(self, f: F) -> Self
5224
0
    where
5225
0
        F: FnOnce(&K, V) -> Option<V>,
5226
0
    {
5227
0
        match self {
5228
0
            Entry::Occupied(entry) => entry.replace_entry_with(f),
5229
0
            Entry::Vacant(_) => self,
5230
        }
5231
0
    }
5232
}
5233
5234
impl<'a, K, V: Default, S, A: Allocator> Entry<'a, K, V, S, A> {
5235
    /// Ensures a value is in the entry by inserting the default value if empty,
5236
    /// and returns a mutable reference to the value in the entry.
5237
    ///
5238
    /// # Examples
5239
    ///
5240
    /// ```
5241
    /// use hashbrown::HashMap;
5242
    ///
5243
    /// let mut map: HashMap<&str, Option<u32>> = HashMap::new();
5244
    ///
5245
    /// // nonexistent key
5246
    /// map.entry("poneyland").or_default();
5247
    /// assert_eq!(map["poneyland"], None);
5248
    ///
5249
    /// map.insert("horseland", Some(3));
5250
    ///
5251
    /// // existing key
5252
    /// assert_eq!(map.entry("horseland").or_default(), &mut Some(3));
5253
    /// ```
5254
    #[cfg_attr(feature = "inline-more", inline)]
5255
0
    pub fn or_default(self) -> &'a mut V
5256
0
    where
5257
0
        K: Hash,
5258
0
        S: BuildHasher,
5259
0
    {
5260
0
        match self {
5261
0
            Entry::Occupied(entry) => entry.into_mut(),
5262
0
            Entry::Vacant(entry) => entry.insert(Default::default()),
5263
        }
5264
0
    }
5265
}
5266
5267
impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
5268
    /// Gets a reference to the key in the entry.
5269
    ///
5270
    /// # Examples
5271
    ///
5272
    /// ```
5273
    /// use hashbrown::hash_map::{Entry, HashMap};
5274
    ///
5275
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5276
    /// map.entry("poneyland").or_insert(12);
5277
    ///
5278
    /// match map.entry("poneyland") {
5279
    ///     Entry::Vacant(_) => panic!(),
5280
    ///     Entry::Occupied(entry) => assert_eq!(entry.key(), &"poneyland"),
5281
    /// }
5282
    /// ```
5283
    #[cfg_attr(feature = "inline-more", inline)]
5284
0
    pub fn key(&self) -> &K {
5285
0
        unsafe { &self.elem.as_ref().0 }
5286
0
    }
5287
5288
    /// Take the ownership of the key and value from the map.
5289
    /// Keeps the allocated memory for reuse.
5290
    ///
5291
    /// # Examples
5292
    ///
5293
    /// ```
5294
    /// use hashbrown::HashMap;
5295
    /// use hashbrown::hash_map::Entry;
5296
    ///
5297
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5298
    /// // The map is empty
5299
    /// assert!(map.is_empty() && map.capacity() == 0);
5300
    ///
5301
    /// map.entry("poneyland").or_insert(12);
5302
    ///
5303
    /// if let Entry::Occupied(o) = map.entry("poneyland") {
5304
    ///     // We delete the entry from the map.
5305
    ///     assert_eq!(o.remove_entry(), ("poneyland", 12));
5306
    /// }
5307
    ///
5308
    /// assert_eq!(map.contains_key("poneyland"), false);
5309
    /// // Now map hold none elements
5310
    /// assert!(map.is_empty());
5311
    /// ```
5312
    #[cfg_attr(feature = "inline-more", inline)]
5313
0
    pub fn remove_entry(self) -> (K, V) {
5314
0
        unsafe { self.table.table.remove(self.elem).0 }
5315
0
    }
5316
5317
    /// Gets a reference to the value in the entry.
5318
    ///
5319
    /// # Examples
5320
    ///
5321
    /// ```
5322
    /// use hashbrown::HashMap;
5323
    /// use hashbrown::hash_map::Entry;
5324
    ///
5325
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5326
    /// map.entry("poneyland").or_insert(12);
5327
    ///
5328
    /// match map.entry("poneyland") {
5329
    ///     Entry::Vacant(_) => panic!(),
5330
    ///     Entry::Occupied(entry) => assert_eq!(entry.get(), &12),
5331
    /// }
5332
    /// ```
5333
    #[cfg_attr(feature = "inline-more", inline)]
5334
0
    pub fn get(&self) -> &V {
5335
0
        unsafe { &self.elem.as_ref().1 }
5336
0
    }
5337
5338
    /// Gets a mutable reference to the value in the entry.
5339
    ///
5340
    /// If you need a reference to the `OccupiedEntry` which may outlive the
5341
    /// destruction of the `Entry` value, see [`into_mut`].
5342
    ///
5343
    /// [`into_mut`]: #method.into_mut
5344
    ///
5345
    /// # Examples
5346
    ///
5347
    /// ```
5348
    /// use hashbrown::HashMap;
5349
    /// use hashbrown::hash_map::Entry;
5350
    ///
5351
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5352
    /// map.entry("poneyland").or_insert(12);
5353
    ///
5354
    /// assert_eq!(map["poneyland"], 12);
5355
    /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
5356
    ///     *o.get_mut() += 10;
5357
    ///     assert_eq!(*o.get(), 22);
5358
    ///
5359
    ///     // We can use the same Entry multiple times.
5360
    ///     *o.get_mut() += 2;
5361
    /// }
5362
    ///
5363
    /// assert_eq!(map["poneyland"], 24);
5364
    /// ```
5365
    #[cfg_attr(feature = "inline-more", inline)]
5366
0
    pub fn get_mut(&mut self) -> &mut V {
5367
0
        unsafe { &mut self.elem.as_mut().1 }
5368
0
    }
5369
5370
    /// Converts the OccupiedEntry into a mutable reference to the value in the entry
5371
    /// with a lifetime bound to the map itself.
5372
    ///
5373
    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
5374
    ///
5375
    /// [`get_mut`]: #method.get_mut
5376
    ///
5377
    /// # Examples
5378
    ///
5379
    /// ```
5380
    /// use hashbrown::hash_map::{Entry, HashMap};
5381
    ///
5382
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5383
    /// map.entry("poneyland").or_insert(12);
5384
    ///
5385
    /// assert_eq!(map["poneyland"], 12);
5386
    ///
5387
    /// let value: &mut u32;
5388
    /// match map.entry("poneyland") {
5389
    ///     Entry::Occupied(entry) => value = entry.into_mut(),
5390
    ///     Entry::Vacant(_) => panic!(),
5391
    /// }
5392
    /// *value += 10;
5393
    ///
5394
    /// assert_eq!(map["poneyland"], 22);
5395
    /// ```
5396
    #[cfg_attr(feature = "inline-more", inline)]
5397
0
    pub fn into_mut(self) -> &'a mut V {
5398
0
        unsafe { &mut self.elem.as_mut().1 }
5399
0
    }
5400
5401
    /// Sets the value of the entry, and returns the entry's old value.
5402
    ///
5403
    /// # Examples
5404
    ///
5405
    /// ```
5406
    /// use hashbrown::HashMap;
5407
    /// use hashbrown::hash_map::Entry;
5408
    ///
5409
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5410
    /// map.entry("poneyland").or_insert(12);
5411
    ///
5412
    /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
5413
    ///     assert_eq!(o.insert(15), 12);
5414
    /// }
5415
    ///
5416
    /// assert_eq!(map["poneyland"], 15);
5417
    /// ```
5418
    #[cfg_attr(feature = "inline-more", inline)]
5419
0
    pub fn insert(&mut self, value: V) -> V {
5420
0
        mem::replace(self.get_mut(), value)
5421
0
    }
5422
5423
    /// Takes the value out of the entry, and returns it.
5424
    /// Keeps the allocated memory for reuse.
5425
    ///
5426
    /// # Examples
5427
    ///
5428
    /// ```
5429
    /// use hashbrown::HashMap;
5430
    /// use hashbrown::hash_map::Entry;
5431
    ///
5432
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5433
    /// // The map is empty
5434
    /// assert!(map.is_empty() && map.capacity() == 0);
5435
    ///
5436
    /// map.entry("poneyland").or_insert(12);
5437
    ///
5438
    /// if let Entry::Occupied(o) = map.entry("poneyland") {
5439
    ///     assert_eq!(o.remove(), 12);
5440
    /// }
5441
    ///
5442
    /// assert_eq!(map.contains_key("poneyland"), false);
5443
    /// // Now map hold none elements
5444
    /// assert!(map.is_empty());
5445
    /// ```
5446
    #[cfg_attr(feature = "inline-more", inline)]
5447
0
    pub fn remove(self) -> V {
5448
0
        self.remove_entry().1
5449
0
    }
5450
5451
    /// Replaces the entry, returning the old key and value. The new key in the hash map will be
5452
    /// the key used to create this entry.
5453
    ///
5454
    /// # Panics
5455
    ///
5456
    /// Will panic if this OccupiedEntry was created through [`Entry::insert`].
5457
    ///
5458
    /// # Examples
5459
    ///
5460
    /// ```
5461
    ///  use hashbrown::hash_map::{Entry, HashMap};
5462
    ///  use std::rc::Rc;
5463
    ///
5464
    ///  let mut map: HashMap<Rc<String>, u32> = HashMap::new();
5465
    ///  let key_one = Rc::new("Stringthing".to_string());
5466
    ///  let key_two = Rc::new("Stringthing".to_string());
5467
    ///
5468
    ///  map.insert(key_one.clone(), 15);
5469
    ///  assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
5470
    ///
5471
    ///  match map.entry(key_two.clone()) {
5472
    ///      Entry::Occupied(entry) => {
5473
    ///          let (old_key, old_value): (Rc<String>, u32) = entry.replace_entry(16);
5474
    ///          assert!(Rc::ptr_eq(&key_one, &old_key) && old_value == 15);
5475
    ///      }
5476
    ///      Entry::Vacant(_) => panic!(),
5477
    ///  }
5478
    ///
5479
    ///  assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
5480
    ///  assert_eq!(map[&"Stringthing".to_owned()], 16);
5481
    /// ```
5482
    #[cfg_attr(feature = "inline-more", inline)]
5483
0
    pub fn replace_entry(self, value: V) -> (K, V) {
5484
0
        let entry = unsafe { self.elem.as_mut() };
5485
0
5486
0
        let old_key = mem::replace(&mut entry.0, self.key.unwrap());
5487
0
        let old_value = mem::replace(&mut entry.1, value);
5488
0
5489
0
        (old_key, old_value)
5490
0
    }
5491
5492
    /// Replaces the key in the hash map with the key used to create this entry.
5493
    ///
5494
    /// # Panics
5495
    ///
5496
    /// Will panic if this OccupiedEntry was created through [`Entry::insert`].
5497
    ///
5498
    /// # Examples
5499
    ///
5500
    /// ```
5501
    /// use hashbrown::hash_map::{Entry, HashMap};
5502
    /// use std::rc::Rc;
5503
    ///
5504
    /// let mut map: HashMap<Rc<String>, usize> = HashMap::with_capacity(6);
5505
    /// let mut keys_one: Vec<Rc<String>> = Vec::with_capacity(6);
5506
    /// let mut keys_two: Vec<Rc<String>> = Vec::with_capacity(6);
5507
    ///
5508
    /// for (value, key) in ["a", "b", "c", "d", "e", "f"].into_iter().enumerate() {
5509
    ///     let rc_key = Rc::new(key.to_owned());
5510
    ///     keys_one.push(rc_key.clone());
5511
    ///     map.insert(rc_key.clone(), value);
5512
    ///     keys_two.push(Rc::new(key.to_owned()));
5513
    /// }
5514
    ///
5515
    /// assert!(
5516
    ///     keys_one.iter().all(|key| Rc::strong_count(key) == 2)
5517
    ///         && keys_two.iter().all(|key| Rc::strong_count(key) == 1)
5518
    /// );
5519
    ///
5520
    /// reclaim_memory(&mut map, &keys_two);
5521
    ///
5522
    /// assert!(
5523
    ///     keys_one.iter().all(|key| Rc::strong_count(key) == 1)
5524
    ///         && keys_two.iter().all(|key| Rc::strong_count(key) == 2)
5525
    /// );
5526
    ///
5527
    /// fn reclaim_memory(map: &mut HashMap<Rc<String>, usize>, keys: &[Rc<String>]) {
5528
    ///     for key in keys {
5529
    ///         if let Entry::Occupied(entry) = map.entry(key.clone()) {
5530
    ///         // Replaces the entry's key with our version of it in `keys`.
5531
    ///             entry.replace_key();
5532
    ///         }
5533
    ///     }
5534
    /// }
5535
    /// ```
5536
    #[cfg_attr(feature = "inline-more", inline)]
5537
0
    pub fn replace_key(self) -> K {
5538
0
        let entry = unsafe { self.elem.as_mut() };
5539
0
        mem::replace(&mut entry.0, self.key.unwrap())
5540
0
    }
5541
5542
    /// Provides shared access to the key and owned access to the value of
5543
    /// the entry and allows to replace or remove it based on the
5544
    /// value of the returned option.
5545
    ///
5546
    /// # Examples
5547
    ///
5548
    /// ```
5549
    /// use hashbrown::HashMap;
5550
    /// use hashbrown::hash_map::Entry;
5551
    ///
5552
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5553
    /// map.insert("poneyland", 42);
5554
    ///
5555
    /// let entry = match map.entry("poneyland") {
5556
    ///     Entry::Occupied(e) => {
5557
    ///         e.replace_entry_with(|k, v| {
5558
    ///             assert_eq!(k, &"poneyland");
5559
    ///             assert_eq!(v, 42);
5560
    ///             Some(v + 1)
5561
    ///         })
5562
    ///     }
5563
    ///     Entry::Vacant(_) => panic!(),
5564
    /// };
5565
    ///
5566
    /// match entry {
5567
    ///     Entry::Occupied(e) => {
5568
    ///         assert_eq!(e.key(), &"poneyland");
5569
    ///         assert_eq!(e.get(), &43);
5570
    ///     }
5571
    ///     Entry::Vacant(_) => panic!(),
5572
    /// }
5573
    ///
5574
    /// assert_eq!(map["poneyland"], 43);
5575
    ///
5576
    /// let entry = match map.entry("poneyland") {
5577
    ///     Entry::Occupied(e) => e.replace_entry_with(|_k, _v| None),
5578
    ///     Entry::Vacant(_) => panic!(),
5579
    /// };
5580
    ///
5581
    /// match entry {
5582
    ///     Entry::Vacant(e) => {
5583
    ///         assert_eq!(e.key(), &"poneyland");
5584
    ///     }
5585
    ///     Entry::Occupied(_) => panic!(),
5586
    /// }
5587
    ///
5588
    /// assert!(!map.contains_key("poneyland"));
5589
    /// ```
5590
    #[cfg_attr(feature = "inline-more", inline)]
5591
0
    pub fn replace_entry_with<F>(self, f: F) -> Entry<'a, K, V, S, A>
5592
0
    where
5593
0
        F: FnOnce(&K, V) -> Option<V>,
5594
0
    {
5595
0
        unsafe {
5596
0
            let mut spare_key = None;
5597
0
5598
0
            self.table
5599
0
                .table
5600
0
                .replace_bucket_with(self.elem.clone(), |(key, value)| {
5601
0
                    if let Some(new_value) = f(&key, value) {
5602
0
                        Some((key, new_value))
5603
                    } else {
5604
0
                        spare_key = Some(key);
5605
0
                        None
5606
                    }
5607
0
                });
5608
5609
0
            if let Some(key) = spare_key {
5610
0
                Entry::Vacant(VacantEntry {
5611
0
                    hash: self.hash,
5612
0
                    key,
5613
0
                    table: self.table,
5614
0
                })
5615
            } else {
5616
0
                Entry::Occupied(self)
5617
            }
5618
        }
5619
0
    }
5620
}
5621
5622
impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
5623
    /// Gets a reference to the key that would be used when inserting a value
5624
    /// through the `VacantEntry`.
5625
    ///
5626
    /// # Examples
5627
    ///
5628
    /// ```
5629
    /// use hashbrown::HashMap;
5630
    ///
5631
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5632
    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
5633
    /// ```
5634
    #[cfg_attr(feature = "inline-more", inline)]
5635
0
    pub fn key(&self) -> &K {
5636
0
        &self.key
5637
0
    }
5638
5639
    /// Take ownership of the key.
5640
    ///
5641
    /// # Examples
5642
    ///
5643
    /// ```
5644
    /// use hashbrown::hash_map::{Entry, HashMap};
5645
    ///
5646
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5647
    ///
5648
    /// match map.entry("poneyland") {
5649
    ///     Entry::Occupied(_) => panic!(),
5650
    ///     Entry::Vacant(v) => assert_eq!(v.into_key(), "poneyland"),
5651
    /// }
5652
    /// ```
5653
    #[cfg_attr(feature = "inline-more", inline)]
5654
0
    pub fn into_key(self) -> K {
5655
0
        self.key
5656
0
    }
5657
5658
    /// Sets the value of the entry with the VacantEntry's key,
5659
    /// and returns a mutable reference to it.
5660
    ///
5661
    /// # Examples
5662
    ///
5663
    /// ```
5664
    /// use hashbrown::HashMap;
5665
    /// use hashbrown::hash_map::Entry;
5666
    ///
5667
    /// let mut map: HashMap<&str, u32> = HashMap::new();
5668
    ///
5669
    /// if let Entry::Vacant(o) = map.entry("poneyland") {
5670
    ///     o.insert(37);
5671
    /// }
5672
    /// assert_eq!(map["poneyland"], 37);
5673
    /// ```
5674
    #[cfg_attr(feature = "inline-more", inline)]
5675
0
    pub fn insert(self, value: V) -> &'a mut V
5676
0
    where
5677
0
        K: Hash,
5678
0
        S: BuildHasher,
5679
0
    {
5680
0
        let table = &mut self.table.table;
5681
0
        let entry = table.insert_entry(
5682
0
            self.hash,
5683
0
            (self.key, value),
5684
0
            make_hasher::<_, V, S>(&self.table.hash_builder),
5685
0
        );
5686
0
        &mut entry.1
5687
0
    }
5688
5689
    #[cfg_attr(feature = "inline-more", inline)]
5690
0
    pub(crate) fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, S, A>
5691
0
    where
5692
0
        K: Hash,
5693
0
        S: BuildHasher,
5694
0
    {
5695
0
        let elem = self.table.table.insert(
5696
0
            self.hash,
5697
0
            (self.key, value),
5698
0
            make_hasher::<_, V, S>(&self.table.hash_builder),
5699
0
        );
5700
0
        OccupiedEntry {
5701
0
            hash: self.hash,
5702
0
            key: None,
5703
0
            elem,
5704
0
            table: self.table,
5705
0
        }
5706
0
    }
5707
}
5708
5709
impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> EntryRef<'a, 'b, K, Q, V, S, A> {
5710
    /// Sets the value of the entry, and returns an OccupiedEntryRef.
5711
    ///
5712
    /// # Examples
5713
    ///
5714
    /// ```
5715
    /// use hashbrown::HashMap;
5716
    ///
5717
    /// let mut map: HashMap<String, u32> = HashMap::new();
5718
    /// let entry = map.entry_ref("horseyland").insert(37);
5719
    ///
5720
    /// assert_eq!(entry.key(), "horseyland");
5721
    /// ```
5722
    #[cfg_attr(feature = "inline-more", inline)]
5723
0
    pub fn insert(self, value: V) -> OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
5724
0
    where
5725
0
        K: Hash + From<&'b Q>,
5726
0
        S: BuildHasher,
5727
0
    {
5728
0
        match self {
5729
0
            EntryRef::Occupied(mut entry) => {
5730
0
                entry.insert(value);
5731
0
                entry
5732
            }
5733
0
            EntryRef::Vacant(entry) => entry.insert_entry(value),
5734
        }
5735
0
    }
5736
5737
    /// Ensures a value is in the entry by inserting the default if empty, and returns
5738
    /// a mutable reference to the value in the entry.
5739
    ///
5740
    /// # Examples
5741
    ///
5742
    /// ```
5743
    /// use hashbrown::HashMap;
5744
    ///
5745
    /// let mut map: HashMap<String, u32> = HashMap::new();
5746
    ///
5747
    /// // nonexistent key
5748
    /// map.entry_ref("poneyland").or_insert(3);
5749
    /// assert_eq!(map["poneyland"], 3);
5750
    ///
5751
    /// // existing key
5752
    /// *map.entry_ref("poneyland").or_insert(10) *= 2;
5753
    /// assert_eq!(map["poneyland"], 6);
5754
    /// ```
5755
    #[cfg_attr(feature = "inline-more", inline)]
5756
0
    pub fn or_insert(self, default: V) -> &'a mut V
5757
0
    where
5758
0
        K: Hash + From<&'b Q>,
5759
0
        S: BuildHasher,
5760
0
    {
5761
0
        match self {
5762
0
            EntryRef::Occupied(entry) => entry.into_mut(),
5763
0
            EntryRef::Vacant(entry) => entry.insert(default),
5764
        }
5765
0
    }
5766
5767
    /// Ensures a value is in the entry by inserting the result of the default function if empty,
5768
    /// and returns a mutable reference to the value in the entry.
5769
    ///
5770
    /// # Examples
5771
    ///
5772
    /// ```
5773
    /// use hashbrown::HashMap;
5774
    ///
5775
    /// let mut map: HashMap<String, u32> = HashMap::new();
5776
    ///
5777
    /// // nonexistent key
5778
    /// map.entry_ref("poneyland").or_insert_with(|| 3);
5779
    /// assert_eq!(map["poneyland"], 3);
5780
    ///
5781
    /// // existing key
5782
    /// *map.entry_ref("poneyland").or_insert_with(|| 10) *= 2;
5783
    /// assert_eq!(map["poneyland"], 6);
5784
    /// ```
5785
    #[cfg_attr(feature = "inline-more", inline)]
5786
0
    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V
5787
0
    where
5788
0
        K: Hash + From<&'b Q>,
5789
0
        S: BuildHasher,
5790
0
    {
5791
0
        match self {
5792
0
            EntryRef::Occupied(entry) => entry.into_mut(),
5793
0
            EntryRef::Vacant(entry) => entry.insert(default()),
5794
        }
5795
0
    }
5796
5797
    /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
5798
    /// This method allows for generating key-derived values for insertion by providing the default
5799
    /// function an access to the borrower form of the key.
5800
    ///
5801
    /// # Examples
5802
    ///
5803
    /// ```
5804
    /// use hashbrown::HashMap;
5805
    ///
5806
    /// let mut map: HashMap<String, usize> = HashMap::new();
5807
    ///
5808
    /// // nonexistent key
5809
    /// map.entry_ref("poneyland").or_insert_with_key(|key| key.chars().count());
5810
    /// assert_eq!(map["poneyland"], 9);
5811
    ///
5812
    /// // existing key
5813
    /// *map.entry_ref("poneyland").or_insert_with_key(|key| key.chars().count() * 10) *= 2;
5814
    /// assert_eq!(map["poneyland"], 18);
5815
    /// ```
5816
    #[cfg_attr(feature = "inline-more", inline)]
5817
0
    pub fn or_insert_with_key<F: FnOnce(&Q) -> V>(self, default: F) -> &'a mut V
5818
0
    where
5819
0
        K: Hash + Borrow<Q> + From<&'b Q>,
5820
0
        S: BuildHasher,
5821
0
    {
5822
0
        match self {
5823
0
            EntryRef::Occupied(entry) => entry.into_mut(),
5824
0
            EntryRef::Vacant(entry) => {
5825
0
                let value = default(entry.key.as_ref());
5826
0
                entry.insert(value)
5827
            }
5828
        }
5829
0
    }
5830
5831
    /// Returns a reference to this entry's key.
5832
    ///
5833
    /// # Examples
5834
    ///
5835
    /// ```
5836
    /// use hashbrown::HashMap;
5837
    ///
5838
    /// let mut map: HashMap<String, u32> = HashMap::new();
5839
    /// map.entry_ref("poneyland").or_insert(3);
5840
    /// // existing key
5841
    /// assert_eq!(map.entry_ref("poneyland").key(), "poneyland");
5842
    /// // nonexistent key
5843
    /// assert_eq!(map.entry_ref("horseland").key(), "horseland");
5844
    /// ```
5845
    #[cfg_attr(feature = "inline-more", inline)]
5846
0
    pub fn key(&self) -> &Q
5847
0
    where
5848
0
        K: Borrow<Q>,
5849
0
    {
5850
0
        match *self {
5851
0
            EntryRef::Occupied(ref entry) => entry.key().borrow(),
5852
0
            EntryRef::Vacant(ref entry) => entry.key(),
5853
        }
5854
0
    }
5855
5856
    /// Provides in-place mutable access to an occupied entry before any
5857
    /// potential inserts into the map.
5858
    ///
5859
    /// # Examples
5860
    ///
5861
    /// ```
5862
    /// use hashbrown::HashMap;
5863
    ///
5864
    /// let mut map: HashMap<String, u32> = HashMap::new();
5865
    ///
5866
    /// map.entry_ref("poneyland")
5867
    ///    .and_modify(|e| { *e += 1 })
5868
    ///    .or_insert(42);
5869
    /// assert_eq!(map["poneyland"], 42);
5870
    ///
5871
    /// map.entry_ref("poneyland")
5872
    ///    .and_modify(|e| { *e += 1 })
5873
    ///    .or_insert(42);
5874
    /// assert_eq!(map["poneyland"], 43);
5875
    /// ```
5876
    #[cfg_attr(feature = "inline-more", inline)]
5877
0
    pub fn and_modify<F>(self, f: F) -> Self
5878
0
    where
5879
0
        F: FnOnce(&mut V),
5880
0
    {
5881
0
        match self {
5882
0
            EntryRef::Occupied(mut entry) => {
5883
0
                f(entry.get_mut());
5884
0
                EntryRef::Occupied(entry)
5885
            }
5886
0
            EntryRef::Vacant(entry) => EntryRef::Vacant(entry),
5887
        }
5888
0
    }
5889
5890
    /// Provides shared access to the key and owned access to the value of
5891
    /// an occupied entry and allows to replace or remove it based on the
5892
    /// value of the returned option.
5893
    ///
5894
    /// # Examples
5895
    ///
5896
    /// ```
5897
    /// use hashbrown::HashMap;
5898
    /// use hashbrown::hash_map::EntryRef;
5899
    ///
5900
    /// let mut map: HashMap<String, u32> = HashMap::new();
5901
    ///
5902
    /// let entry = map
5903
    ///     .entry_ref("poneyland")
5904
    ///     .and_replace_entry_with(|_k, _v| panic!());
5905
    ///
5906
    /// match entry {
5907
    ///     EntryRef::Vacant(e) => {
5908
    ///         assert_eq!(e.key(), "poneyland");
5909
    ///     }
5910
    ///     EntryRef::Occupied(_) => panic!(),
5911
    /// }
5912
    ///
5913
    /// map.insert("poneyland".to_string(), 42);
5914
    ///
5915
    /// let entry = map
5916
    ///     .entry_ref("poneyland")
5917
    ///     .and_replace_entry_with(|k, v| {
5918
    ///         assert_eq!(k, "poneyland");
5919
    ///         assert_eq!(v, 42);
5920
    ///         Some(v + 1)
5921
    ///     });
5922
    ///
5923
    /// match entry {
5924
    ///     EntryRef::Occupied(e) => {
5925
    ///         assert_eq!(e.key(), "poneyland");
5926
    ///         assert_eq!(e.get(), &43);
5927
    ///     }
5928
    ///     EntryRef::Vacant(_) => panic!(),
5929
    /// }
5930
    ///
5931
    /// assert_eq!(map["poneyland"], 43);
5932
    ///
5933
    /// let entry = map
5934
    ///     .entry_ref("poneyland")
5935
    ///     .and_replace_entry_with(|_k, _v| None);
5936
    ///
5937
    /// match entry {
5938
    ///     EntryRef::Vacant(e) => assert_eq!(e.key(), "poneyland"),
5939
    ///     EntryRef::Occupied(_) => panic!(),
5940
    /// }
5941
    ///
5942
    /// assert!(!map.contains_key("poneyland"));
5943
    /// ```
5944
    #[cfg_attr(feature = "inline-more", inline)]
5945
0
    pub fn and_replace_entry_with<F>(self, f: F) -> Self
5946
0
    where
5947
0
        F: FnOnce(&K, V) -> Option<V>,
5948
0
    {
5949
0
        match self {
5950
0
            EntryRef::Occupied(entry) => entry.replace_entry_with(f),
5951
0
            EntryRef::Vacant(_) => self,
5952
        }
5953
0
    }
5954
}
5955
5956
impl<'a, 'b, K, Q: ?Sized, V: Default, S, A: Allocator> EntryRef<'a, 'b, K, Q, V, S, A> {
5957
    /// Ensures a value is in the entry by inserting the default value if empty,
5958
    /// and returns a mutable reference to the value in the entry.
5959
    ///
5960
    /// # Examples
5961
    ///
5962
    /// ```
5963
    /// use hashbrown::HashMap;
5964
    ///
5965
    /// let mut map: HashMap<String, Option<u32>> = HashMap::new();
5966
    ///
5967
    /// // nonexistent key
5968
    /// map.entry_ref("poneyland").or_default();
5969
    /// assert_eq!(map["poneyland"], None);
5970
    ///
5971
    /// map.insert("horseland".to_string(), Some(3));
5972
    ///
5973
    /// // existing key
5974
    /// assert_eq!(map.entry_ref("horseland").or_default(), &mut Some(3));
5975
    /// ```
5976
    #[cfg_attr(feature = "inline-more", inline)]
5977
0
    pub fn or_default(self) -> &'a mut V
5978
0
    where
5979
0
        K: Hash + From<&'b Q>,
5980
0
        S: BuildHasher,
5981
0
    {
5982
0
        match self {
5983
0
            EntryRef::Occupied(entry) => entry.into_mut(),
5984
0
            EntryRef::Vacant(entry) => entry.insert(Default::default()),
5985
        }
5986
0
    }
5987
}
5988
5989
impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> OccupiedEntryRef<'a, 'b, K, Q, V, S, A> {
5990
    /// Gets a reference to the key in the entry.
5991
    ///
5992
    /// # Examples
5993
    ///
5994
    /// ```
5995
    /// use hashbrown::hash_map::{EntryRef, HashMap};
5996
    ///
5997
    /// let mut map: HashMap<String, u32> = HashMap::new();
5998
    /// map.entry_ref("poneyland").or_insert(12);
5999
    ///
6000
    /// match map.entry_ref("poneyland") {
6001
    ///     EntryRef::Vacant(_) => panic!(),
6002
    ///     EntryRef::Occupied(entry) => assert_eq!(entry.key(), "poneyland"),
6003
    /// }
6004
    /// ```
6005
    #[cfg_attr(feature = "inline-more", inline)]
6006
0
    pub fn key(&self) -> &K {
6007
0
        unsafe { &self.elem.as_ref().0 }
6008
0
    }
6009
6010
    /// Take the ownership of the key and value from the map.
6011
    /// Keeps the allocated memory for reuse.
6012
    ///
6013
    /// # Examples
6014
    ///
6015
    /// ```
6016
    /// use hashbrown::HashMap;
6017
    /// use hashbrown::hash_map::EntryRef;
6018
    ///
6019
    /// let mut map: HashMap<String, u32> = HashMap::new();
6020
    /// // The map is empty
6021
    /// assert!(map.is_empty() && map.capacity() == 0);
6022
    ///
6023
    /// map.entry_ref("poneyland").or_insert(12);
6024
    ///
6025
    /// if let EntryRef::Occupied(o) = map.entry_ref("poneyland") {
6026
    ///     // We delete the entry from the map.
6027
    ///     assert_eq!(o.remove_entry(), ("poneyland".to_owned(), 12));
6028
    /// }
6029
    ///
6030
    /// assert_eq!(map.contains_key("poneyland"), false);
6031
    /// // Now map hold none elements but capacity is equal to the old one
6032
    /// assert!(map.is_empty());
6033
    /// ```
6034
    #[cfg_attr(feature = "inline-more", inline)]
6035
0
    pub fn remove_entry(self) -> (K, V) {
6036
0
        unsafe { self.table.table.remove(self.elem).0 }
6037
0
    }
6038
6039
    /// Gets a reference to the value in the entry.
6040
    ///
6041
    /// # Examples
6042
    ///
6043
    /// ```
6044
    /// use hashbrown::HashMap;
6045
    /// use hashbrown::hash_map::EntryRef;
6046
    ///
6047
    /// let mut map: HashMap<String, u32> = HashMap::new();
6048
    /// map.entry_ref("poneyland").or_insert(12);
6049
    ///
6050
    /// match map.entry_ref("poneyland") {
6051
    ///     EntryRef::Vacant(_) => panic!(),
6052
    ///     EntryRef::Occupied(entry) => assert_eq!(entry.get(), &12),
6053
    /// }
6054
    /// ```
6055
    #[cfg_attr(feature = "inline-more", inline)]
6056
0
    pub fn get(&self) -> &V {
6057
0
        unsafe { &self.elem.as_ref().1 }
6058
0
    }
6059
6060
    /// Gets a mutable reference to the value in the entry.
6061
    ///
6062
    /// If you need a reference to the `OccupiedEntryRef` which may outlive the
6063
    /// destruction of the `EntryRef` value, see [`into_mut`].
6064
    ///
6065
    /// [`into_mut`]: #method.into_mut
6066
    ///
6067
    /// # Examples
6068
    ///
6069
    /// ```
6070
    /// use hashbrown::HashMap;
6071
    /// use hashbrown::hash_map::EntryRef;
6072
    ///
6073
    /// let mut map: HashMap<String, u32> = HashMap::new();
6074
    /// map.entry_ref("poneyland").or_insert(12);
6075
    ///
6076
    /// assert_eq!(map["poneyland"], 12);
6077
    /// if let EntryRef::Occupied(mut o) = map.entry_ref("poneyland") {
6078
    ///     *o.get_mut() += 10;
6079
    ///     assert_eq!(*o.get(), 22);
6080
    ///
6081
    ///     // We can use the same Entry multiple times.
6082
    ///     *o.get_mut() += 2;
6083
    /// }
6084
    ///
6085
    /// assert_eq!(map["poneyland"], 24);
6086
    /// ```
6087
    #[cfg_attr(feature = "inline-more", inline)]
6088
0
    pub fn get_mut(&mut self) -> &mut V {
6089
0
        unsafe { &mut self.elem.as_mut().1 }
6090
0
    }
6091
6092
    /// Converts the OccupiedEntryRef into a mutable reference to the value in the entry
6093
    /// with a lifetime bound to the map itself.
6094
    ///
6095
    /// If you need multiple references to the `OccupiedEntryRef`, see [`get_mut`].
6096
    ///
6097
    /// [`get_mut`]: #method.get_mut
6098
    ///
6099
    /// # Examples
6100
    ///
6101
    /// ```
6102
    /// use hashbrown::hash_map::{EntryRef, HashMap};
6103
    ///
6104
    /// let mut map: HashMap<String, u32> = HashMap::new();
6105
    /// map.entry_ref("poneyland").or_insert(12);
6106
    ///
6107
    /// let value: &mut u32;
6108
    /// match map.entry_ref("poneyland") {
6109
    ///     EntryRef::Occupied(entry) => value = entry.into_mut(),
6110
    ///     EntryRef::Vacant(_) => panic!(),
6111
    /// }
6112
    /// *value += 10;
6113
    ///
6114
    /// assert_eq!(map["poneyland"], 22);
6115
    /// ```
6116
    #[cfg_attr(feature = "inline-more", inline)]
6117
0
    pub fn into_mut(self) -> &'a mut V {
6118
0
        unsafe { &mut self.elem.as_mut().1 }
6119
0
    }
6120
6121
    /// Sets the value of the entry, and returns the entry's old value.
6122
    ///
6123
    /// # Examples
6124
    ///
6125
    /// ```
6126
    /// use hashbrown::HashMap;
6127
    /// use hashbrown::hash_map::EntryRef;
6128
    ///
6129
    /// let mut map: HashMap<String, u32> = HashMap::new();
6130
    /// map.entry_ref("poneyland").or_insert(12);
6131
    ///
6132
    /// if let EntryRef::Occupied(mut o) = map.entry_ref("poneyland") {
6133
    ///     assert_eq!(o.insert(15), 12);
6134
    /// }
6135
    ///
6136
    /// assert_eq!(map["poneyland"], 15);
6137
    /// ```
6138
    #[cfg_attr(feature = "inline-more", inline)]
6139
0
    pub fn insert(&mut self, value: V) -> V {
6140
0
        mem::replace(self.get_mut(), value)
6141
0
    }
6142
6143
    /// Takes the value out of the entry, and returns it.
6144
    /// Keeps the allocated memory for reuse.
6145
    ///
6146
    /// # Examples
6147
    ///
6148
    /// ```
6149
    /// use hashbrown::HashMap;
6150
    /// use hashbrown::hash_map::EntryRef;
6151
    ///
6152
    /// let mut map: HashMap<String, u32> = HashMap::new();
6153
    /// // The map is empty
6154
    /// assert!(map.is_empty() && map.capacity() == 0);
6155
    ///
6156
    /// map.entry_ref("poneyland").or_insert(12);
6157
    ///
6158
    /// if let EntryRef::Occupied(o) = map.entry_ref("poneyland") {
6159
    ///     assert_eq!(o.remove(), 12);
6160
    /// }
6161
    ///
6162
    /// assert_eq!(map.contains_key("poneyland"), false);
6163
    /// // Now map hold none elements but capacity is equal to the old one
6164
    /// assert!(map.is_empty());
6165
    /// ```
6166
    #[cfg_attr(feature = "inline-more", inline)]
6167
0
    pub fn remove(self) -> V {
6168
0
        self.remove_entry().1
6169
0
    }
6170
6171
    /// Replaces the entry, returning the old key and value. The new key in the hash map will be
6172
    /// the key used to create this entry.
6173
    ///
6174
    /// # Panics
6175
    ///
6176
    /// Will panic if this OccupiedEntryRef was created through [`EntryRef::insert`].
6177
    ///
6178
    /// # Examples
6179
    ///
6180
    /// ```
6181
    /// use hashbrown::hash_map::{EntryRef, HashMap};
6182
    /// use std::rc::Rc;
6183
    ///
6184
    /// let mut map: HashMap<Rc<str>, u32> = HashMap::new();
6185
    /// let key: Rc<str> = Rc::from("Stringthing");
6186
    ///
6187
    /// map.insert(key.clone(), 15);
6188
    /// assert_eq!(Rc::strong_count(&key), 2);
6189
    ///
6190
    /// match map.entry_ref("Stringthing") {
6191
    ///     EntryRef::Occupied(entry) => {
6192
    ///         let (old_key, old_value): (Rc<str>, u32) = entry.replace_entry(16);
6193
    ///         assert!(Rc::ptr_eq(&key, &old_key) && old_value == 15);
6194
    ///     }
6195
    ///     EntryRef::Vacant(_) => panic!(),
6196
    /// }
6197
    ///
6198
    /// assert_eq!(Rc::strong_count(&key), 1);
6199
    /// assert_eq!(map["Stringthing"], 16);
6200
    /// ```
6201
    #[cfg_attr(feature = "inline-more", inline)]
6202
0
    pub fn replace_entry(self, value: V) -> (K, V)
6203
0
    where
6204
0
        K: From<&'b Q>,
6205
0
    {
6206
0
        let entry = unsafe { self.elem.as_mut() };
6207
0
6208
0
        let old_key = mem::replace(&mut entry.0, self.key.unwrap().into_owned());
6209
0
        let old_value = mem::replace(&mut entry.1, value);
6210
0
6211
0
        (old_key, old_value)
6212
0
    }
6213
6214
    /// Replaces the key in the hash map with the key used to create this entry.
6215
    ///
6216
    /// # Panics
6217
    ///
6218
    /// Will panic if this OccupiedEntryRef was created through [`EntryRef::insert`].
6219
    ///
6220
    /// # Examples
6221
    ///
6222
    /// ```
6223
    /// use hashbrown::hash_map::{EntryRef, HashMap};
6224
    /// use std::rc::Rc;
6225
    ///
6226
    /// let mut map: HashMap<Rc<str>, usize> = HashMap::with_capacity(6);
6227
    /// let mut keys: Vec<Rc<str>> = Vec::with_capacity(6);
6228
    ///
6229
    /// for (value, key) in ["a", "b", "c", "d", "e", "f"].into_iter().enumerate() {
6230
    ///     let rc_key: Rc<str> = Rc::from(key);
6231
    ///     keys.push(rc_key.clone());
6232
    ///     map.insert(rc_key.clone(), value);
6233
    /// }
6234
    ///
6235
    /// assert!(keys.iter().all(|key| Rc::strong_count(key) == 2));
6236
    ///
6237
    /// // It doesn't matter that we kind of use a vector with the same keys,
6238
    /// // because all keys will be newly created from the references
6239
    /// reclaim_memory(&mut map, &keys);
6240
    ///
6241
    /// assert!(keys.iter().all(|key| Rc::strong_count(key) == 1));
6242
    ///
6243
    /// fn reclaim_memory(map: &mut HashMap<Rc<str>, usize>, keys: &[Rc<str>]) {
6244
    ///     for key in keys {
6245
    ///         if let EntryRef::Occupied(entry) = map.entry_ref(key.as_ref()) {
6246
    ///             // Replaces the entry's key with our version of it in `keys`.
6247
    ///             entry.replace_key();
6248
    ///         }
6249
    ///     }
6250
    /// }
6251
    /// ```
6252
    #[cfg_attr(feature = "inline-more", inline)]
6253
0
    pub fn replace_key(self) -> K
6254
0
    where
6255
0
        K: From<&'b Q>,
6256
0
    {
6257
0
        let entry = unsafe { self.elem.as_mut() };
6258
0
        mem::replace(&mut entry.0, self.key.unwrap().into_owned())
6259
0
    }
6260
6261
    /// Provides shared access to the key and owned access to the value of
6262
    /// the entry and allows to replace or remove it based on the
6263
    /// value of the returned option.
6264
    ///
6265
    /// # Examples
6266
    ///
6267
    /// ```
6268
    /// use hashbrown::HashMap;
6269
    /// use hashbrown::hash_map::EntryRef;
6270
    ///
6271
    /// let mut map: HashMap<String, u32> = HashMap::new();
6272
    /// map.insert("poneyland".to_string(), 42);
6273
    ///
6274
    /// let entry = match map.entry_ref("poneyland") {
6275
    ///     EntryRef::Occupied(e) => {
6276
    ///         e.replace_entry_with(|k, v| {
6277
    ///             assert_eq!(k, "poneyland");
6278
    ///             assert_eq!(v, 42);
6279
    ///             Some(v + 1)
6280
    ///         })
6281
    ///     }
6282
    ///     EntryRef::Vacant(_) => panic!(),
6283
    /// };
6284
    ///
6285
    /// match entry {
6286
    ///     EntryRef::Occupied(e) => {
6287
    ///         assert_eq!(e.key(), "poneyland");
6288
    ///         assert_eq!(e.get(), &43);
6289
    ///     }
6290
    ///     EntryRef::Vacant(_) => panic!(),
6291
    /// }
6292
    ///
6293
    /// assert_eq!(map["poneyland"], 43);
6294
    ///
6295
    /// let entry = match map.entry_ref("poneyland") {
6296
    ///     EntryRef::Occupied(e) => e.replace_entry_with(|_k, _v| None),
6297
    ///     EntryRef::Vacant(_) => panic!(),
6298
    /// };
6299
    ///
6300
    /// match entry {
6301
    ///     EntryRef::Vacant(e) => {
6302
    ///         assert_eq!(e.key(), "poneyland");
6303
    ///     }
6304
    ///     EntryRef::Occupied(_) => panic!(),
6305
    /// }
6306
    ///
6307
    /// assert!(!map.contains_key("poneyland"));
6308
    /// ```
6309
    #[cfg_attr(feature = "inline-more", inline)]
6310
0
    pub fn replace_entry_with<F>(self, f: F) -> EntryRef<'a, 'b, K, Q, V, S, A>
6311
0
    where
6312
0
        F: FnOnce(&K, V) -> Option<V>,
6313
0
    {
6314
0
        unsafe {
6315
0
            let mut spare_key = None;
6316
0
6317
0
            self.table
6318
0
                .table
6319
0
                .replace_bucket_with(self.elem.clone(), |(key, value)| {
6320
0
                    if let Some(new_value) = f(&key, value) {
6321
0
                        Some((key, new_value))
6322
                    } else {
6323
0
                        spare_key = Some(KeyOrRef::Owned(key));
6324
0
                        None
6325
                    }
6326
0
                });
6327
6328
0
            if let Some(key) = spare_key {
6329
0
                EntryRef::Vacant(VacantEntryRef {
6330
0
                    hash: self.hash,
6331
0
                    key,
6332
0
                    table: self.table,
6333
0
                })
6334
            } else {
6335
0
                EntryRef::Occupied(self)
6336
            }
6337
        }
6338
0
    }
6339
}
6340
6341
impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S, A> {
6342
    /// Gets a reference to the key that would be used when inserting a value
6343
    /// through the `VacantEntryRef`.
6344
    ///
6345
    /// # Examples
6346
    ///
6347
    /// ```
6348
    /// use hashbrown::HashMap;
6349
    ///
6350
    /// let mut map: HashMap<String, u32> = HashMap::new();
6351
    /// let key: &str = "poneyland";
6352
    /// assert_eq!(map.entry_ref(key).key(), "poneyland");
6353
    /// ```
6354
    #[cfg_attr(feature = "inline-more", inline)]
6355
0
    pub fn key(&self) -> &Q
6356
0
    where
6357
0
        K: Borrow<Q>,
6358
0
    {
6359
0
        self.key.as_ref()
6360
0
    }
6361
6362
    /// Take ownership of the key.
6363
    ///
6364
    /// # Examples
6365
    ///
6366
    /// ```
6367
    /// use hashbrown::hash_map::{EntryRef, HashMap};
6368
    ///
6369
    /// let mut map: HashMap<String, u32> = HashMap::new();
6370
    /// let key: &str = "poneyland";
6371
    ///
6372
    /// match map.entry_ref(key) {
6373
    ///     EntryRef::Occupied(_) => panic!(),
6374
    ///     EntryRef::Vacant(v) => assert_eq!(v.into_key(), "poneyland".to_owned()),
6375
    /// }
6376
    /// ```
6377
    #[cfg_attr(feature = "inline-more", inline)]
6378
0
    pub fn into_key(self) -> K
6379
0
    where
6380
0
        K: From<&'b Q>,
6381
0
    {
6382
0
        self.key.into_owned()
6383
0
    }
6384
6385
    /// Sets the value of the entry with the VacantEntryRef's key,
6386
    /// and returns a mutable reference to it.
6387
    ///
6388
    /// # Examples
6389
    ///
6390
    /// ```
6391
    /// use hashbrown::HashMap;
6392
    /// use hashbrown::hash_map::EntryRef;
6393
    ///
6394
    /// let mut map: HashMap<String, u32> = HashMap::new();
6395
    /// let key: &str = "poneyland";
6396
    ///
6397
    /// if let EntryRef::Vacant(o) = map.entry_ref(key) {
6398
    ///     o.insert(37);
6399
    /// }
6400
    /// assert_eq!(map["poneyland"], 37);
6401
    /// ```
6402
    #[cfg_attr(feature = "inline-more", inline)]
6403
0
    pub fn insert(self, value: V) -> &'a mut V
6404
0
    where
6405
0
        K: Hash + From<&'b Q>,
6406
0
        S: BuildHasher,
6407
0
    {
6408
0
        let table = &mut self.table.table;
6409
0
        let entry = table.insert_entry(
6410
0
            self.hash,
6411
0
            (self.key.into_owned(), value),
6412
0
            make_hasher::<_, V, S>(&self.table.hash_builder),
6413
0
        );
6414
0
        &mut entry.1
6415
0
    }
6416
6417
    #[cfg_attr(feature = "inline-more", inline)]
6418
0
    fn insert_entry(self, value: V) -> OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
6419
0
    where
6420
0
        K: Hash + From<&'b Q>,
6421
0
        S: BuildHasher,
6422
0
    {
6423
0
        let elem = self.table.table.insert(
6424
0
            self.hash,
6425
0
            (self.key.into_owned(), value),
6426
0
            make_hasher::<_, V, S>(&self.table.hash_builder),
6427
0
        );
6428
0
        OccupiedEntryRef {
6429
0
            hash: self.hash,
6430
0
            key: None,
6431
0
            elem,
6432
0
            table: self.table,
6433
0
        }
6434
0
    }
6435
}
6436
6437
impl<K, V, S, A> FromIterator<(K, V)> for HashMap<K, V, S, A>
6438
where
6439
    K: Eq + Hash,
6440
    S: BuildHasher + Default,
6441
    A: Default + Allocator,
6442
{
6443
    #[cfg_attr(feature = "inline-more", inline)]
6444
0
    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
6445
0
        let iter = iter.into_iter();
6446
0
        let mut map =
6447
0
            Self::with_capacity_and_hasher_in(iter.size_hint().0, S::default(), A::default());
6448
0
        iter.for_each(|(k, v)| {
6449
0
            map.insert(k, v);
6450
0
        });
6451
0
        map
6452
0
    }
6453
}
6454
6455
/// Inserts all new key-values from the iterator and replaces values with existing
6456
/// keys with new values returned from the iterator.
6457
impl<K, V, S, A> Extend<(K, V)> for HashMap<K, V, S, A>
6458
where
6459
    K: Eq + Hash,
6460
    S: BuildHasher,
6461
    A: Allocator,
6462
{
6463
    /// Inserts all new key-values from the iterator to existing `HashMap<K, V, S, A>`.
6464
    /// Replace values with existing keys with new values returned from the iterator.
6465
    ///
6466
    /// # Examples
6467
    ///
6468
    /// ```
6469
    /// use hashbrown::hash_map::HashMap;
6470
    ///
6471
    /// let mut map = HashMap::new();
6472
    /// map.insert(1, 100);
6473
    ///
6474
    /// let some_iter = [(1, 1), (2, 2)].into_iter();
6475
    /// map.extend(some_iter);
6476
    /// // Replace values with existing keys with new values returned from the iterator.
6477
    /// // So that the map.get(&1) doesn't return Some(&100).
6478
    /// assert_eq!(map.get(&1), Some(&1));
6479
    ///
6480
    /// let some_vec: Vec<_> = vec![(3, 3), (4, 4)];
6481
    /// map.extend(some_vec);
6482
    ///
6483
    /// let some_arr = [(5, 5), (6, 6)];
6484
    /// map.extend(some_arr);
6485
    /// let old_map_len = map.len();
6486
    ///
6487
    /// // You can also extend from another HashMap
6488
    /// let mut new_map = HashMap::new();
6489
    /// new_map.extend(map);
6490
    /// assert_eq!(new_map.len(), old_map_len);
6491
    ///
6492
    /// let mut vec: Vec<_> = new_map.into_iter().collect();
6493
    /// // The `IntoIter` iterator produces items in arbitrary order, so the
6494
    /// // items must be sorted to test them against a sorted array.
6495
    /// vec.sort_unstable();
6496
    /// assert_eq!(vec, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]);
6497
    /// ```
6498
    #[cfg_attr(feature = "inline-more", inline)]
6499
0
    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
6500
0
        // Keys may be already present or show multiple times in the iterator.
6501
0
        // Reserve the entire hint lower bound if the map is empty.
6502
0
        // Otherwise reserve half the hint (rounded up), so the map
6503
0
        // will only resize twice in the worst case.
6504
0
        let iter = iter.into_iter();
6505
0
        let reserve = if self.is_empty() {
6506
0
            iter.size_hint().0
6507
        } else {
6508
0
            (iter.size_hint().0 + 1) / 2
6509
        };
6510
0
        self.reserve(reserve);
6511
0
        iter.for_each(move |(k, v)| {
6512
0
            self.insert(k, v);
6513
0
        });
6514
0
    }
6515
6516
    #[inline]
6517
    #[cfg(feature = "nightly")]
6518
    fn extend_one(&mut self, (k, v): (K, V)) {
6519
        self.insert(k, v);
6520
    }
6521
6522
    #[inline]
6523
    #[cfg(feature = "nightly")]
6524
    fn extend_reserve(&mut self, additional: usize) {
6525
        // Keys may be already present or show multiple times in the iterator.
6526
        // Reserve the entire hint lower bound if the map is empty.
6527
        // Otherwise reserve half the hint (rounded up), so the map
6528
        // will only resize twice in the worst case.
6529
        let reserve = if self.is_empty() {
6530
            additional
6531
        } else {
6532
            (additional + 1) / 2
6533
        };
6534
        self.reserve(reserve);
6535
    }
6536
}
6537
6538
/// Inserts all new key-values from the iterator and replaces values with existing
6539
/// keys with new values returned from the iterator.
6540
impl<'a, K, V, S, A> Extend<(&'a K, &'a V)> for HashMap<K, V, S, A>
6541
where
6542
    K: Eq + Hash + Copy,
6543
    V: Copy,
6544
    S: BuildHasher,
6545
    A: Allocator,
6546
{
6547
    /// Inserts all new key-values from the iterator to existing `HashMap<K, V, S, A>`.
6548
    /// Replace values with existing keys with new values returned from the iterator.
6549
    /// The keys and values must implement [`Copy`] trait.
6550
    ///
6551
    /// [`Copy`]: https://doc.rust-lang.org/core/marker/trait.Copy.html
6552
    ///
6553
    /// # Examples
6554
    ///
6555
    /// ```
6556
    /// use hashbrown::hash_map::HashMap;
6557
    ///
6558
    /// let mut map = HashMap::new();
6559
    /// map.insert(1, 100);
6560
    ///
6561
    /// let arr = [(1, 1), (2, 2)];
6562
    /// let some_iter = arr.iter().map(|(k, v)| (k, v));
6563
    /// map.extend(some_iter);
6564
    /// // Replace values with existing keys with new values returned from the iterator.
6565
    /// // So that the map.get(&1) doesn't return Some(&100).
6566
    /// assert_eq!(map.get(&1), Some(&1));
6567
    ///
6568
    /// let some_vec: Vec<_> = vec![(3, 3), (4, 4)];
6569
    /// map.extend(some_vec.iter().map(|(k, v)| (k, v)));
6570
    ///
6571
    /// let some_arr = [(5, 5), (6, 6)];
6572
    /// map.extend(some_arr.iter().map(|(k, v)| (k, v)));
6573
    ///
6574
    /// // You can also extend from another HashMap
6575
    /// let mut new_map = HashMap::new();
6576
    /// new_map.extend(&map);
6577
    /// assert_eq!(new_map, map);
6578
    ///
6579
    /// let mut vec: Vec<_> = new_map.into_iter().collect();
6580
    /// // The `IntoIter` iterator produces items in arbitrary order, so the
6581
    /// // items must be sorted to test them against a sorted array.
6582
    /// vec.sort_unstable();
6583
    /// assert_eq!(vec, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]);
6584
    /// ```
6585
    #[cfg_attr(feature = "inline-more", inline)]
6586
0
    fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) {
6587
0
        self.extend(iter.into_iter().map(|(&key, &value)| (key, value)));
6588
0
    }
6589
6590
    #[inline]
6591
    #[cfg(feature = "nightly")]
6592
    fn extend_one(&mut self, (k, v): (&'a K, &'a V)) {
6593
        self.insert(*k, *v);
6594
    }
6595
6596
    #[inline]
6597
    #[cfg(feature = "nightly")]
6598
    fn extend_reserve(&mut self, additional: usize) {
6599
        Extend::<(K, V)>::extend_reserve(self, additional);
6600
    }
6601
}
6602
6603
/// Inserts all new key-values from the iterator and replaces values with existing
6604
/// keys with new values returned from the iterator.
6605
impl<'a, K, V, S, A> Extend<&'a (K, V)> for HashMap<K, V, S, A>
6606
where
6607
    K: Eq + Hash + Copy,
6608
    V: Copy,
6609
    S: BuildHasher,
6610
    A: Allocator,
6611
{
6612
    /// Inserts all new key-values from the iterator to existing `HashMap<K, V, S, A>`.
6613
    /// Replace values with existing keys with new values returned from the iterator.
6614
    /// The keys and values must implement [`Copy`] trait.
6615
    ///
6616
    /// [`Copy`]: https://doc.rust-lang.org/core/marker/trait.Copy.html
6617
    ///
6618
    /// # Examples
6619
    ///
6620
    /// ```
6621
    /// use hashbrown::hash_map::HashMap;
6622
    ///
6623
    /// let mut map = HashMap::new();
6624
    /// map.insert(1, 100);
6625
    ///
6626
    /// let arr = [(1, 1), (2, 2)];
6627
    /// let some_iter = arr.iter();
6628
    /// map.extend(some_iter);
6629
    /// // Replace values with existing keys with new values returned from the iterator.
6630
    /// // So that the map.get(&1) doesn't return Some(&100).
6631
    /// assert_eq!(map.get(&1), Some(&1));
6632
    ///
6633
    /// let some_vec: Vec<_> = vec![(3, 3), (4, 4)];
6634
    /// map.extend(&some_vec);
6635
    ///
6636
    /// let some_arr = [(5, 5), (6, 6)];
6637
    /// map.extend(&some_arr);
6638
    ///
6639
    /// let mut vec: Vec<_> = map.into_iter().collect();
6640
    /// // The `IntoIter` iterator produces items in arbitrary order, so the
6641
    /// // items must be sorted to test them against a sorted array.
6642
    /// vec.sort_unstable();
6643
    /// assert_eq!(vec, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]);
6644
    /// ```
6645
    #[cfg_attr(feature = "inline-more", inline)]
6646
0
    fn extend<T: IntoIterator<Item = &'a (K, V)>>(&mut self, iter: T) {
6647
0
        self.extend(iter.into_iter().map(|&(key, value)| (key, value)));
6648
0
    }
6649
6650
    #[inline]
6651
    #[cfg(feature = "nightly")]
6652
    fn extend_one(&mut self, &(k, v): &'a (K, V)) {
6653
        self.insert(k, v);
6654
    }
6655
6656
    #[inline]
6657
    #[cfg(feature = "nightly")]
6658
    fn extend_reserve(&mut self, additional: usize) {
6659
        Extend::<(K, V)>::extend_reserve(self, additional);
6660
    }
6661
}
6662
6663
#[allow(dead_code)]
6664
0
fn assert_covariance() {
6665
0
    fn map_key<'new>(v: HashMap<&'static str, u8>) -> HashMap<&'new str, u8> {
6666
0
        v
6667
0
    }
6668
0
    fn map_val<'new>(v: HashMap<u8, &'static str>) -> HashMap<u8, &'new str> {
6669
0
        v
6670
0
    }
6671
0
    fn iter_key<'a, 'new>(v: Iter<'a, &'static str, u8>) -> Iter<'a, &'new str, u8> {
6672
0
        v
6673
0
    }
6674
0
    fn iter_val<'a, 'new>(v: Iter<'a, u8, &'static str>) -> Iter<'a, u8, &'new str> {
6675
0
        v
6676
0
    }
6677
0
    fn into_iter_key<'new, A: Allocator>(
6678
0
        v: IntoIter<&'static str, u8, A>,
6679
0
    ) -> IntoIter<&'new str, u8, A> {
6680
0
        v
6681
0
    }
6682
0
    fn into_iter_val<'new, A: Allocator>(
6683
0
        v: IntoIter<u8, &'static str, A>,
6684
0
    ) -> IntoIter<u8, &'new str, A> {
6685
0
        v
6686
0
    }
6687
0
    fn keys_key<'a, 'new>(v: Keys<'a, &'static str, u8>) -> Keys<'a, &'new str, u8> {
6688
0
        v
6689
0
    }
6690
0
    fn keys_val<'a, 'new>(v: Keys<'a, u8, &'static str>) -> Keys<'a, u8, &'new str> {
6691
0
        v
6692
0
    }
6693
0
    fn values_key<'a, 'new>(v: Values<'a, &'static str, u8>) -> Values<'a, &'new str, u8> {
6694
0
        v
6695
0
    }
6696
0
    fn values_val<'a, 'new>(v: Values<'a, u8, &'static str>) -> Values<'a, u8, &'new str> {
6697
0
        v
6698
0
    }
6699
0
    fn drain<'new>(
6700
0
        d: Drain<'static, &'static str, &'static str>,
6701
0
    ) -> Drain<'new, &'new str, &'new str> {
6702
0
        d
6703
0
    }
6704
0
}
6705
6706
#[cfg(test)]
6707
mod test_map {
6708
    use super::DefaultHashBuilder;
6709
    use super::Entry::{Occupied, Vacant};
6710
    use super::EntryRef;
6711
    use super::{HashMap, RawEntryMut};
6712
    use alloc::string::{String, ToString};
6713
    use alloc::sync::Arc;
6714
    use allocator_api2::alloc::{AllocError, Allocator, Global};
6715
    use core::alloc::Layout;
6716
    use core::ptr::NonNull;
6717
    use core::sync::atomic::{AtomicI8, Ordering};
6718
    use rand::{rngs::SmallRng, Rng, SeedableRng};
6719
    use std::borrow::ToOwned;
6720
    use std::cell::RefCell;
6721
    use std::usize;
6722
    use std::vec::Vec;
6723
6724
    #[test]
6725
    fn test_zero_capacities() {
6726
        type HM = HashMap<i32, i32>;
6727
6728
        let m = HM::new();
6729
        assert_eq!(m.capacity(), 0);
6730
6731
        let m = HM::default();
6732
        assert_eq!(m.capacity(), 0);
6733
6734
        let m = HM::with_hasher(DefaultHashBuilder::default());
6735
        assert_eq!(m.capacity(), 0);
6736
6737
        let m = HM::with_capacity(0);
6738
        assert_eq!(m.capacity(), 0);
6739
6740
        let m = HM::with_capacity_and_hasher(0, DefaultHashBuilder::default());
6741
        assert_eq!(m.capacity(), 0);
6742
6743
        let mut m = HM::new();
6744
        m.insert(1, 1);
6745
        m.insert(2, 2);
6746
        m.remove(&1);
6747
        m.remove(&2);
6748
        m.shrink_to_fit();
6749
        assert_eq!(m.capacity(), 0);
6750
6751
        let mut m = HM::new();
6752
        m.reserve(0);
6753
        assert_eq!(m.capacity(), 0);
6754
    }
6755
6756
    #[test]
6757
    fn test_create_capacity_zero() {
6758
        let mut m = HashMap::with_capacity(0);
6759
6760
        assert!(m.insert(1, 1).is_none());
6761
6762
        assert!(m.contains_key(&1));
6763
        assert!(!m.contains_key(&0));
6764
    }
6765
6766
    #[test]
6767
    fn test_insert() {
6768
        let mut m = HashMap::new();
6769
        assert_eq!(m.len(), 0);
6770
        assert!(m.insert(1, 2).is_none());
6771
        assert_eq!(m.len(), 1);
6772
        assert!(m.insert(2, 4).is_none());
6773
        assert_eq!(m.len(), 2);
6774
        assert_eq!(*m.get(&1).unwrap(), 2);
6775
        assert_eq!(*m.get(&2).unwrap(), 4);
6776
    }
6777
6778
    #[test]
6779
    fn test_clone() {
6780
        let mut m = HashMap::new();
6781
        assert_eq!(m.len(), 0);
6782
        assert!(m.insert(1, 2).is_none());
6783
        assert_eq!(m.len(), 1);
6784
        assert!(m.insert(2, 4).is_none());
6785
        assert_eq!(m.len(), 2);
6786
        #[allow(clippy::redundant_clone)]
6787
        let m2 = m.clone();
6788
        assert_eq!(*m2.get(&1).unwrap(), 2);
6789
        assert_eq!(*m2.get(&2).unwrap(), 4);
6790
        assert_eq!(m2.len(), 2);
6791
    }
6792
6793
    #[test]
6794
    fn test_clone_from() {
6795
        let mut m = HashMap::new();
6796
        let mut m2 = HashMap::new();
6797
        assert_eq!(m.len(), 0);
6798
        assert!(m.insert(1, 2).is_none());
6799
        assert_eq!(m.len(), 1);
6800
        assert!(m.insert(2, 4).is_none());
6801
        assert_eq!(m.len(), 2);
6802
        m2.clone_from(&m);
6803
        assert_eq!(*m2.get(&1).unwrap(), 2);
6804
        assert_eq!(*m2.get(&2).unwrap(), 4);
6805
        assert_eq!(m2.len(), 2);
6806
    }
6807
6808
    thread_local! { static DROP_VECTOR: RefCell<Vec<i32>> = const { RefCell::new(Vec::new()) } }
6809
6810
    #[derive(Hash, PartialEq, Eq)]
6811
    struct Droppable {
6812
        k: usize,
6813
    }
6814
6815
    impl Droppable {
6816
        fn new(k: usize) -> Droppable {
6817
            DROP_VECTOR.with(|slot| {
6818
                slot.borrow_mut()[k] += 1;
6819
            });
6820
6821
            Droppable { k }
6822
        }
6823
    }
6824
6825
    impl Drop for Droppable {
6826
        fn drop(&mut self) {
6827
            DROP_VECTOR.with(|slot| {
6828
                slot.borrow_mut()[self.k] -= 1;
6829
            });
6830
        }
6831
    }
6832
6833
    impl Clone for Droppable {
6834
        fn clone(&self) -> Self {
6835
            Droppable::new(self.k)
6836
        }
6837
    }
6838
6839
    #[test]
6840
    fn test_drops() {
6841
        DROP_VECTOR.with(|slot| {
6842
            *slot.borrow_mut() = vec![0; 200];
6843
        });
6844
6845
        {
6846
            let mut m = HashMap::new();
6847
6848
            DROP_VECTOR.with(|v| {
6849
                for i in 0..200 {
6850
                    assert_eq!(v.borrow()[i], 0);
6851
                }
6852
            });
6853
6854
            for i in 0..100 {
6855
                let d1 = Droppable::new(i);
6856
                let d2 = Droppable::new(i + 100);
6857
                m.insert(d1, d2);
6858
            }
6859
6860
            DROP_VECTOR.with(|v| {
6861
                for i in 0..200 {
6862
                    assert_eq!(v.borrow()[i], 1);
6863
                }
6864
            });
6865
6866
            for i in 0..50 {
6867
                let k = Droppable::new(i);
6868
                let v = m.remove(&k);
6869
6870
                assert!(v.is_some());
6871
6872
                DROP_VECTOR.with(|v| {
6873
                    assert_eq!(v.borrow()[i], 1);
6874
                    assert_eq!(v.borrow()[i + 100], 1);
6875
                });
6876
            }
6877
6878
            DROP_VECTOR.with(|v| {
6879
                for i in 0..50 {
6880
                    assert_eq!(v.borrow()[i], 0);
6881
                    assert_eq!(v.borrow()[i + 100], 0);
6882
                }
6883
6884
                for i in 50..100 {
6885
                    assert_eq!(v.borrow()[i], 1);
6886
                    assert_eq!(v.borrow()[i + 100], 1);
6887
                }
6888
            });
6889
        }
6890
6891
        DROP_VECTOR.with(|v| {
6892
            for i in 0..200 {
6893
                assert_eq!(v.borrow()[i], 0);
6894
            }
6895
        });
6896
    }
6897
6898
    #[test]
6899
    fn test_into_iter_drops() {
6900
        DROP_VECTOR.with(|v| {
6901
            *v.borrow_mut() = vec![0; 200];
6902
        });
6903
6904
        let hm = {
6905
            let mut hm = HashMap::new();
6906
6907
            DROP_VECTOR.with(|v| {
6908
                for i in 0..200 {
6909
                    assert_eq!(v.borrow()[i], 0);
6910
                }
6911
            });
6912
6913
            for i in 0..100 {
6914
                let d1 = Droppable::new(i);
6915
                let d2 = Droppable::new(i + 100);
6916
                hm.insert(d1, d2);
6917
            }
6918
6919
            DROP_VECTOR.with(|v| {
6920
                for i in 0..200 {
6921
                    assert_eq!(v.borrow()[i], 1);
6922
                }
6923
            });
6924
6925
            hm
6926
        };
6927
6928
        // By the way, ensure that cloning doesn't screw up the dropping.
6929
        drop(hm.clone());
6930
6931
        {
6932
            let mut half = hm.into_iter().take(50);
6933
6934
            DROP_VECTOR.with(|v| {
6935
                for i in 0..200 {
6936
                    assert_eq!(v.borrow()[i], 1);
6937
                }
6938
            });
6939
6940
            for _ in half.by_ref() {}
6941
6942
            DROP_VECTOR.with(|v| {
6943
                let nk = (0..100).filter(|&i| v.borrow()[i] == 1).count();
6944
6945
                let nv = (0..100).filter(|&i| v.borrow()[i + 100] == 1).count();
6946
6947
                assert_eq!(nk, 50);
6948
                assert_eq!(nv, 50);
6949
            });
6950
        };
6951
6952
        DROP_VECTOR.with(|v| {
6953
            for i in 0..200 {
6954
                assert_eq!(v.borrow()[i], 0);
6955
            }
6956
        });
6957
    }
6958
6959
    #[test]
6960
    fn test_empty_remove() {
6961
        let mut m: HashMap<i32, bool> = HashMap::new();
6962
        assert_eq!(m.remove(&0), None);
6963
    }
6964
6965
    #[test]
6966
    fn test_empty_entry() {
6967
        let mut m: HashMap<i32, bool> = HashMap::new();
6968
        match m.entry(0) {
6969
            Occupied(_) => panic!(),
6970
            Vacant(_) => {}
6971
        }
6972
        assert!(*m.entry(0).or_insert(true));
6973
        assert_eq!(m.len(), 1);
6974
    }
6975
6976
    #[test]
6977
    fn test_empty_entry_ref() {
6978
        let mut m: HashMap<std::string::String, bool> = HashMap::new();
6979
        match m.entry_ref("poneyland") {
6980
            EntryRef::Occupied(_) => panic!(),
6981
            EntryRef::Vacant(_) => {}
6982
        }
6983
        assert!(*m.entry_ref("poneyland").or_insert(true));
6984
        assert_eq!(m.len(), 1);
6985
    }
6986
6987
    #[test]
6988
    fn test_empty_iter() {
6989
        let mut m: HashMap<i32, bool> = HashMap::new();
6990
        assert_eq!(m.drain().next(), None);
6991
        assert_eq!(m.keys().next(), None);
6992
        assert_eq!(m.values().next(), None);
6993
        assert_eq!(m.values_mut().next(), None);
6994
        assert_eq!(m.iter().next(), None);
6995
        assert_eq!(m.iter_mut().next(), None);
6996
        assert_eq!(m.len(), 0);
6997
        assert!(m.is_empty());
6998
        assert_eq!(m.into_iter().next(), None);
6999
    }
7000
7001
    #[test]
7002
    #[cfg_attr(miri, ignore)] // FIXME: takes too long
7003
    fn test_lots_of_insertions() {
7004
        let mut m = HashMap::new();
7005
7006
        // Try this a few times to make sure we never screw up the hashmap's
7007
        // internal state.
7008
        for _ in 0..10 {
7009
            assert!(m.is_empty());
7010
7011
            for i in 1..1001 {
7012
                assert!(m.insert(i, i).is_none());
7013
7014
                for j in 1..=i {
7015
                    let r = m.get(&j);
7016
                    assert_eq!(r, Some(&j));
7017
                }
7018
7019
                for j in i + 1..1001 {
7020
                    let r = m.get(&j);
7021
                    assert_eq!(r, None);
7022
                }
7023
            }
7024
7025
            for i in 1001..2001 {
7026
                assert!(!m.contains_key(&i));
7027
            }
7028
7029
            // remove forwards
7030
            for i in 1..1001 {
7031
                assert!(m.remove(&i).is_some());
7032
7033
                for j in 1..=i {
7034
                    assert!(!m.contains_key(&j));
7035
                }
7036
7037
                for j in i + 1..1001 {
7038
                    assert!(m.contains_key(&j));
7039
                }
7040
            }
7041
7042
            for i in 1..1001 {
7043
                assert!(!m.contains_key(&i));
7044
            }
7045
7046
            for i in 1..1001 {
7047
                assert!(m.insert(i, i).is_none());
7048
            }
7049
7050
            // remove backwards
7051
            for i in (1..1001).rev() {
7052
                assert!(m.remove(&i).is_some());
7053
7054
                for j in i..1001 {
7055
                    assert!(!m.contains_key(&j));
7056
                }
7057
7058
                for j in 1..i {
7059
                    assert!(m.contains_key(&j));
7060
                }
7061
            }
7062
        }
7063
    }
7064
7065
    #[test]
7066
    fn test_find_mut() {
7067
        let mut m = HashMap::new();
7068
        assert!(m.insert(1, 12).is_none());
7069
        assert!(m.insert(2, 8).is_none());
7070
        assert!(m.insert(5, 14).is_none());
7071
        let new = 100;
7072
        match m.get_mut(&5) {
7073
            None => panic!(),
7074
            Some(x) => *x = new,
7075
        }
7076
        assert_eq!(m.get(&5), Some(&new));
7077
    }
7078
7079
    #[test]
7080
    fn test_insert_overwrite() {
7081
        let mut m = HashMap::new();
7082
        assert!(m.insert(1, 2).is_none());
7083
        assert_eq!(*m.get(&1).unwrap(), 2);
7084
        assert!(m.insert(1, 3).is_some());
7085
        assert_eq!(*m.get(&1).unwrap(), 3);
7086
    }
7087
7088
    #[test]
7089
    fn test_insert_conflicts() {
7090
        let mut m = HashMap::with_capacity(4);
7091
        assert!(m.insert(1, 2).is_none());
7092
        assert!(m.insert(5, 3).is_none());
7093
        assert!(m.insert(9, 4).is_none());
7094
        assert_eq!(*m.get(&9).unwrap(), 4);
7095
        assert_eq!(*m.get(&5).unwrap(), 3);
7096
        assert_eq!(*m.get(&1).unwrap(), 2);
7097
    }
7098
7099
    #[test]
7100
    fn test_conflict_remove() {
7101
        let mut m = HashMap::with_capacity(4);
7102
        assert!(m.insert(1, 2).is_none());
7103
        assert_eq!(*m.get(&1).unwrap(), 2);
7104
        assert!(m.insert(5, 3).is_none());
7105
        assert_eq!(*m.get(&1).unwrap(), 2);
7106
        assert_eq!(*m.get(&5).unwrap(), 3);
7107
        assert!(m.insert(9, 4).is_none());
7108
        assert_eq!(*m.get(&1).unwrap(), 2);
7109
        assert_eq!(*m.get(&5).unwrap(), 3);
7110
        assert_eq!(*m.get(&9).unwrap(), 4);
7111
        assert!(m.remove(&1).is_some());
7112
        assert_eq!(*m.get(&9).unwrap(), 4);
7113
        assert_eq!(*m.get(&5).unwrap(), 3);
7114
    }
7115
7116
    #[test]
7117
    fn test_insert_unique_unchecked() {
7118
        let mut map = HashMap::new();
7119
        let (k1, v1) = map.insert_unique_unchecked(10, 11);
7120
        assert_eq!((&10, &mut 11), (k1, v1));
7121
        let (k2, v2) = map.insert_unique_unchecked(20, 21);
7122
        assert_eq!((&20, &mut 21), (k2, v2));
7123
        assert_eq!(Some(&11), map.get(&10));
7124
        assert_eq!(Some(&21), map.get(&20));
7125
        assert_eq!(None, map.get(&30));
7126
    }
7127
7128
    #[test]
7129
    fn test_is_empty() {
7130
        let mut m = HashMap::with_capacity(4);
7131
        assert!(m.insert(1, 2).is_none());
7132
        assert!(!m.is_empty());
7133
        assert!(m.remove(&1).is_some());
7134
        assert!(m.is_empty());
7135
    }
7136
7137
    #[test]
7138
    fn test_remove() {
7139
        let mut m = HashMap::new();
7140
        m.insert(1, 2);
7141
        assert_eq!(m.remove(&1), Some(2));
7142
        assert_eq!(m.remove(&1), None);
7143
    }
7144
7145
    #[test]
7146
    fn test_remove_entry() {
7147
        let mut m = HashMap::new();
7148
        m.insert(1, 2);
7149
        assert_eq!(m.remove_entry(&1), Some((1, 2)));
7150
        assert_eq!(m.remove(&1), None);
7151
    }
7152
7153
    #[test]
7154
    fn test_iterate() {
7155
        let mut m = HashMap::with_capacity(4);
7156
        for i in 0..32 {
7157
            assert!(m.insert(i, i * 2).is_none());
7158
        }
7159
        assert_eq!(m.len(), 32);
7160
7161
        let mut observed: u32 = 0;
7162
7163
        for (k, v) in &m {
7164
            assert_eq!(*v, *k * 2);
7165
            observed |= 1 << *k;
7166
        }
7167
        assert_eq!(observed, 0xFFFF_FFFF);
7168
    }
7169
7170
    #[test]
7171
    fn test_keys() {
7172
        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
7173
        let map: HashMap<_, _> = vec.into_iter().collect();
7174
        let keys: Vec<_> = map.keys().copied().collect();
7175
        assert_eq!(keys.len(), 3);
7176
        assert!(keys.contains(&1));
7177
        assert!(keys.contains(&2));
7178
        assert!(keys.contains(&3));
7179
    }
7180
7181
    #[test]
7182
    fn test_values() {
7183
        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
7184
        let map: HashMap<_, _> = vec.into_iter().collect();
7185
        let values: Vec<_> = map.values().copied().collect();
7186
        assert_eq!(values.len(), 3);
7187
        assert!(values.contains(&'a'));
7188
        assert!(values.contains(&'b'));
7189
        assert!(values.contains(&'c'));
7190
    }
7191
7192
    #[test]
7193
    fn test_values_mut() {
7194
        let vec = vec![(1, 1), (2, 2), (3, 3)];
7195
        let mut map: HashMap<_, _> = vec.into_iter().collect();
7196
        for value in map.values_mut() {
7197
            *value *= 2;
7198
        }
7199
        let values: Vec<_> = map.values().copied().collect();
7200
        assert_eq!(values.len(), 3);
7201
        assert!(values.contains(&2));
7202
        assert!(values.contains(&4));
7203
        assert!(values.contains(&6));
7204
    }
7205
7206
    #[test]
7207
    fn test_into_keys() {
7208
        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
7209
        let map: HashMap<_, _> = vec.into_iter().collect();
7210
        let keys: Vec<_> = map.into_keys().collect();
7211
7212
        assert_eq!(keys.len(), 3);
7213
        assert!(keys.contains(&1));
7214
        assert!(keys.contains(&2));
7215
        assert!(keys.contains(&3));
7216
    }
7217
7218
    #[test]
7219
    fn test_into_values() {
7220
        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
7221
        let map: HashMap<_, _> = vec.into_iter().collect();
7222
        let values: Vec<_> = map.into_values().collect();
7223
7224
        assert_eq!(values.len(), 3);
7225
        assert!(values.contains(&'a'));
7226
        assert!(values.contains(&'b'));
7227
        assert!(values.contains(&'c'));
7228
    }
7229
7230
    #[test]
7231
    fn test_find() {
7232
        let mut m = HashMap::new();
7233
        assert!(m.get(&1).is_none());
7234
        m.insert(1, 2);
7235
        match m.get(&1) {
7236
            None => panic!(),
7237
            Some(v) => assert_eq!(*v, 2),
7238
        }
7239
    }
7240
7241
    #[test]
7242
    fn test_eq() {
7243
        let mut m1 = HashMap::new();
7244
        m1.insert(1, 2);
7245
        m1.insert(2, 3);
7246
        m1.insert(3, 4);
7247
7248
        let mut m2 = HashMap::new();
7249
        m2.insert(1, 2);
7250
        m2.insert(2, 3);
7251
7252
        assert!(m1 != m2);
7253
7254
        m2.insert(3, 4);
7255
7256
        assert_eq!(m1, m2);
7257
    }
7258
7259
    #[test]
7260
    fn test_show() {
7261
        let mut map = HashMap::new();
7262
        let empty: HashMap<i32, i32> = HashMap::new();
7263
7264
        map.insert(1, 2);
7265
        map.insert(3, 4);
7266
7267
        let map_str = format!("{map:?}");
7268
7269
        assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
7270
        assert_eq!(format!("{empty:?}"), "{}");
7271
    }
7272
7273
    #[test]
7274
    fn test_expand() {
7275
        let mut m = HashMap::new();
7276
7277
        assert_eq!(m.len(), 0);
7278
        assert!(m.is_empty());
7279
7280
        let mut i = 0;
7281
        let old_raw_cap = m.raw_capacity();
7282
        while old_raw_cap == m.raw_capacity() {
7283
            m.insert(i, i);
7284
            i += 1;
7285
        }
7286
7287
        assert_eq!(m.len(), i);
7288
        assert!(!m.is_empty());
7289
    }
7290
7291
    #[test]
7292
    fn test_behavior_resize_policy() {
7293
        let mut m = HashMap::new();
7294
7295
        assert_eq!(m.len(), 0);
7296
        assert_eq!(m.raw_capacity(), 1);
7297
        assert!(m.is_empty());
7298
7299
        m.insert(0, 0);
7300
        m.remove(&0);
7301
        assert!(m.is_empty());
7302
        let initial_raw_cap = m.raw_capacity();
7303
        m.reserve(initial_raw_cap);
7304
        let raw_cap = m.raw_capacity();
7305
7306
        assert_eq!(raw_cap, initial_raw_cap * 2);
7307
7308
        let mut i = 0;
7309
        for _ in 0..raw_cap * 3 / 4 {
7310
            m.insert(i, i);
7311
            i += 1;
7312
        }
7313
        // three quarters full
7314
7315
        assert_eq!(m.len(), i);
7316
        assert_eq!(m.raw_capacity(), raw_cap);
7317
7318
        for _ in 0..raw_cap / 4 {
7319
            m.insert(i, i);
7320
            i += 1;
7321
        }
7322
        // half full
7323
7324
        let new_raw_cap = m.raw_capacity();
7325
        assert_eq!(new_raw_cap, raw_cap * 2);
7326
7327
        for _ in 0..raw_cap / 2 - 1 {
7328
            i -= 1;
7329
            m.remove(&i);
7330
            assert_eq!(m.raw_capacity(), new_raw_cap);
7331
        }
7332
        // A little more than one quarter full.
7333
        m.shrink_to_fit();
7334
        assert_eq!(m.raw_capacity(), raw_cap);
7335
        // again, a little more than half full
7336
        for _ in 0..raw_cap / 2 {
7337
            i -= 1;
7338
            m.remove(&i);
7339
        }
7340
        m.shrink_to_fit();
7341
7342
        assert_eq!(m.len(), i);
7343
        assert!(!m.is_empty());
7344
        assert_eq!(m.raw_capacity(), initial_raw_cap);
7345
    }
7346
7347
    #[test]
7348
    fn test_reserve_shrink_to_fit() {
7349
        let mut m = HashMap::new();
7350
        m.insert(0, 0);
7351
        m.remove(&0);
7352
        assert!(m.capacity() >= m.len());
7353
        for i in 0..128 {
7354
            m.insert(i, i);
7355
        }
7356
        m.reserve(256);
7357
7358
        let usable_cap = m.capacity();
7359
        for i in 128..(128 + 256) {
7360
            m.insert(i, i);
7361
            assert_eq!(m.capacity(), usable_cap);
7362
        }
7363
7364
        for i in 100..(128 + 256) {
7365
            assert_eq!(m.remove(&i), Some(i));
7366
        }
7367
        m.shrink_to_fit();
7368
7369
        assert_eq!(m.len(), 100);
7370
        assert!(!m.is_empty());
7371
        assert!(m.capacity() >= m.len());
7372
7373
        for i in 0..100 {
7374
            assert_eq!(m.remove(&i), Some(i));
7375
        }
7376
        m.shrink_to_fit();
7377
        m.insert(0, 0);
7378
7379
        assert_eq!(m.len(), 1);
7380
        assert!(m.capacity() >= m.len());
7381
        assert_eq!(m.remove(&0), Some(0));
7382
    }
7383
7384
    #[test]
7385
    fn test_from_iter() {
7386
        let xs = [(1, 1), (2, 2), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
7387
7388
        let map: HashMap<_, _> = xs.iter().copied().collect();
7389
7390
        for &(k, v) in &xs {
7391
            assert_eq!(map.get(&k), Some(&v));
7392
        }
7393
7394
        assert_eq!(map.iter().len(), xs.len() - 1);
7395
    }
7396
7397
    #[test]
7398
    fn test_size_hint() {
7399
        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
7400
7401
        let map: HashMap<_, _> = xs.iter().copied().collect();
7402
7403
        let mut iter = map.iter();
7404
7405
        for _ in iter.by_ref().take(3) {}
7406
7407
        assert_eq!(iter.size_hint(), (3, Some(3)));
7408
    }
7409
7410
    #[test]
7411
    fn test_iter_len() {
7412
        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
7413
7414
        let map: HashMap<_, _> = xs.iter().copied().collect();
7415
7416
        let mut iter = map.iter();
7417
7418
        for _ in iter.by_ref().take(3) {}
7419
7420
        assert_eq!(iter.len(), 3);
7421
    }
7422
7423
    #[test]
7424
    fn test_mut_size_hint() {
7425
        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
7426
7427
        let mut map: HashMap<_, _> = xs.iter().copied().collect();
7428
7429
        let mut iter = map.iter_mut();
7430
7431
        for _ in iter.by_ref().take(3) {}
7432
7433
        assert_eq!(iter.size_hint(), (3, Some(3)));
7434
    }
7435
7436
    #[test]
7437
    fn test_iter_mut_len() {
7438
        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
7439
7440
        let mut map: HashMap<_, _> = xs.iter().copied().collect();
7441
7442
        let mut iter = map.iter_mut();
7443
7444
        for _ in iter.by_ref().take(3) {}
7445
7446
        assert_eq!(iter.len(), 3);
7447
    }
7448
7449
    #[test]
7450
    fn test_index() {
7451
        let mut map = HashMap::new();
7452
7453
        map.insert(1, 2);
7454
        map.insert(2, 1);
7455
        map.insert(3, 4);
7456
7457
        assert_eq!(map[&2], 1);
7458
    }
7459
7460
    #[test]
7461
    #[should_panic]
7462
    fn test_index_nonexistent() {
7463
        let mut map = HashMap::new();
7464
7465
        map.insert(1, 2);
7466
        map.insert(2, 1);
7467
        map.insert(3, 4);
7468
7469
        #[allow(clippy::no_effect)] // false positive lint
7470
        map[&4];
7471
    }
7472
7473
    #[test]
7474
    fn test_entry() {
7475
        let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
7476
7477
        let mut map: HashMap<_, _> = xs.iter().copied().collect();
7478
7479
        // Existing key (insert)
7480
        match map.entry(1) {
7481
            Vacant(_) => unreachable!(),
7482
            Occupied(mut view) => {
7483
                assert_eq!(view.get(), &10);
7484
                assert_eq!(view.insert(100), 10);
7485
            }
7486
        }
7487
        assert_eq!(map.get(&1).unwrap(), &100);
7488
        assert_eq!(map.len(), 6);
7489
7490
        // Existing key (update)
7491
        match map.entry(2) {
7492
            Vacant(_) => unreachable!(),
7493
            Occupied(mut view) => {
7494
                let v = view.get_mut();
7495
                let new_v = (*v) * 10;
7496
                *v = new_v;
7497
            }
7498
        }
7499
        assert_eq!(map.get(&2).unwrap(), &200);
7500
        assert_eq!(map.len(), 6);
7501
7502
        // Existing key (take)
7503
        match map.entry(3) {
7504
            Vacant(_) => unreachable!(),
7505
            Occupied(view) => {
7506
                assert_eq!(view.remove(), 30);
7507
            }
7508
        }
7509
        assert_eq!(map.get(&3), None);
7510
        assert_eq!(map.len(), 5);
7511
7512
        // Inexistent key (insert)
7513
        match map.entry(10) {
7514
            Occupied(_) => unreachable!(),
7515
            Vacant(view) => {
7516
                assert_eq!(*view.insert(1000), 1000);
7517
            }
7518
        }
7519
        assert_eq!(map.get(&10).unwrap(), &1000);
7520
        assert_eq!(map.len(), 6);
7521
    }
7522
7523
    #[test]
7524
    fn test_entry_ref() {
7525
        let xs = [
7526
            ("One".to_owned(), 10),
7527
            ("Two".to_owned(), 20),
7528
            ("Three".to_owned(), 30),
7529
            ("Four".to_owned(), 40),
7530
            ("Five".to_owned(), 50),
7531
            ("Six".to_owned(), 60),
7532
        ];
7533
7534
        let mut map: HashMap<_, _> = xs.iter().cloned().collect();
7535
7536
        // Existing key (insert)
7537
        match map.entry_ref("One") {
7538
            EntryRef::Vacant(_) => unreachable!(),
7539
            EntryRef::Occupied(mut view) => {
7540
                assert_eq!(view.get(), &10);
7541
                assert_eq!(view.insert(100), 10);
7542
            }
7543
        }
7544
        assert_eq!(map.get("One").unwrap(), &100);
7545
        assert_eq!(map.len(), 6);
7546
7547
        // Existing key (update)
7548
        match map.entry_ref("Two") {
7549
            EntryRef::Vacant(_) => unreachable!(),
7550
            EntryRef::Occupied(mut view) => {
7551
                let v = view.get_mut();
7552
                let new_v = (*v) * 10;
7553
                *v = new_v;
7554
            }
7555
        }
7556
        assert_eq!(map.get("Two").unwrap(), &200);
7557
        assert_eq!(map.len(), 6);
7558
7559
        // Existing key (take)
7560
        match map.entry_ref("Three") {
7561
            EntryRef::Vacant(_) => unreachable!(),
7562
            EntryRef::Occupied(view) => {
7563
                assert_eq!(view.remove(), 30);
7564
            }
7565
        }
7566
        assert_eq!(map.get("Three"), None);
7567
        assert_eq!(map.len(), 5);
7568
7569
        // Inexistent key (insert)
7570
        match map.entry_ref("Ten") {
7571
            EntryRef::Occupied(_) => unreachable!(),
7572
            EntryRef::Vacant(view) => {
7573
                assert_eq!(*view.insert(1000), 1000);
7574
            }
7575
        }
7576
        assert_eq!(map.get("Ten").unwrap(), &1000);
7577
        assert_eq!(map.len(), 6);
7578
    }
7579
7580
    #[test]
7581
    fn test_entry_take_doesnt_corrupt() {
7582
        #![allow(deprecated)] //rand
7583
                              // Test for #19292
7584
        fn check(m: &HashMap<i32, ()>) {
7585
            for k in m.keys() {
7586
                assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
7587
            }
7588
        }
7589
7590
        let mut m = HashMap::new();
7591
7592
        let mut rng = {
7593
            let seed = u64::from_le_bytes(*b"testseed");
7594
            SmallRng::seed_from_u64(seed)
7595
        };
7596
7597
        // Populate the map with some items.
7598
        for _ in 0..50 {
7599
            let x = rng.gen_range(-10..10);
7600
            m.insert(x, ());
7601
        }
7602
7603
        for _ in 0..1000 {
7604
            let x = rng.gen_range(-10..10);
7605
            match m.entry(x) {
7606
                Vacant(_) => {}
7607
                Occupied(e) => {
7608
                    e.remove();
7609
                }
7610
            }
7611
7612
            check(&m);
7613
        }
7614
    }
7615
7616
    #[test]
7617
    fn test_entry_ref_take_doesnt_corrupt() {
7618
        #![allow(deprecated)] //rand
7619
                              // Test for #19292
7620
        fn check(m: &HashMap<std::string::String, ()>) {
7621
            for k in m.keys() {
7622
                assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
7623
            }
7624
        }
7625
7626
        let mut m = HashMap::new();
7627
7628
        let mut rng = {
7629
            let seed = u64::from_le_bytes(*b"testseed");
7630
            SmallRng::seed_from_u64(seed)
7631
        };
7632
7633
        // Populate the map with some items.
7634
        for _ in 0..50 {
7635
            let mut x = std::string::String::with_capacity(1);
7636
            x.push(rng.gen_range('a'..='z'));
7637
            m.insert(x, ());
7638
        }
7639
7640
        for _ in 0..1000 {
7641
            let mut x = std::string::String::with_capacity(1);
7642
            x.push(rng.gen_range('a'..='z'));
7643
            match m.entry_ref(x.as_str()) {
7644
                EntryRef::Vacant(_) => {}
7645
                EntryRef::Occupied(e) => {
7646
                    e.remove();
7647
                }
7648
            }
7649
7650
            check(&m);
7651
        }
7652
    }
7653
7654
    #[test]
7655
    fn test_extend_ref_k_ref_v() {
7656
        let mut a = HashMap::new();
7657
        a.insert(1, "one");
7658
        let mut b = HashMap::new();
7659
        b.insert(2, "two");
7660
        b.insert(3, "three");
7661
7662
        a.extend(&b);
7663
7664
        assert_eq!(a.len(), 3);
7665
        assert_eq!(a[&1], "one");
7666
        assert_eq!(a[&2], "two");
7667
        assert_eq!(a[&3], "three");
7668
    }
7669
7670
    #[test]
7671
    #[allow(clippy::needless_borrow)]
7672
    fn test_extend_ref_kv_tuple() {
7673
        use std::ops::AddAssign;
7674
        let mut a = HashMap::new();
7675
        a.insert(0, 0);
7676
7677
        fn create_arr<T: AddAssign<T> + Copy, const N: usize>(start: T, step: T) -> [(T, T); N] {
7678
            let mut outs: [(T, T); N] = [(start, start); N];
7679
            let mut element = step;
7680
            outs.iter_mut().skip(1).for_each(|(k, v)| {
7681
                *k += element;
7682
                *v += element;
7683
                element += step;
7684
            });
7685
            outs
7686
        }
7687
7688
        let for_iter: Vec<_> = (0..100).map(|i| (i, i)).collect();
7689
        let iter = for_iter.iter();
7690
        let vec: Vec<_> = (100..200).map(|i| (i, i)).collect();
7691
        a.extend(iter);
7692
        a.extend(&vec);
7693
        a.extend(create_arr::<i32, 100>(200, 1));
7694
7695
        assert_eq!(a.len(), 300);
7696
7697
        for item in 0..300 {
7698
            assert_eq!(a[&item], item);
7699
        }
7700
    }
7701
7702
    #[test]
7703
    fn test_capacity_not_less_than_len() {
7704
        let mut a = HashMap::new();
7705
        let mut item = 0;
7706
7707
        for _ in 0..116 {
7708
            a.insert(item, 0);
7709
            item += 1;
7710
        }
7711
7712
        assert!(a.capacity() > a.len());
7713
7714
        let free = a.capacity() - a.len();
7715
        for _ in 0..free {
7716
            a.insert(item, 0);
7717
            item += 1;
7718
        }
7719
7720
        assert_eq!(a.len(), a.capacity());
7721
7722
        // Insert at capacity should cause allocation.
7723
        a.insert(item, 0);
7724
        assert!(a.capacity() > a.len());
7725
    }
7726
7727
    #[test]
7728
    fn test_occupied_entry_key() {
7729
        let mut a = HashMap::new();
7730
        let key = "hello there";
7731
        let value = "value goes here";
7732
        assert!(a.is_empty());
7733
        a.insert(key, value);
7734
        assert_eq!(a.len(), 1);
7735
        assert_eq!(a[key], value);
7736
7737
        match a.entry(key) {
7738
            Vacant(_) => panic!(),
7739
            Occupied(e) => assert_eq!(key, *e.key()),
7740
        }
7741
        assert_eq!(a.len(), 1);
7742
        assert_eq!(a[key], value);
7743
    }
7744
7745
    #[test]
7746
    fn test_occupied_entry_ref_key() {
7747
        let mut a = HashMap::new();
7748
        let key = "hello there";
7749
        let value = "value goes here";
7750
        assert!(a.is_empty());
7751
        a.insert(key.to_owned(), value);
7752
        assert_eq!(a.len(), 1);
7753
        assert_eq!(a[key], value);
7754
7755
        match a.entry_ref(key) {
7756
            EntryRef::Vacant(_) => panic!(),
7757
            EntryRef::Occupied(e) => assert_eq!(key, e.key()),
7758
        }
7759
        assert_eq!(a.len(), 1);
7760
        assert_eq!(a[key], value);
7761
    }
7762
7763
    #[test]
7764
    fn test_vacant_entry_key() {
7765
        let mut a = HashMap::new();
7766
        let key = "hello there";
7767
        let value = "value goes here";
7768
7769
        assert!(a.is_empty());
7770
        match a.entry(key) {
7771
            Occupied(_) => panic!(),
7772
            Vacant(e) => {
7773
                assert_eq!(key, *e.key());
7774
                e.insert(value);
7775
            }
7776
        }
7777
        assert_eq!(a.len(), 1);
7778
        assert_eq!(a[key], value);
7779
    }
7780
7781
    #[test]
7782
    fn test_vacant_entry_ref_key() {
7783
        let mut a: HashMap<std::string::String, &str> = HashMap::new();
7784
        let key = "hello there";
7785
        let value = "value goes here";
7786
7787
        assert!(a.is_empty());
7788
        match a.entry_ref(key) {
7789
            EntryRef::Occupied(_) => panic!(),
7790
            EntryRef::Vacant(e) => {
7791
                assert_eq!(key, e.key());
7792
                e.insert(value);
7793
            }
7794
        }
7795
        assert_eq!(a.len(), 1);
7796
        assert_eq!(a[key], value);
7797
    }
7798
7799
    #[test]
7800
    fn test_occupied_entry_replace_entry_with() {
7801
        let mut a = HashMap::new();
7802
7803
        let key = "a key";
7804
        let value = "an initial value";
7805
        let new_value = "a new value";
7806
7807
        let entry = a.entry(key).insert(value).replace_entry_with(|k, v| {
7808
            assert_eq!(k, &key);
7809
            assert_eq!(v, value);
7810
            Some(new_value)
7811
        });
7812
7813
        match entry {
7814
            Occupied(e) => {
7815
                assert_eq!(e.key(), &key);
7816
                assert_eq!(e.get(), &new_value);
7817
            }
7818
            Vacant(_) => panic!(),
7819
        }
7820
7821
        assert_eq!(a[key], new_value);
7822
        assert_eq!(a.len(), 1);
7823
7824
        let entry = match a.entry(key) {
7825
            Occupied(e) => e.replace_entry_with(|k, v| {
7826
                assert_eq!(k, &key);
7827
                assert_eq!(v, new_value);
7828
                None
7829
            }),
7830
            Vacant(_) => panic!(),
7831
        };
7832
7833
        match entry {
7834
            Vacant(e) => assert_eq!(e.key(), &key),
7835
            Occupied(_) => panic!(),
7836
        }
7837
7838
        assert!(!a.contains_key(key));
7839
        assert_eq!(a.len(), 0);
7840
    }
7841
7842
    #[test]
7843
    fn test_occupied_entry_ref_replace_entry_with() {
7844
        let mut a: HashMap<std::string::String, &str> = HashMap::new();
7845
7846
        let key = "a key";
7847
        let value = "an initial value";
7848
        let new_value = "a new value";
7849
7850
        let entry = a.entry_ref(key).insert(value).replace_entry_with(|k, v| {
7851
            assert_eq!(k, key);
7852
            assert_eq!(v, value);
7853
            Some(new_value)
7854
        });
7855
7856
        match entry {
7857
            EntryRef::Occupied(e) => {
7858
                assert_eq!(e.key(), key);
7859
                assert_eq!(e.get(), &new_value);
7860
            }
7861
            EntryRef::Vacant(_) => panic!(),
7862
        }
7863
7864
        assert_eq!(a[key], new_value);
7865
        assert_eq!(a.len(), 1);
7866
7867
        let entry = match a.entry_ref(key) {
7868
            EntryRef::Occupied(e) => e.replace_entry_with(|k, v| {
7869
                assert_eq!(k, key);
7870
                assert_eq!(v, new_value);
7871
                None
7872
            }),
7873
            EntryRef::Vacant(_) => panic!(),
7874
        };
7875
7876
        match entry {
7877
            EntryRef::Vacant(e) => assert_eq!(e.key(), key),
7878
            EntryRef::Occupied(_) => panic!(),
7879
        }
7880
7881
        assert!(!a.contains_key(key));
7882
        assert_eq!(a.len(), 0);
7883
    }
7884
7885
    #[test]
7886
    fn test_entry_and_replace_entry_with() {
7887
        let mut a = HashMap::new();
7888
7889
        let key = "a key";
7890
        let value = "an initial value";
7891
        let new_value = "a new value";
7892
7893
        let entry = a.entry(key).and_replace_entry_with(|_, _| panic!());
7894
7895
        match entry {
7896
            Vacant(e) => assert_eq!(e.key(), &key),
7897
            Occupied(_) => panic!(),
7898
        }
7899
7900
        a.insert(key, value);
7901
7902
        let entry = a.entry(key).and_replace_entry_with(|k, v| {
7903
            assert_eq!(k, &key);
7904
            assert_eq!(v, value);
7905
            Some(new_value)
7906
        });
7907
7908
        match entry {
7909
            Occupied(e) => {
7910
                assert_eq!(e.key(), &key);
7911
                assert_eq!(e.get(), &new_value);
7912
            }
7913
            Vacant(_) => panic!(),
7914
        }
7915
7916
        assert_eq!(a[key], new_value);
7917
        assert_eq!(a.len(), 1);
7918
7919
        let entry = a.entry(key).and_replace_entry_with(|k, v| {
7920
            assert_eq!(k, &key);
7921
            assert_eq!(v, new_value);
7922
            None
7923
        });
7924
7925
        match entry {
7926
            Vacant(e) => assert_eq!(e.key(), &key),
7927
            Occupied(_) => panic!(),
7928
        }
7929
7930
        assert!(!a.contains_key(key));
7931
        assert_eq!(a.len(), 0);
7932
    }
7933
7934
    #[test]
7935
    fn test_entry_ref_and_replace_entry_with() {
7936
        let mut a = HashMap::new();
7937
7938
        let key = "a key";
7939
        let value = "an initial value";
7940
        let new_value = "a new value";
7941
7942
        let entry = a.entry_ref(key).and_replace_entry_with(|_, _| panic!());
7943
7944
        match entry {
7945
            EntryRef::Vacant(e) => assert_eq!(e.key(), key),
7946
            EntryRef::Occupied(_) => panic!(),
7947
        }
7948
7949
        a.insert(key.to_owned(), value);
7950
7951
        let entry = a.entry_ref(key).and_replace_entry_with(|k, v| {
7952
            assert_eq!(k, key);
7953
            assert_eq!(v, value);
7954
            Some(new_value)
7955
        });
7956
7957
        match entry {
7958
            EntryRef::Occupied(e) => {
7959
                assert_eq!(e.key(), key);
7960
                assert_eq!(e.get(), &new_value);
7961
            }
7962
            EntryRef::Vacant(_) => panic!(),
7963
        }
7964
7965
        assert_eq!(a[key], new_value);
7966
        assert_eq!(a.len(), 1);
7967
7968
        let entry = a.entry_ref(key).and_replace_entry_with(|k, v| {
7969
            assert_eq!(k, key);
7970
            assert_eq!(v, new_value);
7971
            None
7972
        });
7973
7974
        match entry {
7975
            EntryRef::Vacant(e) => assert_eq!(e.key(), key),
7976
            EntryRef::Occupied(_) => panic!(),
7977
        }
7978
7979
        assert!(!a.contains_key(key));
7980
        assert_eq!(a.len(), 0);
7981
    }
7982
7983
    #[test]
7984
    fn test_raw_occupied_entry_replace_entry_with() {
7985
        let mut a = HashMap::new();
7986
7987
        let key = "a key";
7988
        let value = "an initial value";
7989
        let new_value = "a new value";
7990
7991
        let entry = a
7992
            .raw_entry_mut()
7993
            .from_key(&key)
7994
            .insert(key, value)
7995
            .replace_entry_with(|k, v| {
7996
                assert_eq!(k, &key);
7997
                assert_eq!(v, value);
7998
                Some(new_value)
7999
            });
8000
8001
        match entry {
8002
            RawEntryMut::Occupied(e) => {
8003
                assert_eq!(e.key(), &key);
8004
                assert_eq!(e.get(), &new_value);
8005
            }
8006
            RawEntryMut::Vacant(_) => panic!(),
8007
        }
8008
8009
        assert_eq!(a[key], new_value);
8010
        assert_eq!(a.len(), 1);
8011
8012
        let entry = match a.raw_entry_mut().from_key(&key) {
8013
            RawEntryMut::Occupied(e) => e.replace_entry_with(|k, v| {
8014
                assert_eq!(k, &key);
8015
                assert_eq!(v, new_value);
8016
                None
8017
            }),
8018
            RawEntryMut::Vacant(_) => panic!(),
8019
        };
8020
8021
        match entry {
8022
            RawEntryMut::Vacant(_) => {}
8023
            RawEntryMut::Occupied(_) => panic!(),
8024
        }
8025
8026
        assert!(!a.contains_key(key));
8027
        assert_eq!(a.len(), 0);
8028
    }
8029
8030
    #[test]
8031
    fn test_raw_entry_and_replace_entry_with() {
8032
        let mut a = HashMap::new();
8033
8034
        let key = "a key";
8035
        let value = "an initial value";
8036
        let new_value = "a new value";
8037
8038
        let entry = a
8039
            .raw_entry_mut()
8040
            .from_key(&key)
8041
            .and_replace_entry_with(|_, _| panic!());
8042
8043
        match entry {
8044
            RawEntryMut::Vacant(_) => {}
8045
            RawEntryMut::Occupied(_) => panic!(),
8046
        }
8047
8048
        a.insert(key, value);
8049
8050
        let entry = a
8051
            .raw_entry_mut()
8052
            .from_key(&key)
8053
            .and_replace_entry_with(|k, v| {
8054
                assert_eq!(k, &key);
8055
                assert_eq!(v, value);
8056
                Some(new_value)
8057
            });
8058
8059
        match entry {
8060
            RawEntryMut::Occupied(e) => {
8061
                assert_eq!(e.key(), &key);
8062
                assert_eq!(e.get(), &new_value);
8063
            }
8064
            RawEntryMut::Vacant(_) => panic!(),
8065
        }
8066
8067
        assert_eq!(a[key], new_value);
8068
        assert_eq!(a.len(), 1);
8069
8070
        let entry = a
8071
            .raw_entry_mut()
8072
            .from_key(&key)
8073
            .and_replace_entry_with(|k, v| {
8074
                assert_eq!(k, &key);
8075
                assert_eq!(v, new_value);
8076
                None
8077
            });
8078
8079
        match entry {
8080
            RawEntryMut::Vacant(_) => {}
8081
            RawEntryMut::Occupied(_) => panic!(),
8082
        }
8083
8084
        assert!(!a.contains_key(key));
8085
        assert_eq!(a.len(), 0);
8086
    }
8087
8088
    #[test]
8089
    fn test_replace_entry_with_doesnt_corrupt() {
8090
        #![allow(deprecated)] //rand
8091
                              // Test for #19292
8092
        fn check(m: &HashMap<i32, ()>) {
8093
            for k in m.keys() {
8094
                assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
8095
            }
8096
        }
8097
8098
        let mut m = HashMap::new();
8099
8100
        let mut rng = {
8101
            let seed = u64::from_le_bytes(*b"testseed");
8102
            SmallRng::seed_from_u64(seed)
8103
        };
8104
8105
        // Populate the map with some items.
8106
        for _ in 0..50 {
8107
            let x = rng.gen_range(-10..10);
8108
            m.insert(x, ());
8109
        }
8110
8111
        for _ in 0..1000 {
8112
            let x = rng.gen_range(-10..10);
8113
            m.entry(x).and_replace_entry_with(|_, _| None);
8114
            check(&m);
8115
        }
8116
    }
8117
8118
    #[test]
8119
    fn test_replace_entry_ref_with_doesnt_corrupt() {
8120
        #![allow(deprecated)] //rand
8121
                              // Test for #19292
8122
        fn check(m: &HashMap<std::string::String, ()>) {
8123
            for k in m.keys() {
8124
                assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
8125
            }
8126
        }
8127
8128
        let mut m = HashMap::new();
8129
8130
        let mut rng = {
8131
            let seed = u64::from_le_bytes(*b"testseed");
8132
            SmallRng::seed_from_u64(seed)
8133
        };
8134
8135
        // Populate the map with some items.
8136
        for _ in 0..50 {
8137
            let mut x = std::string::String::with_capacity(1);
8138
            x.push(rng.gen_range('a'..='z'));
8139
            m.insert(x, ());
8140
        }
8141
8142
        for _ in 0..1000 {
8143
            let mut x = std::string::String::with_capacity(1);
8144
            x.push(rng.gen_range('a'..='z'));
8145
            m.entry_ref(x.as_str()).and_replace_entry_with(|_, _| None);
8146
            check(&m);
8147
        }
8148
    }
8149
8150
    #[test]
8151
    fn test_retain() {
8152
        let mut map: HashMap<i32, i32> = (0..100).map(|x| (x, x * 10)).collect();
8153
8154
        map.retain(|&k, _| k % 2 == 0);
8155
        assert_eq!(map.len(), 50);
8156
        assert_eq!(map[&2], 20);
8157
        assert_eq!(map[&4], 40);
8158
        assert_eq!(map[&6], 60);
8159
    }
8160
8161
    #[test]
8162
    fn test_extract_if() {
8163
        {
8164
            let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x * 10)).collect();
8165
            let drained = map.extract_if(|&k, _| k % 2 == 0);
8166
            let mut out = drained.collect::<Vec<_>>();
8167
            out.sort_unstable();
8168
            assert_eq!(vec![(0, 0), (2, 20), (4, 40), (6, 60)], out);
8169
            assert_eq!(map.len(), 4);
8170
        }
8171
        {
8172
            let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x * 10)).collect();
8173
            map.extract_if(|&k, _| k % 2 == 0).for_each(drop);
8174
            assert_eq!(map.len(), 4);
8175
        }
8176
    }
8177
8178
    #[test]
8179
    #[cfg_attr(miri, ignore)] // FIXME: no OOM signalling (https://github.com/rust-lang/miri/issues/613)
8180
    fn test_try_reserve() {
8181
        use crate::TryReserveError::{AllocError, CapacityOverflow};
8182
8183
        const MAX_ISIZE: usize = isize::MAX as usize;
8184
8185
        let mut empty_bytes: HashMap<u8, u8> = HashMap::new();
8186
8187
        if let Err(CapacityOverflow) = empty_bytes.try_reserve(usize::MAX) {
8188
        } else {
8189
            panic!("usize::MAX should trigger an overflow!");
8190
        }
8191
8192
        if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_ISIZE) {
8193
        } else {
8194
            panic!("isize::MAX should trigger an overflow!");
8195
        }
8196
8197
        if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_ISIZE / 5) {
8198
        } else {
8199
            // This may succeed if there is enough free memory. Attempt to
8200
            // allocate a few more hashmaps to ensure the allocation will fail.
8201
            let mut empty_bytes2: HashMap<u8, u8> = HashMap::new();
8202
            let _ = empty_bytes2.try_reserve(MAX_ISIZE / 5);
8203
            let mut empty_bytes3: HashMap<u8, u8> = HashMap::new();
8204
            let _ = empty_bytes3.try_reserve(MAX_ISIZE / 5);
8205
            let mut empty_bytes4: HashMap<u8, u8> = HashMap::new();
8206
            if let Err(AllocError { .. }) = empty_bytes4.try_reserve(MAX_ISIZE / 5) {
8207
            } else {
8208
                panic!("isize::MAX / 5 should trigger an OOM!");
8209
            }
8210
        }
8211
    }
8212
8213
    #[test]
8214
    fn test_raw_entry() {
8215
        use super::RawEntryMut::{Occupied, Vacant};
8216
8217
        let xs = [(1_i32, 10_i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
8218
8219
        let mut map: HashMap<_, _> = xs.iter().copied().collect();
8220
8221
        let compute_hash = |map: &HashMap<i32, i32>, k: i32| -> u64 {
8222
            super::make_hash::<i32, _>(map.hasher(), &k)
8223
        };
8224
8225
        // Existing key (insert)
8226
        match map.raw_entry_mut().from_key(&1) {
8227
            Vacant(_) => unreachable!(),
8228
            Occupied(mut view) => {
8229
                assert_eq!(view.get(), &10);
8230
                assert_eq!(view.insert(100), 10);
8231
            }
8232
        }
8233
        let hash1 = compute_hash(&map, 1);
8234
        assert_eq!(map.raw_entry().from_key(&1).unwrap(), (&1, &100));
8235
        assert_eq!(
8236
            map.raw_entry().from_hash(hash1, |k| *k == 1).unwrap(),
8237
            (&1, &100)
8238
        );
8239
        assert_eq!(
8240
            map.raw_entry().from_key_hashed_nocheck(hash1, &1).unwrap(),
8241
            (&1, &100)
8242
        );
8243
        assert_eq!(map.len(), 6);
8244
8245
        // Existing key (update)
8246
        match map.raw_entry_mut().from_key(&2) {
8247
            Vacant(_) => unreachable!(),
8248
            Occupied(mut view) => {
8249
                let v = view.get_mut();
8250
                let new_v = (*v) * 10;
8251
                *v = new_v;
8252
            }
8253
        }
8254
        let hash2 = compute_hash(&map, 2);
8255
        assert_eq!(map.raw_entry().from_key(&2).unwrap(), (&2, &200));
8256
        assert_eq!(
8257
            map.raw_entry().from_hash(hash2, |k| *k == 2).unwrap(),
8258
            (&2, &200)
8259
        );
8260
        assert_eq!(
8261
            map.raw_entry().from_key_hashed_nocheck(hash2, &2).unwrap(),
8262
            (&2, &200)
8263
        );
8264
        assert_eq!(map.len(), 6);
8265
8266
        // Existing key (take)
8267
        let hash3 = compute_hash(&map, 3);
8268
        match map.raw_entry_mut().from_key_hashed_nocheck(hash3, &3) {
8269
            Vacant(_) => unreachable!(),
8270
            Occupied(view) => {
8271
                assert_eq!(view.remove_entry(), (3, 30));
8272
            }
8273
        }
8274
        assert_eq!(map.raw_entry().from_key(&3), None);
8275
        assert_eq!(map.raw_entry().from_hash(hash3, |k| *k == 3), None);
8276
        assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash3, &3), None);
8277
        assert_eq!(map.len(), 5);
8278
8279
        // Nonexistent key (insert)
8280
        match map.raw_entry_mut().from_key(&10) {
8281
            Occupied(_) => unreachable!(),
8282
            Vacant(view) => {
8283
                assert_eq!(view.insert(10, 1000), (&mut 10, &mut 1000));
8284
            }
8285
        }
8286
        assert_eq!(map.raw_entry().from_key(&10).unwrap(), (&10, &1000));
8287
        assert_eq!(map.len(), 6);
8288
8289
        // Ensure all lookup methods produce equivalent results.
8290
        for k in 0..12 {
8291
            let hash = compute_hash(&map, k);
8292
            let v = map.get(&k).copied();
8293
            let kv = v.as_ref().map(|v| (&k, v));
8294
8295
            assert_eq!(map.raw_entry().from_key(&k), kv);
8296
            assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
8297
            assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
8298
8299
            match map.raw_entry_mut().from_key(&k) {
8300
                Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
8301
                Vacant(_) => assert_eq!(v, None),
8302
            }
8303
            match map.raw_entry_mut().from_key_hashed_nocheck(hash, &k) {
8304
                Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
8305
                Vacant(_) => assert_eq!(v, None),
8306
            }
8307
            match map.raw_entry_mut().from_hash(hash, |q| *q == k) {
8308
                Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
8309
                Vacant(_) => assert_eq!(v, None),
8310
            }
8311
        }
8312
    }
8313
8314
    #[test]
8315
    fn test_key_without_hash_impl() {
8316
        #[derive(Debug)]
8317
        struct IntWrapper(u64);
8318
8319
        let mut m: HashMap<IntWrapper, (), ()> = HashMap::default();
8320
        {
8321
            assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_none());
8322
        }
8323
        {
8324
            let vacant_entry = match m.raw_entry_mut().from_hash(0, |k| k.0 == 0) {
8325
                RawEntryMut::Occupied(..) => panic!("Found entry for key 0"),
8326
                RawEntryMut::Vacant(e) => e,
8327
            };
8328
            vacant_entry.insert_with_hasher(0, IntWrapper(0), (), |k| k.0);
8329
        }
8330
        {
8331
            assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_some());
8332
            assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_none());
8333
            assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
8334
        }
8335
        {
8336
            let vacant_entry = match m.raw_entry_mut().from_hash(1, |k| k.0 == 1) {
8337
                RawEntryMut::Occupied(..) => panic!("Found entry for key 1"),
8338
                RawEntryMut::Vacant(e) => e,
8339
            };
8340
            vacant_entry.insert_with_hasher(1, IntWrapper(1), (), |k| k.0);
8341
        }
8342
        {
8343
            assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_some());
8344
            assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_some());
8345
            assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
8346
        }
8347
        {
8348
            let occupied_entry = match m.raw_entry_mut().from_hash(0, |k| k.0 == 0) {
8349
                RawEntryMut::Occupied(e) => e,
8350
                RawEntryMut::Vacant(..) => panic!("Couldn't find entry for key 0"),
8351
            };
8352
            occupied_entry.remove();
8353
        }
8354
        assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_none());
8355
        assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_some());
8356
        assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
8357
    }
8358
8359
    #[test]
8360
    #[cfg(feature = "raw")]
8361
    fn test_into_iter_refresh() {
8362
        #[cfg(miri)]
8363
        const N: usize = 32;
8364
        #[cfg(not(miri))]
8365
        const N: usize = 128;
8366
8367
        let mut rng = rand::thread_rng();
8368
        for n in 0..N {
8369
            let mut map = HashMap::new();
8370
            for i in 0..n {
8371
                assert!(map.insert(i, 2 * i).is_none());
8372
            }
8373
            let hash_builder = map.hasher().clone();
8374
8375
            let mut it = unsafe { map.table.iter() };
8376
            assert_eq!(it.len(), n);
8377
8378
            let mut i = 0;
8379
            let mut left = n;
8380
            let mut removed = Vec::new();
8381
            loop {
8382
                // occasionally remove some elements
8383
                if i < n && rng.gen_bool(0.1) {
8384
                    let hash_value = super::make_hash(&hash_builder, &i);
8385
8386
                    unsafe {
8387
                        let e = map.table.find(hash_value, |q| q.0.eq(&i));
8388
                        if let Some(e) = e {
8389
                            it.reflect_remove(&e);
8390
                            let t = map.table.remove(e).0;
8391
                            removed.push(t);
8392
                            left -= 1;
8393
                        } else {
8394
                            assert!(removed.contains(&(i, 2 * i)), "{i} not in {removed:?}");
8395
                            let e = map.table.insert(
8396
                                hash_value,
8397
                                (i, 2 * i),
8398
                                super::make_hasher::<_, usize, _>(&hash_builder),
8399
                            );
8400
                            it.reflect_insert(&e);
8401
                            if let Some(p) = removed.iter().position(|e| e == &(i, 2 * i)) {
8402
                                removed.swap_remove(p);
8403
                            }
8404
                            left += 1;
8405
                        }
8406
                    }
8407
                }
8408
8409
                let e = it.next();
8410
                if e.is_none() {
8411
                    break;
8412
                }
8413
                assert!(i < n);
8414
                let t = unsafe { e.unwrap().as_ref() };
8415
                assert!(!removed.contains(t));
8416
                let (key, value) = t;
8417
                assert_eq!(*value, 2 * key);
8418
                i += 1;
8419
            }
8420
            assert!(i <= n);
8421
8422
            // just for safety:
8423
            assert_eq!(map.table.len(), left);
8424
        }
8425
    }
8426
8427
    #[test]
8428
    fn test_const_with_hasher() {
8429
        use core::hash::BuildHasher;
8430
        use std::collections::hash_map::DefaultHasher;
8431
8432
        #[derive(Clone)]
8433
        struct MyHasher;
8434
        impl BuildHasher for MyHasher {
8435
            type Hasher = DefaultHasher;
8436
8437
            fn build_hasher(&self) -> DefaultHasher {
8438
                DefaultHasher::new()
8439
            }
8440
        }
8441
8442
        const EMPTY_MAP: HashMap<u32, std::string::String, MyHasher> =
8443
            HashMap::with_hasher(MyHasher);
8444
8445
        let mut map = EMPTY_MAP;
8446
        map.insert(17, "seventeen".to_owned());
8447
        assert_eq!("seventeen", map[&17]);
8448
    }
8449
8450
    #[test]
8451
    fn test_get_each_mut() {
8452
        let mut map = HashMap::new();
8453
        map.insert("foo".to_owned(), 0);
8454
        map.insert("bar".to_owned(), 10);
8455
        map.insert("baz".to_owned(), 20);
8456
        map.insert("qux".to_owned(), 30);
8457
8458
        let xs = map.get_many_mut(["foo", "qux"]);
8459
        assert_eq!(xs, Some([&mut 0, &mut 30]));
8460
8461
        let xs = map.get_many_mut(["foo", "dud"]);
8462
        assert_eq!(xs, None);
8463
8464
        let xs = map.get_many_mut(["foo", "foo"]);
8465
        assert_eq!(xs, None);
8466
8467
        let ys = map.get_many_key_value_mut(["bar", "baz"]);
8468
        assert_eq!(
8469
            ys,
8470
            Some([(&"bar".to_owned(), &mut 10), (&"baz".to_owned(), &mut 20),]),
8471
        );
8472
8473
        let ys = map.get_many_key_value_mut(["bar", "dip"]);
8474
        assert_eq!(ys, None);
8475
8476
        let ys = map.get_many_key_value_mut(["baz", "baz"]);
8477
        assert_eq!(ys, None);
8478
    }
8479
8480
    #[test]
8481
    #[should_panic = "panic in drop"]
8482
    fn test_clone_from_double_drop() {
8483
        #[derive(Clone)]
8484
        struct CheckedDrop {
8485
            panic_in_drop: bool,
8486
            dropped: bool,
8487
        }
8488
        impl Drop for CheckedDrop {
8489
            fn drop(&mut self) {
8490
                if self.panic_in_drop {
8491
                    self.dropped = true;
8492
                    panic!("panic in drop");
8493
                }
8494
                if self.dropped {
8495
                    panic!("double drop");
8496
                }
8497
                self.dropped = true;
8498
            }
8499
        }
8500
        const DISARMED: CheckedDrop = CheckedDrop {
8501
            panic_in_drop: false,
8502
            dropped: false,
8503
        };
8504
        const ARMED: CheckedDrop = CheckedDrop {
8505
            panic_in_drop: true,
8506
            dropped: false,
8507
        };
8508
8509
        let mut map1 = HashMap::new();
8510
        map1.insert(1, DISARMED);
8511
        map1.insert(2, DISARMED);
8512
        map1.insert(3, DISARMED);
8513
        map1.insert(4, DISARMED);
8514
8515
        let mut map2 = HashMap::new();
8516
        map2.insert(1, DISARMED);
8517
        map2.insert(2, ARMED);
8518
        map2.insert(3, DISARMED);
8519
        map2.insert(4, DISARMED);
8520
8521
        map2.clone_from(&map1);
8522
    }
8523
8524
    #[test]
8525
    #[should_panic = "panic in clone"]
8526
    fn test_clone_from_memory_leaks() {
8527
        use alloc::vec::Vec;
8528
8529
        struct CheckedClone {
8530
            panic_in_clone: bool,
8531
            need_drop: Vec<i32>,
8532
        }
8533
        impl Clone for CheckedClone {
8534
            fn clone(&self) -> Self {
8535
                if self.panic_in_clone {
8536
                    panic!("panic in clone")
8537
                }
8538
                Self {
8539
                    panic_in_clone: self.panic_in_clone,
8540
                    need_drop: self.need_drop.clone(),
8541
                }
8542
            }
8543
        }
8544
        let mut map1 = HashMap::new();
8545
        map1.insert(
8546
            1,
8547
            CheckedClone {
8548
                panic_in_clone: false,
8549
                need_drop: vec![0, 1, 2],
8550
            },
8551
        );
8552
        map1.insert(
8553
            2,
8554
            CheckedClone {
8555
                panic_in_clone: false,
8556
                need_drop: vec![3, 4, 5],
8557
            },
8558
        );
8559
        map1.insert(
8560
            3,
8561
            CheckedClone {
8562
                panic_in_clone: true,
8563
                need_drop: vec![6, 7, 8],
8564
            },
8565
        );
8566
        let _map2 = map1.clone();
8567
    }
8568
8569
    struct MyAllocInner {
8570
        drop_count: Arc<AtomicI8>,
8571
    }
8572
8573
    #[derive(Clone)]
8574
    struct MyAlloc {
8575
        _inner: Arc<MyAllocInner>,
8576
    }
8577
8578
    impl MyAlloc {
8579
        fn new(drop_count: Arc<AtomicI8>) -> Self {
8580
            MyAlloc {
8581
                _inner: Arc::new(MyAllocInner { drop_count }),
8582
            }
8583
        }
8584
    }
8585
8586
    impl Drop for MyAllocInner {
8587
        fn drop(&mut self) {
8588
            println!("MyAlloc freed.");
8589
            self.drop_count.fetch_sub(1, Ordering::SeqCst);
8590
        }
8591
    }
8592
8593
    unsafe impl Allocator for MyAlloc {
8594
        fn allocate(&self, layout: Layout) -> std::result::Result<NonNull<[u8]>, AllocError> {
8595
            let g = Global;
8596
            g.allocate(layout)
8597
        }
8598
8599
        unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
8600
            let g = Global;
8601
            g.deallocate(ptr, layout)
8602
        }
8603
    }
8604
8605
    #[test]
8606
    fn test_hashmap_into_iter_bug() {
8607
        let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(1));
8608
8609
        {
8610
            let mut map = HashMap::with_capacity_in(10, MyAlloc::new(dropped.clone()));
8611
            for i in 0..10 {
8612
                map.entry(i).or_insert_with(|| "i".to_string());
8613
            }
8614
8615
            for (k, v) in map {
8616
                println!("{}, {}", k, v);
8617
            }
8618
        }
8619
8620
        // All allocator clones should already be dropped.
8621
        assert_eq!(dropped.load(Ordering::SeqCst), 0);
8622
    }
8623
8624
    #[derive(Debug)]
8625
    struct CheckedCloneDrop<T> {
8626
        panic_in_clone: bool,
8627
        panic_in_drop: bool,
8628
        dropped: bool,
8629
        data: T,
8630
    }
8631
8632
    impl<T> CheckedCloneDrop<T> {
8633
        fn new(panic_in_clone: bool, panic_in_drop: bool, data: T) -> Self {
8634
            CheckedCloneDrop {
8635
                panic_in_clone,
8636
                panic_in_drop,
8637
                dropped: false,
8638
                data,
8639
            }
8640
        }
8641
    }
8642
8643
    impl<T: Clone> Clone for CheckedCloneDrop<T> {
8644
        fn clone(&self) -> Self {
8645
            if self.panic_in_clone {
8646
                panic!("panic in clone")
8647
            }
8648
            Self {
8649
                panic_in_clone: self.panic_in_clone,
8650
                panic_in_drop: self.panic_in_drop,
8651
                dropped: self.dropped,
8652
                data: self.data.clone(),
8653
            }
8654
        }
8655
    }
8656
8657
    impl<T> Drop for CheckedCloneDrop<T> {
8658
        fn drop(&mut self) {
8659
            if self.panic_in_drop {
8660
                self.dropped = true;
8661
                panic!("panic in drop");
8662
            }
8663
            if self.dropped {
8664
                panic!("double drop");
8665
            }
8666
            self.dropped = true;
8667
        }
8668
    }
8669
8670
    /// Return hashmap with predefined distribution of elements.
8671
    /// All elements will be located in the same order as elements
8672
    /// returned by iterator.
8673
    ///
8674
    /// This function does not panic, but returns an error as a `String`
8675
    /// to distinguish between a test panic and an error in the input data.
8676
    fn get_test_map<I, T, A>(
8677
        iter: I,
8678
        mut fun: impl FnMut(u64) -> T,
8679
        alloc: A,
8680
    ) -> Result<HashMap<u64, CheckedCloneDrop<T>, DefaultHashBuilder, A>, String>
8681
    where
8682
        I: Iterator<Item = (bool, bool)> + Clone + ExactSizeIterator,
8683
        A: Allocator,
8684
        T: PartialEq + core::fmt::Debug,
8685
    {
8686
        use crate::scopeguard::guard;
8687
8688
        let mut map: HashMap<u64, CheckedCloneDrop<T>, _, A> =
8689
            HashMap::with_capacity_in(iter.size_hint().0, alloc);
8690
        {
8691
            let mut guard = guard(&mut map, |map| {
8692
                for (_, value) in map.iter_mut() {
8693
                    value.panic_in_drop = false
8694
                }
8695
            });
8696
8697
            let mut count = 0;
8698
            // Hash and Key must be equal to each other for controlling the elements placement.
8699
            for (panic_in_clone, panic_in_drop) in iter.clone() {
8700
                if core::mem::needs_drop::<T>() && panic_in_drop {
8701
                    return Err(String::from(
8702
                        "panic_in_drop can be set with a type that doesn't need to be dropped",
8703
                    ));
8704
                }
8705
                guard.table.insert(
8706
                    count,
8707
                    (
8708
                        count,
8709
                        CheckedCloneDrop::new(panic_in_clone, panic_in_drop, fun(count)),
8710
                    ),
8711
                    |(k, _)| *k,
8712
                );
8713
                count += 1;
8714
            }
8715
8716
            // Let's check that all elements are located as we wanted
8717
            let mut check_count = 0;
8718
            for ((key, value), (panic_in_clone, panic_in_drop)) in guard.iter().zip(iter) {
8719
                if *key != check_count {
8720
                    return Err(format!(
8721
                        "key != check_count,\nkey: `{}`,\ncheck_count: `{}`",
8722
                        key, check_count
8723
                    ));
8724
                }
8725
                if value.dropped
8726
                    || value.panic_in_clone != panic_in_clone
8727
                    || value.panic_in_drop != panic_in_drop
8728
                    || value.data != fun(check_count)
8729
                {
8730
                    return Err(format!(
8731
                        "Value is not equal to expected,\nvalue: `{:?}`,\nexpected: \
8732
                        `CheckedCloneDrop {{ panic_in_clone: {}, panic_in_drop: {}, dropped: {}, data: {:?} }}`",
8733
                        value, panic_in_clone, panic_in_drop, false, fun(check_count)
8734
                    ));
8735
                }
8736
                check_count += 1;
8737
            }
8738
8739
            if guard.len() != check_count as usize {
8740
                return Err(format!(
8741
                    "map.len() != check_count,\nmap.len(): `{}`,\ncheck_count: `{}`",
8742
                    guard.len(),
8743
                    check_count
8744
                ));
8745
            }
8746
8747
            if count != check_count {
8748
                return Err(format!(
8749
                    "count != check_count,\ncount: `{}`,\ncheck_count: `{}`",
8750
                    count, check_count
8751
                ));
8752
            }
8753
            core::mem::forget(guard);
8754
        }
8755
        Ok(map)
8756
    }
8757
8758
    const DISARMED: bool = false;
8759
    const ARMED: bool = true;
8760
8761
    const ARMED_FLAGS: [bool; 8] = [
8762
        DISARMED, DISARMED, DISARMED, ARMED, DISARMED, DISARMED, DISARMED, DISARMED,
8763
    ];
8764
8765
    const DISARMED_FLAGS: [bool; 8] = [
8766
        DISARMED, DISARMED, DISARMED, DISARMED, DISARMED, DISARMED, DISARMED, DISARMED,
8767
    ];
8768
8769
    #[test]
8770
    #[should_panic = "panic in clone"]
8771
    fn test_clone_memory_leaks_and_double_drop_one() {
8772
        let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
8773
8774
        {
8775
            assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
8776
8777
            let map: HashMap<u64, CheckedCloneDrop<Vec<u64>>, DefaultHashBuilder, MyAlloc> =
8778
                match get_test_map(
8779
                    ARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
8780
                    |n| vec![n],
8781
                    MyAlloc::new(dropped.clone()),
8782
                ) {
8783
                    Ok(map) => map,
8784
                    Err(msg) => panic!("{msg}"),
8785
                };
8786
8787
            // Clone should normally clone a few elements, and then (when the
8788
            // clone function panics), deallocate both its own memory, memory
8789
            // of `dropped: Arc<AtomicI8>` and the memory of already cloned
8790
            // elements (Vec<i32> memory inside CheckedCloneDrop).
8791
            let _map2 = map.clone();
8792
        }
8793
    }
8794
8795
    #[test]
8796
    #[should_panic = "panic in drop"]
8797
    fn test_clone_memory_leaks_and_double_drop_two() {
8798
        let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
8799
8800
        {
8801
            assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
8802
8803
            let map: HashMap<u64, CheckedCloneDrop<u64>, DefaultHashBuilder, _> = match get_test_map(
8804
                DISARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
8805
                |n| n,
8806
                MyAlloc::new(dropped.clone()),
8807
            ) {
8808
                Ok(map) => map,
8809
                Err(msg) => panic!("{msg}"),
8810
            };
8811
8812
            let mut map2 = match get_test_map(
8813
                DISARMED_FLAGS.into_iter().zip(ARMED_FLAGS),
8814
                |n| n,
8815
                MyAlloc::new(dropped.clone()),
8816
            ) {
8817
                Ok(map) => map,
8818
                Err(msg) => panic!("{msg}"),
8819
            };
8820
8821
            // The `clone_from` should try to drop the elements of `map2` without
8822
            // double drop and leaking the allocator. Elements that have not been
8823
            // dropped leak their memory.
8824
            map2.clone_from(&map);
8825
        }
8826
    }
8827
8828
    /// We check that we have a working table if the clone operation from another
8829
    /// thread ended in a panic (when buckets of maps are equal to each other).
8830
    #[test]
8831
    fn test_catch_panic_clone_from_when_len_is_equal() {
8832
        use std::thread;
8833
8834
        let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
8835
8836
        {
8837
            assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
8838
8839
            let mut map = match get_test_map(
8840
                DISARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
8841
                |n| vec![n],
8842
                MyAlloc::new(dropped.clone()),
8843
            ) {
8844
                Ok(map) => map,
8845
                Err(msg) => panic!("{msg}"),
8846
            };
8847
8848
            thread::scope(|s| {
8849
                let result: thread::ScopedJoinHandle<'_, String> = s.spawn(|| {
8850
                    let scope_map =
8851
                        match get_test_map(ARMED_FLAGS.into_iter().zip(DISARMED_FLAGS), |n| vec![n * 2], MyAlloc::new(dropped.clone())) {
8852
                            Ok(map) => map,
8853
                            Err(msg) => return msg,
8854
                        };
8855
                    if map.table.buckets() != scope_map.table.buckets() {
8856
                        return format!(
8857
                            "map.table.buckets() != scope_map.table.buckets(),\nleft: `{}`,\nright: `{}`",
8858
                            map.table.buckets(), scope_map.table.buckets()
8859
                        );
8860
                    }
8861
                    map.clone_from(&scope_map);
8862
                    "We must fail the cloning!!!".to_owned()
8863
                });
8864
                if let Ok(msg) = result.join() {
8865
                    panic!("{msg}")
8866
                }
8867
            });
8868
8869
            // Let's check that all iterators work fine and do not return elements
8870
            // (especially `RawIterRange`, which does not depend on the number of
8871
            // elements in the table, but looks directly at the control bytes)
8872
            //
8873
            // SAFETY: We know for sure that `RawTable` will outlive
8874
            // the returned `RawIter / RawIterRange` iterator.
8875
            assert_eq!(map.len(), 0);
8876
            assert_eq!(map.iter().count(), 0);
8877
            assert_eq!(unsafe { map.table.iter().count() }, 0);
8878
            assert_eq!(unsafe { map.table.iter().iter.count() }, 0);
8879
8880
            for idx in 0..map.table.buckets() {
8881
                let idx = idx as u64;
8882
                assert!(
8883
                    map.table.find(idx, |(k, _)| *k == idx).is_none(),
8884
                    "Index: {idx}"
8885
                );
8886
            }
8887
        }
8888
8889
        // All allocator clones should already be dropped.
8890
        assert_eq!(dropped.load(Ordering::SeqCst), 0);
8891
    }
8892
8893
    /// We check that we have a working table if the clone operation from another
8894
    /// thread ended in a panic (when buckets of maps are not equal to each other).
8895
    #[test]
8896
    fn test_catch_panic_clone_from_when_len_is_not_equal() {
8897
        use std::thread;
8898
8899
        let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
8900
8901
        {
8902
            assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
8903
8904
            let mut map = match get_test_map(
8905
                [DISARMED].into_iter().zip([DISARMED]),
8906
                |n| vec![n],
8907
                MyAlloc::new(dropped.clone()),
8908
            ) {
8909
                Ok(map) => map,
8910
                Err(msg) => panic!("{msg}"),
8911
            };
8912
8913
            thread::scope(|s| {
8914
                let result: thread::ScopedJoinHandle<'_, String> = s.spawn(|| {
8915
                    let scope_map = match get_test_map(
8916
                        ARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
8917
                        |n| vec![n * 2],
8918
                        MyAlloc::new(dropped.clone()),
8919
                    ) {
8920
                        Ok(map) => map,
8921
                        Err(msg) => return msg,
8922
                    };
8923
                    if map.table.buckets() == scope_map.table.buckets() {
8924
                        return format!(
8925
                            "map.table.buckets() == scope_map.table.buckets(): `{}`",
8926
                            map.table.buckets()
8927
                        );
8928
                    }
8929
                    map.clone_from(&scope_map);
8930
                    "We must fail the cloning!!!".to_owned()
8931
                });
8932
                if let Ok(msg) = result.join() {
8933
                    panic!("{msg}")
8934
                }
8935
            });
8936
8937
            // Let's check that all iterators work fine and do not return elements
8938
            // (especially `RawIterRange`, which does not depend on the number of
8939
            // elements in the table, but looks directly at the control bytes)
8940
            //
8941
            // SAFETY: We know for sure that `RawTable` will outlive
8942
            // the returned `RawIter / RawIterRange` iterator.
8943
            assert_eq!(map.len(), 0);
8944
            assert_eq!(map.iter().count(), 0);
8945
            assert_eq!(unsafe { map.table.iter().count() }, 0);
8946
            assert_eq!(unsafe { map.table.iter().iter.count() }, 0);
8947
8948
            for idx in 0..map.table.buckets() {
8949
                let idx = idx as u64;
8950
                assert!(
8951
                    map.table.find(idx, |(k, _)| *k == idx).is_none(),
8952
                    "Index: {idx}"
8953
                );
8954
            }
8955
        }
8956
8957
        // All allocator clones should already be dropped.
8958
        assert_eq!(dropped.load(Ordering::SeqCst), 0);
8959
    }
8960
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/raw/alloc.rs
Line
Count
Source
1
pub(crate) use self::inner::{do_alloc, Allocator, Global};
2
3
// Nightly-case.
4
// Use unstable `allocator_api` feature.
5
// This is compatible with `allocator-api2` which can be enabled or not.
6
// This is used when building for `std`.
7
#[cfg(feature = "nightly")]
8
mod inner {
9
    use crate::alloc::alloc::Layout;
10
    pub use crate::alloc::alloc::{Allocator, Global};
11
    use core::ptr::NonNull;
12
13
    #[allow(clippy::map_err_ignore)]
14
    pub(crate) fn do_alloc<A: Allocator>(alloc: &A, layout: Layout) -> Result<NonNull<u8>, ()> {
15
        match alloc.allocate(layout) {
16
            Ok(ptr) => Ok(ptr.as_non_null_ptr()),
17
            Err(_) => Err(()),
18
        }
19
    }
20
}
21
22
// Basic non-nightly case.
23
// This uses `allocator-api2` enabled by default.
24
// If any crate enables "nightly" in `allocator-api2`,
25
// this will be equivalent to the nightly case,
26
// since `allocator_api2::alloc::Allocator` would be re-export of
27
// `core::alloc::Allocator`.
28
#[cfg(all(not(feature = "nightly"), feature = "allocator-api2"))]
29
mod inner {
30
    use crate::alloc::alloc::Layout;
31
    pub use allocator_api2::alloc::{Allocator, Global};
32
    use core::ptr::NonNull;
33
34
    #[allow(clippy::map_err_ignore)]
35
0
    pub(crate) fn do_alloc<A: Allocator>(alloc: &A, layout: Layout) -> Result<NonNull<u8>, ()> {
36
0
        match alloc.allocate(layout) {
37
0
            Ok(ptr) => Ok(ptr.cast()),
38
0
            Err(_) => Err(()),
39
        }
40
0
    }
Unexecuted instantiation: _RINvNtNtNtCsgkA6tlBCRmB_9hashbrown3raw5alloc5inner8do_allocNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvNtNtNtCsgkA6tlBCRmB_9hashbrown3raw5alloc5inner8do_allocpEB8_
41
}
42
43
// No-defaults case.
44
// When building with default-features turned off and
45
// neither `nightly` nor `allocator-api2` is enabled,
46
// this will be used.
47
// Making it impossible to use any custom allocator with collections defined
48
// in this crate.
49
// Any crate in build-tree can enable `allocator-api2`,
50
// or `nightly` without disturbing users that don't want to use it.
51
#[cfg(not(any(feature = "nightly", feature = "allocator-api2")))]
52
mod inner {
53
    use crate::alloc::alloc::{alloc, dealloc, Layout};
54
    use core::ptr::NonNull;
55
56
    #[allow(clippy::missing_safety_doc)] // not exposed outside of this crate
57
    pub unsafe trait Allocator {
58
        fn allocate(&self, layout: Layout) -> Result<NonNull<u8>, ()>;
59
        unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout);
60
    }
61
62
    #[derive(Copy, Clone)]
63
    pub struct Global;
64
65
    unsafe impl Allocator for Global {
66
        #[inline]
67
        fn allocate(&self, layout: Layout) -> Result<NonNull<u8>, ()> {
68
            unsafe { NonNull::new(alloc(layout)).ok_or(()) }
69
        }
70
        #[inline]
71
        unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
72
            dealloc(ptr.as_ptr(), layout);
73
        }
74
    }
75
76
    impl Default for Global {
77
        #[inline]
78
        fn default() -> Self {
79
            Global
80
        }
81
    }
82
83
    pub(crate) fn do_alloc<A: Allocator>(alloc: &A, layout: Layout) -> Result<NonNull<u8>, ()> {
84
        alloc.allocate(layout)
85
    }
86
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/raw/bitmask.rs
Line
Count
Source
1
use super::imp::{
2
    BitMaskWord, NonZeroBitMaskWord, BITMASK_ITER_MASK, BITMASK_MASK, BITMASK_STRIDE,
3
};
4
5
/// A bit mask which contains the result of a `Match` operation on a `Group` and
6
/// allows iterating through them.
7
///
8
/// The bit mask is arranged so that low-order bits represent lower memory
9
/// addresses for group match results.
10
///
11
/// For implementation reasons, the bits in the set may be sparsely packed with
12
/// groups of 8 bits representing one element. If any of these bits are non-zero
13
/// then this element is considered to true in the mask. If this is the
14
/// case, `BITMASK_STRIDE` will be 8 to indicate a divide-by-8 should be
15
/// performed on counts/indices to normalize this difference. `BITMASK_MASK` is
16
/// similarly a mask of all the actually-used bits.
17
///
18
/// To iterate over a bit mask, it must be converted to a form where only 1 bit
19
/// is set per element. This is done by applying `BITMASK_ITER_MASK` on the
20
/// mask bits.
21
#[derive(Copy, Clone)]
22
pub(crate) struct BitMask(pub(crate) BitMaskWord);
23
24
#[allow(clippy::use_self)]
25
impl BitMask {
26
    /// Returns a new `BitMask` with all bits inverted.
27
    #[inline]
28
    #[must_use]
29
    #[allow(dead_code)]
30
0
    pub(crate) fn invert(self) -> Self {
31
0
        BitMask(self.0 ^ BITMASK_MASK)
32
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask6invertCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask6invertB6_
33
34
    /// Returns a new `BitMask` with the lowest bit removed.
35
    #[inline]
36
    #[must_use]
37
0
    fn remove_lowest_bit(self) -> Self {
38
0
        BitMask(self.0 & (self.0 - 1))
39
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask17remove_lowest_bitCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask17remove_lowest_bitB6_
40
41
    /// Returns whether the `BitMask` has at least one set bit.
42
    #[inline]
43
0
    pub(crate) fn any_bit_set(self) -> bool {
44
0
        self.0 != 0
45
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask11any_bit_setCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask11any_bit_setB6_
46
47
    /// Returns the first set bit in the `BitMask`, if there is one.
48
    #[inline]
49
0
    pub(crate) fn lowest_set_bit(self) -> Option<usize> {
50
0
        if let Some(nonzero) = NonZeroBitMaskWord::new(self.0) {
51
0
            Some(Self::nonzero_trailing_zeros(nonzero))
52
        } else {
53
0
            None
54
        }
55
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask14lowest_set_bitCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask14lowest_set_bitB6_
56
57
    /// Returns the number of trailing zeroes in the `BitMask`.
58
    #[inline]
59
0
    pub(crate) fn trailing_zeros(self) -> usize {
60
0
        // ARM doesn't have a trailing_zeroes instruction, and instead uses
61
0
        // reverse_bits (RBIT) + leading_zeroes (CLZ). However older ARM
62
0
        // versions (pre-ARMv7) don't have RBIT and need to emulate it
63
0
        // instead. Since we only have 1 bit set in each byte on ARM, we can
64
0
        // use swap_bytes (REV) + leading_zeroes instead.
65
0
        if cfg!(target_arch = "arm") && BITMASK_STRIDE % 8 == 0 {
66
0
            self.0.swap_bytes().leading_zeros() as usize / BITMASK_STRIDE
67
        } else {
68
0
            self.0.trailing_zeros() as usize / BITMASK_STRIDE
69
        }
70
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask14trailing_zerosCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask14trailing_zerosB6_
71
72
    /// Same as above but takes a `NonZeroBitMaskWord`.
73
    #[inline]
74
0
    fn nonzero_trailing_zeros(nonzero: NonZeroBitMaskWord) -> usize {
75
0
        if cfg!(target_arch = "arm") && BITMASK_STRIDE % 8 == 0 {
76
            // SAFETY: A byte-swapped non-zero value is still non-zero.
77
0
            let swapped = unsafe { NonZeroBitMaskWord::new_unchecked(nonzero.get().swap_bytes()) };
78
0
            swapped.leading_zeros() as usize / BITMASK_STRIDE
79
        } else {
80
0
            nonzero.trailing_zeros() as usize / BITMASK_STRIDE
81
        }
82
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask22nonzero_trailing_zerosCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask22nonzero_trailing_zerosB6_
83
84
    /// Returns the number of leading zeroes in the `BitMask`.
85
    #[inline]
86
0
    pub(crate) fn leading_zeros(self) -> usize {
87
0
        self.0.leading_zeros() as usize / BITMASK_STRIDE
88
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask13leading_zerosCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB2_7BitMask13leading_zerosB6_
89
}
90
91
impl IntoIterator for BitMask {
92
    type Item = usize;
93
    type IntoIter = BitMaskIter;
94
95
    #[inline]
96
0
    fn into_iter(self) -> BitMaskIter {
97
0
        // A BitMask only requires each element (group of bits) to be non-zero.
98
0
        // However for iteration we need each element to only contain 1 bit.
99
0
        BitMaskIter(BitMask(self.0 & BITMASK_ITER_MASK))
100
0
    }
Unexecuted instantiation: _RNvXs_NtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB4_7BitMaskNtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits7collect12IntoIterator9into_iterCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs_NtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB4_7BitMaskNtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits7collect12IntoIterator9into_iterB8_
101
}
102
103
/// Iterator over the contents of a `BitMask`, returning the indices of set
104
/// bits.
105
#[derive(Copy, Clone)]
106
pub(crate) struct BitMaskIter(pub(crate) BitMask);
107
108
impl BitMaskIter {
109
    /// Flip the bit in the mask for the entry at the given index.
110
    ///
111
    /// Returns the bit's previous state.
112
    #[inline]
113
    #[allow(clippy::cast_ptr_alignment)]
114
    #[cfg(feature = "raw")]
115
    pub(crate) unsafe fn flip(&mut self, index: usize) -> bool {
116
        // NOTE: The + BITMASK_STRIDE - 1 is to set the high bit.
117
        let mask = 1 << (index * BITMASK_STRIDE + BITMASK_STRIDE - 1);
118
        self.0 .0 ^= mask;
119
        // The bit was set if the bit is now 0.
120
        self.0 .0 & mask == 0
121
    }
122
}
123
124
impl Iterator for BitMaskIter {
125
    type Item = usize;
126
127
    #[inline]
128
0
    fn next(&mut self) -> Option<usize> {
129
0
        let bit = self.0.lowest_set_bit()?;
130
0
        self.0 = self.0.remove_lowest_bit();
131
0
        Some(bit)
132
0
    }
Unexecuted instantiation: _RNvXs1_NtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB5_11BitMaskIterNtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits8iterator8Iterator4nextCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs1_NtNtCsgkA6tlBCRmB_9hashbrown3raw7bitmaskNtB5_11BitMaskIterNtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits8iterator8Iterator4nextB9_
133
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/raw/mod.rs
Line
Count
Source
1
use crate::alloc::alloc::{handle_alloc_error, Layout};
2
use crate::scopeguard::{guard, ScopeGuard};
3
use crate::TryReserveError;
4
use core::iter::FusedIterator;
5
use core::marker::PhantomData;
6
use core::mem;
7
use core::mem::MaybeUninit;
8
use core::ptr::NonNull;
9
use core::{hint, ptr};
10
11
cfg_if! {
12
    // Use the SSE2 implementation if possible: it allows us to scan 16 buckets
13
    // at once instead of 8. We don't bother with AVX since it would require
14
    // runtime dispatch and wouldn't gain us much anyways: the probability of
15
    // finding a match drops off drastically after the first few buckets.
16
    //
17
    // I attempted an implementation on ARM using NEON instructions, but it
18
    // turns out that most NEON instructions have multi-cycle latency, which in
19
    // the end outweighs any gains over the generic implementation.
20
    if #[cfg(all(
21
        target_feature = "sse2",
22
        any(target_arch = "x86", target_arch = "x86_64"),
23
        not(miri),
24
    ))] {
25
        mod sse2;
26
        use sse2 as imp;
27
    } else if #[cfg(all(
28
        target_arch = "aarch64",
29
        target_feature = "neon",
30
        // NEON intrinsics are currently broken on big-endian targets.
31
        // See https://github.com/rust-lang/stdarch/issues/1484.
32
        target_endian = "little",
33
        not(miri),
34
    ))] {
35
        mod neon;
36
        use neon as imp;
37
    } else {
38
        mod generic;
39
        use generic as imp;
40
    }
41
}
42
43
mod alloc;
44
pub(crate) use self::alloc::{do_alloc, Allocator, Global};
45
46
mod bitmask;
47
48
use self::bitmask::BitMaskIter;
49
use self::imp::Group;
50
51
// Branch prediction hint. This is currently only available on nightly but it
52
// consistently improves performance by 10-15%.
53
#[cfg(not(feature = "nightly"))]
54
use core::convert::identity as likely;
55
#[cfg(not(feature = "nightly"))]
56
use core::convert::identity as unlikely;
57
#[cfg(feature = "nightly")]
58
use core::intrinsics::{likely, unlikely};
59
60
// FIXME: use strict provenance functions once they are stable.
61
// Implement it with a transmute for now.
62
#[inline(always)]
63
#[allow(clippy::useless_transmute)] // clippy is wrong, cast and transmute are different here
64
0
fn invalid_mut<T>(addr: usize) -> *mut T {
65
0
    unsafe { core::mem::transmute(addr) }
66
0
}
67
68
#[inline]
69
0
unsafe fn offset_from<T>(to: *const T, from: *const T) -> usize {
70
0
    to.offset_from(from) as usize
71
0
}
Unexecuted instantiation: _RINvNtCsgkA6tlBCRmB_9hashbrown3raw11offset_fromTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBN_8LruEntryB1c_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEEB2r_
Unexecuted instantiation: _RINvNtCsgkA6tlBCRmB_9hashbrown3raw11offset_frompEB4_
72
73
/// Whether memory allocation errors should return an error or abort.
74
#[derive(Copy, Clone)]
75
enum Fallibility {
76
    Fallible,
77
    Infallible,
78
}
79
80
impl Fallibility {
81
    /// Error to return on capacity overflow.
82
    #[cfg_attr(feature = "inline-more", inline)]
83
0
    fn capacity_overflow(self) -> TryReserveError {
84
0
        match self {
85
0
            Fallibility::Fallible => TryReserveError::CapacityOverflow,
86
0
            Fallibility::Infallible => panic!("Hash table capacity overflow"),
87
        }
88
0
    }
Unexecuted instantiation: _RNvMNtCsgkA6tlBCRmB_9hashbrown3rawNtB2_11Fallibility17capacity_overflowCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtCsgkA6tlBCRmB_9hashbrown3rawNtB2_11Fallibility17capacity_overflowB4_
89
90
    /// Error to return on allocation error.
91
    #[cfg_attr(feature = "inline-more", inline)]
92
0
    fn alloc_err(self, layout: Layout) -> TryReserveError {
93
0
        match self {
94
0
            Fallibility::Fallible => TryReserveError::AllocError { layout },
95
0
            Fallibility::Infallible => handle_alloc_error(layout),
96
        }
97
0
    }
Unexecuted instantiation: _RNvMNtCsgkA6tlBCRmB_9hashbrown3rawNtB2_11Fallibility9alloc_errCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtCsgkA6tlBCRmB_9hashbrown3rawNtB2_11Fallibility9alloc_errB4_
98
}
99
100
trait SizedTypeProperties: Sized {
101
    const IS_ZERO_SIZED: bool = mem::size_of::<Self>() == 0;
102
    const NEEDS_DROP: bool = mem::needs_drop::<Self>();
103
}
104
105
impl<T> SizedTypeProperties for T {}
106
107
/// Control byte value for an empty bucket.
108
const EMPTY: u8 = 0b1111_1111;
109
110
/// Control byte value for a deleted bucket.
111
const DELETED: u8 = 0b1000_0000;
112
113
/// Checks whether a control byte represents a full bucket (top bit is clear).
114
#[inline]
115
0
fn is_full(ctrl: u8) -> bool {
116
0
    ctrl & 0x80 == 0
117
0
}
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw7is_fullCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw7is_fullB3_
118
119
/// Checks whether a control byte represents a special value (top bit is set).
120
#[inline]
121
0
fn is_special(ctrl: u8) -> bool {
122
0
    ctrl & 0x80 != 0
123
0
}
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw10is_specialCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw10is_specialB3_
124
125
/// Checks whether a special control value is EMPTY (just check 1 bit).
126
#[inline]
127
0
fn special_is_empty(ctrl: u8) -> bool {
128
0
    debug_assert!(is_special(ctrl));
129
0
    ctrl & 0x01 != 0
130
0
}
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw16special_is_emptyCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw16special_is_emptyB3_
131
132
/// Primary hash function, used to select the initial bucket to probe from.
133
#[inline]
134
#[allow(clippy::cast_possible_truncation)]
135
0
fn h1(hash: u64) -> usize {
136
0
    // On 32-bit platforms we simply ignore the higher hash bits.
137
0
    hash as usize
138
0
}
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw2h1Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw2h1B3_
139
140
// Constant for h2 function that grabing the top 7 bits of the hash.
141
const MIN_HASH_LEN: usize = if mem::size_of::<usize>() < mem::size_of::<u64>() {
142
    mem::size_of::<usize>()
143
} else {
144
    mem::size_of::<u64>()
145
};
146
147
/// Secondary hash function, saved in the low 7 bits of the control byte.
148
#[inline]
149
#[allow(clippy::cast_possible_truncation)]
150
0
fn h2(hash: u64) -> u8 {
151
0
    // Grab the top 7 bits of the hash. While the hash is normally a full 64-bit
152
0
    // value, some hash functions (such as FxHash) produce a usize result
153
0
    // instead, which means that the top 32 bits are 0 on 32-bit platforms.
154
0
    // So we use MIN_HASH_LEN constant to handle this.
155
0
    let top7 = hash >> (MIN_HASH_LEN * 8 - 7);
156
0
    (top7 & 0x7f) as u8 // truncation
157
0
}
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw2h2Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw2h2B3_
158
159
/// Probe sequence based on triangular numbers, which is guaranteed (since our
160
/// table size is a power of two) to visit every group of elements exactly once.
161
///
162
/// A triangular probe has us jump by 1 more group every time. So first we
163
/// jump by 1 group (meaning we just continue our linear scan), then 2 groups
164
/// (skipping over 1 group), then 3 groups (skipping over 2 groups), and so on.
165
///
166
/// Proof that the probe will visit every group in the table:
167
/// <https://fgiesen.wordpress.com/2015/02/22/triangular-numbers-mod-2n/>
168
struct ProbeSeq {
169
    pos: usize,
170
    stride: usize,
171
}
172
173
impl ProbeSeq {
174
    #[inline]
175
0
    fn move_next(&mut self, bucket_mask: usize) {
176
0
        // We should have found an empty bucket by now and ended the probe.
177
0
        debug_assert!(
178
0
            self.stride <= bucket_mask,
179
0
            "Went past end of probe sequence"
180
        );
181
182
0
        self.stride += Group::WIDTH;
183
0
        self.pos += self.stride;
184
0
        self.pos &= bucket_mask;
185
0
    }
Unexecuted instantiation: _RNvMs0_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_8ProbeSeq9move_nextCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs0_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_8ProbeSeq9move_nextB7_
186
}
187
188
/// Returns the number of buckets needed to hold the given number of items,
189
/// taking the maximum load factor into account.
190
///
191
/// Returns `None` if an overflow occurs.
192
// Workaround for emscripten bug emscripten-core/emscripten-fastcomp#258
193
#[cfg_attr(target_os = "emscripten", inline(never))]
194
#[cfg_attr(not(target_os = "emscripten"), inline)]
195
0
fn capacity_to_buckets(cap: usize) -> Option<usize> {
196
0
    debug_assert_ne!(cap, 0);
197
198
    // For small tables we require at least 1 empty bucket so that lookups are
199
    // guaranteed to terminate if an element doesn't exist in the table.
200
0
    if cap < 8 {
201
        // We don't bother with a table size of 2 buckets since that can only
202
        // hold a single element. Instead we skip directly to a 4 bucket table
203
        // which can hold 3 elements.
204
0
        return Some(if cap < 4 { 4 } else { 8 });
205
0
    }
206
207
    // Otherwise require 1/8 buckets to be empty (87.5% load)
208
    //
209
    // Be careful when modifying this, calculate_layout relies on the
210
    // overflow check here.
211
0
    let adjusted_cap = cap.checked_mul(8)? / 7;
212
213
    // Any overflows will have been caught by the checked_mul. Also, any
214
    // rounding errors from the division above will be cleaned up by
215
    // next_power_of_two (which can't overflow because of the previous division).
216
0
    Some(adjusted_cap.next_power_of_two())
217
0
}
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw19capacity_to_bucketsCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw19capacity_to_bucketsB3_
218
219
/// Returns the maximum effective capacity for the given bucket mask, taking
220
/// the maximum load factor into account.
221
#[inline]
222
0
fn bucket_mask_to_capacity(bucket_mask: usize) -> usize {
223
0
    if bucket_mask < 8 {
224
        // For tables with 1/2/4/8 buckets, we always reserve one empty slot.
225
        // Keep in mind that the bucket mask is one less than the bucket count.
226
0
        bucket_mask
227
    } else {
228
        // For larger tables we reserve 12.5% of the slots as empty.
229
0
        ((bucket_mask + 1) / 8) * 7
230
    }
231
0
}
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw23bucket_mask_to_capacityCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvNtCsgkA6tlBCRmB_9hashbrown3raw23bucket_mask_to_capacityB3_
232
233
/// Helper which allows the max calculation for ctrl_align to be statically computed for each T
234
/// while keeping the rest of `calculate_layout_for` independent of `T`
235
#[derive(Copy, Clone)]
236
struct TableLayout {
237
    size: usize,
238
    ctrl_align: usize,
239
}
240
241
impl TableLayout {
242
    #[inline]
243
0
    const fn new<T>() -> Self {
244
0
        let layout = Layout::new::<T>();
245
0
        Self {
246
0
            size: layout.size(),
247
0
            ctrl_align: if layout.align() > Group::WIDTH {
248
0
                layout.align()
249
            } else {
250
0
                Group::WIDTH
251
            },
252
        }
253
0
    }
254
255
    #[inline]
256
0
    fn calculate_layout_for(self, buckets: usize) -> Option<(Layout, usize)> {
257
0
        debug_assert!(buckets.is_power_of_two());
258
259
0
        let TableLayout { size, ctrl_align } = self;
260
        // Manual layout calculation since Layout methods are not yet stable.
261
0
        let ctrl_offset =
262
0
            size.checked_mul(buckets)?.checked_add(ctrl_align - 1)? & !(ctrl_align - 1);
263
0
        let len = ctrl_offset.checked_add(buckets + Group::WIDTH)?;
264
265
        // We need an additional check to ensure that the allocation doesn't
266
        // exceed `isize::MAX` (https://github.com/rust-lang/rust/pull/95295).
267
0
        if len > isize::MAX as usize - (ctrl_align - 1) {
268
0
            return None;
269
0
        }
270
0
271
0
        Some((
272
0
            unsafe { Layout::from_size_align_unchecked(len, ctrl_align) },
273
0
            ctrl_offset,
274
0
        ))
275
0
    }
Unexecuted instantiation: _RNvMs1_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_11TableLayout20calculate_layout_forCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs1_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_11TableLayout20calculate_layout_forB7_
276
}
277
278
/// A reference to an empty bucket into which an can be inserted.
279
pub struct InsertSlot {
280
    index: usize,
281
}
282
283
/// A reference to a hash table bucket containing a `T`.
284
///
285
/// This is usually just a pointer to the element itself. However if the element
286
/// is a ZST, then we instead track the index of the element in the table so
287
/// that `erase` works properly.
288
pub struct Bucket<T> {
289
    // Actually it is pointer to next element than element itself
290
    // this is needed to maintain pointer arithmetic invariants
291
    // keeping direct pointer to element introduces difficulty.
292
    // Using `NonNull` for variance and niche layout
293
    ptr: NonNull<T>,
294
}
295
296
// This Send impl is needed for rayon support. This is safe since Bucket is
297
// never exposed in a public API.
298
unsafe impl<T> Send for Bucket<T> {}
299
300
impl<T> Clone for Bucket<T> {
301
    #[inline]
302
0
    fn clone(&self) -> Self {
303
0
        Self { ptr: self.ptr }
304
0
    }
305
}
306
307
impl<T> Bucket<T> {
308
    /// Creates a [`Bucket`] that contain pointer to the data.
309
    /// The pointer calculation is performed by calculating the
310
    /// offset from given `base` pointer (convenience for
311
    /// `base.as_ptr().sub(index)`).
312
    ///
313
    /// `index` is in units of `T`; e.g., an `index` of 3 represents a pointer
314
    /// offset of `3 * size_of::<T>()` bytes.
315
    ///
316
    /// If the `T` is a ZST, then we instead track the index of the element
317
    /// in the table so that `erase` works properly (return
318
    /// `NonNull::new_unchecked((index + 1) as *mut T)`)
319
    ///
320
    /// # Safety
321
    ///
322
    /// If `mem::size_of::<T>() != 0`, then the safety rules are directly derived
323
    /// from the safety rules for [`<*mut T>::sub`] method of `*mut T` and the safety
324
    /// rules of [`NonNull::new_unchecked`] function.
325
    ///
326
    /// Thus, in order to uphold the safety contracts for the [`<*mut T>::sub`] method
327
    /// and [`NonNull::new_unchecked`] function, as well as for the correct
328
    /// logic of the work of this crate, the following rules are necessary and
329
    /// sufficient:
330
    ///
331
    /// * the `base` pointer must not be `dangling` and must points to the
332
    ///   end of the first `value element` from the `data part` of the table, i.e.
333
    ///   must be the pointer that returned by [`RawTable::data_end`] or by
334
    ///   [`RawTableInner::data_end<T>`];
335
    ///
336
    /// * `index` must not be greater than `RawTableInner.bucket_mask`, i.e.
337
    ///   `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)`
338
    ///   must be no greater than the number returned by the function
339
    ///   [`RawTable::buckets`] or [`RawTableInner::buckets`].
340
    ///
341
    /// If `mem::size_of::<T>() == 0`, then the only requirement is that the
342
    /// `index` must not be greater than `RawTableInner.bucket_mask`, i.e.
343
    /// `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)`
344
    /// must be no greater than the number returned by the function
345
    /// [`RawTable::buckets`] or [`RawTableInner::buckets`].
346
    ///
347
    /// [`Bucket`]: crate::raw::Bucket
348
    /// [`<*mut T>::sub`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.sub-1
349
    /// [`NonNull::new_unchecked`]: https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.new_unchecked
350
    /// [`RawTable::data_end`]: crate::raw::RawTable::data_end
351
    /// [`RawTableInner::data_end<T>`]: RawTableInner::data_end<T>
352
    /// [`RawTable::buckets`]: crate::raw::RawTable::buckets
353
    /// [`RawTableInner::buckets`]: RawTableInner::buckets
354
    #[inline]
355
0
    unsafe fn from_base_index(base: NonNull<T>, index: usize) -> Self {
356
        // If mem::size_of::<T>() != 0 then return a pointer to an `element` in
357
        // the data part of the table (we start counting from "0", so that
358
        // in the expression T[last], the "last" index actually one less than the
359
        // "buckets" number in the table, i.e. "last = RawTableInner.bucket_mask"):
360
        //
361
        //                   `from_base_index(base, 1).as_ptr()` returns a pointer that
362
        //                   points here in the data part of the table
363
        //                   (to the start of T1)
364
        //                        |
365
        //                        |        `base: NonNull<T>` must point here
366
        //                        |         (to the end of T0 or to the start of C0)
367
        //                        v         v
368
        // [Padding], Tlast, ..., |T1|, T0, |C0, C1, ..., Clast
369
        //                           ^
370
        //                           `from_base_index(base, 1)` returns a pointer
371
        //                           that points here in the data part of the table
372
        //                           (to the end of T1)
373
        //
374
        // where: T0...Tlast - our stored data; C0...Clast - control bytes
375
        // or metadata for data.
376
0
        let ptr = if T::IS_ZERO_SIZED {
377
            // won't overflow because index must be less than length (bucket_mask)
378
            // and bucket_mask is guaranteed to be less than `isize::MAX`
379
            // (see TableLayout::calculate_layout_for method)
380
0
            invalid_mut(index + 1)
381
        } else {
382
0
            base.as_ptr().sub(index)
383
        };
384
0
        Self {
385
0
            ptr: NonNull::new_unchecked(ptr),
386
0
        }
387
0
    }
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE15from_base_indexB2u_
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketpE15from_base_indexB7_
388
389
    /// Calculates the index of a [`Bucket`] as distance between two pointers
390
    /// (convenience for `base.as_ptr().offset_from(self.ptr.as_ptr()) as usize`).
391
    /// The returned value is in units of T: the distance in bytes divided by
392
    /// [`core::mem::size_of::<T>()`].
393
    ///
394
    /// If the `T` is a ZST, then we return the index of the element in
395
    /// the table so that `erase` works properly (return `self.ptr.as_ptr() as usize - 1`).
396
    ///
397
    /// This function is the inverse of [`from_base_index`].
398
    ///
399
    /// # Safety
400
    ///
401
    /// If `mem::size_of::<T>() != 0`, then the safety rules are directly derived
402
    /// from the safety rules for [`<*const T>::offset_from`] method of `*const T`.
403
    ///
404
    /// Thus, in order to uphold the safety contracts for [`<*const T>::offset_from`]
405
    /// method, as well as for the correct logic of the work of this crate, the
406
    /// following rules are necessary and sufficient:
407
    ///
408
    /// * `base` contained pointer must not be `dangling` and must point to the
409
    ///   end of the first `element` from the `data part` of the table, i.e.
410
    ///   must be a pointer that returns by [`RawTable::data_end`] or by
411
    ///   [`RawTableInner::data_end<T>`];
412
    ///
413
    /// * `self` also must not contain dangling pointer;
414
    ///
415
    /// * both `self` and `base` must be created from the same [`RawTable`]
416
    ///   (or [`RawTableInner`]).
417
    ///
418
    /// If `mem::size_of::<T>() == 0`, this function is always safe.
419
    ///
420
    /// [`Bucket`]: crate::raw::Bucket
421
    /// [`from_base_index`]: crate::raw::Bucket::from_base_index
422
    /// [`RawTable::data_end`]: crate::raw::RawTable::data_end
423
    /// [`RawTableInner::data_end<T>`]: RawTableInner::data_end<T>
424
    /// [`RawTable`]: crate::raw::RawTable
425
    /// [`RawTableInner`]: RawTableInner
426
    /// [`<*const T>::offset_from`]: https://doc.rust-lang.org/nightly/core/primitive.pointer.html#method.offset_from
427
    #[inline]
428
0
    unsafe fn to_base_index(&self, base: NonNull<T>) -> usize {
429
0
        // If mem::size_of::<T>() != 0 then return an index under which we used to store the
430
0
        // `element` in the data part of the table (we start counting from "0", so
431
0
        // that in the expression T[last], the "last" index actually is one less than the
432
0
        // "buckets" number in the table, i.e. "last = RawTableInner.bucket_mask").
433
0
        // For example for 5th element in table calculation is performed like this:
434
0
        //
435
0
        //                        mem::size_of::<T>()
436
0
        //                          |
437
0
        //                          |         `self = from_base_index(base, 5)` that returns pointer
438
0
        //                          |         that points here in tha data part of the table
439
0
        //                          |         (to the end of T5)
440
0
        //                          |           |                    `base: NonNull<T>` must point here
441
0
        //                          v           |                    (to the end of T0 or to the start of C0)
442
0
        //                        /???\         v                      v
443
0
        // [Padding], Tlast, ..., |T10|, ..., T5|, T4, T3, T2, T1, T0, |C0, C1, C2, C3, C4, C5, ..., C10, ..., Clast
444
0
        //                                      \__________  __________/
445
0
        //                                                 \/
446
0
        //                                     `bucket.to_base_index(base)` = 5
447
0
        //                                     (base.as_ptr() as usize - self.ptr.as_ptr() as usize) / mem::size_of::<T>()
448
0
        //
449
0
        // where: T0...Tlast - our stored data; C0...Clast - control bytes or metadata for data.
450
0
        if T::IS_ZERO_SIZED {
451
            // this can not be UB
452
0
            self.ptr.as_ptr() as usize - 1
453
        } else {
454
0
            offset_from(base.as_ptr(), self.ptr.as_ptr())
455
        }
456
0
    }
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE13to_base_indexB2u_
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketpE13to_base_indexB7_
457
458
    /// Acquires the underlying raw pointer `*mut T` to `data`.
459
    ///
460
    /// # Note
461
    ///
462
    /// If `T` is not [`Copy`], do not use `*mut T` methods that can cause calling the
463
    /// destructor of `T` (for example the [`<*mut T>::drop_in_place`] method), because
464
    /// for properly dropping the data we also need to clear `data` control bytes. If we
465
    /// drop data, but do not clear `data control byte` it leads to double drop when
466
    /// [`RawTable`] goes out of scope.
467
    ///
468
    /// If you modify an already initialized `value`, so [`Hash`] and [`Eq`] on the new
469
    /// `T` value and its borrowed form *must* match those for the old `T` value, as the map
470
    /// will not re-evaluate where the new value should go, meaning the value may become
471
    /// "lost" if their location does not reflect their state.
472
    ///
473
    /// [`RawTable`]: crate::raw::RawTable
474
    /// [`<*mut T>::drop_in_place`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.drop_in_place
475
    /// [`Hash`]: https://doc.rust-lang.org/core/hash/trait.Hash.html
476
    /// [`Eq`]: https://doc.rust-lang.org/core/cmp/trait.Eq.html
477
    ///
478
    /// # Examples
479
    ///
480
    /// ```
481
    /// # #[cfg(feature = "raw")]
482
    /// # fn test() {
483
    /// use core::hash::{BuildHasher, Hash};
484
    /// use hashbrown::raw::{Bucket, RawTable};
485
    ///
486
    /// type NewHashBuilder = core::hash::BuildHasherDefault<ahash::AHasher>;
487
    ///
488
    /// fn make_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
489
    ///     use core::hash::Hasher;
490
    ///     let mut state = hash_builder.build_hasher();
491
    ///     key.hash(&mut state);
492
    ///     state.finish()
493
    /// }
494
    ///
495
    /// let hash_builder = NewHashBuilder::default();
496
    /// let mut table = RawTable::new();
497
    ///
498
    /// let value = ("a", 100);
499
    /// let hash = make_hash(&hash_builder, &value.0);
500
    ///
501
    /// table.insert(hash, value.clone(), |val| make_hash(&hash_builder, &val.0));
502
    ///
503
    /// let bucket: Bucket<(&str, i32)> = table.find(hash, |(k1, _)| k1 == &value.0).unwrap();
504
    ///
505
    /// assert_eq!(unsafe { &*bucket.as_ptr() }, &("a", 100));
506
    /// # }
507
    /// # fn main() {
508
    /// #     #[cfg(feature = "raw")]
509
    /// #     test()
510
    /// # }
511
    /// ```
512
    #[inline]
513
0
    pub fn as_ptr(&self) -> *mut T {
514
0
        if T::IS_ZERO_SIZED {
515
            // Just return an arbitrary ZST pointer which is properly aligned
516
            // invalid pointer is good enough for ZST
517
0
            invalid_mut(mem::align_of::<T>())
518
        } else {
519
0
            unsafe { self.ptr.as_ptr().sub(1) }
520
        }
521
0
    }
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE6as_ptrB2u_
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketpE6as_ptrB7_
522
523
    /// Create a new [`Bucket`] that is offset from the `self` by the given
524
    /// `offset`. The pointer calculation is performed by calculating the
525
    /// offset from `self` pointer (convenience for `self.ptr.as_ptr().sub(offset)`).
526
    /// This function is used for iterators.
527
    ///
528
    /// `offset` is in units of `T`; e.g., a `offset` of 3 represents a pointer
529
    /// offset of `3 * size_of::<T>()` bytes.
530
    ///
531
    /// # Safety
532
    ///
533
    /// If `mem::size_of::<T>() != 0`, then the safety rules are directly derived
534
    /// from the safety rules for [`<*mut T>::sub`] method of `*mut T` and safety
535
    /// rules of [`NonNull::new_unchecked`] function.
536
    ///
537
    /// Thus, in order to uphold the safety contracts for [`<*mut T>::sub`] method
538
    /// and [`NonNull::new_unchecked`] function, as well as for the correct
539
    /// logic of the work of this crate, the following rules are necessary and
540
    /// sufficient:
541
    ///
542
    /// * `self` contained pointer must not be `dangling`;
543
    ///
544
    /// * `self.to_base_index() + ofset` must not be greater than `RawTableInner.bucket_mask`,
545
    ///   i.e. `(self.to_base_index() + ofset) <= RawTableInner.bucket_mask` or, in other
546
    ///   words, `self.to_base_index() + ofset + 1` must be no greater than the number returned
547
    ///   by the function [`RawTable::buckets`] or [`RawTableInner::buckets`].
548
    ///
549
    /// If `mem::size_of::<T>() == 0`, then the only requirement is that the
550
    /// `self.to_base_index() + ofset` must not be greater than `RawTableInner.bucket_mask`,
551
    /// i.e. `(self.to_base_index() + ofset) <= RawTableInner.bucket_mask` or, in other words,
552
    /// `self.to_base_index() + ofset + 1` must be no greater than the number returned by the
553
    /// function [`RawTable::buckets`] or [`RawTableInner::buckets`].
554
    ///
555
    /// [`Bucket`]: crate::raw::Bucket
556
    /// [`<*mut T>::sub`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.sub-1
557
    /// [`NonNull::new_unchecked`]: https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.new_unchecked
558
    /// [`RawTable::buckets`]: crate::raw::RawTable::buckets
559
    /// [`RawTableInner::buckets`]: RawTableInner::buckets
560
    #[inline]
561
0
    unsafe fn next_n(&self, offset: usize) -> Self {
562
0
        let ptr = if T::IS_ZERO_SIZED {
563
            // invalid pointer is good enough for ZST
564
0
            invalid_mut(self.ptr.as_ptr() as usize + offset)
565
        } else {
566
0
            self.ptr.as_ptr().sub(offset)
567
        };
568
0
        Self {
569
0
            ptr: NonNull::new_unchecked(ptr),
570
0
        }
571
0
    }
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE6next_nB2u_
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketpE6next_nB7_
572
573
    /// Executes the destructor (if any) of the pointed-to `data`.
574
    ///
575
    /// # Safety
576
    ///
577
    /// See [`ptr::drop_in_place`] for safety concerns.
578
    ///
579
    /// You should use [`RawTable::erase`] instead of this function,
580
    /// or be careful with calling this function directly, because for
581
    /// properly dropping the data we need also clear `data` control bytes.
582
    /// If we drop data, but do not erase `data control byte` it leads to
583
    /// double drop when [`RawTable`] goes out of scope.
584
    ///
585
    /// [`ptr::drop_in_place`]: https://doc.rust-lang.org/core/ptr/fn.drop_in_place.html
586
    /// [`RawTable`]: crate::raw::RawTable
587
    /// [`RawTable::erase`]: crate::raw::RawTable::erase
588
    #[cfg_attr(feature = "inline-more", inline)]
589
0
    pub(crate) unsafe fn drop(&self) {
590
0
        self.as_ptr().drop_in_place();
591
0
    }
592
593
    /// Reads the `value` from `self` without moving it. This leaves the
594
    /// memory in `self` unchanged.
595
    ///
596
    /// # Safety
597
    ///
598
    /// See [`ptr::read`] for safety concerns.
599
    ///
600
    /// You should use [`RawTable::remove`] instead of this function,
601
    /// or be careful with calling this function directly, because compiler
602
    /// calls its destructor when readed `value` goes out of scope. It
603
    /// can cause double dropping when [`RawTable`] goes out of scope,
604
    /// because of not erased `data control byte`.
605
    ///
606
    /// [`ptr::read`]: https://doc.rust-lang.org/core/ptr/fn.read.html
607
    /// [`RawTable`]: crate::raw::RawTable
608
    /// [`RawTable::remove`]: crate::raw::RawTable::remove
609
    #[inline]
610
0
    pub(crate) unsafe fn read(&self) -> T {
611
0
        self.as_ptr().read()
612
0
    }
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE4readB2u_
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketpE4readB7_
613
614
    /// Overwrites a memory location with the given `value` without reading
615
    /// or dropping the old value (like [`ptr::write`] function).
616
    ///
617
    /// # Safety
618
    ///
619
    /// See [`ptr::write`] for safety concerns.
620
    ///
621
    /// # Note
622
    ///
623
    /// [`Hash`] and [`Eq`] on the new `T` value and its borrowed form *must* match
624
    /// those for the old `T` value, as the map will not re-evaluate where the new
625
    /// value should go, meaning the value may become "lost" if their location
626
    /// does not reflect their state.
627
    ///
628
    /// [`ptr::write`]: https://doc.rust-lang.org/core/ptr/fn.write.html
629
    /// [`Hash`]: https://doc.rust-lang.org/core/hash/trait.Hash.html
630
    /// [`Eq`]: https://doc.rust-lang.org/core/cmp/trait.Eq.html
631
    #[inline]
632
0
    pub(crate) unsafe fn write(&self, val: T) {
633
0
        self.as_ptr().write(val);
634
0
    }
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE5writeB2u_
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketpE5writeB7_
635
636
    /// Returns a shared immutable reference to the `value`.
637
    ///
638
    /// # Safety
639
    ///
640
    /// See [`NonNull::as_ref`] for safety concerns.
641
    ///
642
    /// [`NonNull::as_ref`]: https://doc.rust-lang.org/core/ptr/struct.NonNull.html#method.as_ref
643
    ///
644
    /// # Examples
645
    ///
646
    /// ```
647
    /// # #[cfg(feature = "raw")]
648
    /// # fn test() {
649
    /// use core::hash::{BuildHasher, Hash};
650
    /// use hashbrown::raw::{Bucket, RawTable};
651
    ///
652
    /// type NewHashBuilder = core::hash::BuildHasherDefault<ahash::AHasher>;
653
    ///
654
    /// fn make_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
655
    ///     use core::hash::Hasher;
656
    ///     let mut state = hash_builder.build_hasher();
657
    ///     key.hash(&mut state);
658
    ///     state.finish()
659
    /// }
660
    ///
661
    /// let hash_builder = NewHashBuilder::default();
662
    /// let mut table = RawTable::new();
663
    ///
664
    /// let value: (&str, String) = ("A pony", "is a small horse".to_owned());
665
    /// let hash = make_hash(&hash_builder, &value.0);
666
    ///
667
    /// table.insert(hash, value.clone(), |val| make_hash(&hash_builder, &val.0));
668
    ///
669
    /// let bucket: Bucket<(&str, String)> = table.find(hash, |(k, _)| k == &value.0).unwrap();
670
    ///
671
    /// assert_eq!(
672
    ///     unsafe { bucket.as_ref() },
673
    ///     &("A pony", "is a small horse".to_owned())
674
    /// );
675
    /// # }
676
    /// # fn main() {
677
    /// #     #[cfg(feature = "raw")]
678
    /// #     test()
679
    /// # }
680
    /// ```
681
    #[inline]
682
0
    pub unsafe fn as_ref<'a>(&self) -> &'a T {
683
0
        &*self.as_ptr()
684
0
    }
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE6as_refB2u_
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketpE6as_refB7_
685
686
    /// Returns a unique mutable reference to the `value`.
687
    ///
688
    /// # Safety
689
    ///
690
    /// See [`NonNull::as_mut`] for safety concerns.
691
    ///
692
    /// # Note
693
    ///
694
    /// [`Hash`] and [`Eq`] on the new `T` value and its borrowed form *must* match
695
    /// those for the old `T` value, as the map will not re-evaluate where the new
696
    /// value should go, meaning the value may become "lost" if their location
697
    /// does not reflect their state.
698
    ///
699
    /// [`NonNull::as_mut`]: https://doc.rust-lang.org/core/ptr/struct.NonNull.html#method.as_mut
700
    /// [`Hash`]: https://doc.rust-lang.org/core/hash/trait.Hash.html
701
    /// [`Eq`]: https://doc.rust-lang.org/core/cmp/trait.Eq.html
702
    ///
703
    /// # Examples
704
    ///
705
    /// ```
706
    /// # #[cfg(feature = "raw")]
707
    /// # fn test() {
708
    /// use core::hash::{BuildHasher, Hash};
709
    /// use hashbrown::raw::{Bucket, RawTable};
710
    ///
711
    /// type NewHashBuilder = core::hash::BuildHasherDefault<ahash::AHasher>;
712
    ///
713
    /// fn make_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
714
    ///     use core::hash::Hasher;
715
    ///     let mut state = hash_builder.build_hasher();
716
    ///     key.hash(&mut state);
717
    ///     state.finish()
718
    /// }
719
    ///
720
    /// let hash_builder = NewHashBuilder::default();
721
    /// let mut table = RawTable::new();
722
    ///
723
    /// let value: (&str, String) = ("A pony", "is a small horse".to_owned());
724
    /// let hash = make_hash(&hash_builder, &value.0);
725
    ///
726
    /// table.insert(hash, value.clone(), |val| make_hash(&hash_builder, &val.0));
727
    ///
728
    /// let bucket: Bucket<(&str, String)> = table.find(hash, |(k, _)| k == &value.0).unwrap();
729
    ///
730
    /// unsafe {
731
    ///     bucket
732
    ///         .as_mut()
733
    ///         .1
734
    ///         .push_str(" less than 147 cm at the withers")
735
    /// };
736
    /// assert_eq!(
737
    ///     unsafe { bucket.as_ref() },
738
    ///     &(
739
    ///         "A pony",
740
    ///         "is a small horse less than 147 cm at the withers".to_owned()
741
    ///     )
742
    /// );
743
    /// # }
744
    /// # fn main() {
745
    /// #     #[cfg(feature = "raw")]
746
    /// #     test()
747
    /// # }
748
    /// ```
749
    #[inline]
750
0
    pub unsafe fn as_mut<'a>(&self) -> &'a mut T {
751
0
        &mut *self.as_ptr()
752
0
    }
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBQ_8LruEntryB1f_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE6as_mutB2u_
Unexecuted instantiation: _RNvMs4_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_6BucketpE6as_mutB7_
753
754
    /// Copies `size_of<T>` bytes from `other` to `self`. The source
755
    /// and destination may *not* overlap.
756
    ///
757
    /// # Safety
758
    ///
759
    /// See [`ptr::copy_nonoverlapping`] for safety concerns.
760
    ///
761
    /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
762
    /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
763
    /// in the region beginning at `*self` and the region beginning at `*other` can
764
    /// [violate memory safety].
765
    ///
766
    /// # Note
767
    ///
768
    /// [`Hash`] and [`Eq`] on the new `T` value and its borrowed form *must* match
769
    /// those for the old `T` value, as the map will not re-evaluate where the new
770
    /// value should go, meaning the value may become "lost" if their location
771
    /// does not reflect their state.
772
    ///
773
    /// [`ptr::copy_nonoverlapping`]: https://doc.rust-lang.org/core/ptr/fn.copy_nonoverlapping.html
774
    /// [`read`]: https://doc.rust-lang.org/core/ptr/fn.read.html
775
    /// [violate memory safety]: https://doc.rust-lang.org/std/ptr/fn.read.html#ownership-of-the-returned-value
776
    /// [`Hash`]: https://doc.rust-lang.org/core/hash/trait.Hash.html
777
    /// [`Eq`]: https://doc.rust-lang.org/core/cmp/trait.Eq.html
778
    #[cfg(feature = "raw")]
779
    #[inline]
780
    pub unsafe fn copy_from_nonoverlapping(&self, other: &Self) {
781
        self.as_ptr().copy_from_nonoverlapping(other.as_ptr(), 1);
782
    }
783
}
784
785
/// A raw hash table with an unsafe API.
786
pub struct RawTable<T, A: Allocator = Global> {
787
    table: RawTableInner,
788
    alloc: A,
789
    // Tell dropck that we own instances of T.
790
    marker: PhantomData<T>,
791
}
792
793
/// Non-generic part of `RawTable` which allows functions to be instantiated only once regardless
794
/// of how many different key-value types are used.
795
struct RawTableInner {
796
    // Mask to get an index from a hash value. The value is one less than the
797
    // number of buckets in the table.
798
    bucket_mask: usize,
799
800
    // [Padding], T1, T2, ..., Tlast, C1, C2, ...
801
    //                                ^ points here
802
    ctrl: NonNull<u8>,
803
804
    // Number of elements that can be inserted before we need to grow the table
805
    growth_left: usize,
806
807
    // Number of elements in the table, only really used by len()
808
    items: usize,
809
}
810
811
impl<T> RawTable<T, Global> {
812
    /// Creates a new empty hash table without allocating any memory.
813
    ///
814
    /// In effect this returns a table with exactly 1 bucket. However we can
815
    /// leave the data pointer dangling since that bucket is never written to
816
    /// due to our load factor forcing us to always have at least 1 free bucket.
817
    #[inline]
818
0
    pub const fn new() -> Self {
819
0
        Self {
820
0
            table: RawTableInner::NEW,
821
0
            alloc: Global,
822
0
            marker: PhantomData,
823
0
        }
824
0
    }
825
826
    /// Attempts to allocate a new hash table with at least enough capacity
827
    /// for inserting the given number of elements without reallocating.
828
    #[cfg(feature = "raw")]
829
    pub fn try_with_capacity(capacity: usize) -> Result<Self, TryReserveError> {
830
        Self::try_with_capacity_in(capacity, Global)
831
    }
832
833
    /// Allocates a new hash table with at least enough capacity for inserting
834
    /// the given number of elements without reallocating.
835
0
    pub fn with_capacity(capacity: usize) -> Self {
836
0
        Self::with_capacity_in(capacity, Global)
837
0
    }
Unexecuted instantiation: _RNvMs5_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE13with_capacityB2w_
Unexecuted instantiation: _RNvMs5_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTablepE13with_capacityB7_
838
}
839
840
impl<T, A: Allocator> RawTable<T, A> {
841
    const TABLE_LAYOUT: TableLayout = TableLayout::new::<T>();
842
843
    /// Creates a new empty hash table without allocating any memory, using the
844
    /// given allocator.
845
    ///
846
    /// In effect this returns a table with exactly 1 bucket. However we can
847
    /// leave the data pointer dangling since that bucket is never written to
848
    /// due to our load factor forcing us to always have at least 1 free bucket.
849
    #[inline]
850
0
    pub const fn new_in(alloc: A) -> Self {
851
0
        Self {
852
0
            table: RawTableInner::NEW,
853
0
            alloc,
854
0
            marker: PhantomData,
855
0
        }
856
0
    }
857
858
    /// Allocates a new hash table with the given number of buckets.
859
    ///
860
    /// The control bytes are left uninitialized.
861
    #[cfg_attr(feature = "inline-more", inline)]
862
0
    unsafe fn new_uninitialized(
863
0
        alloc: A,
864
0
        buckets: usize,
865
0
        fallibility: Fallibility,
866
0
    ) -> Result<Self, TryReserveError> {
867
0
        debug_assert!(buckets.is_power_of_two());
868
869
        Ok(Self {
870
0
            table: RawTableInner::new_uninitialized(
871
0
                &alloc,
872
0
                Self::TABLE_LAYOUT,
873
0
                buckets,
874
0
                fallibility,
875
0
            )?,
876
0
            alloc,
877
0
            marker: PhantomData,
878
        })
879
0
    }
880
881
    /// Attempts to allocate a new hash table using the given allocator, with at least enough
882
    /// capacity for inserting the given number of elements without reallocating.
883
    #[cfg(feature = "raw")]
884
    pub fn try_with_capacity_in(capacity: usize, alloc: A) -> Result<Self, TryReserveError> {
885
        Ok(Self {
886
            table: RawTableInner::fallible_with_capacity(
887
                &alloc,
888
                Self::TABLE_LAYOUT,
889
                capacity,
890
                Fallibility::Fallible,
891
            )?,
892
            alloc,
893
            marker: PhantomData,
894
        })
895
    }
896
897
    /// Allocates a new hash table using the given allocator, with at least enough capacity for
898
    /// inserting the given number of elements without reallocating.
899
0
    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
900
0
        Self {
901
0
            table: RawTableInner::with_capacity(&alloc, Self::TABLE_LAYOUT, capacity),
902
0
            alloc,
903
0
            marker: PhantomData,
904
0
        }
905
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE16with_capacity_inB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE16with_capacity_inB7_
906
907
    /// Returns a reference to the underlying allocator.
908
    #[inline]
909
0
    pub fn allocator(&self) -> &A {
910
0
        &self.alloc
911
0
    }
912
913
    /// Returns pointer to one past last `data` element in the table as viewed from
914
    /// the start point of the allocation.
915
    ///
916
    /// The caller must ensure that the `RawTable` outlives the returned [`NonNull<T>`],
917
    /// otherwise using it may result in [`undefined behavior`].
918
    ///
919
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
920
    #[inline]
921
0
    pub fn data_end(&self) -> NonNull<T> {
922
0
        //                        `self.table.ctrl.cast()` returns pointer that
923
0
        //                        points here (to the end of `T0`)
924
0
        //                          ∨
925
0
        // [Pad], T_n, ..., T1, T0, |CT0, CT1, ..., CT_n|, CTa_0, CTa_1, ..., CTa_m
926
0
        //                           \________  ________/
927
0
        //                                    \/
928
0
        //       `n = buckets - 1`, i.e. `RawTable::buckets() - 1`
929
0
        //
930
0
        // where: T0...T_n  - our stored data;
931
0
        //        CT0...CT_n - control bytes or metadata for `data`.
932
0
        //        CTa_0...CTa_m - additional control bytes, where `m = Group::WIDTH - 1` (so that the search
933
0
        //                        with loading `Group` bytes from the heap works properly, even if the result
934
0
        //                        of `h1(hash) & self.bucket_mask` is equal to `self.bucket_mask`). See also
935
0
        //                        `RawTableInner::set_ctrl` function.
936
0
        //
937
0
        // P.S. `h1(hash) & self.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
938
0
        // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
939
0
        self.table.ctrl.cast()
940
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE8data_endB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE8data_endB7_
941
942
    /// Returns pointer to start of data table.
943
    #[inline]
944
    #[cfg(any(feature = "raw", feature = "nightly"))]
945
    pub unsafe fn data_start(&self) -> NonNull<T> {
946
        NonNull::new_unchecked(self.data_end().as_ptr().wrapping_sub(self.buckets()))
947
    }
948
949
    /// Return the information about memory allocated by the table.
950
    ///
951
    /// `RawTable` allocates single memory block to store both data and metadata.
952
    /// This function returns allocation size and alignment and the beginning of the area.
953
    /// These are the arguments which will be passed to `dealloc` when the table is dropped.
954
    ///
955
    /// This function might be useful for memory profiling.
956
    #[inline]
957
    #[cfg(feature = "raw")]
958
    pub fn allocation_info(&self) -> (NonNull<u8>, Layout) {
959
        // SAFETY: We use the same `table_layout` that was used to allocate
960
        // this table.
961
        unsafe { self.table.allocation_info_or_zero(Self::TABLE_LAYOUT) }
962
    }
963
964
    /// Returns the index of a bucket from a `Bucket`.
965
    #[inline]
966
0
    pub unsafe fn bucket_index(&self, bucket: &Bucket<T>) -> usize {
967
0
        bucket.to_base_index(self.data_end())
968
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE12bucket_indexB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE12bucket_indexB7_
969
970
    /// Returns a pointer to an element in the table.
971
    ///
972
    /// The caller must ensure that the `RawTable` outlives the returned [`Bucket<T>`],
973
    /// otherwise using it may result in [`undefined behavior`].
974
    ///
975
    /// # Safety
976
    ///
977
    /// If `mem::size_of::<T>() != 0`, then the caller of this function must observe the
978
    /// following safety rules:
979
    ///
980
    /// * The table must already be allocated;
981
    ///
982
    /// * The `index` must not be greater than the number returned by the [`RawTable::buckets`]
983
    ///   function, i.e. `(index + 1) <= self.buckets()`.
984
    ///
985
    /// It is safe to call this function with index of zero (`index == 0`) on a table that has
986
    /// not been allocated, but using the returned [`Bucket`] results in [`undefined behavior`].
987
    ///
988
    /// If `mem::size_of::<T>() == 0`, then the only requirement is that the `index` must
989
    /// not be greater than the number returned by the [`RawTable::buckets`] function, i.e.
990
    /// `(index + 1) <= self.buckets()`.
991
    ///
992
    /// [`RawTable::buckets`]: RawTable::buckets
993
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
994
    #[inline]
995
0
    pub unsafe fn bucket(&self, index: usize) -> Bucket<T> {
996
0
        // If mem::size_of::<T>() != 0 then return a pointer to the `element` in the `data part` of the table
997
0
        // (we start counting from "0", so that in the expression T[n], the "n" index actually one less than
998
0
        // the "buckets" number of our `RawTable`, i.e. "n = RawTable::buckets() - 1"):
999
0
        //
1000
0
        //           `table.bucket(3).as_ptr()` returns a pointer that points here in the `data`
1001
0
        //           part of the `RawTable`, i.e. to the start of T3 (see `Bucket::as_ptr`)
1002
0
        //                  |
1003
0
        //                  |               `base = self.data_end()` points here
1004
0
        //                  |               (to the start of CT0 or to the end of T0)
1005
0
        //                  v                 v
1006
0
        // [Pad], T_n, ..., |T3|, T2, T1, T0, |CT0, CT1, CT2, CT3, ..., CT_n, CTa_0, CTa_1, ..., CTa_m
1007
0
        //                     ^                                              \__________  __________/
1008
0
        //        `table.bucket(3)` returns a pointer that points                        \/
1009
0
        //         here in the `data` part of the `RawTable` (to              additional control bytes
1010
0
        //         the end of T3)                                              `m = Group::WIDTH - 1`
1011
0
        //
1012
0
        // where: T0...T_n  - our stored data;
1013
0
        //        CT0...CT_n - control bytes or metadata for `data`;
1014
0
        //        CTa_0...CTa_m - additional control bytes (so that the search with loading `Group` bytes from
1015
0
        //                        the heap works properly, even if the result of `h1(hash) & self.table.bucket_mask`
1016
0
        //                        is equal to `self.table.bucket_mask`). See also `RawTableInner::set_ctrl` function.
1017
0
        //
1018
0
        // P.S. `h1(hash) & self.table.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
1019
0
        // of buckets is a power of two, and `self.table.bucket_mask = self.buckets() - 1`.
1020
0
        debug_assert_ne!(self.table.bucket_mask, 0);
1021
0
        debug_assert!(index < self.buckets());
1022
0
        Bucket::from_base_index(self.data_end(), index)
1023
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE6bucketB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE6bucketB7_
1024
1025
    /// Erases an element from the table without dropping it.
1026
    #[cfg_attr(feature = "inline-more", inline)]
1027
0
    unsafe fn erase_no_drop(&mut self, item: &Bucket<T>) {
1028
0
        let index = self.bucket_index(item);
1029
0
        self.table.erase(index);
1030
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE13erase_no_dropB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE13erase_no_dropB7_
1031
1032
    /// Erases an element from the table, dropping it in place.
1033
    #[cfg_attr(feature = "inline-more", inline)]
1034
    #[allow(clippy::needless_pass_by_value)]
1035
0
    pub unsafe fn erase(&mut self, item: Bucket<T>) {
1036
0
        // Erase the element from the table first since drop might panic.
1037
0
        self.erase_no_drop(&item);
1038
0
        item.drop();
1039
0
    }
1040
1041
    /// Finds and erases an element from the table, dropping it in place.
1042
    /// Returns true if an element was found.
1043
    #[cfg(feature = "raw")]
1044
    #[cfg_attr(feature = "inline-more", inline)]
1045
    pub fn erase_entry(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> bool {
1046
        // Avoid `Option::map` because it bloats LLVM IR.
1047
        if let Some(bucket) = self.find(hash, eq) {
1048
            unsafe {
1049
                self.erase(bucket);
1050
            }
1051
            true
1052
        } else {
1053
            false
1054
        }
1055
    }
1056
1057
    /// Removes an element from the table, returning it.
1058
    ///
1059
    /// This also returns an `InsertSlot` pointing to the newly free bucket.
1060
    #[cfg_attr(feature = "inline-more", inline)]
1061
    #[allow(clippy::needless_pass_by_value)]
1062
0
    pub unsafe fn remove(&mut self, item: Bucket<T>) -> (T, InsertSlot) {
1063
0
        self.erase_no_drop(&item);
1064
0
        (
1065
0
            item.read(),
1066
0
            InsertSlot {
1067
0
                index: self.bucket_index(&item),
1068
0
            },
1069
0
        )
1070
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE6removeB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE6removeB7_
1071
1072
    /// Finds and removes an element from the table, returning it.
1073
    #[cfg_attr(feature = "inline-more", inline)]
1074
0
    pub fn remove_entry(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<T> {
1075
0
        // Avoid `Option::map` because it bloats LLVM IR.
1076
0
        match self.find(hash, eq) {
1077
0
            Some(bucket) => Some(unsafe { self.remove(bucket).0 }),
1078
0
            None => None,
1079
        }
1080
0
    }
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBT_8LruEntryB1i_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE12remove_entryNCINvNtB8_3map14equivalent_keyBQ_BQ_B1p_E0EB2x_
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableppE12remove_entrypEB8_
1081
1082
    /// Marks all table buckets as empty without dropping their contents.
1083
    #[cfg_attr(feature = "inline-more", inline)]
1084
0
    pub fn clear_no_drop(&mut self) {
1085
0
        self.table.clear_no_drop();
1086
0
    }
1087
1088
    /// Removes all elements from the table without freeing the backing memory.
1089
    #[cfg_attr(feature = "inline-more", inline)]
1090
0
    pub fn clear(&mut self) {
1091
0
        if self.is_empty() {
1092
            // Special case empty table to avoid surprising O(capacity) time.
1093
0
            return;
1094
0
        }
1095
0
        // Ensure that the table is reset even if one of the drops panic
1096
0
        let mut self_ = guard(self, |self_| self_.clear_no_drop());
1097
0
        unsafe {
1098
0
            // SAFETY: ScopeGuard sets to zero the `items` field of the table
1099
0
            // even in case of panic during the dropping of the elements so
1100
0
            // that there will be no double drop of the elements.
1101
0
            self_.table.drop_elements::<T>();
1102
0
        }
1103
0
    }
1104
1105
    /// Shrinks the table to fit `max(self.len(), min_size)` elements.
1106
    #[cfg_attr(feature = "inline-more", inline)]
1107
0
    pub fn shrink_to(&mut self, min_size: usize, hasher: impl Fn(&T) -> u64) {
1108
0
        // Calculate the minimal number of elements that we need to reserve
1109
0
        // space for.
1110
0
        let min_size = usize::max(self.table.items, min_size);
1111
0
        if min_size == 0 {
1112
0
            let mut old_inner = mem::replace(&mut self.table, RawTableInner::NEW);
1113
0
            unsafe {
1114
0
                // SAFETY:
1115
0
                // 1. We call the function only once;
1116
0
                // 2. We know for sure that `alloc` and `table_layout` matches the [`Allocator`]
1117
0
                //    and [`TableLayout`] that were used to allocate this table.
1118
0
                // 3. If any elements' drop function panics, then there will only be a memory leak,
1119
0
                //    because we have replaced the inner table with a new one.
1120
0
                old_inner.drop_inner_table::<T, _>(&self.alloc, Self::TABLE_LAYOUT);
1121
0
            }
1122
0
            return;
1123
0
        }
1124
1125
        // Calculate the number of buckets that we need for this number of
1126
        // elements. If the calculation overflows then the requested bucket
1127
        // count must be larger than what we have right and nothing needs to be
1128
        // done.
1129
0
        let min_buckets = match capacity_to_buckets(min_size) {
1130
0
            Some(buckets) => buckets,
1131
0
            None => return,
1132
        };
1133
1134
        // If we have more buckets than we need, shrink the table.
1135
0
        if min_buckets < self.buckets() {
1136
            // Fast path if the table is empty
1137
0
            if self.table.items == 0 {
1138
0
                let new_inner =
1139
0
                    RawTableInner::with_capacity(&self.alloc, Self::TABLE_LAYOUT, min_size);
1140
0
                let mut old_inner = mem::replace(&mut self.table, new_inner);
1141
0
                unsafe {
1142
0
                    // SAFETY:
1143
0
                    // 1. We call the function only once;
1144
0
                    // 2. We know for sure that `alloc` and `table_layout` matches the [`Allocator`]
1145
0
                    //    and [`TableLayout`] that were used to allocate this table.
1146
0
                    // 3. If any elements' drop function panics, then there will only be a memory leak,
1147
0
                    //    because we have replaced the inner table with a new one.
1148
0
                    old_inner.drop_inner_table::<T, _>(&self.alloc, Self::TABLE_LAYOUT);
1149
0
                }
1150
            } else {
1151
                // Avoid `Result::unwrap_or_else` because it bloats LLVM IR.
1152
                unsafe {
1153
                    // SAFETY:
1154
                    // 1. We know for sure that `min_size >= self.table.items`.
1155
                    // 2. The [`RawTableInner`] must already have properly initialized control bytes since
1156
                    //    we will never expose RawTable::new_uninitialized in a public API.
1157
0
                    if self
1158
0
                        .resize(min_size, hasher, Fallibility::Infallible)
1159
0
                        .is_err()
1160
                    {
1161
                        // SAFETY: The result of calling the `resize` function cannot be an error
1162
                        // because `fallibility == Fallibility::Infallible.
1163
0
                        hint::unreachable_unchecked()
1164
0
                    }
1165
                }
1166
            }
1167
0
        }
1168
0
    }
1169
1170
    /// Ensures that at least `additional` items can be inserted into the table
1171
    /// without reallocation.
1172
    #[cfg_attr(feature = "inline-more", inline)]
1173
0
    pub fn reserve(&mut self, additional: usize, hasher: impl Fn(&T) -> u64) {
1174
0
        if unlikely(additional > self.table.growth_left) {
1175
            // Avoid `Result::unwrap_or_else` because it bloats LLVM IR.
1176
            unsafe {
1177
                // SAFETY: The [`RawTableInner`] must already have properly initialized control
1178
                // bytes since we will never expose RawTable::new_uninitialized in a public API.
1179
0
                if self
1180
0
                    .reserve_rehash(additional, hasher, Fallibility::Infallible)
1181
0
                    .is_err()
1182
                {
1183
                    // SAFETY: All allocation errors will be caught inside `RawTableInner::reserve_rehash`.
1184
0
                    hint::unreachable_unchecked()
1185
0
                }
1186
            }
1187
0
        }
1188
0
    }
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBT_8LruEntryB1i_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE7reserveNCINvNtB8_3map11make_hasherBQ_B1p_INtNtB1w_4hash18BuildHasherDefaultNtNtCseb6QmliwlWD_5ahash13fallback_hash7AHasherEE0EB2x_
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableppE7reservepEB8_
1189
1190
    /// Tries to ensure that at least `additional` items can be inserted into
1191
    /// the table without reallocation.
1192
    #[cfg_attr(feature = "inline-more", inline)]
1193
0
    pub fn try_reserve(
1194
0
        &mut self,
1195
0
        additional: usize,
1196
0
        hasher: impl Fn(&T) -> u64,
1197
0
    ) -> Result<(), TryReserveError> {
1198
0
        if additional > self.table.growth_left {
1199
            // SAFETY: The [`RawTableInner`] must already have properly initialized control
1200
            // bytes since we will never expose RawTable::new_uninitialized in a public API.
1201
0
            unsafe { self.reserve_rehash(additional, hasher, Fallibility::Fallible) }
1202
        } else {
1203
0
            Ok(())
1204
        }
1205
0
    }
1206
1207
    /// Out-of-line slow path for `reserve` and `try_reserve`.
1208
    ///
1209
    /// # Safety
1210
    ///
1211
    /// The [`RawTableInner`] must have properly initialized control bytes,
1212
    /// otherwise calling this function results in [`undefined behavior`]
1213
    ///
1214
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1215
    #[cold]
1216
    #[inline(never)]
1217
0
    unsafe fn reserve_rehash(
1218
0
        &mut self,
1219
0
        additional: usize,
1220
0
        hasher: impl Fn(&T) -> u64,
1221
0
        fallibility: Fallibility,
1222
0
    ) -> Result<(), TryReserveError> {
1223
0
        unsafe {
1224
0
            // SAFETY:
1225
0
            // 1. We know for sure that `alloc` and `layout` matches the [`Allocator`] and
1226
0
            //    [`TableLayout`] that were used to allocate this table.
1227
0
            // 2. The `drop` function is the actual drop function of the elements stored in
1228
0
            //    the table.
1229
0
            // 3. The caller ensures that the control bytes of the `RawTableInner`
1230
0
            //    are already initialized.
1231
0
            self.table.reserve_rehash_inner(
1232
0
                &self.alloc,
1233
0
                additional,
1234
0
                &|table, index| hasher(table.bucket::<T>(index).as_ref()),
Unexecuted instantiation: _RNCINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB8_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBV_8LruEntryB1k_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE14reserve_rehashNCINvNtBa_3map11make_hasherBS_B1r_INtNtB1y_4hash18BuildHasherDefaultNtNtCseb6QmliwlWD_5ahash13fallback_hash7AHasherEE0E0B2z_
Unexecuted instantiation: _RNCINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB8_8RawTableppE14reserve_rehashpE0Ba_
1235
0
                fallibility,
1236
0
                Self::TABLE_LAYOUT,
1237
0
                if T::NEEDS_DROP {
1238
0
                    Some(mem::transmute(ptr::drop_in_place::<T> as unsafe fn(*mut T)))
1239
                } else {
1240
0
                    None
1241
                },
1242
            )
1243
        }
1244
0
    }
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBT_8LruEntryB1i_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE14reserve_rehashNCINvNtB8_3map11make_hasherBQ_B1p_INtNtB1w_4hash18BuildHasherDefaultNtNtCseb6QmliwlWD_5ahash13fallback_hash7AHasherEE0EB2x_
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableppE14reserve_rehashpEB8_
1245
1246
    /// Allocates a new table of a different size and moves the contents of the
1247
    /// current table into it.
1248
    ///
1249
    /// # Safety
1250
    ///
1251
    /// The [`RawTableInner`] must have properly initialized control bytes,
1252
    /// otherwise calling this function results in [`undefined behavior`]
1253
    ///
1254
    /// The caller of this function must ensure that `capacity >= self.table.items`
1255
    /// otherwise:
1256
    ///
1257
    /// * If `self.table.items != 0`, calling of this function with `capacity`
1258
    ///   equal to 0 (`capacity == 0`) results in [`undefined behavior`].
1259
    ///
1260
    /// * If `capacity_to_buckets(capacity) < Group::WIDTH` and
1261
    ///   `self.table.items > capacity_to_buckets(capacity)`
1262
    ///   calling this function results in [`undefined behavior`].
1263
    ///
1264
    /// * If `capacity_to_buckets(capacity) >= Group::WIDTH` and
1265
    ///   `self.table.items > capacity_to_buckets(capacity)`
1266
    ///   calling this function are never return (will go into an
1267
    ///   infinite loop).
1268
    ///
1269
    /// See [`RawTableInner::find_insert_slot`] for more information.
1270
    ///
1271
    /// [`RawTableInner::find_insert_slot`]: RawTableInner::find_insert_slot
1272
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1273
0
    unsafe fn resize(
1274
0
        &mut self,
1275
0
        capacity: usize,
1276
0
        hasher: impl Fn(&T) -> u64,
1277
0
        fallibility: Fallibility,
1278
0
    ) -> Result<(), TryReserveError> {
1279
0
        // SAFETY:
1280
0
        // 1. The caller of this function guarantees that `capacity >= self.table.items`.
1281
0
        // 2. We know for sure that `alloc` and `layout` matches the [`Allocator`] and
1282
0
        //    [`TableLayout`] that were used to allocate this table.
1283
0
        // 3. The caller ensures that the control bytes of the `RawTableInner`
1284
0
        //    are already initialized.
1285
0
        self.table.resize_inner(
1286
0
            &self.alloc,
1287
0
            capacity,
1288
0
            &|table, index| hasher(table.bucket::<T>(index).as_ref()),
1289
0
            fallibility,
1290
0
            Self::TABLE_LAYOUT,
1291
0
        )
1292
0
    }
1293
1294
    /// Inserts a new element into the table, and returns its raw bucket.
1295
    ///
1296
    /// This does not check if the given element already exists in the table.
1297
    #[cfg_attr(feature = "inline-more", inline)]
1298
0
    pub fn insert(&mut self, hash: u64, value: T, hasher: impl Fn(&T) -> u64) -> Bucket<T> {
1299
0
        unsafe {
1300
0
            // SAFETY:
1301
0
            // 1. The [`RawTableInner`] must already have properly initialized control bytes since
1302
0
            //    we will never expose `RawTable::new_uninitialized` in a public API.
1303
0
            //
1304
0
            // 2. We reserve additional space (if necessary) right after calling this function.
1305
0
            let mut slot = self.table.find_insert_slot(hash);
1306
0
1307
0
            // We can avoid growing the table once we have reached our load factor if we are replacing
1308
0
            // a tombstone. This works since the number of EMPTY slots does not change in this case.
1309
0
            //
1310
0
            // SAFETY: The function is guaranteed to return [`InsertSlot`] that contains an index
1311
0
            // in the range `0..=self.buckets()`.
1312
0
            let old_ctrl = *self.table.ctrl(slot.index);
1313
0
            if unlikely(self.table.growth_left == 0 && special_is_empty(old_ctrl)) {
1314
0
                self.reserve(1, hasher);
1315
0
                // SAFETY: We know for sure that `RawTableInner` has control bytes
1316
0
                // initialized and that there is extra space in the table.
1317
0
                slot = self.table.find_insert_slot(hash);
1318
0
            }
1319
1320
0
            self.insert_in_slot(hash, slot, value)
1321
0
        }
1322
0
    }
1323
1324
    /// Attempts to insert a new element without growing the table and return its raw bucket.
1325
    ///
1326
    /// Returns an `Err` containing the given element if inserting it would require growing the
1327
    /// table.
1328
    ///
1329
    /// This does not check if the given element already exists in the table.
1330
    #[cfg(feature = "raw")]
1331
    #[cfg_attr(feature = "inline-more", inline)]
1332
    pub fn try_insert_no_grow(&mut self, hash: u64, value: T) -> Result<Bucket<T>, T> {
1333
        unsafe {
1334
            match self.table.prepare_insert_no_grow(hash) {
1335
                Ok(index) => {
1336
                    let bucket = self.bucket(index);
1337
                    bucket.write(value);
1338
                    Ok(bucket)
1339
                }
1340
                Err(()) => Err(value),
1341
            }
1342
        }
1343
    }
1344
1345
    /// Inserts a new element into the table, and returns a mutable reference to it.
1346
    ///
1347
    /// This does not check if the given element already exists in the table.
1348
    #[cfg_attr(feature = "inline-more", inline)]
1349
0
    pub fn insert_entry(&mut self, hash: u64, value: T, hasher: impl Fn(&T) -> u64) -> &mut T {
1350
0
        unsafe { self.insert(hash, value, hasher).as_mut() }
1351
0
    }
1352
1353
    /// Inserts a new element into the table, without growing the table.
1354
    ///
1355
    /// There must be enough space in the table to insert the new element.
1356
    ///
1357
    /// This does not check if the given element already exists in the table.
1358
    #[cfg_attr(feature = "inline-more", inline)]
1359
    #[cfg(any(feature = "raw", feature = "rustc-internal-api"))]
1360
    pub unsafe fn insert_no_grow(&mut self, hash: u64, value: T) -> Bucket<T> {
1361
        let (index, old_ctrl) = self.table.prepare_insert_slot(hash);
1362
        let bucket = self.table.bucket(index);
1363
1364
        // If we are replacing a DELETED entry then we don't need to update
1365
        // the load counter.
1366
        self.table.growth_left -= special_is_empty(old_ctrl) as usize;
1367
1368
        bucket.write(value);
1369
        self.table.items += 1;
1370
        bucket
1371
    }
1372
1373
    /// Temporary removes a bucket, applying the given function to the removed
1374
    /// element and optionally put back the returned value in the same bucket.
1375
    ///
1376
    /// Returns `true` if the bucket still contains an element
1377
    ///
1378
    /// This does not check if the given bucket is actually occupied.
1379
    #[cfg_attr(feature = "inline-more", inline)]
1380
0
    pub unsafe fn replace_bucket_with<F>(&mut self, bucket: Bucket<T>, f: F) -> bool
1381
0
    where
1382
0
        F: FnOnce(T) -> Option<T>,
1383
0
    {
1384
0
        let index = self.bucket_index(&bucket);
1385
0
        let old_ctrl = *self.table.ctrl(index);
1386
0
        debug_assert!(self.is_bucket_full(index));
1387
0
        let old_growth_left = self.table.growth_left;
1388
0
        let item = self.remove(bucket).0;
1389
0
        if let Some(new_item) = f(item) {
1390
0
            self.table.growth_left = old_growth_left;
1391
0
            self.table.set_ctrl(index, old_ctrl);
1392
0
            self.table.items += 1;
1393
0
            self.bucket(index).write(new_item);
1394
0
            true
1395
        } else {
1396
0
            false
1397
        }
1398
0
    }
1399
1400
    /// Searches for an element in the table. If the element is not found,
1401
    /// returns `Err` with the position of a slot where an element with the
1402
    /// same hash could be inserted.
1403
    ///
1404
    /// This function may resize the table if additional space is required for
1405
    /// inserting an element.
1406
    #[inline]
1407
0
    pub fn find_or_find_insert_slot(
1408
0
        &mut self,
1409
0
        hash: u64,
1410
0
        mut eq: impl FnMut(&T) -> bool,
1411
0
        hasher: impl Fn(&T) -> u64,
1412
0
    ) -> Result<Bucket<T>, InsertSlot> {
1413
0
        self.reserve(1, hasher);
1414
0
1415
0
        unsafe {
1416
0
            // SAFETY:
1417
0
            // 1. We know for sure that there is at least one empty `bucket` in the table.
1418
0
            // 2. The [`RawTableInner`] must already have properly initialized control bytes since we will
1419
0
            //    never expose `RawTable::new_uninitialized` in a public API.
1420
0
            // 3. The `find_or_find_insert_slot_inner` function returns the `index` of only the full bucket,
1421
0
            //    which is in the range `0..self.buckets()` (since there is at least one empty `bucket` in
1422
0
            //    the table), so calling `self.bucket(index)` and `Bucket::as_ref` is safe.
1423
0
            match self
1424
0
                .table
1425
0
                .find_or_find_insert_slot_inner(hash, &mut |index| eq(self.bucket(index).as_ref()))
Unexecuted instantiation: _RNCINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB8_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBV_8LruEntryB1k_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE24find_or_find_insert_slotNCINvNtBa_3map14equivalent_keyBS_BS_B1r_E0NCINvB3P_11make_hasherBS_B1r_INtNtB1y_4hash18BuildHasherDefaultNtNtCseb6QmliwlWD_5ahash13fallback_hash7AHasherEE0E0B2z_
Unexecuted instantiation: _RNCINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB8_8RawTableppE24find_or_find_insert_slotppE0Ba_
1426
            {
1427
                // SAFETY: See explanation above.
1428
0
                Ok(index) => Ok(self.bucket(index)),
1429
0
                Err(slot) => Err(slot),
1430
            }
1431
        }
1432
0
    }
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBT_8LruEntryB1i_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE24find_or_find_insert_slotNCINvNtB8_3map14equivalent_keyBQ_BQ_B1p_E0NCINvB3N_11make_hasherBQ_B1p_INtNtB1w_4hash18BuildHasherDefaultNtNtCseb6QmliwlWD_5ahash13fallback_hash7AHasherEE0EB2x_
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableppE24find_or_find_insert_slotppEB8_
1433
1434
    /// Inserts a new element into the table in the given slot, and returns its
1435
    /// raw bucket.
1436
    ///
1437
    /// # Safety
1438
    ///
1439
    /// `slot` must point to a slot previously returned by
1440
    /// `find_or_find_insert_slot`, and no mutation of the table must have
1441
    /// occurred since that call.
1442
    #[inline]
1443
0
    pub unsafe fn insert_in_slot(&mut self, hash: u64, slot: InsertSlot, value: T) -> Bucket<T> {
1444
0
        let old_ctrl = *self.table.ctrl(slot.index);
1445
0
        self.table.record_item_insert_at(slot.index, old_ctrl, hash);
1446
0
1447
0
        let bucket = self.bucket(slot.index);
1448
0
        bucket.write(value);
1449
0
        bucket
1450
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE14insert_in_slotB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE14insert_in_slotB7_
1451
1452
    /// Searches for an element in the table.
1453
    #[inline]
1454
0
    pub fn find(&self, hash: u64, mut eq: impl FnMut(&T) -> bool) -> Option<Bucket<T>> {
1455
0
        unsafe {
1456
0
            // SAFETY:
1457
0
            // 1. The [`RawTableInner`] must already have properly initialized control bytes since we
1458
0
            //    will never expose `RawTable::new_uninitialized` in a public API.
1459
0
            // 1. The `find_inner` function returns the `index` of only the full bucket, which is in
1460
0
            //    the range `0..self.buckets()`, so calling `self.bucket(index)` and `Bucket::as_ref`
1461
0
            //    is safe.
1462
0
            let result = self
1463
0
                .table
1464
0
                .find_inner(hash, &mut |index| eq(self.bucket(index).as_ref()));
Unexecuted instantiation: _RNCINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB8_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBV_8LruEntryB1k_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE4findNCINvNtBa_3map14equivalent_keyBS_BS_B1r_E0E0B2z_
Unexecuted instantiation: _RNCINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB8_8RawTableppE4findpE0Ba_
1465
0
1466
0
            // Avoid `Option::map` because it bloats LLVM IR.
1467
0
            match result {
1468
                // SAFETY: See explanation above.
1469
0
                Some(index) => Some(self.bucket(index)),
1470
0
                None => None,
1471
            }
1472
        }
1473
0
    }
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBT_8LruEntryB1i_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE4findNCINvNtB8_3map14equivalent_keyBQ_BQ_B1p_E0EB2x_
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableppE4findpEB8_
1474
1475
    /// Gets a reference to an element in the table.
1476
    #[inline]
1477
0
    pub fn get(&self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&T> {
1478
0
        // Avoid `Option::map` because it bloats LLVM IR.
1479
0
        match self.find(hash, eq) {
1480
0
            Some(bucket) => Some(unsafe { bucket.as_ref() }),
1481
0
            None => None,
1482
        }
1483
0
    }
1484
1485
    /// Gets a mutable reference to an element in the table.
1486
    #[inline]
1487
0
    pub fn get_mut(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&mut T> {
1488
0
        // Avoid `Option::map` because it bloats LLVM IR.
1489
0
        match self.find(hash, eq) {
1490
0
            Some(bucket) => Some(unsafe { bucket.as_mut() }),
1491
0
            None => None,
1492
        }
1493
0
    }
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBT_8LruEntryB1i_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE7get_mutNCINvNtB8_3map14equivalent_keyBQ_BQ_B1p_E0EB2x_
Unexecuted instantiation: _RINvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_8RawTableppE7get_mutpEB8_
1494
1495
    /// Attempts to get mutable references to `N` entries in the table at once.
1496
    ///
1497
    /// Returns an array of length `N` with the results of each query.
1498
    ///
1499
    /// At most one mutable reference will be returned to any entry. `None` will be returned if any
1500
    /// of the hashes are duplicates. `None` will be returned if the hash is not found.
1501
    ///
1502
    /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
1503
    /// the `i`th key to be looked up.
1504
0
    pub fn get_many_mut<const N: usize>(
1505
0
        &mut self,
1506
0
        hashes: [u64; N],
1507
0
        eq: impl FnMut(usize, &T) -> bool,
1508
0
    ) -> Option<[&'_ mut T; N]> {
1509
        unsafe {
1510
0
            let ptrs = self.get_many_mut_pointers(hashes, eq)?;
1511
1512
0
            for (i, &cur) in ptrs.iter().enumerate() {
1513
0
                if ptrs[..i].iter().any(|&prev| ptr::eq::<T>(prev, cur)) {
1514
0
                    return None;
1515
0
                }
1516
            }
1517
            // All bucket are distinct from all previous buckets so we're clear to return the result
1518
            // of the lookup.
1519
1520
            // TODO use `MaybeUninit::array_assume_init` here instead once that's stable.
1521
0
            Some(mem::transmute_copy(&ptrs))
1522
        }
1523
0
    }
1524
1525
0
    pub unsafe fn get_many_unchecked_mut<const N: usize>(
1526
0
        &mut self,
1527
0
        hashes: [u64; N],
1528
0
        eq: impl FnMut(usize, &T) -> bool,
1529
0
    ) -> Option<[&'_ mut T; N]> {
1530
0
        let ptrs = self.get_many_mut_pointers(hashes, eq)?;
1531
0
        Some(mem::transmute_copy(&ptrs))
1532
0
    }
1533
1534
0
    unsafe fn get_many_mut_pointers<const N: usize>(
1535
0
        &mut self,
1536
0
        hashes: [u64; N],
1537
0
        mut eq: impl FnMut(usize, &T) -> bool,
1538
0
    ) -> Option<[*mut T; N]> {
1539
0
        // TODO use `MaybeUninit::uninit_array` here instead once that's stable.
1540
0
        let mut outs: MaybeUninit<[*mut T; N]> = MaybeUninit::uninit();
1541
0
        let outs_ptr = outs.as_mut_ptr();
1542
1543
0
        for (i, &hash) in hashes.iter().enumerate() {
1544
0
            let cur = self.find(hash, |k| eq(i, k))?;
1545
0
            *(*outs_ptr).get_unchecked_mut(i) = cur.as_mut();
1546
        }
1547
1548
        // TODO use `MaybeUninit::array_assume_init` here instead once that's stable.
1549
0
        Some(outs.assume_init())
1550
0
    }
1551
1552
    /// Returns the number of elements the map can hold without reallocating.
1553
    ///
1554
    /// This number is a lower bound; the table might be able to hold
1555
    /// more, but is guaranteed to be able to hold at least this many.
1556
    #[inline]
1557
0
    pub fn capacity(&self) -> usize {
1558
0
        self.table.items + self.table.growth_left
1559
0
    }
1560
1561
    /// Returns the number of elements in the table.
1562
    #[inline]
1563
0
    pub fn len(&self) -> usize {
1564
0
        self.table.items
1565
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE3lenB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE3lenB7_
1566
1567
    /// Returns `true` if the table contains no elements.
1568
    #[inline]
1569
0
    pub fn is_empty(&self) -> bool {
1570
0
        self.len() == 0
1571
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE8is_emptyB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE8is_emptyB7_
1572
1573
    /// Returns the number of buckets in the table.
1574
    #[inline]
1575
0
    pub fn buckets(&self) -> usize {
1576
0
        self.table.bucket_mask + 1
1577
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE7bucketsB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE7bucketsB7_
1578
1579
    /// Checks whether the bucket at `index` is full.
1580
    ///
1581
    /// # Safety
1582
    ///
1583
    /// The caller must ensure `index` is less than the number of buckets.
1584
    #[inline]
1585
0
    pub unsafe fn is_bucket_full(&self, index: usize) -> bool {
1586
0
        self.table.is_bucket_full(index)
1587
0
    }
1588
1589
    /// Returns an iterator over every element in the table. It is up to
1590
    /// the caller to ensure that the `RawTable` outlives the `RawIter`.
1591
    /// Because we cannot make the `next` method unsafe on the `RawIter`
1592
    /// struct, we have to make the `iter` method unsafe.
1593
    #[inline]
1594
0
    pub unsafe fn iter(&self) -> RawIter<T> {
1595
0
        // SAFETY:
1596
0
        // 1. The caller must uphold the safety contract for `iter` method.
1597
0
        // 2. The [`RawTableInner`] must already have properly initialized control bytes since
1598
0
        //    we will never expose RawTable::new_uninitialized in a public API.
1599
0
        self.table.iter()
1600
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE4iterB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE4iterB7_
1601
1602
    /// Returns an iterator over occupied buckets that could match a given hash.
1603
    ///
1604
    /// `RawTable` only stores 7 bits of the hash value, so this iterator may
1605
    /// return items that have a hash value different than the one provided. You
1606
    /// should always validate the returned values before using them.
1607
    ///
1608
    /// It is up to the caller to ensure that the `RawTable` outlives the
1609
    /// `RawIterHash`. Because we cannot make the `next` method unsafe on the
1610
    /// `RawIterHash` struct, we have to make the `iter_hash` method unsafe.
1611
    #[cfg_attr(feature = "inline-more", inline)]
1612
    #[cfg(feature = "raw")]
1613
    pub unsafe fn iter_hash(&self, hash: u64) -> RawIterHash<T> {
1614
        RawIterHash::new(self, hash)
1615
    }
1616
1617
    /// Returns an iterator which removes all elements from the table without
1618
    /// freeing the memory.
1619
    #[cfg_attr(feature = "inline-more", inline)]
1620
0
    pub fn drain(&mut self) -> RawDrain<'_, T, A> {
1621
0
        unsafe {
1622
0
            let iter = self.iter();
1623
0
            self.drain_iter_from(iter)
1624
0
        }
1625
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE5drainB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE5drainB7_
1626
1627
    /// Returns an iterator which removes all elements from the table without
1628
    /// freeing the memory.
1629
    ///
1630
    /// Iteration starts at the provided iterator's current location.
1631
    ///
1632
    /// It is up to the caller to ensure that the iterator is valid for this
1633
    /// `RawTable` and covers all items that remain in the table.
1634
    #[cfg_attr(feature = "inline-more", inline)]
1635
0
    pub unsafe fn drain_iter_from(&mut self, iter: RawIter<T>) -> RawDrain<'_, T, A> {
1636
0
        debug_assert_eq!(iter.len(), self.len());
1637
0
        RawDrain {
1638
0
            iter,
1639
0
            table: mem::replace(&mut self.table, RawTableInner::NEW),
1640
0
            orig_table: NonNull::from(&mut self.table),
1641
0
            marker: PhantomData,
1642
0
        }
1643
0
    }
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE15drain_iter_fromB2w_
Unexecuted instantiation: _RNvMs6_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableppE15drain_iter_fromB7_
1644
1645
    /// Returns an iterator which consumes all elements from the table.
1646
    ///
1647
    /// Iteration starts at the provided iterator's current location.
1648
    ///
1649
    /// It is up to the caller to ensure that the iterator is valid for this
1650
    /// `RawTable` and covers all items that remain in the table.
1651
0
    pub unsafe fn into_iter_from(self, iter: RawIter<T>) -> RawIntoIter<T, A> {
1652
0
        debug_assert_eq!(iter.len(), self.len());
1653
1654
0
        let allocation = self.into_allocation();
1655
0
        RawIntoIter {
1656
0
            iter,
1657
0
            allocation,
1658
0
            marker: PhantomData,
1659
0
        }
1660
0
    }
1661
1662
    /// Converts the table into a raw allocation. The contents of the table
1663
    /// should be dropped using a `RawIter` before freeing the allocation.
1664
    #[cfg_attr(feature = "inline-more", inline)]
1665
0
    pub(crate) fn into_allocation(self) -> Option<(NonNull<u8>, Layout, A)> {
1666
0
        let alloc = if self.table.is_empty_singleton() {
1667
0
            None
1668
        } else {
1669
            // Avoid `Option::unwrap_or_else` because it bloats LLVM IR.
1670
0
            let (layout, ctrl_offset) =
1671
0
                match Self::TABLE_LAYOUT.calculate_layout_for(self.table.buckets()) {
1672
0
                    Some(lco) => lco,
1673
0
                    None => unsafe { hint::unreachable_unchecked() },
1674
                };
1675
0
            Some((
1676
0
                unsafe { NonNull::new_unchecked(self.table.ctrl.as_ptr().sub(ctrl_offset)) },
1677
0
                layout,
1678
0
                unsafe { ptr::read(&self.alloc) },
1679
0
            ))
1680
        };
1681
0
        mem::forget(self);
1682
0
        alloc
1683
0
    }
1684
}
1685
1686
unsafe impl<T, A: Allocator> Send for RawTable<T, A>
1687
where
1688
    T: Send,
1689
    A: Send,
1690
{
1691
}
1692
unsafe impl<T, A: Allocator> Sync for RawTable<T, A>
1693
where
1694
    T: Sync,
1695
    A: Sync,
1696
{
1697
}
1698
1699
impl RawTableInner {
1700
    const NEW: Self = RawTableInner::new();
1701
1702
    /// Creates a new empty hash table without allocating any memory.
1703
    ///
1704
    /// In effect this returns a table with exactly 1 bucket. However we can
1705
    /// leave the data pointer dangling since that bucket is never accessed
1706
    /// due to our load factor forcing us to always have at least 1 free bucket.
1707
    #[inline]
1708
0
    const fn new() -> Self {
1709
0
        Self {
1710
0
            // Be careful to cast the entire slice to a raw pointer.
1711
0
            ctrl: unsafe { NonNull::new_unchecked(Group::static_empty() as *const _ as *mut u8) },
1712
0
            bucket_mask: 0,
1713
0
            items: 0,
1714
0
            growth_left: 0,
1715
0
        }
1716
0
    }
1717
}
1718
1719
impl RawTableInner {
1720
    /// Allocates a new [`RawTableInner`] with the given number of buckets.
1721
    /// The control bytes and buckets are left uninitialized.
1722
    ///
1723
    /// # Safety
1724
    ///
1725
    /// The caller of this function must ensure that the `buckets` is power of two
1726
    /// and also initialize all control bytes of the length `self.bucket_mask + 1 +
1727
    /// Group::WIDTH` with the [`EMPTY`] bytes.
1728
    ///
1729
    /// See also [`Allocator`] API for other safety concerns.
1730
    ///
1731
    /// [`Allocator`]: https://doc.rust-lang.org/alloc/alloc/trait.Allocator.html
1732
    #[cfg_attr(feature = "inline-more", inline)]
1733
0
    unsafe fn new_uninitialized<A>(
1734
0
        alloc: &A,
1735
0
        table_layout: TableLayout,
1736
0
        buckets: usize,
1737
0
        fallibility: Fallibility,
1738
0
    ) -> Result<Self, TryReserveError>
1739
0
    where
1740
0
        A: Allocator,
1741
0
    {
1742
0
        debug_assert!(buckets.is_power_of_two());
1743
1744
        // Avoid `Option::ok_or_else` because it bloats LLVM IR.
1745
0
        let (layout, ctrl_offset) = match table_layout.calculate_layout_for(buckets) {
1746
0
            Some(lco) => lco,
1747
0
            None => return Err(fallibility.capacity_overflow()),
1748
        };
1749
1750
0
        let ptr: NonNull<u8> = match do_alloc(alloc, layout) {
1751
0
            Ok(block) => block.cast(),
1752
0
            Err(_) => return Err(fallibility.alloc_err(layout)),
1753
        };
1754
1755
        // SAFETY: null pointer will be caught in above check
1756
0
        let ctrl = NonNull::new_unchecked(ptr.as_ptr().add(ctrl_offset));
1757
0
        Ok(Self {
1758
0
            ctrl,
1759
0
            bucket_mask: buckets - 1,
1760
0
            items: 0,
1761
0
            growth_left: bucket_mask_to_capacity(buckets - 1),
1762
0
        })
1763
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner17new_uninitializedNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner17new_uninitializedpEB8_
1764
1765
    /// Attempts to allocate a new [`RawTableInner`] with at least enough
1766
    /// capacity for inserting the given number of elements without reallocating.
1767
    ///
1768
    /// All the control bytes are initialized with the [`EMPTY`] bytes.
1769
    #[inline]
1770
0
    fn fallible_with_capacity<A>(
1771
0
        alloc: &A,
1772
0
        table_layout: TableLayout,
1773
0
        capacity: usize,
1774
0
        fallibility: Fallibility,
1775
0
    ) -> Result<Self, TryReserveError>
1776
0
    where
1777
0
        A: Allocator,
1778
0
    {
1779
0
        if capacity == 0 {
1780
0
            Ok(Self::NEW)
1781
        } else {
1782
            // SAFETY: We checked that we could successfully allocate the new table, and then
1783
            // initialized all control bytes with the constant `EMPTY` byte.
1784
            unsafe {
1785
0
                let buckets =
1786
0
                    capacity_to_buckets(capacity).ok_or_else(|| fallibility.capacity_overflow())?;
Unexecuted instantiation: _RNCINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB8_13RawTableInner22fallible_with_capacityNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalE0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB8_13RawTableInner22fallible_with_capacitypE0Ba_
1787
1788
0
                let result = Self::new_uninitialized(alloc, table_layout, buckets, fallibility)?;
1789
                // SAFETY: We checked that the table is allocated and therefore the table already has
1790
                // `self.bucket_mask + 1 + Group::WIDTH` number of control bytes (see TableLayout::calculate_layout_for)
1791
                // so writing `self.num_ctrl_bytes() == bucket_mask + 1 + Group::WIDTH` bytes is safe.
1792
0
                result.ctrl(0).write_bytes(EMPTY, result.num_ctrl_bytes());
1793
0
1794
0
                Ok(result)
1795
            }
1796
        }
1797
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner22fallible_with_capacityNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner22fallible_with_capacitypEB8_
1798
1799
    /// Allocates a new [`RawTableInner`] with at least enough capacity for inserting
1800
    /// the given number of elements without reallocating.
1801
    ///
1802
    /// Panics if the new capacity exceeds [`isize::MAX`] bytes and [`abort`] the program
1803
    /// in case of allocation error. Use [`fallible_with_capacity`] instead if you want to
1804
    /// handle memory allocation failure.
1805
    ///
1806
    /// All the control bytes are initialized with the [`EMPTY`] bytes.
1807
    ///
1808
    /// [`fallible_with_capacity`]: RawTableInner::fallible_with_capacity
1809
    /// [`abort`]: https://doc.rust-lang.org/alloc/alloc/fn.handle_alloc_error.html
1810
0
    fn with_capacity<A>(alloc: &A, table_layout: TableLayout, capacity: usize) -> Self
1811
0
    where
1812
0
        A: Allocator,
1813
0
    {
1814
0
        // Avoid `Result::unwrap_or_else` because it bloats LLVM IR.
1815
0
        match Self::fallible_with_capacity(alloc, table_layout, capacity, Fallibility::Infallible) {
1816
0
            Ok(table_inner) => table_inner,
1817
            // SAFETY: All allocation errors will be caught inside `RawTableInner::new_uninitialized`.
1818
0
            Err(_) => unsafe { hint::unreachable_unchecked() },
1819
        }
1820
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner13with_capacityNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner13with_capacitypEB8_
1821
1822
    /// Fixes up an insertion slot returned by the [`RawTableInner::find_insert_slot_in_group`] method.
1823
    ///
1824
    /// In tables smaller than the group width (`self.buckets() < Group::WIDTH`), trailing control
1825
    /// bytes outside the range of the table are filled with [`EMPTY`] entries. These will unfortunately
1826
    /// trigger a match of [`RawTableInner::find_insert_slot_in_group`] function. This is because
1827
    /// the `Some(bit)` returned by `group.match_empty_or_deleted().lowest_set_bit()` after masking
1828
    /// (`(probe_seq.pos + bit) & self.bucket_mask`) may point to a full bucket that is already occupied.
1829
    /// We detect this situation here and perform a second scan starting at the beginning of the table.
1830
    /// This second scan is guaranteed to find an empty slot (due to the load factor) before hitting the
1831
    /// trailing control bytes (containing [`EMPTY`] bytes).
1832
    ///
1833
    /// If this function is called correctly, it is guaranteed to return [`InsertSlot`] with an
1834
    /// index of an empty or deleted bucket in the range `0..self.buckets()` (see `Warning` and
1835
    /// `Safety`).
1836
    ///
1837
    /// # Warning
1838
    ///
1839
    /// The table must have at least 1 empty or deleted `bucket`, otherwise if the table is less than
1840
    /// the group width (`self.buckets() < Group::WIDTH`) this function returns an index outside of the
1841
    /// table indices range `0..self.buckets()` (`0..=self.bucket_mask`). Attempt to write data at that
1842
    /// index will cause immediate [`undefined behavior`].
1843
    ///
1844
    /// # Safety
1845
    ///
1846
    /// The safety rules are directly derived from the safety rules for [`RawTableInner::ctrl`] method.
1847
    /// Thus, in order to uphold those safety contracts, as well as for the correct logic of the work
1848
    /// of this crate, the following rules are necessary and sufficient:
1849
    ///
1850
    /// * The [`RawTableInner`] must have properly initialized control bytes otherwise calling this
1851
    ///   function results in [`undefined behavior`].
1852
    ///
1853
    /// * This function must only be used on insertion slots found by [`RawTableInner::find_insert_slot_in_group`]
1854
    ///   (after the `find_insert_slot_in_group` function, but before insertion into the table).
1855
    ///
1856
    /// * The `index` must not be greater than the `self.bucket_mask`, i.e. `(index + 1) <= self.buckets()`
1857
    ///   (this one is provided by the [`RawTableInner::find_insert_slot_in_group`] function).
1858
    ///
1859
    /// Calling this function with an index not provided by [`RawTableInner::find_insert_slot_in_group`]
1860
    /// may result in [`undefined behavior`] even if the index satisfies the safety rules of the
1861
    /// [`RawTableInner::ctrl`] function (`index < self.bucket_mask + 1 + Group::WIDTH`).
1862
    ///
1863
    /// [`RawTableInner::ctrl`]: RawTableInner::ctrl
1864
    /// [`RawTableInner::find_insert_slot_in_group`]: RawTableInner::find_insert_slot_in_group
1865
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1866
    #[inline]
1867
0
    unsafe fn fix_insert_slot(&self, mut index: usize) -> InsertSlot {
1868
0
        // SAFETY: The caller of this function ensures that `index` is in the range `0..=self.bucket_mask`.
1869
0
        if unlikely(self.is_bucket_full(index)) {
1870
0
            debug_assert!(self.bucket_mask < Group::WIDTH);
1871
            // SAFETY:
1872
            //
1873
            // * Since the caller of this function ensures that the control bytes are properly
1874
            //   initialized and `ptr = self.ctrl(0)` points to the start of the array of control
1875
            //   bytes, therefore: `ctrl` is valid for reads, properly aligned to `Group::WIDTH`
1876
            //   and points to the properly initialized control bytes (see also
1877
            //   `TableLayout::calculate_layout_for` and `ptr::read`);
1878
            //
1879
            // * Because the caller of this function ensures that the index was provided by the
1880
            //   `self.find_insert_slot_in_group()` function, so for for tables larger than the
1881
            //   group width (self.buckets() >= Group::WIDTH), we will never end up in the given
1882
            //   branch, since `(probe_seq.pos + bit) & self.bucket_mask` in `find_insert_slot_in_group`
1883
            //   cannot return a full bucket index. For tables smaller than the group width, calling
1884
            //   the `unwrap_unchecked` function is also safe, as the trailing control bytes outside
1885
            //   the range of the table are filled with EMPTY bytes (and we know for sure that there
1886
            //   is at least one FULL bucket), so this second scan either finds an empty slot (due to
1887
            //   the load factor) or hits the trailing control bytes (containing EMPTY).
1888
0
            index = Group::load_aligned(self.ctrl(0))
1889
0
                .match_empty_or_deleted()
1890
0
                .lowest_set_bit()
1891
0
                .unwrap_unchecked();
1892
0
        }
1893
0
        InsertSlot { index }
1894
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner15fix_insert_slotCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner15fix_insert_slotB7_
1895
1896
    /// Finds the position to insert something in a group.
1897
    ///
1898
    /// **This may have false positives and must be fixed up with `fix_insert_slot`
1899
    /// before it's used.**
1900
    ///
1901
    /// The function is guaranteed to return the index of an empty or deleted [`Bucket`]
1902
    /// in the range `0..self.buckets()` (`0..=self.bucket_mask`).
1903
    #[inline]
1904
0
    fn find_insert_slot_in_group(&self, group: &Group, probe_seq: &ProbeSeq) -> Option<usize> {
1905
0
        let bit = group.match_empty_or_deleted().lowest_set_bit();
1906
0
1907
0
        if likely(bit.is_some()) {
1908
            // This is the same as `(probe_seq.pos + bit) % self.buckets()` because the number
1909
            // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
1910
0
            Some((probe_seq.pos + bit.unwrap()) & self.bucket_mask)
1911
        } else {
1912
0
            None
1913
        }
1914
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner25find_insert_slot_in_groupCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner25find_insert_slot_in_groupB7_
1915
1916
    /// Searches for an element in the table, or a potential slot where that element could
1917
    /// be inserted (an empty or deleted [`Bucket`] index).
1918
    ///
1919
    /// This uses dynamic dispatch to reduce the amount of code generated, but that is
1920
    /// eliminated by LLVM optimizations.
1921
    ///
1922
    /// This function does not make any changes to the `data` part of the table, or any
1923
    /// changes to the `items` or `growth_left` field of the table.
1924
    ///
1925
    /// The table must have at least 1 empty or deleted `bucket`, otherwise, if the
1926
    /// `eq: &mut dyn FnMut(usize) -> bool` function does not return `true`, this function
1927
    /// will never return (will go into an infinite loop) for tables larger than the group
1928
    /// width, or return an index outside of the table indices range if the table is less
1929
    /// than the group width.
1930
    ///
1931
    /// This function is guaranteed to provide the `eq: &mut dyn FnMut(usize) -> bool`
1932
    /// function with only `FULL` buckets' indices and return the `index` of the found
1933
    /// element (as `Ok(index)`). If the element is not found and there is at least 1
1934
    /// empty or deleted [`Bucket`] in the table, the function is guaranteed to return
1935
    /// [InsertSlot] with an index in the range `0..self.buckets()`, but in any case,
1936
    /// if this function returns [`InsertSlot`], it will contain an index in the range
1937
    /// `0..=self.buckets()`.
1938
    ///
1939
    /// # Safety
1940
    ///
1941
    /// The [`RawTableInner`] must have properly initialized control bytes otherwise calling
1942
    /// this function results in [`undefined behavior`].
1943
    ///
1944
    /// Attempt to write data at the [`InsertSlot`] returned by this function when the table is
1945
    /// less than the group width and if there was not at least one empty or deleted bucket in
1946
    /// the table will cause immediate [`undefined behavior`]. This is because in this case the
1947
    /// function will return `self.bucket_mask + 1` as an index due to the trailing [`EMPTY]
1948
    /// control bytes outside the table range.
1949
    ///
1950
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1951
    #[inline]
1952
0
    unsafe fn find_or_find_insert_slot_inner(
1953
0
        &self,
1954
0
        hash: u64,
1955
0
        eq: &mut dyn FnMut(usize) -> bool,
1956
0
    ) -> Result<usize, InsertSlot> {
1957
0
        let mut insert_slot = None;
1958
0
1959
0
        let h2_hash = h2(hash);
1960
0
        let mut probe_seq = self.probe_seq(hash);
1961
1962
        loop {
1963
            // SAFETY:
1964
            // * Caller of this function ensures that the control bytes are properly initialized.
1965
            //
1966
            // * `ProbeSeq.pos` cannot be greater than `self.bucket_mask = self.buckets() - 1`
1967
            //   of the table due to masking with `self.bucket_mask` and also because mumber of
1968
            //   buckets is a power of two (see `self.probe_seq` function).
1969
            //
1970
            // * Even if `ProbeSeq.pos` returns `position == self.bucket_mask`, it is safe to
1971
            //   call `Group::load` due to the extended control bytes range, which is
1972
            //  `self.bucket_mask + 1 + Group::WIDTH` (in fact, this means that the last control
1973
            //   byte will never be read for the allocated table);
1974
            //
1975
            // * Also, even if `RawTableInner` is not already allocated, `ProbeSeq.pos` will
1976
            //   always return "0" (zero), so Group::load will read unaligned `Group::static_empty()`
1977
            //   bytes, which is safe (see RawTableInner::new).
1978
0
            let group = unsafe { Group::load(self.ctrl(probe_seq.pos)) };
1979
1980
0
            for bit in group.match_byte(h2_hash) {
1981
0
                let index = (probe_seq.pos + bit) & self.bucket_mask;
1982
0
1983
0
                if likely(eq(index)) {
1984
0
                    return Ok(index);
1985
0
                }
1986
            }
1987
1988
            // We didn't find the element we were looking for in the group, try to get an
1989
            // insertion slot from the group if we don't have one yet.
1990
0
            if likely(insert_slot.is_none()) {
1991
0
                insert_slot = self.find_insert_slot_in_group(&group, &probe_seq);
1992
0
            }
1993
1994
            // Only stop the search if the group contains at least one empty element.
1995
            // Otherwise, the element that we are looking for might be in a following group.
1996
0
            if likely(group.match_empty().any_bit_set()) {
1997
                // We must have found a insert slot by now, since the current group contains at
1998
                // least one. For tables smaller than the group width, there will still be an
1999
                // empty element in the current (and only) group due to the load factor.
2000
                unsafe {
2001
                    // SAFETY:
2002
                    // * Caller of this function ensures that the control bytes are properly initialized.
2003
                    //
2004
                    // * We use this function with the slot / index found by `self.find_insert_slot_in_group`
2005
0
                    return Err(self.fix_insert_slot(insert_slot.unwrap_unchecked()));
2006
                }
2007
0
            }
2008
0
2009
0
            probe_seq.move_next(self.bucket_mask);
2010
        }
2011
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner30find_or_find_insert_slot_innerCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner30find_or_find_insert_slot_innerB7_
2012
2013
    /// Searches for an empty or deleted bucket which is suitable for inserting a new
2014
    /// element and sets the hash for that slot. Returns an index of that slot and the
2015
    /// old control byte stored in the found index.
2016
    ///
2017
    /// This function does not check if the given element exists in the table. Also,
2018
    /// this function does not check if there is enough space in the table to insert
2019
    /// a new element. Caller of the funtion must make ensure that the table has at
2020
    /// least 1 empty or deleted `bucket`, otherwise this function will never return
2021
    /// (will go into an infinite loop) for tables larger than the group width, or
2022
    /// return an index outside of the table indices range if the table is less than
2023
    /// the group width.
2024
    ///
2025
    /// If there is at least 1 empty or deleted `bucket` in the table, the function is
2026
    /// guaranteed to return an `index` in the range `0..self.buckets()`, but in any case,
2027
    /// if this function returns an `index` it will be in the range `0..=self.buckets()`.
2028
    ///
2029
    /// This function does not make any changes to the `data` parts of the table,
2030
    /// or any changes to the `items` or `growth_left` field of the table.
2031
    ///
2032
    /// # Safety
2033
    ///
2034
    /// The safety rules are directly derived from the safety rules for the
2035
    /// [`RawTableInner::set_ctrl_h2`] and [`RawTableInner::find_insert_slot`] methods.
2036
    /// Thus, in order to uphold the safety contracts for that methods, as well as for
2037
    /// the correct logic of the work of this crate, you must observe the following rules
2038
    /// when calling this function:
2039
    ///
2040
    /// * The [`RawTableInner`] has already been allocated and has properly initialized
2041
    ///   control bytes otherwise calling this function results in [`undefined behavior`].
2042
    ///
2043
    /// * The caller of this function must ensure that the "data" parts of the table
2044
    ///   will have an entry in the returned index (matching the given hash) right
2045
    ///   after calling this function.
2046
    ///
2047
    /// Attempt to write data at the `index` returned by this function when the table is
2048
    /// less than the group width and if there was not at least one empty or deleted bucket in
2049
    /// the table will cause immediate [`undefined behavior`]. This is because in this case the
2050
    /// function will return `self.bucket_mask + 1` as an index due to the trailing [`EMPTY]
2051
    /// control bytes outside the table range.
2052
    ///
2053
    /// The caller must independently increase the `items` field of the table, and also,
2054
    /// if the old control byte was [`EMPTY`], then decrease the table's `growth_left`
2055
    /// field, and do not change it if the old control byte was [`DELETED`].
2056
    ///
2057
    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
2058
    /// or saving `element` from / into the [`RawTable`] / [`RawTableInner`].
2059
    ///
2060
    /// [`Bucket::as_ptr`]: Bucket::as_ptr
2061
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2062
    /// [`RawTableInner::ctrl`]: RawTableInner::ctrl
2063
    /// [`RawTableInner::set_ctrl_h2`]: RawTableInner::set_ctrl_h2
2064
    /// [`RawTableInner::find_insert_slot`]: RawTableInner::find_insert_slot
2065
    #[inline]
2066
0
    unsafe fn prepare_insert_slot(&mut self, hash: u64) -> (usize, u8) {
2067
0
        // SAFETY: Caller of this function ensures that the control bytes are properly initialized.
2068
0
        let index: usize = self.find_insert_slot(hash).index;
2069
0
        // SAFETY:
2070
0
        // 1. The `find_insert_slot` function either returns an `index` less than or
2071
0
        //    equal to `self.buckets() = self.bucket_mask + 1` of the table, or never
2072
0
        //    returns if it cannot find an empty or deleted slot.
2073
0
        // 2. The caller of this function guarantees that the table has already been
2074
0
        //    allocated
2075
0
        let old_ctrl = *self.ctrl(index);
2076
0
        self.set_ctrl_h2(index, hash);
2077
0
        (index, old_ctrl)
2078
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner19prepare_insert_slotCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner19prepare_insert_slotB7_
2079
2080
    /// Searches for an empty or deleted bucket which is suitable for inserting
2081
    /// a new element, returning the `index` for the new [`Bucket`].
2082
    ///
2083
    /// This function does not make any changes to the `data` part of the table, or any
2084
    /// changes to the `items` or `growth_left` field of the table.
2085
    ///
2086
    /// The table must have at least 1 empty or deleted `bucket`, otherwise this function
2087
    /// will never return (will go into an infinite loop) for tables larger than the group
2088
    /// width, or return an index outside of the table indices range if the table is less
2089
    /// than the group width.
2090
    ///
2091
    /// If there is at least 1 empty or deleted `bucket` in the table, the function is
2092
    /// guaranteed to return [`InsertSlot`] with an index in the range `0..self.buckets()`,
2093
    /// but in any case, if this function returns [`InsertSlot`], it will contain an index
2094
    /// in the range `0..=self.buckets()`.
2095
    ///
2096
    /// # Safety
2097
    ///
2098
    /// The [`RawTableInner`] must have properly initialized control bytes otherwise calling
2099
    /// this function results in [`undefined behavior`].
2100
    ///
2101
    /// Attempt to write data at the [`InsertSlot`] returned by this function when the table is
2102
    /// less than the group width and if there was not at least one empty or deleted bucket in
2103
    /// the table will cause immediate [`undefined behavior`]. This is because in this case the
2104
    /// function will return `self.bucket_mask + 1` as an index due to the trailing [`EMPTY]
2105
    /// control bytes outside the table range.
2106
    ///
2107
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2108
    #[inline]
2109
0
    unsafe fn find_insert_slot(&self, hash: u64) -> InsertSlot {
2110
0
        let mut probe_seq = self.probe_seq(hash);
2111
        loop {
2112
            // SAFETY:
2113
            // * Caller of this function ensures that the control bytes are properly initialized.
2114
            //
2115
            // * `ProbeSeq.pos` cannot be greater than `self.bucket_mask = self.buckets() - 1`
2116
            //   of the table due to masking with `self.bucket_mask` and also because mumber of
2117
            //   buckets is a power of two (see `self.probe_seq` function).
2118
            //
2119
            // * Even if `ProbeSeq.pos` returns `position == self.bucket_mask`, it is safe to
2120
            //   call `Group::load` due to the extended control bytes range, which is
2121
            //  `self.bucket_mask + 1 + Group::WIDTH` (in fact, this means that the last control
2122
            //   byte will never be read for the allocated table);
2123
            //
2124
            // * Also, even if `RawTableInner` is not already allocated, `ProbeSeq.pos` will
2125
            //   always return "0" (zero), so Group::load will read unaligned `Group::static_empty()`
2126
            //   bytes, which is safe (see RawTableInner::new).
2127
0
            let group = unsafe { Group::load(self.ctrl(probe_seq.pos)) };
2128
0
2129
0
            let index = self.find_insert_slot_in_group(&group, &probe_seq);
2130
0
            if likely(index.is_some()) {
2131
                // SAFETY:
2132
                // * Caller of this function ensures that the control bytes are properly initialized.
2133
                //
2134
                // * We use this function with the slot / index found by `self.find_insert_slot_in_group`
2135
                unsafe {
2136
0
                    return self.fix_insert_slot(index.unwrap_unchecked());
2137
                }
2138
0
            }
2139
0
            probe_seq.move_next(self.bucket_mask);
2140
        }
2141
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner16find_insert_slotCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner16find_insert_slotB7_
2142
2143
    /// Searches for an element in a table, returning the `index` of the found element.
2144
    /// This uses dynamic dispatch to reduce the amount of code generated, but it is
2145
    /// eliminated by LLVM optimizations.
2146
    ///
2147
    /// This function does not make any changes to the `data` part of the table, or any
2148
    /// changes to the `items` or `growth_left` field of the table.
2149
    ///
2150
    /// The table must have at least 1 empty `bucket`, otherwise, if the
2151
    /// `eq: &mut dyn FnMut(usize) -> bool` function does not return `true`,
2152
    /// this function will also never return (will go into an infinite loop).
2153
    ///
2154
    /// This function is guaranteed to provide the `eq: &mut dyn FnMut(usize) -> bool`
2155
    /// function with only `FULL` buckets' indices and return the `index` of the found
2156
    /// element as `Some(index)`, so the index will always be in the range
2157
    /// `0..self.buckets()`.
2158
    ///
2159
    /// # Safety
2160
    ///
2161
    /// The [`RawTableInner`] must have properly initialized control bytes otherwise calling
2162
    /// this function results in [`undefined behavior`].
2163
    ///
2164
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2165
    #[inline(always)]
2166
0
    unsafe fn find_inner(&self, hash: u64, eq: &mut dyn FnMut(usize) -> bool) -> Option<usize> {
2167
0
        let h2_hash = h2(hash);
2168
0
        let mut probe_seq = self.probe_seq(hash);
2169
2170
        loop {
2171
            // SAFETY:
2172
            // * Caller of this function ensures that the control bytes are properly initialized.
2173
            //
2174
            // * `ProbeSeq.pos` cannot be greater than `self.bucket_mask = self.buckets() - 1`
2175
            //   of the table due to masking with `self.bucket_mask`.
2176
            //
2177
            // * Even if `ProbeSeq.pos` returns `position == self.bucket_mask`, it is safe to
2178
            //   call `Group::load` due to the extended control bytes range, which is
2179
            //  `self.bucket_mask + 1 + Group::WIDTH` (in fact, this means that the last control
2180
            //   byte will never be read for the allocated table);
2181
            //
2182
            // * Also, even if `RawTableInner` is not already allocated, `ProbeSeq.pos` will
2183
            //   always return "0" (zero), so Group::load will read unaligned `Group::static_empty()`
2184
            //   bytes, which is safe (see RawTableInner::new_in).
2185
0
            let group = unsafe { Group::load(self.ctrl(probe_seq.pos)) };
2186
2187
0
            for bit in group.match_byte(h2_hash) {
2188
                // This is the same as `(probe_seq.pos + bit) % self.buckets()` because the number
2189
                // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2190
0
                let index = (probe_seq.pos + bit) & self.bucket_mask;
2191
0
2192
0
                if likely(eq(index)) {
2193
0
                    return Some(index);
2194
0
                }
2195
            }
2196
2197
0
            if likely(group.match_empty().any_bit_set()) {
2198
0
                return None;
2199
0
            }
2200
0
2201
0
            probe_seq.move_next(self.bucket_mask);
2202
        }
2203
0
    }
2204
2205
    /// Prepares for rehashing data in place (that is, without allocating new memory).
2206
    /// Converts all full index `control bytes` to `DELETED` and all `DELETED` control
2207
    /// bytes to `EMPTY`, i.e. performs the following conversion:
2208
    ///
2209
    /// - `EMPTY` control bytes   -> `EMPTY`;
2210
    /// - `DELETED` control bytes -> `EMPTY`;
2211
    /// - `FULL` control bytes    -> `DELETED`.
2212
    ///
2213
    /// This function does not make any changes to the `data` parts of the table,
2214
    /// or any changes to the `items` or `growth_left` field of the table.
2215
    ///
2216
    /// # Safety
2217
    ///
2218
    /// You must observe the following safety rules when calling this function:
2219
    ///
2220
    /// * The [`RawTableInner`] has already been allocated;
2221
    ///
2222
    /// * The caller of this function must convert the `DELETED` bytes back to `FULL`
2223
    ///   bytes when re-inserting them into their ideal position (which was impossible
2224
    ///   to do during the first insert due to tombstones). If the caller does not do
2225
    ///   this, then calling this function may result in a memory leak.
2226
    ///
2227
    /// * The [`RawTableInner`] must have properly initialized control bytes otherwise
2228
    ///   calling this function results in [`undefined behavior`].
2229
    ///
2230
    /// Calling this function on a table that has not been allocated results in
2231
    /// [`undefined behavior`].
2232
    ///
2233
    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
2234
    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
2235
    ///
2236
    /// [`Bucket::as_ptr`]: Bucket::as_ptr
2237
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2238
    #[allow(clippy::mut_mut)]
2239
    #[inline]
2240
0
    unsafe fn prepare_rehash_in_place(&mut self) {
2241
        // Bulk convert all full control bytes to DELETED, and all DELETED control bytes to EMPTY.
2242
        // This effectively frees up all buckets containing a DELETED entry.
2243
        //
2244
        // SAFETY:
2245
        // 1. `i` is guaranteed to be within bounds since we are iterating from zero to `buckets - 1`;
2246
        // 2. Even if `i` will be `i == self.bucket_mask`, it is safe to call `Group::load_aligned`
2247
        //    due to the extended control bytes range, which is `self.bucket_mask + 1 + Group::WIDTH`;
2248
        // 3. The caller of this function guarantees that [`RawTableInner`] has already been allocated;
2249
        // 4. We can use `Group::load_aligned` and `Group::store_aligned` here since we start from 0
2250
        //    and go to the end with a step equal to `Group::WIDTH` (see TableLayout::calculate_layout_for).
2251
0
        for i in (0..self.buckets()).step_by(Group::WIDTH) {
2252
0
            let group = Group::load_aligned(self.ctrl(i));
2253
0
            let group = group.convert_special_to_empty_and_full_to_deleted();
2254
0
            group.store_aligned(self.ctrl(i));
2255
0
        }
2256
2257
        // Fix up the trailing control bytes. See the comments in set_ctrl
2258
        // for the handling of tables smaller than the group width.
2259
        //
2260
        // SAFETY: The caller of this function guarantees that [`RawTableInner`]
2261
        // has already been allocated
2262
0
        if unlikely(self.buckets() < Group::WIDTH) {
2263
0
            // SAFETY: We have `self.bucket_mask + 1 + Group::WIDTH` number of control bytes,
2264
0
            // so copying `self.buckets() == self.bucket_mask + 1` bytes with offset equal to
2265
0
            // `Group::WIDTH` is safe
2266
0
            self.ctrl(0)
2267
0
                .copy_to(self.ctrl(Group::WIDTH), self.buckets());
2268
0
        } else {
2269
0
            // SAFETY: We have `self.bucket_mask + 1 + Group::WIDTH` number of
2270
0
            // control bytes,so copying `Group::WIDTH` bytes with offset equal
2271
0
            // to `self.buckets() == self.bucket_mask + 1` is safe
2272
0
            self.ctrl(0)
2273
0
                .copy_to(self.ctrl(self.buckets()), Group::WIDTH);
2274
0
        }
2275
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner23prepare_rehash_in_placeCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner23prepare_rehash_in_placeB7_
2276
2277
    /// Returns an iterator over every element in the table.
2278
    ///
2279
    /// # Safety
2280
    ///
2281
    /// If any of the following conditions are violated, the result
2282
    /// is [`undefined behavior`]:
2283
    ///
2284
    /// * The caller has to ensure that the `RawTableInner` outlives the
2285
    ///   `RawIter`. Because we cannot make the `next` method unsafe on
2286
    ///   the `RawIter` struct, we have to make the `iter` method unsafe.
2287
    ///
2288
    /// * The [`RawTableInner`] must have properly initialized control bytes.
2289
    ///
2290
    /// The type `T` must be the actual type of the elements stored in the table,
2291
    /// otherwise using the returned [`RawIter`] results in [`undefined behavior`].
2292
    ///
2293
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2294
    #[inline]
2295
0
    unsafe fn iter<T>(&self) -> RawIter<T> {
2296
0
        // SAFETY:
2297
0
        // 1. Since the caller of this function ensures that the control bytes
2298
0
        //    are properly initialized and `self.data_end()` points to the start
2299
0
        //    of the array of control bytes, therefore: `ctrl` is valid for reads,
2300
0
        //    properly aligned to `Group::WIDTH` and points to the properly initialized
2301
0
        //    control bytes.
2302
0
        // 2. `data` bucket index in the table is equal to the `ctrl` index (i.e.
2303
0
        //    equal to zero).
2304
0
        // 3. We pass the exact value of buckets of the table to the function.
2305
0
        //
2306
0
        //                         `ctrl` points here (to the start
2307
0
        //                         of the first control byte `CT0`)
2308
0
        //                          ∨
2309
0
        // [Pad], T_n, ..., T1, T0, |CT0, CT1, ..., CT_n|, CTa_0, CTa_1, ..., CTa_m
2310
0
        //                           \________  ________/
2311
0
        //                                    \/
2312
0
        //       `n = buckets - 1`, i.e. `RawTableInner::buckets() - 1`
2313
0
        //
2314
0
        // where: T0...T_n  - our stored data;
2315
0
        //        CT0...CT_n - control bytes or metadata for `data`.
2316
0
        //        CTa_0...CTa_m - additional control bytes, where `m = Group::WIDTH - 1` (so that the search
2317
0
        //                        with loading `Group` bytes from the heap works properly, even if the result
2318
0
        //                        of `h1(hash) & self.bucket_mask` is equal to `self.bucket_mask`). See also
2319
0
        //                        `RawTableInner::set_ctrl` function.
2320
0
        //
2321
0
        // P.S. `h1(hash) & self.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
2322
0
        // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2323
0
        let data = Bucket::from_base_index(self.data_end(), 0);
2324
0
        RawIter {
2325
0
            // SAFETY: See explanation above
2326
0
            iter: RawIterRange::new(self.ctrl.as_ptr(), data, self.buckets()),
2327
0
            items: self.items,
2328
0
        }
2329
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner4iterTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtB13_8LruEntryB1s_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEEB2I_
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner4iterpEB8_
2330
2331
    /// Executes the destructors (if any) of the values stored in the table.
2332
    ///
2333
    /// # Note
2334
    ///
2335
    /// This function does not erase the control bytes of the table and does
2336
    /// not make any changes to the `items` or `growth_left` fields of the
2337
    /// table. If necessary, the caller of this function must manually set
2338
    /// up these table fields, for example using the [`clear_no_drop`] function.
2339
    ///
2340
    /// Be careful during calling this function, because drop function of
2341
    /// the elements can panic, and this can leave table in an inconsistent
2342
    /// state.
2343
    ///
2344
    /// # Safety
2345
    ///
2346
    /// The type `T` must be the actual type of the elements stored in the table,
2347
    /// otherwise calling this function may result in [`undefined behavior`].
2348
    ///
2349
    /// If `T` is a type that should be dropped and **the table is not empty**,
2350
    /// calling this function more than once results in [`undefined behavior`].
2351
    ///
2352
    /// If `T` is not [`Copy`], attempting to use values stored in the table after
2353
    /// calling this function may result in [`undefined behavior`].
2354
    ///
2355
    /// It is safe to call this function on a table that has not been allocated,
2356
    /// on a table with uninitialized control bytes, and on a table with no actual
2357
    /// data but with `Full` control bytes if `self.items == 0`.
2358
    ///
2359
    /// See also [`Bucket::drop`] / [`Bucket::as_ptr`] methods, for more information
2360
    /// about of properly removing or saving `element` from / into the [`RawTable`] /
2361
    /// [`RawTableInner`].
2362
    ///
2363
    /// [`Bucket::drop`]: Bucket::drop
2364
    /// [`Bucket::as_ptr`]: Bucket::as_ptr
2365
    /// [`clear_no_drop`]: RawTableInner::clear_no_drop
2366
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2367
0
    unsafe fn drop_elements<T>(&mut self) {
2368
0
        // Check that `self.items != 0`. Protects against the possibility
2369
0
        // of creating an iterator on an table with uninitialized control bytes.
2370
0
        if T::NEEDS_DROP && self.items != 0 {
2371
            // SAFETY: We know for sure that RawTableInner will outlive the
2372
            // returned `RawIter` iterator, and the caller of this function
2373
            // must uphold the safety contract for `drop_elements` method.
2374
0
            for item in self.iter::<T>() {
2375
0
                // SAFETY: The caller must uphold the safety contract for
2376
0
                // `drop_elements` method.
2377
0
                item.drop();
2378
0
            }
2379
0
        }
2380
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner13drop_elementsTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtB1d_8LruEntryB1C_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEEB2S_
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner13drop_elementspEB8_
2381
2382
    /// Executes the destructors (if any) of the values stored in the table and than
2383
    /// deallocates the table.
2384
    ///
2385
    /// # Note
2386
    ///
2387
    /// Calling this function automatically makes invalid (dangling) all instances of
2388
    /// buckets ([`Bucket`]) and makes invalid (dangling) the `ctrl` field of the table.
2389
    ///
2390
    /// This function does not make any changes to the `bucket_mask`, `items` or `growth_left`
2391
    /// fields of the table. If necessary, the caller of this function must manually set
2392
    /// up these table fields.
2393
    ///
2394
    /// # Safety
2395
    ///
2396
    /// If any of the following conditions are violated, the result is [`undefined behavior`]:
2397
    ///
2398
    /// * Calling this function more than once;
2399
    ///
2400
    /// * The type `T` must be the actual type of the elements stored in the table.
2401
    ///
2402
    /// * The `alloc` must be the same [`Allocator`] as the `Allocator` that was used
2403
    ///   to allocate this table.
2404
    ///
2405
    /// * The `table_layout` must be the same [`TableLayout`] as the `TableLayout` that
2406
    ///   was used to allocate this table.
2407
    ///
2408
    /// The caller of this function should pay attention to the possibility of the
2409
    /// elements' drop function panicking, because this:
2410
    ///
2411
    ///    * May leave the table in an inconsistent state;
2412
    ///
2413
    ///    * Memory is never deallocated, so a memory leak may occur.
2414
    ///
2415
    /// Attempt to use the `ctrl` field of the table (dereference) after calling this
2416
    /// function results in [`undefined behavior`].
2417
    ///
2418
    /// It is safe to call this function on a table that has not been allocated,
2419
    /// on a table with uninitialized control bytes, and on a table with no actual
2420
    /// data but with `Full` control bytes if `self.items == 0`.
2421
    ///
2422
    /// See also [`RawTableInner::drop_elements`] or [`RawTableInner::free_buckets`]
2423
    /// for more  information.
2424
    ///
2425
    /// [`RawTableInner::drop_elements`]: RawTableInner::drop_elements
2426
    /// [`RawTableInner::free_buckets`]: RawTableInner::free_buckets
2427
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2428
0
    unsafe fn drop_inner_table<T, A: Allocator>(&mut self, alloc: &A, table_layout: TableLayout) {
2429
0
        if !self.is_empty_singleton() {
2430
0
            unsafe {
2431
0
                // SAFETY: The caller must uphold the safety contract for `drop_inner_table` method.
2432
0
                self.drop_elements::<T>();
2433
0
                // SAFETY:
2434
0
                // 1. We have checked that our table is allocated.
2435
0
                // 2. The caller must uphold the safety contract for `drop_inner_table` method.
2436
0
                self.free_buckets(alloc, table_layout);
2437
0
            }
2438
0
        }
2439
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner16drop_inner_tableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtB1g_8LruEntryB1F_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEENtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalEB2V_
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner16drop_inner_tableppEB8_
2440
2441
    /// Returns a pointer to an element in the table (convenience for
2442
    /// `Bucket::from_base_index(self.data_end::<T>(), index)`).
2443
    ///
2444
    /// The caller must ensure that the `RawTableInner` outlives the returned [`Bucket<T>`],
2445
    /// otherwise using it may result in [`undefined behavior`].
2446
    ///
2447
    /// # Safety
2448
    ///
2449
    /// If `mem::size_of::<T>() != 0`, then the safety rules are directly derived from the
2450
    /// safety rules of the [`Bucket::from_base_index`] function. Therefore, when calling
2451
    /// this function, the following safety rules must be observed:
2452
    ///
2453
    /// * The table must already be allocated;
2454
    ///
2455
    /// * The `index` must not be greater than the number returned by the [`RawTableInner::buckets`]
2456
    ///   function, i.e. `(index + 1) <= self.buckets()`.
2457
    ///
2458
    /// * The type `T` must be the actual type of the elements stored in the table, otherwise
2459
    ///   using the returned [`Bucket`] may result in [`undefined behavior`].
2460
    ///
2461
    /// It is safe to call this function with index of zero (`index == 0`) on a table that has
2462
    /// not been allocated, but using the returned [`Bucket`] results in [`undefined behavior`].
2463
    ///
2464
    /// If `mem::size_of::<T>() == 0`, then the only requirement is that the `index` must
2465
    /// not be greater than the number returned by the [`RawTable::buckets`] function, i.e.
2466
    /// `(index + 1) <= self.buckets()`.
2467
    ///
2468
    /// ```none
2469
    /// If mem::size_of::<T>() != 0 then return a pointer to the `element` in the `data part` of the table
2470
    /// (we start counting from "0", so that in the expression T[n], the "n" index actually one less than
2471
    /// the "buckets" number of our `RawTableInner`, i.e. "n = RawTableInner::buckets() - 1"):
2472
    ///
2473
    ///           `table.bucket(3).as_ptr()` returns a pointer that points here in the `data`
2474
    ///           part of the `RawTableInner`, i.e. to the start of T3 (see [`Bucket::as_ptr`])
2475
    ///                  |
2476
    ///                  |               `base = table.data_end::<T>()` points here
2477
    ///                  |               (to the start of CT0 or to the end of T0)
2478
    ///                  v                 v
2479
    /// [Pad], T_n, ..., |T3|, T2, T1, T0, |CT0, CT1, CT2, CT3, ..., CT_n, CTa_0, CTa_1, ..., CTa_m
2480
    ///                     ^                                              \__________  __________/
2481
    ///        `table.bucket(3)` returns a pointer that points                        \/
2482
    ///         here in the `data` part of the `RawTableInner`             additional control bytes
2483
    ///         (to the end of T3)                                          `m = Group::WIDTH - 1`
2484
    ///
2485
    /// where: T0...T_n  - our stored data;
2486
    ///        CT0...CT_n - control bytes or metadata for `data`;
2487
    ///        CTa_0...CTa_m - additional control bytes (so that the search with loading `Group` bytes from
2488
    ///                        the heap works properly, even if the result of `h1(hash) & self.bucket_mask`
2489
    ///                        is equal to `self.bucket_mask`). See also `RawTableInner::set_ctrl` function.
2490
    ///
2491
    /// P.S. `h1(hash) & self.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
2492
    /// of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2493
    /// ```
2494
    ///
2495
    /// [`Bucket::from_base_index`]: Bucket::from_base_index
2496
    /// [`RawTableInner::buckets`]: RawTableInner::buckets
2497
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2498
    #[inline]
2499
0
    unsafe fn bucket<T>(&self, index: usize) -> Bucket<T> {
2500
0
        debug_assert_ne!(self.bucket_mask, 0);
2501
0
        debug_assert!(index < self.buckets());
2502
0
        Bucket::from_base_index(self.data_end(), index)
2503
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner6bucketTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtB15_8LruEntryB1u_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEEB2K_
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner6bucketpEB8_
2504
2505
    /// Returns a raw `*mut u8` pointer to the start of the `data` element in the table
2506
    /// (convenience for `self.data_end::<u8>().as_ptr().sub((index + 1) * size_of)`).
2507
    ///
2508
    /// The caller must ensure that the `RawTableInner` outlives the returned `*mut u8`,
2509
    /// otherwise using it may result in [`undefined behavior`].
2510
    ///
2511
    /// # Safety
2512
    ///
2513
    /// If any of the following conditions are violated, the result is [`undefined behavior`]:
2514
    ///
2515
    /// * The table must already be allocated;
2516
    ///
2517
    /// * The `index` must not be greater than the number returned by the [`RawTableInner::buckets`]
2518
    ///   function, i.e. `(index + 1) <= self.buckets()`;
2519
    ///
2520
    /// * The `size_of` must be equal to the size of the elements stored in the table;
2521
    ///
2522
    /// ```none
2523
    /// If mem::size_of::<T>() != 0 then return a pointer to the `element` in the `data part` of the table
2524
    /// (we start counting from "0", so that in the expression T[n], the "n" index actually one less than
2525
    /// the "buckets" number of our `RawTableInner`, i.e. "n = RawTableInner::buckets() - 1"):
2526
    ///
2527
    ///           `table.bucket_ptr(3, mem::size_of::<T>())` returns a pointer that points here in the
2528
    ///           `data` part of the `RawTableInner`, i.e. to the start of T3
2529
    ///                  |
2530
    ///                  |               `base = table.data_end::<u8>()` points here
2531
    ///                  |               (to the start of CT0 or to the end of T0)
2532
    ///                  v                 v
2533
    /// [Pad], T_n, ..., |T3|, T2, T1, T0, |CT0, CT1, CT2, CT3, ..., CT_n, CTa_0, CTa_1, ..., CTa_m
2534
    ///                                                                    \__________  __________/
2535
    ///                                                                               \/
2536
    ///                                                                    additional control bytes
2537
    ///                                                                     `m = Group::WIDTH - 1`
2538
    ///
2539
    /// where: T0...T_n  - our stored data;
2540
    ///        CT0...CT_n - control bytes or metadata for `data`;
2541
    ///        CTa_0...CTa_m - additional control bytes (so that the search with loading `Group` bytes from
2542
    ///                        the heap works properly, even if the result of `h1(hash) & self.bucket_mask`
2543
    ///                        is equal to `self.bucket_mask`). See also `RawTableInner::set_ctrl` function.
2544
    ///
2545
    /// P.S. `h1(hash) & self.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
2546
    /// of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2547
    /// ```
2548
    ///
2549
    /// [`RawTableInner::buckets`]: RawTableInner::buckets
2550
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2551
    #[inline]
2552
0
    unsafe fn bucket_ptr(&self, index: usize, size_of: usize) -> *mut u8 {
2553
0
        debug_assert_ne!(self.bucket_mask, 0);
2554
0
        debug_assert!(index < self.buckets());
2555
0
        let base: *mut u8 = self.data_end().as_ptr();
2556
0
        base.sub((index + 1) * size_of)
2557
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner10bucket_ptrCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner10bucket_ptrB7_
2558
2559
    /// Returns pointer to one past last `data` element in the table as viewed from
2560
    /// the start point of the allocation (convenience for `self.ctrl.cast()`).
2561
    ///
2562
    /// This function actually returns a pointer to the end of the `data element` at
2563
    /// index "0" (zero).
2564
    ///
2565
    /// The caller must ensure that the `RawTableInner` outlives the returned [`NonNull<T>`],
2566
    /// otherwise using it may result in [`undefined behavior`].
2567
    ///
2568
    /// # Note
2569
    ///
2570
    /// The type `T` must be the actual type of the elements stored in the table, otherwise
2571
    /// using the returned [`NonNull<T>`] may result in [`undefined behavior`].
2572
    ///
2573
    /// ```none
2574
    ///                        `table.data_end::<T>()` returns pointer that points here
2575
    ///                        (to the end of `T0`)
2576
    ///                          ∨
2577
    /// [Pad], T_n, ..., T1, T0, |CT0, CT1, ..., CT_n|, CTa_0, CTa_1, ..., CTa_m
2578
    ///                           \________  ________/
2579
    ///                                    \/
2580
    ///       `n = buckets - 1`, i.e. `RawTableInner::buckets() - 1`
2581
    ///
2582
    /// where: T0...T_n  - our stored data;
2583
    ///        CT0...CT_n - control bytes or metadata for `data`.
2584
    ///        CTa_0...CTa_m - additional control bytes, where `m = Group::WIDTH - 1` (so that the search
2585
    ///                        with loading `Group` bytes from the heap works properly, even if the result
2586
    ///                        of `h1(hash) & self.bucket_mask` is equal to `self.bucket_mask`). See also
2587
    ///                        `RawTableInner::set_ctrl` function.
2588
    ///
2589
    /// P.S. `h1(hash) & self.bucket_mask` is the same as `hash as usize % self.buckets()` because the number
2590
    /// of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2591
    /// ```
2592
    ///
2593
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2594
    #[inline]
2595
0
    fn data_end<T>(&self) -> NonNull<T> {
2596
0
        self.ctrl.cast()
2597
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner8data_endTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtB17_8LruEntryB1w_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEEB2M_
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner8data_endhECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner8data_endhEB8_
2598
2599
    /// Returns an iterator-like object for a probe sequence on the table.
2600
    ///
2601
    /// This iterator never terminates, but is guaranteed to visit each bucket
2602
    /// group exactly once. The loop using `probe_seq` must terminate upon
2603
    /// reaching a group containing an empty bucket.
2604
    #[inline]
2605
0
    fn probe_seq(&self, hash: u64) -> ProbeSeq {
2606
0
        ProbeSeq {
2607
0
            // This is the same as `hash as usize % self.buckets()` because the number
2608
0
            // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2609
0
            pos: h1(hash) & self.bucket_mask,
2610
0
            stride: 0,
2611
0
        }
2612
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner9probe_seqCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner9probe_seqB7_
2613
2614
    /// Returns the index of a bucket for which a value must be inserted if there is enough rooom
2615
    /// in the table, otherwise returns error
2616
    #[cfg(feature = "raw")]
2617
    #[inline]
2618
    unsafe fn prepare_insert_no_grow(&mut self, hash: u64) -> Result<usize, ()> {
2619
        let index = self.find_insert_slot(hash).index;
2620
        let old_ctrl = *self.ctrl(index);
2621
        if unlikely(self.growth_left == 0 && special_is_empty(old_ctrl)) {
2622
            Err(())
2623
        } else {
2624
            self.record_item_insert_at(index, old_ctrl, hash);
2625
            Ok(index)
2626
        }
2627
    }
2628
2629
    #[inline]
2630
0
    unsafe fn record_item_insert_at(&mut self, index: usize, old_ctrl: u8, hash: u64) {
2631
0
        self.growth_left -= usize::from(special_is_empty(old_ctrl));
2632
0
        self.set_ctrl_h2(index, hash);
2633
0
        self.items += 1;
2634
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner21record_item_insert_atCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner21record_item_insert_atB7_
2635
2636
    #[inline]
2637
0
    fn is_in_same_group(&self, i: usize, new_i: usize, hash: u64) -> bool {
2638
0
        let probe_seq_pos = self.probe_seq(hash).pos;
2639
0
        let probe_index =
2640
0
            |pos: usize| (pos.wrapping_sub(probe_seq_pos) & self.bucket_mask) / Group::WIDTH;
Unexecuted instantiation: _RNCNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB7_13RawTableInner16is_in_same_group0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB7_13RawTableInner16is_in_same_group0B9_
2641
0
        probe_index(i) == probe_index(new_i)
2642
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner16is_in_same_groupCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner16is_in_same_groupB7_
2643
2644
    /// Sets a control byte to the hash, and possibly also the replicated control byte at
2645
    /// the end of the array.
2646
    ///
2647
    /// This function does not make any changes to the `data` parts of the table,
2648
    /// or any changes to the `items` or `growth_left` field of the table.
2649
    ///
2650
    /// # Safety
2651
    ///
2652
    /// The safety rules are directly derived from the safety rules for [`RawTableInner::set_ctrl`]
2653
    /// method. Thus, in order to uphold the safety contracts for the method, you must observe the
2654
    /// following rules when calling this function:
2655
    ///
2656
    /// * The [`RawTableInner`] has already been allocated;
2657
    ///
2658
    /// * The `index` must not be greater than the `RawTableInner.bucket_mask`, i.e.
2659
    ///   `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)` must
2660
    ///   be no greater than the number returned by the function [`RawTableInner::buckets`].
2661
    ///
2662
    /// Calling this function on a table that has not been allocated results in [`undefined behavior`].
2663
    ///
2664
    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
2665
    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
2666
    ///
2667
    /// [`RawTableInner::set_ctrl`]: RawTableInner::set_ctrl
2668
    /// [`RawTableInner::buckets`]: RawTableInner::buckets
2669
    /// [`Bucket::as_ptr`]: Bucket::as_ptr
2670
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2671
    #[inline]
2672
0
    unsafe fn set_ctrl_h2(&mut self, index: usize, hash: u64) {
2673
0
        // SAFETY: The caller must uphold the safety rules for the [`RawTableInner::set_ctrl_h2`]
2674
0
        self.set_ctrl(index, h2(hash));
2675
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner11set_ctrl_h2Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner11set_ctrl_h2B7_
2676
2677
    /// Replaces the hash in the control byte at the given index with the provided one,
2678
    /// and possibly also replicates the new control byte at the end of the array of control
2679
    /// bytes, returning the old control byte.
2680
    ///
2681
    /// This function does not make any changes to the `data` parts of the table,
2682
    /// or any changes to the `items` or `growth_left` field of the table.
2683
    ///
2684
    /// # Safety
2685
    ///
2686
    /// The safety rules are directly derived from the safety rules for [`RawTableInner::set_ctrl_h2`]
2687
    /// and [`RawTableInner::ctrl`] methods. Thus, in order to uphold the safety contracts for both
2688
    /// methods, you must observe the following rules when calling this function:
2689
    ///
2690
    /// * The [`RawTableInner`] has already been allocated;
2691
    ///
2692
    /// * The `index` must not be greater than the `RawTableInner.bucket_mask`, i.e.
2693
    ///   `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)` must
2694
    ///   be no greater than the number returned by the function [`RawTableInner::buckets`].
2695
    ///
2696
    /// Calling this function on a table that has not been allocated results in [`undefined behavior`].
2697
    ///
2698
    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
2699
    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
2700
    ///
2701
    /// [`RawTableInner::set_ctrl_h2`]: RawTableInner::set_ctrl_h2
2702
    /// [`RawTableInner::buckets`]: RawTableInner::buckets
2703
    /// [`Bucket::as_ptr`]: Bucket::as_ptr
2704
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2705
    #[inline]
2706
0
    unsafe fn replace_ctrl_h2(&mut self, index: usize, hash: u64) -> u8 {
2707
0
        // SAFETY: The caller must uphold the safety rules for the [`RawTableInner::replace_ctrl_h2`]
2708
0
        let prev_ctrl = *self.ctrl(index);
2709
0
        self.set_ctrl_h2(index, hash);
2710
0
        prev_ctrl
2711
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner15replace_ctrl_h2Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner15replace_ctrl_h2B7_
2712
2713
    /// Sets a control byte, and possibly also the replicated control byte at
2714
    /// the end of the array.
2715
    ///
2716
    /// This function does not make any changes to the `data` parts of the table,
2717
    /// or any changes to the `items` or `growth_left` field of the table.
2718
    ///
2719
    /// # Safety
2720
    ///
2721
    /// You must observe the following safety rules when calling this function:
2722
    ///
2723
    /// * The [`RawTableInner`] has already been allocated;
2724
    ///
2725
    /// * The `index` must not be greater than the `RawTableInner.bucket_mask`, i.e.
2726
    ///   `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)` must
2727
    ///   be no greater than the number returned by the function [`RawTableInner::buckets`].
2728
    ///
2729
    /// Calling this function on a table that has not been allocated results in [`undefined behavior`].
2730
    ///
2731
    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
2732
    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
2733
    ///
2734
    /// [`RawTableInner::buckets`]: RawTableInner::buckets
2735
    /// [`Bucket::as_ptr`]: Bucket::as_ptr
2736
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2737
    #[inline]
2738
0
    unsafe fn set_ctrl(&mut self, index: usize, ctrl: u8) {
2739
0
        // Replicate the first Group::WIDTH control bytes at the end of
2740
0
        // the array without using a branch. If the tables smaller than
2741
0
        // the group width (self.buckets() < Group::WIDTH),
2742
0
        // `index2 = Group::WIDTH + index`, otherwise `index2` is:
2743
0
        //
2744
0
        // - If index >= Group::WIDTH then index == index2.
2745
0
        // - Otherwise index2 == self.bucket_mask + 1 + index.
2746
0
        //
2747
0
        // The very last replicated control byte is never actually read because
2748
0
        // we mask the initial index for unaligned loads, but we write it
2749
0
        // anyways because it makes the set_ctrl implementation simpler.
2750
0
        //
2751
0
        // If there are fewer buckets than Group::WIDTH then this code will
2752
0
        // replicate the buckets at the end of the trailing group. For example
2753
0
        // with 2 buckets and a group size of 4, the control bytes will look
2754
0
        // like this:
2755
0
        //
2756
0
        //     Real    |             Replicated
2757
0
        // ---------------------------------------------
2758
0
        // | [A] | [B] | [EMPTY] | [EMPTY] | [A] | [B] |
2759
0
        // ---------------------------------------------
2760
0
2761
0
        // This is the same as `(index.wrapping_sub(Group::WIDTH)) % self.buckets() + Group::WIDTH`
2762
0
        // because the number of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
2763
0
        let index2 = ((index.wrapping_sub(Group::WIDTH)) & self.bucket_mask) + Group::WIDTH;
2764
0
2765
0
        // SAFETY: The caller must uphold the safety rules for the [`RawTableInner::set_ctrl`]
2766
0
        *self.ctrl(index) = ctrl;
2767
0
        *self.ctrl(index2) = ctrl;
2768
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner8set_ctrlCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner8set_ctrlB7_
2769
2770
    /// Returns a pointer to a control byte.
2771
    ///
2772
    /// # Safety
2773
    ///
2774
    /// For the allocated [`RawTableInner`], the result is [`Undefined Behavior`],
2775
    /// if the `index` is greater than the `self.bucket_mask + 1 + Group::WIDTH`.
2776
    /// In that case, calling this function with `index == self.bucket_mask + 1 + Group::WIDTH`
2777
    /// will return a pointer to the end of the allocated table and it is useless on its own.
2778
    ///
2779
    /// Calling this function with `index >= self.bucket_mask + 1 + Group::WIDTH` on a
2780
    /// table that has not been allocated results in [`Undefined Behavior`].
2781
    ///
2782
    /// So to satisfy both requirements you should always follow the rule that
2783
    /// `index < self.bucket_mask + 1 + Group::WIDTH`
2784
    ///
2785
    /// Calling this function on [`RawTableInner`] that are not already allocated is safe
2786
    /// for read-only purpose.
2787
    ///
2788
    /// See also [`Bucket::as_ptr()`] method, for more information about of properly removing
2789
    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
2790
    ///
2791
    /// [`Bucket::as_ptr()`]: Bucket::as_ptr()
2792
    /// [`Undefined Behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2793
    #[inline]
2794
0
    unsafe fn ctrl(&self, index: usize) -> *mut u8 {
2795
0
        debug_assert!(index < self.num_ctrl_bytes());
2796
        // SAFETY: The caller must uphold the safety rules for the [`RawTableInner::ctrl`]
2797
0
        self.ctrl.as_ptr().add(index)
2798
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner4ctrlCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner4ctrlB7_
2799
2800
    #[inline]
2801
0
    fn buckets(&self) -> usize {
2802
0
        self.bucket_mask + 1
2803
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner7bucketsCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner7bucketsB7_
2804
2805
    /// Checks whether the bucket at `index` is full.
2806
    ///
2807
    /// # Safety
2808
    ///
2809
    /// The caller must ensure `index` is less than the number of buckets.
2810
    #[inline]
2811
0
    unsafe fn is_bucket_full(&self, index: usize) -> bool {
2812
0
        debug_assert!(index < self.buckets());
2813
0
        is_full(*self.ctrl(index))
2814
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner14is_bucket_fullCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner14is_bucket_fullB7_
2815
2816
    #[inline]
2817
0
    fn num_ctrl_bytes(&self) -> usize {
2818
0
        self.bucket_mask + 1 + Group::WIDTH
2819
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner14num_ctrl_bytesCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner14num_ctrl_bytesB7_
2820
2821
    #[inline]
2822
0
    fn is_empty_singleton(&self) -> bool {
2823
0
        self.bucket_mask == 0
2824
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner18is_empty_singletonCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner18is_empty_singletonB7_
2825
2826
    /// Attempts to allocate a new hash table with at least enough capacity
2827
    /// for inserting the given number of elements without reallocating,
2828
    /// and return it inside ScopeGuard to protect against panic in the hash
2829
    /// function.
2830
    ///
2831
    /// # Note
2832
    ///
2833
    /// It is recommended (but not required):
2834
    ///
2835
    /// * That the new table's `capacity` be greater than or equal to `self.items`.
2836
    ///
2837
    /// * The `alloc` is the same [`Allocator`] as the `Allocator` used
2838
    ///   to allocate this table.
2839
    ///
2840
    /// * The `table_layout` is the same [`TableLayout`] as the `TableLayout` used
2841
    ///   to allocate this table.
2842
    ///
2843
    /// If `table_layout` does not match the `TableLayout` that was used to allocate
2844
    /// this table, then using `mem::swap` with the `self` and the new table returned
2845
    /// by this function results in [`undefined behavior`].
2846
    ///
2847
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2848
    #[allow(clippy::mut_mut)]
2849
    #[inline]
2850
0
    fn prepare_resize<'a, A>(
2851
0
        &self,
2852
0
        alloc: &'a A,
2853
0
        table_layout: TableLayout,
2854
0
        capacity: usize,
2855
0
        fallibility: Fallibility,
2856
0
    ) -> Result<crate::scopeguard::ScopeGuard<Self, impl FnMut(&mut Self) + 'a>, TryReserveError>
2857
0
    where
2858
0
        A: Allocator,
2859
0
    {
2860
0
        debug_assert!(self.items <= capacity);
2861
2862
        // Allocate and initialize the new table.
2863
0
        let new_table =
2864
0
            RawTableInner::fallible_with_capacity(alloc, table_layout, capacity, fallibility)?;
2865
2866
        // The hash function may panic, in which case we simply free the new
2867
        // table without dropping any elements that may have been copied into
2868
        // it.
2869
        //
2870
        // This guard is also used to free the old table on success, see
2871
        // the comment at the bottom of this function.
2872
0
        Ok(guard(new_table, move |self_| {
2873
0
            if !self_.is_empty_singleton() {
2874
0
                // SAFETY:
2875
0
                // 1. We have checked that our table is allocated.
2876
0
                // 2. We know for sure that the `alloc` and `table_layout` matches the
2877
0
                //    [`Allocator`] and [`TableLayout`] used to allocate this table.
2878
0
                unsafe { self_.free_buckets(alloc, table_layout) };
2879
0
            }
2880
0
        }))
Unexecuted instantiation: _RNCINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB8_13RawTableInner14prepare_resizeNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalE0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB8_13RawTableInner14prepare_resizepE0Ba_
2881
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner14prepare_resizeNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner14prepare_resizepEB8_
2882
2883
    /// Reserves or rehashes to make room for `additional` more elements.
2884
    ///
2885
    /// This uses dynamic dispatch to reduce the amount of
2886
    /// code generated, but it is eliminated by LLVM optimizations when inlined.
2887
    ///
2888
    /// # Safety
2889
    ///
2890
    /// If any of the following conditions are violated, the result is
2891
    /// [`undefined behavior`]:
2892
    ///
2893
    /// * The `alloc` must be the same [`Allocator`] as the `Allocator` used
2894
    ///   to allocate this table.
2895
    ///
2896
    /// * The `layout` must be the same [`TableLayout`] as the `TableLayout`
2897
    ///   used to allocate this table.
2898
    ///
2899
    /// * The `drop` function (`fn(*mut u8)`) must be the actual drop function of
2900
    ///   the elements stored in the table.
2901
    ///
2902
    /// * The [`RawTableInner`] must have properly initialized control bytes.
2903
    ///
2904
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2905
    #[allow(clippy::inline_always)]
2906
    #[inline(always)]
2907
0
    unsafe fn reserve_rehash_inner<A>(
2908
0
        &mut self,
2909
0
        alloc: &A,
2910
0
        additional: usize,
2911
0
        hasher: &dyn Fn(&mut Self, usize) -> u64,
2912
0
        fallibility: Fallibility,
2913
0
        layout: TableLayout,
2914
0
        drop: Option<fn(*mut u8)>,
2915
0
    ) -> Result<(), TryReserveError>
2916
0
    where
2917
0
        A: Allocator,
2918
0
    {
2919
        // Avoid `Option::ok_or_else` because it bloats LLVM IR.
2920
0
        let new_items = match self.items.checked_add(additional) {
2921
0
            Some(new_items) => new_items,
2922
0
            None => return Err(fallibility.capacity_overflow()),
2923
        };
2924
0
        let full_capacity = bucket_mask_to_capacity(self.bucket_mask);
2925
0
        if new_items <= full_capacity / 2 {
2926
            // Rehash in-place without re-allocating if we have plenty of spare
2927
            // capacity that is locked up due to DELETED entries.
2928
2929
            // SAFETY:
2930
            // 1. We know for sure that `[`RawTableInner`]` has already been allocated
2931
            //    (since new_items <= full_capacity / 2);
2932
            // 2. The caller ensures that `drop` function is the actual drop function of
2933
            //    the elements stored in the table.
2934
            // 3. The caller ensures that `layout` matches the [`TableLayout`] that was
2935
            //    used to allocate this table.
2936
            // 4. The caller ensures that the control bytes of the `RawTableInner`
2937
            //    are already initialized.
2938
0
            self.rehash_in_place(hasher, layout.size, drop);
2939
0
            Ok(())
2940
        } else {
2941
            // Otherwise, conservatively resize to at least the next size up
2942
            // to avoid churning deletes into frequent rehashes.
2943
            //
2944
            // SAFETY:
2945
            // 1. We know for sure that `capacity >= self.items`.
2946
            // 2. The caller ensures that `alloc` and `layout` matches the [`Allocator`] and
2947
            //    [`TableLayout`] that were used to allocate this table.
2948
            // 3. The caller ensures that the control bytes of the `RawTableInner`
2949
            //    are already initialized.
2950
0
            self.resize_inner(
2951
0
                alloc,
2952
0
                usize::max(new_items, full_capacity + 1),
2953
0
                hasher,
2954
0
                fallibility,
2955
0
                layout,
2956
0
            )
2957
        }
2958
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner20reserve_rehash_innerNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner20reserve_rehash_innerpEB8_
2959
2960
    /// Returns an iterator over full buckets indices in the table.
2961
    ///
2962
    /// # Safety
2963
    ///
2964
    /// Behavior is undefined if any of the following conditions are violated:
2965
    ///
2966
    /// * The caller has to ensure that the `RawTableInner` outlives the
2967
    ///   `FullBucketsIndices`. Because we cannot make the `next` method
2968
    ///   unsafe on the `FullBucketsIndices` struct, we have to make the
2969
    ///   `full_buckets_indices` method unsafe.
2970
    ///
2971
    /// * The [`RawTableInner`] must have properly initialized control bytes.
2972
    #[inline(always)]
2973
0
    unsafe fn full_buckets_indices(&self) -> FullBucketsIndices {
2974
0
        // SAFETY:
2975
0
        // 1. Since the caller of this function ensures that the control bytes
2976
0
        //    are properly initialized and `self.ctrl(0)` points to the start
2977
0
        //    of the array of control bytes, therefore: `ctrl` is valid for reads,
2978
0
        //    properly aligned to `Group::WIDTH` and points to the properly initialized
2979
0
        //    control bytes.
2980
0
        // 2. The value of `items` is equal to the amount of data (values) added
2981
0
        //    to the table.
2982
0
        //
2983
0
        //                         `ctrl` points here (to the start
2984
0
        //                         of the first control byte `CT0`)
2985
0
        //                          ∨
2986
0
        // [Pad], T_n, ..., T1, T0, |CT0, CT1, ..., CT_n|, Group::WIDTH
2987
0
        //                           \________  ________/
2988
0
        //                                    \/
2989
0
        //       `n = buckets - 1`, i.e. `RawTableInner::buckets() - 1`
2990
0
        //
2991
0
        // where: T0...T_n  - our stored data;
2992
0
        //        CT0...CT_n - control bytes or metadata for `data`.
2993
0
        let ctrl = NonNull::new_unchecked(self.ctrl(0));
2994
0
2995
0
        FullBucketsIndices {
2996
0
            // Load the first group
2997
0
            // SAFETY: See explanation above.
2998
0
            current_group: Group::load_aligned(ctrl.as_ptr()).match_full().into_iter(),
2999
0
            group_first_index: 0,
3000
0
            ctrl,
3001
0
            items: self.items,
3002
0
        }
3003
0
    }
3004
3005
    /// Allocates a new table of a different size and moves the contents of the
3006
    /// current table into it.
3007
    ///
3008
    /// This uses dynamic dispatch to reduce the amount of
3009
    /// code generated, but it is eliminated by LLVM optimizations when inlined.
3010
    ///
3011
    /// # Safety
3012
    ///
3013
    /// If any of the following conditions are violated, the result is
3014
    /// [`undefined behavior`]:
3015
    ///
3016
    /// * The `alloc` must be the same [`Allocator`] as the `Allocator` used
3017
    ///   to allocate this table;
3018
    ///
3019
    /// * The `layout` must be the same [`TableLayout`] as the `TableLayout`
3020
    ///   used to allocate this table;
3021
    ///
3022
    /// * The [`RawTableInner`] must have properly initialized control bytes.
3023
    ///
3024
    /// The caller of this function must ensure that `capacity >= self.items`
3025
    /// otherwise:
3026
    ///
3027
    /// * If `self.items != 0`, calling of this function with `capacity == 0`
3028
    ///   results in [`undefined behavior`].
3029
    ///
3030
    /// * If `capacity_to_buckets(capacity) < Group::WIDTH` and
3031
    ///   `self.items > capacity_to_buckets(capacity)` calling this function
3032
    ///   results in [`undefined behavior`].
3033
    ///
3034
    /// * If `capacity_to_buckets(capacity) >= Group::WIDTH` and
3035
    ///   `self.items > capacity_to_buckets(capacity)` calling this function
3036
    ///   are never return (will go into an infinite loop).
3037
    ///
3038
    /// Note: It is recommended (but not required) that the new table's `capacity`
3039
    /// be greater than or equal to `self.items`. In case if `capacity <= self.items`
3040
    /// this function can never return. See [`RawTableInner::find_insert_slot`] for
3041
    /// more information.
3042
    ///
3043
    /// [`RawTableInner::find_insert_slot`]: RawTableInner::find_insert_slot
3044
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3045
    #[allow(clippy::inline_always)]
3046
    #[inline(always)]
3047
0
    unsafe fn resize_inner<A>(
3048
0
        &mut self,
3049
0
        alloc: &A,
3050
0
        capacity: usize,
3051
0
        hasher: &dyn Fn(&mut Self, usize) -> u64,
3052
0
        fallibility: Fallibility,
3053
0
        layout: TableLayout,
3054
0
    ) -> Result<(), TryReserveError>
3055
0
    where
3056
0
        A: Allocator,
3057
0
    {
3058
        // SAFETY: We know for sure that `alloc` and `layout` matches the [`Allocator`] and [`TableLayout`]
3059
        // that were used to allocate this table.
3060
0
        let mut new_table = self.prepare_resize(alloc, layout, capacity, fallibility)?;
3061
3062
        // SAFETY: We know for sure that RawTableInner will outlive the
3063
        // returned `FullBucketsIndices` iterator, and the caller of this
3064
        // function ensures that the control bytes are properly initialized.
3065
0
        for full_byte_index in self.full_buckets_indices() {
3066
0
            // This may panic.
3067
0
            let hash = hasher(self, full_byte_index);
3068
0
3069
0
            // SAFETY:
3070
0
            // We can use a simpler version of insert() here since:
3071
0
            // 1. There are no DELETED entries.
3072
0
            // 2. We know there is enough space in the table.
3073
0
            // 3. All elements are unique.
3074
0
            // 4. The caller of this function guarantees that `capacity > 0`
3075
0
            //    so `new_table` must already have some allocated memory.
3076
0
            // 5. We set `growth_left` and `items` fields of the new table
3077
0
            //    after the loop.
3078
0
            // 6. We insert into the table, at the returned index, the data
3079
0
            //    matching the given hash immediately after calling this function.
3080
0
            let (new_index, _) = new_table.prepare_insert_slot(hash);
3081
0
3082
0
            // SAFETY:
3083
0
            //
3084
0
            // * `src` is valid for reads of `layout.size` bytes, since the
3085
0
            //   table is alive and the `full_byte_index` is guaranteed to be
3086
0
            //   within bounds (see `FullBucketsIndices::next_impl`);
3087
0
            //
3088
0
            // * `dst` is valid for writes of `layout.size` bytes, since the
3089
0
            //   caller ensures that `table_layout` matches the [`TableLayout`]
3090
0
            //   that was used to allocate old table and we have the `new_index`
3091
0
            //   returned by `prepare_insert_slot`.
3092
0
            //
3093
0
            // * Both `src` and `dst` are properly aligned.
3094
0
            //
3095
0
            // * Both `src` and `dst` point to different region of memory.
3096
0
            ptr::copy_nonoverlapping(
3097
0
                self.bucket_ptr(full_byte_index, layout.size),
3098
0
                new_table.bucket_ptr(new_index, layout.size),
3099
0
                layout.size,
3100
0
            );
3101
0
        }
3102
3103
        // The hash function didn't panic, so we can safely set the
3104
        // `growth_left` and `items` fields of the new table.
3105
0
        new_table.growth_left -= self.items;
3106
0
        new_table.items = self.items;
3107
0
3108
0
        // We successfully copied all elements without panicking. Now replace
3109
0
        // self with the new table. The old table will have its memory freed but
3110
0
        // the items will not be dropped (since they have been moved into the
3111
0
        // new table).
3112
0
        // SAFETY: The caller ensures that `table_layout` matches the [`TableLayout`]
3113
0
        // that was used to allocate this table.
3114
0
        mem::swap(self, &mut new_table);
3115
0
3116
0
        Ok(())
3117
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner12resize_innerNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner12resize_innerpEB8_
3118
3119
    /// Rehashes the contents of the table in place (i.e. without changing the
3120
    /// allocation).
3121
    ///
3122
    /// If `hasher` panics then some the table's contents may be lost.
3123
    ///
3124
    /// This uses dynamic dispatch to reduce the amount of
3125
    /// code generated, but it is eliminated by LLVM optimizations when inlined.
3126
    ///
3127
    /// # Safety
3128
    ///
3129
    /// If any of the following conditions are violated, the result is [`undefined behavior`]:
3130
    ///
3131
    /// * The `size_of` must be equal to the size of the elements stored in the table;
3132
    ///
3133
    /// * The `drop` function (`fn(*mut u8)`) must be the actual drop function of
3134
    ///   the elements stored in the table.
3135
    ///
3136
    /// * The [`RawTableInner`] has already been allocated;
3137
    ///
3138
    /// * The [`RawTableInner`] must have properly initialized control bytes.
3139
    ///
3140
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3141
    #[allow(clippy::inline_always)]
3142
    #[cfg_attr(feature = "inline-more", inline(always))]
3143
    #[cfg_attr(not(feature = "inline-more"), inline)]
3144
0
    unsafe fn rehash_in_place(
3145
0
        &mut self,
3146
0
        hasher: &dyn Fn(&mut Self, usize) -> u64,
3147
0
        size_of: usize,
3148
0
        drop: Option<fn(*mut u8)>,
3149
0
    ) {
3150
0
        // If the hash function panics then properly clean up any elements
3151
0
        // that we haven't rehashed yet. We unfortunately can't preserve the
3152
0
        // element since we lost their hash and have no way of recovering it
3153
0
        // without risking another panic.
3154
0
        self.prepare_rehash_in_place();
3155
0
3156
0
        let mut guard = guard(self, move |self_| {
3157
0
            if let Some(drop) = drop {
3158
0
                for i in 0..self_.buckets() {
3159
0
                    if *self_.ctrl(i) == DELETED {
3160
0
                        self_.set_ctrl(i, EMPTY);
3161
0
                        drop(self_.bucket_ptr(i, size_of));
3162
0
                        self_.items -= 1;
3163
0
                    }
3164
                }
3165
0
            }
3166
0
            self_.growth_left = bucket_mask_to_capacity(self_.bucket_mask) - self_.items;
3167
0
        });
Unexecuted instantiation: _RNCNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB7_13RawTableInner15rehash_in_place0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB7_13RawTableInner15rehash_in_place0B9_
3168
3169
        // At this point, DELETED elements are elements that we haven't
3170
        // rehashed yet. Find them and re-insert them at their ideal
3171
        // position.
3172
0
        'outer: for i in 0..guard.buckets() {
3173
0
            if *guard.ctrl(i) != DELETED {
3174
0
                continue;
3175
0
            }
3176
0
3177
0
            let i_p = guard.bucket_ptr(i, size_of);
3178
3179
            'inner: loop {
3180
                // Hash the current item
3181
0
                let hash = hasher(*guard, i);
3182
0
3183
0
                // Search for a suitable place to put it
3184
0
                //
3185
0
                // SAFETY: Caller of this function ensures that the control bytes
3186
0
                // are properly initialized.
3187
0
                let new_i = guard.find_insert_slot(hash).index;
3188
0
3189
0
                // Probing works by scanning through all of the control
3190
0
                // bytes in groups, which may not be aligned to the group
3191
0
                // size. If both the new and old position fall within the
3192
0
                // same unaligned group, then there is no benefit in moving
3193
0
                // it and we can just continue to the next item.
3194
0
                if likely(guard.is_in_same_group(i, new_i, hash)) {
3195
0
                    guard.set_ctrl_h2(i, hash);
3196
0
                    continue 'outer;
3197
0
                }
3198
0
3199
0
                let new_i_p = guard.bucket_ptr(new_i, size_of);
3200
0
3201
0
                // We are moving the current item to a new position. Write
3202
0
                // our H2 to the control byte of the new position.
3203
0
                let prev_ctrl = guard.replace_ctrl_h2(new_i, hash);
3204
0
                if prev_ctrl == EMPTY {
3205
0
                    guard.set_ctrl(i, EMPTY);
3206
0
                    // If the target slot is empty, simply move the current
3207
0
                    // element into the new slot and clear the old control
3208
0
                    // byte.
3209
0
                    ptr::copy_nonoverlapping(i_p, new_i_p, size_of);
3210
0
                    continue 'outer;
3211
                } else {
3212
                    // If the target slot is occupied, swap the two elements
3213
                    // and then continue processing the element that we just
3214
                    // swapped into the old slot.
3215
0
                    debug_assert_eq!(prev_ctrl, DELETED);
3216
0
                    ptr::swap_nonoverlapping(i_p, new_i_p, size_of);
3217
0
                    continue 'inner;
3218
                }
3219
            }
3220
        }
3221
3222
0
        guard.growth_left = bucket_mask_to_capacity(guard.bucket_mask) - guard.items;
3223
0
3224
0
        mem::forget(guard);
3225
0
    }
3226
3227
    /// Deallocates the table without dropping any entries.
3228
    ///
3229
    /// # Note
3230
    ///
3231
    /// This function must be called only after [`drop_elements`](RawTableInner::drop_elements),
3232
    /// else it can lead to leaking of memory. Also calling this function automatically
3233
    /// makes invalid (dangling) all instances of buckets ([`Bucket`]) and makes invalid
3234
    /// (dangling) the `ctrl` field of the table.
3235
    ///
3236
    /// # Safety
3237
    ///
3238
    /// If any of the following conditions are violated, the result is [`Undefined Behavior`]:
3239
    ///
3240
    /// * The [`RawTableInner`] has already been allocated;
3241
    ///
3242
    /// * The `alloc` must be the same [`Allocator`] as the `Allocator` that was used
3243
    ///   to allocate this table.
3244
    ///
3245
    /// * The `table_layout` must be the same [`TableLayout`] as the `TableLayout` that was used
3246
    ///   to allocate this table.
3247
    ///
3248
    /// See also [`GlobalAlloc::dealloc`] or [`Allocator::deallocate`] for more  information.
3249
    ///
3250
    /// [`Undefined Behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3251
    /// [`GlobalAlloc::dealloc`]: https://doc.rust-lang.org/alloc/alloc/trait.GlobalAlloc.html#tymethod.dealloc
3252
    /// [`Allocator::deallocate`]: https://doc.rust-lang.org/alloc/alloc/trait.Allocator.html#tymethod.deallocate
3253
    #[inline]
3254
0
    unsafe fn free_buckets<A>(&mut self, alloc: &A, table_layout: TableLayout)
3255
0
    where
3256
0
        A: Allocator,
3257
0
    {
3258
0
        // SAFETY: The caller must uphold the safety contract for `free_buckets`
3259
0
        // method.
3260
0
        let (ptr, layout) = self.allocation_info(table_layout);
3261
0
        alloc.deallocate(ptr, layout);
3262
0
    }
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner12free_bucketsNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB6_13RawTableInner12free_bucketspEB8_
3263
3264
    /// Returns a pointer to the allocated memory and the layout that was used to
3265
    /// allocate the table.
3266
    ///
3267
    /// # Safety
3268
    ///
3269
    /// Caller of this function must observe the following safety rules:
3270
    ///
3271
    /// * The [`RawTableInner`] has already been allocated, otherwise
3272
    ///   calling this function results in [`undefined behavior`]
3273
    ///
3274
    /// * The `table_layout` must be the same [`TableLayout`] as the `TableLayout`
3275
    ///   that was used to allocate this table. Failure to comply with this condition
3276
    ///   may result in [`undefined behavior`].
3277
    ///
3278
    /// See also [`GlobalAlloc::dealloc`] or [`Allocator::deallocate`] for more  information.
3279
    ///
3280
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3281
    /// [`GlobalAlloc::dealloc`]: https://doc.rust-lang.org/alloc/alloc/trait.GlobalAlloc.html#tymethod.dealloc
3282
    /// [`Allocator::deallocate`]: https://doc.rust-lang.org/alloc/alloc/trait.Allocator.html#tymethod.deallocate
3283
    #[inline]
3284
0
    unsafe fn allocation_info(&self, table_layout: TableLayout) -> (NonNull<u8>, Layout) {
3285
0
        debug_assert!(
3286
0
            !self.is_empty_singleton(),
3287
0
            "this function can only be called on non-empty tables"
3288
        );
3289
3290
        // Avoid `Option::unwrap_or_else` because it bloats LLVM IR.
3291
0
        let (layout, ctrl_offset) = match table_layout.calculate_layout_for(self.buckets()) {
3292
0
            Some(lco) => lco,
3293
0
            None => unsafe { hint::unreachable_unchecked() },
3294
        };
3295
0
        (
3296
0
            // SAFETY: The caller must uphold the safety contract for `allocation_info` method.
3297
0
            unsafe { NonNull::new_unchecked(self.ctrl.as_ptr().sub(ctrl_offset)) },
3298
0
            layout,
3299
0
        )
3300
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner15allocation_infoCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner15allocation_infoB7_
3301
3302
    /// Returns a pointer to the allocated memory and the layout that was used to
3303
    /// allocate the table. If [`RawTableInner`] has not been allocated, this
3304
    /// function return `dangling` pointer and `()` (unit) layout.
3305
    ///
3306
    /// # Safety
3307
    ///
3308
    /// The `table_layout` must be the same [`TableLayout`] as the `TableLayout`
3309
    /// that was used to allocate this table. Failure to comply with this condition
3310
    /// may result in [`undefined behavior`].
3311
    ///
3312
    /// See also [`GlobalAlloc::dealloc`] or [`Allocator::deallocate`] for more  information.
3313
    ///
3314
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3315
    /// [`GlobalAlloc::dealloc`]: https://doc.rust-lang.org/alloc/alloc/trait.GlobalAlloc.html#tymethod.dealloc
3316
    /// [`Allocator::deallocate`]: https://doc.rust-lang.org/alloc/alloc/trait.Allocator.html#tymethod.deallocate
3317
    #[cfg(feature = "raw")]
3318
    unsafe fn allocation_info_or_zero(&self, table_layout: TableLayout) -> (NonNull<u8>, Layout) {
3319
        if self.is_empty_singleton() {
3320
            (NonNull::dangling(), Layout::new::<()>())
3321
        } else {
3322
            // SAFETY:
3323
            // 1. We have checked that our table is allocated.
3324
            // 2. The caller ensures that `table_layout` matches the [`TableLayout`]
3325
            // that was used to allocate this table.
3326
            unsafe { self.allocation_info(table_layout) }
3327
        }
3328
    }
3329
3330
    /// Marks all table buckets as empty without dropping their contents.
3331
    #[inline]
3332
0
    fn clear_no_drop(&mut self) {
3333
0
        if !self.is_empty_singleton() {
3334
0
            unsafe {
3335
0
                self.ctrl(0).write_bytes(EMPTY, self.num_ctrl_bytes());
3336
0
            }
3337
0
        }
3338
0
        self.items = 0;
3339
0
        self.growth_left = bucket_mask_to_capacity(self.bucket_mask);
3340
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner13clear_no_dropCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner13clear_no_dropB7_
3341
3342
    /// Erases the [`Bucket`]'s control byte at the given index so that it does not
3343
    /// triggered as full, decreases the `items` of the table and, if it can be done,
3344
    /// increases `self.growth_left`.
3345
    ///
3346
    /// This function does not actually erase / drop the [`Bucket`] itself, i.e. it
3347
    /// does not make any changes to the `data` parts of the table. The caller of this
3348
    /// function must take care to properly drop the `data`, otherwise calling this
3349
    /// function may result in a memory leak.
3350
    ///
3351
    /// # Safety
3352
    ///
3353
    /// You must observe the following safety rules when calling this function:
3354
    ///
3355
    /// * The [`RawTableInner`] has already been allocated;
3356
    ///
3357
    /// * It must be the full control byte at the given position;
3358
    ///
3359
    /// * The `index` must not be greater than the `RawTableInner.bucket_mask`, i.e.
3360
    ///   `index <= RawTableInner.bucket_mask` or, in other words, `(index + 1)` must
3361
    ///   be no greater than the number returned by the function [`RawTableInner::buckets`].
3362
    ///
3363
    /// Calling this function on a table that has not been allocated results in [`undefined behavior`].
3364
    ///
3365
    /// Calling this function on a table with no elements is unspecified, but calling subsequent
3366
    /// functions is likely to result in [`undefined behavior`] due to overflow subtraction
3367
    /// (`self.items -= 1 cause overflow when self.items == 0`).
3368
    ///
3369
    /// See also [`Bucket::as_ptr`] method, for more information about of properly removing
3370
    /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`].
3371
    ///
3372
    /// [`RawTableInner::buckets`]: RawTableInner::buckets
3373
    /// [`Bucket::as_ptr`]: Bucket::as_ptr
3374
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3375
    #[inline]
3376
0
    unsafe fn erase(&mut self, index: usize) {
3377
0
        debug_assert!(self.is_bucket_full(index));
3378
3379
        // This is the same as `index.wrapping_sub(Group::WIDTH) % self.buckets()` because
3380
        // the number of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`.
3381
0
        let index_before = index.wrapping_sub(Group::WIDTH) & self.bucket_mask;
3382
0
        // SAFETY:
3383
0
        // - The caller must uphold the safety contract for `erase` method;
3384
0
        // - `index_before` is guaranteed to be in range due to masking with `self.bucket_mask`
3385
0
        let empty_before = Group::load(self.ctrl(index_before)).match_empty();
3386
0
        let empty_after = Group::load(self.ctrl(index)).match_empty();
3387
3388
        // Inserting and searching in the map is performed by two key functions:
3389
        //
3390
        // - The `find_insert_slot` function that looks up the index of any `EMPTY` or `DELETED`
3391
        //   slot in a group to be able to insert. If it doesn't find an `EMPTY` or `DELETED`
3392
        //   slot immediately in the first group, it jumps to the next `Group` looking for it,
3393
        //   and so on until it has gone through all the groups in the control bytes.
3394
        //
3395
        // - The `find_inner` function that looks for the index of the desired element by looking
3396
        //   at all the `FULL` bytes in the group. If it did not find the element right away, and
3397
        //   there is no `EMPTY` byte in the group, then this means that the `find_insert_slot`
3398
        //   function may have found a suitable slot in the next group. Therefore, `find_inner`
3399
        //   jumps further, and if it does not find the desired element and again there is no `EMPTY`
3400
        //   byte, then it jumps further, and so on. The search stops only if `find_inner` function
3401
        //   finds the desired element or hits an `EMPTY` slot/byte.
3402
        //
3403
        // Accordingly, this leads to two consequences:
3404
        //
3405
        // - The map must have `EMPTY` slots (bytes);
3406
        //
3407
        // - You can't just mark the byte to be erased as `EMPTY`, because otherwise the `find_inner`
3408
        //   function may stumble upon an `EMPTY` byte before finding the desired element and stop
3409
        //   searching.
3410
        //
3411
        // Thus it is necessary to check all bytes after and before the erased element. If we are in
3412
        // a contiguous `Group` of `FULL` or `DELETED` bytes (the number of `FULL` or `DELETED` bytes
3413
        // before and after is greater than or equal to `Group::WIDTH`), then we must mark our byte as
3414
        // `DELETED` in order for the `find_inner` function to go further. On the other hand, if there
3415
        // is at least one `EMPTY` slot in the `Group`, then the `find_inner` function will still stumble
3416
        // upon an `EMPTY` byte, so we can safely mark our erased byte as `EMPTY` as well.
3417
        //
3418
        // Finally, since `index_before == (index.wrapping_sub(Group::WIDTH) & self.bucket_mask) == index`
3419
        // and given all of the above, tables smaller than the group width (self.buckets() < Group::WIDTH)
3420
        // cannot have `DELETED` bytes.
3421
        //
3422
        // Note that in this context `leading_zeros` refers to the bytes at the end of a group, while
3423
        // `trailing_zeros` refers to the bytes at the beginning of a group.
3424
0
        let ctrl = if empty_before.leading_zeros() + empty_after.trailing_zeros() >= Group::WIDTH {
3425
0
            DELETED
3426
        } else {
3427
0
            self.growth_left += 1;
3428
0
            EMPTY
3429
        };
3430
        // SAFETY: the caller must uphold the safety contract for `erase` method.
3431
0
        self.set_ctrl(index, ctrl);
3432
0
        self.items -= 1;
3433
0
    }
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner5eraseCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMsa_NtCsgkA6tlBCRmB_9hashbrown3rawNtB5_13RawTableInner5eraseB7_
3434
}
3435
3436
impl<T: Clone, A: Allocator + Clone> Clone for RawTable<T, A> {
3437
0
    fn clone(&self) -> Self {
3438
0
        if self.table.is_empty_singleton() {
3439
0
            Self::new_in(self.alloc.clone())
3440
        } else {
3441
            unsafe {
3442
                // Avoid `Result::ok_or_else` because it bloats LLVM IR.
3443
                //
3444
                // SAFETY: This is safe as we are taking the size of an already allocated table
3445
                // and therefore сapacity overflow cannot occur, `self.table.buckets()` is power
3446
                // of two and all allocator errors will be caught inside `RawTableInner::new_uninitialized`.
3447
0
                let mut new_table = match Self::new_uninitialized(
3448
0
                    self.alloc.clone(),
3449
0
                    self.table.buckets(),
3450
0
                    Fallibility::Infallible,
3451
0
                ) {
3452
0
                    Ok(table) => table,
3453
0
                    Err(_) => hint::unreachable_unchecked(),
3454
                };
3455
3456
                // Cloning elements may fail (the clone function may panic). But we don't
3457
                // need to worry about uninitialized control bits, since:
3458
                // 1. The number of items (elements) in the table is zero, which means that
3459
                //    the control bits will not be readed by Drop function.
3460
                // 2. The `clone_from_spec` method will first copy all control bits from
3461
                //    `self` (thus initializing them). But this will not affect the `Drop`
3462
                //    function, since the `clone_from_spec` function sets `items` only after
3463
                //    successfully clonning all elements.
3464
0
                new_table.clone_from_spec(self);
3465
0
                new_table
3466
            }
3467
        }
3468
0
    }
3469
3470
0
    fn clone_from(&mut self, source: &Self) {
3471
0
        if source.table.is_empty_singleton() {
3472
0
            let mut old_inner = mem::replace(&mut self.table, RawTableInner::NEW);
3473
0
            unsafe {
3474
0
                // SAFETY:
3475
0
                // 1. We call the function only once;
3476
0
                // 2. We know for sure that `alloc` and `table_layout` matches the [`Allocator`]
3477
0
                //    and [`TableLayout`] that were used to allocate this table.
3478
0
                // 3. If any elements' drop function panics, then there will only be a memory leak,
3479
0
                //    because we have replaced the inner table with a new one.
3480
0
                old_inner.drop_inner_table::<T, _>(&self.alloc, Self::TABLE_LAYOUT);
3481
0
            }
3482
        } else {
3483
            unsafe {
3484
                // Make sure that if any panics occurs, we clear the table and
3485
                // leave it in an empty state.
3486
0
                let mut self_ = guard(self, |self_| {
3487
0
                    self_.clear_no_drop();
3488
0
                });
3489
0
3490
0
                // First, drop all our elements without clearing the control
3491
0
                // bytes. If this panics then the scope guard will clear the
3492
0
                // table, leaking any elements that were not dropped yet.
3493
0
                //
3494
0
                // This leak is unavoidable: we can't try dropping more elements
3495
0
                // since this could lead to another panic and abort the process.
3496
0
                //
3497
0
                // SAFETY: If something gets wrong we clear our table right after
3498
0
                // dropping the elements, so there is no double drop, since `items`
3499
0
                // will be equal to zero.
3500
0
                self_.table.drop_elements::<T>();
3501
0
3502
0
                // If necessary, resize our table to match the source.
3503
0
                if self_.buckets() != source.buckets() {
3504
0
                    let new_inner = match RawTableInner::new_uninitialized(
3505
0
                        &self_.alloc,
3506
0
                        Self::TABLE_LAYOUT,
3507
0
                        source.buckets(),
3508
0
                        Fallibility::Infallible,
3509
0
                    ) {
3510
0
                        Ok(table) => table,
3511
0
                        Err(_) => hint::unreachable_unchecked(),
3512
                    };
3513
                    // Replace the old inner with new uninitialized one. It's ok, since if something gets
3514
                    // wrong `ScopeGuard` will initialize all control bytes and leave empty table.
3515
0
                    let mut old_inner = mem::replace(&mut self_.table, new_inner);
3516
0
                    if !old_inner.is_empty_singleton() {
3517
0
                        // SAFETY:
3518
0
                        // 1. We have checked that our table is allocated.
3519
0
                        // 2. We know for sure that `alloc` and `table_layout` matches
3520
0
                        // the [`Allocator`] and [`TableLayout`] that were used to allocate this table.
3521
0
                        old_inner.free_buckets(&self_.alloc, Self::TABLE_LAYOUT);
3522
0
                    }
3523
0
                }
3524
3525
                // Cloning elements may fail (the clone function may panic), but the `ScopeGuard`
3526
                // inside the `clone_from_impl` function will take care of that, dropping all
3527
                // cloned elements if necessary. Our `ScopeGuard` will clear the table.
3528
0
                self_.clone_from_spec(source);
3529
0
3530
0
                // Disarm the scope guard if cloning was successful.
3531
0
                ScopeGuard::into_inner(self_);
3532
            }
3533
        }
3534
0
    }
3535
}
3536
3537
/// Specialization of `clone_from` for `Copy` types
3538
trait RawTableClone {
3539
    unsafe fn clone_from_spec(&mut self, source: &Self);
3540
}
3541
impl<T: Clone, A: Allocator + Clone> RawTableClone for RawTable<T, A> {
3542
    default_fn! {
3543
        #[cfg_attr(feature = "inline-more", inline)]
3544
0
        unsafe fn clone_from_spec(&mut self, source: &Self) {
3545
0
            self.clone_from_impl(source);
3546
0
        }
3547
    }
3548
}
3549
#[cfg(feature = "nightly")]
3550
impl<T: Copy, A: Allocator + Clone> RawTableClone for RawTable<T, A> {
3551
    #[cfg_attr(feature = "inline-more", inline)]
3552
    unsafe fn clone_from_spec(&mut self, source: &Self) {
3553
        source
3554
            .table
3555
            .ctrl(0)
3556
            .copy_to_nonoverlapping(self.table.ctrl(0), self.table.num_ctrl_bytes());
3557
        source
3558
            .data_start()
3559
            .as_ptr()
3560
            .copy_to_nonoverlapping(self.data_start().as_ptr(), self.table.buckets());
3561
3562
        self.table.items = source.table.items;
3563
        self.table.growth_left = source.table.growth_left;
3564
    }
3565
}
3566
3567
impl<T: Clone, A: Allocator + Clone> RawTable<T, A> {
3568
    /// Common code for clone and clone_from. Assumes:
3569
    /// - `self.buckets() == source.buckets()`.
3570
    /// - Any existing elements have been dropped.
3571
    /// - The control bytes are not initialized yet.
3572
    #[cfg_attr(feature = "inline-more", inline)]
3573
0
    unsafe fn clone_from_impl(&mut self, source: &Self) {
3574
0
        // Copy the control bytes unchanged. We do this in a single pass
3575
0
        source
3576
0
            .table
3577
0
            .ctrl(0)
3578
0
            .copy_to_nonoverlapping(self.table.ctrl(0), self.table.num_ctrl_bytes());
3579
0
3580
0
        // The cloning of elements may panic, in which case we need
3581
0
        // to make sure we drop only the elements that have been
3582
0
        // cloned so far.
3583
0
        let mut guard = guard((0, &mut *self), |(index, self_)| {
3584
0
            if T::NEEDS_DROP {
3585
0
                for i in 0..*index {
3586
0
                    if self_.is_bucket_full(i) {
3587
0
                        self_.bucket(i).drop();
3588
0
                    }
3589
                }
3590
0
            }
3591
0
        });
3592
3593
0
        for from in source.iter() {
3594
0
            let index = source.bucket_index(&from);
3595
0
            let to = guard.1.bucket(index);
3596
0
            to.write(from.as_ref().clone());
3597
0
3598
0
            // Update the index in case we need to unwind.
3599
0
            guard.0 = index + 1;
3600
0
        }
3601
3602
        // Successfully cloned all items, no need to clean up.
3603
0
        mem::forget(guard);
3604
0
3605
0
        self.table.items = source.table.items;
3606
0
        self.table.growth_left = source.table.growth_left;
3607
0
    }
3608
3609
    /// Variant of `clone_from` to use when a hasher is available.
3610
    #[cfg(feature = "raw")]
3611
    pub fn clone_from_with_hasher(&mut self, source: &Self, hasher: impl Fn(&T) -> u64) {
3612
        // If we have enough capacity in the table, just clear it and insert
3613
        // elements one by one. We don't do this if we have the same number of
3614
        // buckets as the source since we can just copy the contents directly
3615
        // in that case.
3616
        if self.table.buckets() != source.table.buckets()
3617
            && bucket_mask_to_capacity(self.table.bucket_mask) >= source.len()
3618
        {
3619
            self.clear();
3620
3621
            let mut guard_self = guard(&mut *self, |self_| {
3622
                // Clear the partially copied table if a panic occurs, otherwise
3623
                // items and growth_left will be out of sync with the contents
3624
                // of the table.
3625
                self_.clear();
3626
            });
3627
3628
            unsafe {
3629
                for item in source.iter() {
3630
                    // This may panic.
3631
                    let item = item.as_ref().clone();
3632
                    let hash = hasher(&item);
3633
3634
                    // We can use a simpler version of insert() here since:
3635
                    // - there are no DELETED entries.
3636
                    // - we know there is enough space in the table.
3637
                    // - all elements are unique.
3638
                    let (index, _) = guard_self.table.prepare_insert_slot(hash);
3639
                    guard_self.bucket(index).write(item);
3640
                }
3641
            }
3642
3643
            // Successfully cloned all items, no need to clean up.
3644
            mem::forget(guard_self);
3645
3646
            self.table.items = source.table.items;
3647
            self.table.growth_left -= source.table.items;
3648
        } else {
3649
            self.clone_from(source);
3650
        }
3651
    }
3652
}
3653
3654
impl<T, A: Allocator + Default> Default for RawTable<T, A> {
3655
    #[inline]
3656
0
    fn default() -> Self {
3657
0
        Self::new_in(Default::default())
3658
0
    }
3659
}
3660
3661
#[cfg(feature = "nightly")]
3662
unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawTable<T, A> {
3663
    #[cfg_attr(feature = "inline-more", inline)]
3664
    fn drop(&mut self) {
3665
        unsafe {
3666
            // SAFETY:
3667
            // 1. We call the function only once;
3668
            // 2. We know for sure that `alloc` and `table_layout` matches the [`Allocator`]
3669
            //    and [`TableLayout`] that were used to allocate this table.
3670
            // 3. If the drop function of any elements fails, then only a memory leak will occur,
3671
            //    and we don't care because we are inside the `Drop` function of the `RawTable`,
3672
            //    so there won't be any table left in an inconsistent state.
3673
            self.table
3674
                .drop_inner_table::<T, _>(&self.alloc, Self::TABLE_LAYOUT);
3675
        }
3676
    }
3677
}
3678
#[cfg(not(feature = "nightly"))]
3679
impl<T, A: Allocator> Drop for RawTable<T, A> {
3680
    #[cfg_attr(feature = "inline-more", inline)]
3681
0
    fn drop(&mut self) {
3682
0
        unsafe {
3683
0
            // SAFETY:
3684
0
            // 1. We call the function only once;
3685
0
            // 2. We know for sure that `alloc` and `table_layout` matches the [`Allocator`]
3686
0
            //    and [`TableLayout`] that were used to allocate this table.
3687
0
            // 3. If the drop function of any elements fails, then only a memory leak will occur,
3688
0
            //    and we don't care because we are inside the `Drop` function of the `RawTable`,
3689
0
            //    so there won't be any table left in an inconsistent state.
3690
0
            self.table
3691
0
                .drop_inner_table::<T, _>(&self.alloc, Self::TABLE_LAYOUT);
3692
0
        }
3693
0
    }
Unexecuted instantiation: _RNvXsf_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawTableTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEENtNtNtB1v_3ops4drop4Drop4dropB2w_
Unexecuted instantiation: _RNvXININtCsgkA6tlBCRmB_9hashbrown3rawsf_0ppEINtB5_8RawTableppENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropB7_
3694
}
3695
3696
impl<T, A: Allocator> IntoIterator for RawTable<T, A> {
3697
    type Item = T;
3698
    type IntoIter = RawIntoIter<T, A>;
3699
3700
    #[cfg_attr(feature = "inline-more", inline)]
3701
0
    fn into_iter(self) -> RawIntoIter<T, A> {
3702
0
        unsafe {
3703
0
            let iter = self.iter();
3704
0
            self.into_iter_from(iter)
3705
0
        }
3706
0
    }
3707
}
3708
3709
/// Iterator over a sub-range of a table. Unlike `RawIter` this iterator does
3710
/// not track an item count.
3711
pub(crate) struct RawIterRange<T> {
3712
    // Mask of full buckets in the current group. Bits are cleared from this
3713
    // mask as each element is processed.
3714
    current_group: BitMaskIter,
3715
3716
    // Pointer to the buckets for the current group.
3717
    data: Bucket<T>,
3718
3719
    // Pointer to the next group of control bytes,
3720
    // Must be aligned to the group size.
3721
    next_ctrl: *const u8,
3722
3723
    // Pointer one past the last control byte of this range.
3724
    end: *const u8,
3725
}
3726
3727
impl<T> RawIterRange<T> {
3728
    /// Returns a `RawIterRange` covering a subset of a table.
3729
    ///
3730
    /// # Safety
3731
    ///
3732
    /// If any of the following conditions are violated, the result is
3733
    /// [`undefined behavior`]:
3734
    ///
3735
    /// * `ctrl` must be [valid] for reads, i.e. table outlives the `RawIterRange`;
3736
    ///
3737
    /// * `ctrl` must be properly aligned to the group size (Group::WIDTH);
3738
    ///
3739
    /// * `ctrl` must point to the array of properly initialized control bytes;
3740
    ///
3741
    /// * `data` must be the [`Bucket`] at the `ctrl` index in the table;
3742
    ///
3743
    /// * the value of `len` must be less than or equal to the number of table buckets,
3744
    ///   and the returned value of `ctrl.as_ptr().add(len).offset_from(ctrl.as_ptr())`
3745
    ///   must be positive.
3746
    ///
3747
    /// * The `ctrl.add(len)` pointer must be either in bounds or one
3748
    ///   byte past the end of the same [allocated table].
3749
    ///
3750
    /// * The `len` must be a power of two.
3751
    ///
3752
    /// [valid]: https://doc.rust-lang.org/std/ptr/index.html#safety
3753
    /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3754
    #[cfg_attr(feature = "inline-more", inline)]
3755
0
    unsafe fn new(ctrl: *const u8, data: Bucket<T>, len: usize) -> Self {
3756
0
        debug_assert_ne!(len, 0);
3757
0
        debug_assert_eq!(ctrl as usize % Group::WIDTH, 0);
3758
        // SAFETY: The caller must uphold the safety rules for the [`RawIterRange::new`]
3759
0
        let end = ctrl.add(len);
3760
0
3761
0
        // Load the first group and advance ctrl to point to the next group
3762
0
        // SAFETY: The caller must uphold the safety rules for the [`RawIterRange::new`]
3763
0
        let current_group = Group::load_aligned(ctrl).match_full();
3764
0
        let next_ctrl = ctrl.add(Group::WIDTH);
3765
0
3766
0
        Self {
3767
0
            current_group: current_group.into_iter(),
3768
0
            data,
3769
0
            next_ctrl,
3770
0
            end,
3771
0
        }
3772
0
    }
Unexecuted instantiation: _RNvMsh_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_12RawIterRangeTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBX_8LruEntryB1m_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE3newB2B_
Unexecuted instantiation: _RNvMsh_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_12RawIterRangepE3newB7_
3773
3774
    /// Splits a `RawIterRange` into two halves.
3775
    ///
3776
    /// Returns `None` if the remaining range is smaller than or equal to the
3777
    /// group width.
3778
    #[cfg_attr(feature = "inline-more", inline)]
3779
    #[cfg(feature = "rayon")]
3780
    pub(crate) fn split(mut self) -> (Self, Option<RawIterRange<T>>) {
3781
        unsafe {
3782
            if self.end <= self.next_ctrl {
3783
                // Nothing to split if the group that we are current processing
3784
                // is the last one.
3785
                (self, None)
3786
            } else {
3787
                // len is the remaining number of elements after the group that
3788
                // we are currently processing. It must be a multiple of the
3789
                // group size (small tables are caught by the check above).
3790
                let len = offset_from(self.end, self.next_ctrl);
3791
                debug_assert_eq!(len % Group::WIDTH, 0);
3792
3793
                // Split the remaining elements into two halves, but round the
3794
                // midpoint down in case there is an odd number of groups
3795
                // remaining. This ensures that:
3796
                // - The tail is at least 1 group long.
3797
                // - The split is roughly even considering we still have the
3798
                //   current group to process.
3799
                let mid = (len / 2) & !(Group::WIDTH - 1);
3800
3801
                let tail = Self::new(
3802
                    self.next_ctrl.add(mid),
3803
                    self.data.next_n(Group::WIDTH).next_n(mid),
3804
                    len - mid,
3805
                );
3806
                debug_assert_eq!(
3807
                    self.data.next_n(Group::WIDTH).next_n(mid).ptr,
3808
                    tail.data.ptr
3809
                );
3810
                debug_assert_eq!(self.end, tail.end);
3811
                self.end = self.next_ctrl.add(mid);
3812
                debug_assert_eq!(self.end.add(Group::WIDTH), tail.next_ctrl);
3813
                (self, Some(tail))
3814
            }
3815
        }
3816
    }
3817
3818
    /// # Safety
3819
    /// If DO_CHECK_PTR_RANGE is false, caller must ensure that we never try to iterate
3820
    /// after yielding all elements.
3821
    #[cfg_attr(feature = "inline-more", inline)]
3822
0
    unsafe fn next_impl<const DO_CHECK_PTR_RANGE: bool>(&mut self) -> Option<Bucket<T>> {
3823
        loop {
3824
0
            if let Some(index) = self.current_group.next() {
3825
0
                return Some(self.data.next_n(index));
3826
0
            }
3827
0
3828
0
            if DO_CHECK_PTR_RANGE && self.next_ctrl >= self.end {
3829
0
                return None;
3830
0
            }
3831
0
3832
0
            // We might read past self.end up to the next group boundary,
3833
0
            // but this is fine because it only occurs on tables smaller
3834
0
            // than the group size where the trailing control bytes are all
3835
0
            // EMPTY. On larger tables self.end is guaranteed to be aligned
3836
0
            // to the group size (since tables are power-of-two sized).
3837
0
            self.current_group = Group::load_aligned(self.next_ctrl).match_full().into_iter();
3838
0
            self.data = self.data.next_n(Group::WIDTH);
3839
0
            self.next_ctrl = self.next_ctrl.add(Group::WIDTH);
3840
        }
3841
0
    }
Unexecuted instantiation: _RINvMsh_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_12RawIterRangeTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBY_8LruEntryB1n_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE9next_implKb0_EB2C_
Unexecuted instantiation: _RINvMsh_NtCsgkA6tlBCRmB_9hashbrown3rawINtB6_12RawIterRangepE9next_implKpEB8_
3842
3843
    /// Folds every element into an accumulator by applying an operation,
3844
    /// returning the final result.
3845
    ///
3846
    /// `fold_impl()` takes three arguments: the number of items remaining in
3847
    /// the iterator, an initial value, and a closure with two arguments: an
3848
    /// 'accumulator', and an element. The closure returns the value that the
3849
    /// accumulator should have for the next iteration.
3850
    ///
3851
    /// The initial value is the value the accumulator will have on the first call.
3852
    ///
3853
    /// After applying this closure to every element of the iterator, `fold_impl()`
3854
    /// returns the accumulator.
3855
    ///
3856
    /// # Safety
3857
    ///
3858
    /// If any of the following conditions are violated, the result is
3859
    /// [`Undefined Behavior`]:
3860
    ///
3861
    /// * The [`RawTableInner`] / [`RawTable`] must be alive and not moved,
3862
    ///   i.e. table outlives the `RawIterRange`;
3863
    ///
3864
    /// * The provided `n` value must match the actual number of items
3865
    ///   in the table.
3866
    ///
3867
    /// [`Undefined Behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
3868
    #[allow(clippy::while_let_on_iterator)]
3869
    #[cfg_attr(feature = "inline-more", inline)]
3870
0
    unsafe fn fold_impl<F, B>(mut self, mut n: usize, mut acc: B, mut f: F) -> B
3871
0
    where
3872
0
        F: FnMut(B, Bucket<T>) -> B,
3873
0
    {
3874
        loop {
3875
0
            while let Some(index) = self.current_group.next() {
3876
                // The returned `index` will always be in the range `0..Group::WIDTH`,
3877
                // so that calling `self.data.next_n(index)` is safe (see detailed explanation below).
3878
0
                debug_assert!(n != 0);
3879
0
                let bucket = self.data.next_n(index);
3880
0
                acc = f(acc, bucket);
3881
0
                n -= 1;
3882
            }
3883
3884
0
            if n == 0 {
3885
0
                return acc;
3886
0
            }
3887
0
3888
0
            // SAFETY: The caller of this function ensures that:
3889
0
            //
3890
0
            // 1. The provided `n` value matches the actual number of items in the table;
3891
0
            // 2. The table is alive and did not moved.
3892
0
            //
3893
0
            // Taking the above into account, we always stay within the bounds, because:
3894
0
            //
3895
0
            // 1. For tables smaller than the group width (self.buckets() <= Group::WIDTH),
3896
0
            //    we will never end up in the given branch, since we should have already
3897
0
            //    yielded all the elements of the table.
3898
0
            //
3899
0
            // 2. For tables larger than the group width. The number of buckets is a
3900
0
            //    power of two (2 ^ n), Group::WIDTH is also power of two (2 ^ k). Since
3901
0
            //    `(2 ^ n) > (2 ^ k)`, than `(2 ^ n) % (2 ^ k) = 0`. As we start from the
3902
0
            //    start of the array of control bytes, and never try to iterate after
3903
0
            //    getting all the elements, the last `self.current_group` will read bytes
3904
0
            //    from the `self.buckets() - Group::WIDTH` index.  We know also that
3905
0
            //    `self.current_group.next()` will always retun indices within the range
3906
0
            //    `0..Group::WIDTH`.
3907
0
            //
3908
0
            //    Knowing all of the above and taking into account that we are synchronizing
3909
0
            //    the `self.data` index with the index we used to read the `self.current_group`,
3910
0
            //    the subsequent `self.data.next_n(index)` will always return a bucket with
3911
0
            //    an index number less than `self.buckets()`.
3912
0
            //
3913
0
            //    The last `self.next_ctrl`, whose index would be `self.buckets()`, will never
3914
0
            //    actually be read, since we should have already yielded all the elements of
3915
0
            //    the table.
3916
0
            self.current_group = Group::load_aligned(self.next_ctrl).match_full().into_iter();
3917
0
            self.data = self.data.next_n(Group::WIDTH);
3918
0
            self.next_ctrl = self.next_ctrl.add(Group::WIDTH);
3919
        }
3920
0
    }
3921
}
3922
3923
// We make raw iterators unconditionally Send and Sync, and let the PhantomData
3924
// in the actual iterator implementations determine the real Send/Sync bounds.
3925
unsafe impl<T> Send for RawIterRange<T> {}
3926
unsafe impl<T> Sync for RawIterRange<T> {}
3927
3928
impl<T> Clone for RawIterRange<T> {
3929
    #[cfg_attr(feature = "inline-more", inline)]
3930
0
    fn clone(&self) -> Self {
3931
0
        Self {
3932
0
            data: self.data.clone(),
3933
0
            next_ctrl: self.next_ctrl,
3934
0
            current_group: self.current_group,
3935
0
            end: self.end,
3936
0
        }
3937
0
    }
3938
}
3939
3940
impl<T> Iterator for RawIterRange<T> {
3941
    type Item = Bucket<T>;
3942
3943
    #[cfg_attr(feature = "inline-more", inline)]
3944
0
    fn next(&mut self) -> Option<Bucket<T>> {
3945
0
        unsafe {
3946
0
            // SAFETY: We set checker flag to true.
3947
0
            self.next_impl::<true>()
3948
0
        }
3949
0
    }
3950
3951
    #[inline]
3952
0
    fn size_hint(&self) -> (usize, Option<usize>) {
3953
        // We don't have an item count, so just guess based on the range size.
3954
0
        let remaining_buckets = if self.end > self.next_ctrl {
3955
0
            unsafe { offset_from(self.end, self.next_ctrl) }
3956
        } else {
3957
0
            0
3958
        };
3959
3960
        // Add a group width to include the group we are currently processing.
3961
0
        (0, Some(Group::WIDTH + remaining_buckets))
3962
0
    }
3963
}
3964
3965
impl<T> FusedIterator for RawIterRange<T> {}
3966
3967
/// Iterator which returns a raw pointer to every full bucket in the table.
3968
///
3969
/// For maximum flexibility this iterator is not bound by a lifetime, but you
3970
/// must observe several rules when using it:
3971
/// - You must not free the hash table while iterating (including via growing/shrinking).
3972
/// - It is fine to erase a bucket that has been yielded by the iterator.
3973
/// - Erasing a bucket that has not yet been yielded by the iterator may still
3974
///   result in the iterator yielding that bucket (unless `reflect_remove` is called).
3975
/// - It is unspecified whether an element inserted after the iterator was
3976
///   created will be yielded by that iterator (unless `reflect_insert` is called).
3977
/// - The order in which the iterator yields bucket is unspecified and may
3978
///   change in the future.
3979
pub struct RawIter<T> {
3980
    pub(crate) iter: RawIterRange<T>,
3981
    items: usize,
3982
}
3983
3984
impl<T> RawIter<T> {
3985
    /// Refresh the iterator so that it reflects a removal from the given bucket.
3986
    ///
3987
    /// For the iterator to remain valid, this method must be called once
3988
    /// for each removed bucket before `next` is called again.
3989
    ///
3990
    /// This method should be called _before_ the removal is made. It is not necessary to call this
3991
    /// method if you are removing an item that this iterator yielded in the past.
3992
    #[cfg(feature = "raw")]
3993
    pub unsafe fn reflect_remove(&mut self, b: &Bucket<T>) {
3994
        self.reflect_toggle_full(b, false);
3995
    }
3996
3997
    /// Refresh the iterator so that it reflects an insertion into the given bucket.
3998
    ///
3999
    /// For the iterator to remain valid, this method must be called once
4000
    /// for each insert before `next` is called again.
4001
    ///
4002
    /// This method does not guarantee that an insertion of a bucket with a greater
4003
    /// index than the last one yielded will be reflected in the iterator.
4004
    ///
4005
    /// This method should be called _after_ the given insert is made.
4006
    #[cfg(feature = "raw")]
4007
    pub unsafe fn reflect_insert(&mut self, b: &Bucket<T>) {
4008
        self.reflect_toggle_full(b, true);
4009
    }
4010
4011
    /// Refresh the iterator so that it reflects a change to the state of the given bucket.
4012
    #[cfg(feature = "raw")]
4013
    unsafe fn reflect_toggle_full(&mut self, b: &Bucket<T>, is_insert: bool) {
4014
        if b.as_ptr() > self.iter.data.as_ptr() {
4015
            // The iterator has already passed the bucket's group.
4016
            // So the toggle isn't relevant to this iterator.
4017
            return;
4018
        }
4019
4020
        if self.iter.next_ctrl < self.iter.end
4021
            && b.as_ptr() <= self.iter.data.next_n(Group::WIDTH).as_ptr()
4022
        {
4023
            // The iterator has not yet reached the bucket's group.
4024
            // We don't need to reload anything, but we do need to adjust the item count.
4025
4026
            if cfg!(debug_assertions) {
4027
                // Double-check that the user isn't lying to us by checking the bucket state.
4028
                // To do that, we need to find its control byte. We know that self.iter.data is
4029
                // at self.iter.next_ctrl - Group::WIDTH, so we work from there:
4030
                let offset = offset_from(self.iter.data.as_ptr(), b.as_ptr());
4031
                let ctrl = self.iter.next_ctrl.sub(Group::WIDTH).add(offset);
4032
                // This method should be called _before_ a removal, or _after_ an insert,
4033
                // so in both cases the ctrl byte should indicate that the bucket is full.
4034
                assert!(is_full(*ctrl));
4035
            }
4036
4037
            if is_insert {
4038
                self.items += 1;
4039
            } else {
4040
                self.items -= 1;
4041
            }
4042
4043
            return;
4044
        }
4045
4046
        // The iterator is at the bucket group that the toggled bucket is in.
4047
        // We need to do two things:
4048
        //
4049
        //  - Determine if the iterator already yielded the toggled bucket.
4050
        //    If it did, we're done.
4051
        //  - Otherwise, update the iterator cached group so that it won't
4052
        //    yield a to-be-removed bucket, or _will_ yield a to-be-added bucket.
4053
        //    We'll also need to update the item count accordingly.
4054
        if let Some(index) = self.iter.current_group.0.lowest_set_bit() {
4055
            let next_bucket = self.iter.data.next_n(index);
4056
            if b.as_ptr() > next_bucket.as_ptr() {
4057
                // The toggled bucket is "before" the bucket the iterator would yield next. We
4058
                // therefore don't need to do anything --- the iterator has already passed the
4059
                // bucket in question.
4060
                //
4061
                // The item count must already be correct, since a removal or insert "prior" to
4062
                // the iterator's position wouldn't affect the item count.
4063
            } else {
4064
                // The removed bucket is an upcoming bucket. We need to make sure it does _not_
4065
                // get yielded, and also that it's no longer included in the item count.
4066
                //
4067
                // NOTE: We can't just reload the group here, both since that might reflect
4068
                // inserts we've already passed, and because that might inadvertently unset the
4069
                // bits for _other_ removals. If we do that, we'd have to also decrement the
4070
                // item count for those other bits that we unset. But the presumably subsequent
4071
                // call to reflect for those buckets might _also_ decrement the item count.
4072
                // Instead, we _just_ flip the bit for the particular bucket the caller asked
4073
                // us to reflect.
4074
                let our_bit = offset_from(self.iter.data.as_ptr(), b.as_ptr());
4075
                let was_full = self.iter.current_group.flip(our_bit);
4076
                debug_assert_ne!(was_full, is_insert);
4077
4078
                if is_insert {
4079
                    self.items += 1;
4080
                } else {
4081
                    self.items -= 1;
4082
                }
4083
4084
                if cfg!(debug_assertions) {
4085
                    if b.as_ptr() == next_bucket.as_ptr() {
4086
                        // The removed bucket should no longer be next
4087
                        debug_assert_ne!(self.iter.current_group.0.lowest_set_bit(), Some(index));
4088
                    } else {
4089
                        // We should not have changed what bucket comes next.
4090
                        debug_assert_eq!(self.iter.current_group.0.lowest_set_bit(), Some(index));
4091
                    }
4092
                }
4093
            }
4094
        } else {
4095
            // We must have already iterated past the removed item.
4096
        }
4097
    }
4098
4099
0
    unsafe fn drop_elements(&mut self) {
4100
0
        if T::NEEDS_DROP && self.items != 0 {
4101
0
            for item in self {
4102
0
                item.drop();
4103
0
            }
4104
0
        }
4105
0
    }
Unexecuted instantiation: _RNvMsn_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_7RawIterTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBR_8LruEntryB1g_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEE13drop_elementsB2v_
Unexecuted instantiation: _RNvMsn_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_7RawIterpE13drop_elementsB7_
4106
}
4107
4108
impl<T> Clone for RawIter<T> {
4109
    #[cfg_attr(feature = "inline-more", inline)]
4110
0
    fn clone(&self) -> Self {
4111
0
        Self {
4112
0
            iter: self.iter.clone(),
4113
0
            items: self.items,
4114
0
        }
4115
0
    }
4116
}
4117
4118
impl<T> Iterator for RawIter<T> {
4119
    type Item = Bucket<T>;
4120
4121
    #[cfg_attr(feature = "inline-more", inline)]
4122
0
    fn next(&mut self) -> Option<Bucket<T>> {
4123
0
        // Inner iterator iterates over buckets
4124
0
        // so it can do unnecessary work if we already yielded all items.
4125
0
        if self.items == 0 {
4126
0
            return None;
4127
0
        }
4128
0
4129
0
        let nxt = unsafe {
4130
0
            // SAFETY: We check number of items to yield using `items` field.
4131
0
            self.iter.next_impl::<false>()
4132
0
        };
4133
0
4134
0
        debug_assert!(nxt.is_some());
4135
0
        self.items -= 1;
4136
0
4137
0
        nxt
4138
0
    }
Unexecuted instantiation: _RNvXsp_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_7RawIterTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBR_8LruEntryB1g_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEENtNtNtNtB1u_4iter6traits8iterator8Iterator4nextB2v_
Unexecuted instantiation: _RNvXININtCsgkA6tlBCRmB_9hashbrown3rawsp_0pEINtB5_7RawIterpENtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits8iterator8Iterator4nextB7_
4139
4140
    #[inline]
4141
0
    fn size_hint(&self) -> (usize, Option<usize>) {
4142
0
        (self.items, Some(self.items))
4143
0
    }
Unexecuted instantiation: _RNvXsp_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_7RawIterTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBR_8LruEntryB1g_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEENtNtNtNtB1u_4iter6traits8iterator8Iterator9size_hintB2v_
Unexecuted instantiation: _RNvXININtCsgkA6tlBCRmB_9hashbrown3rawsp_0pEINtB5_7RawIterpENtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits8iterator8Iterator9size_hintB7_
4144
4145
    #[inline]
4146
0
    fn fold<B, F>(self, init: B, f: F) -> B
4147
0
    where
4148
0
        Self: Sized,
4149
0
        F: FnMut(B, Self::Item) -> B,
4150
0
    {
4151
0
        unsafe { self.iter.fold_impl(self.items, init, f) }
4152
0
    }
4153
}
4154
4155
impl<T> ExactSizeIterator for RawIter<T> {}
4156
impl<T> FusedIterator for RawIter<T> {}
4157
4158
/// Iterator which returns an index of every full bucket in the table.
4159
///
4160
/// For maximum flexibility this iterator is not bound by a lifetime, but you
4161
/// must observe several rules when using it:
4162
/// - You must not free the hash table while iterating (including via growing/shrinking).
4163
/// - It is fine to erase a bucket that has been yielded by the iterator.
4164
/// - Erasing a bucket that has not yet been yielded by the iterator may still
4165
///   result in the iterator yielding index of that bucket.
4166
/// - It is unspecified whether an element inserted after the iterator was
4167
///   created will be yielded by that iterator.
4168
/// - The order in which the iterator yields indices of the buckets is unspecified
4169
///   and may change in the future.
4170
pub(crate) struct FullBucketsIndices {
4171
    // Mask of full buckets in the current group. Bits are cleared from this
4172
    // mask as each element is processed.
4173
    current_group: BitMaskIter,
4174
4175
    // Initial value of the bytes' indices of the current group (relative
4176
    // to the start of the control bytes).
4177
    group_first_index: usize,
4178
4179
    // Pointer to the current group of control bytes,
4180
    // Must be aligned to the group size (Group::WIDTH).
4181
    ctrl: NonNull<u8>,
4182
4183
    // Number of elements in the table.
4184
    items: usize,
4185
}
4186
4187
impl FullBucketsIndices {
4188
    /// Advances the iterator and returns the next value.
4189
    ///
4190
    /// # Safety
4191
    ///
4192
    /// If any of the following conditions are violated, the result is
4193
    /// [`Undefined Behavior`]:
4194
    ///
4195
    /// * The [`RawTableInner`] / [`RawTable`] must be alive and not moved,
4196
    ///   i.e. table outlives the `FullBucketsIndices`;
4197
    ///
4198
    /// * It never tries to iterate after getting all elements.
4199
    ///
4200
    /// [`Undefined Behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
4201
    #[inline(always)]
4202
0
    unsafe fn next_impl(&mut self) -> Option<usize> {
4203
        loop {
4204
0
            if let Some(index) = self.current_group.next() {
4205
                // The returned `self.group_first_index + index` will always
4206
                // be in the range `0..self.buckets()`. See explanation below.
4207
0
                return Some(self.group_first_index + index);
4208
0
            }
4209
0
4210
0
            // SAFETY: The caller of this function ensures that:
4211
0
            //
4212
0
            // 1. It never tries to iterate after getting all the elements;
4213
0
            // 2. The table is alive and did not moved;
4214
0
            // 3. The first `self.ctrl` pointed to the start of the array of control bytes.
4215
0
            //
4216
0
            // Taking the above into account, we always stay within the bounds, because:
4217
0
            //
4218
0
            // 1. For tables smaller than the group width (self.buckets() <= Group::WIDTH),
4219
0
            //    we will never end up in the given branch, since we should have already
4220
0
            //    yielded all the elements of the table.
4221
0
            //
4222
0
            // 2. For tables larger than the group width. The number of buckets is a
4223
0
            //    power of two (2 ^ n), Group::WIDTH is also power of two (2 ^ k). Since
4224
0
            //    `(2 ^ n) > (2 ^ k)`, than `(2 ^ n) % (2 ^ k) = 0`. As we start from the
4225
0
            //    the start of the array of control bytes, and never try to iterate after
4226
0
            //    getting all the elements, the last `self.ctrl` will be equal to
4227
0
            //    the `self.buckets() - Group::WIDTH`, so `self.current_group.next()`
4228
0
            //    will always contains indices within the range `0..Group::WIDTH`,
4229
0
            //    and subsequent `self.group_first_index + index` will always return a
4230
0
            //    number less than `self.buckets()`.
4231
0
            self.ctrl = NonNull::new_unchecked(self.ctrl.as_ptr().add(Group::WIDTH));
4232
0
4233
0
            // SAFETY: See explanation above.
4234
0
            self.current_group = Group::load_aligned(self.ctrl.as_ptr())
4235
0
                .match_full()
4236
0
                .into_iter();
4237
0
            self.group_first_index += Group::WIDTH;
4238
        }
4239
0
    }
4240
}
4241
4242
impl Iterator for FullBucketsIndices {
4243
    type Item = usize;
4244
4245
    /// Advances the iterator and returns the next value. It is up to
4246
    /// the caller to ensure that the `RawTable` outlives the `FullBucketsIndices`,
4247
    /// because we cannot make the `next` method unsafe.
4248
    #[inline(always)]
4249
0
    fn next(&mut self) -> Option<usize> {
4250
0
        // Return if we already yielded all items.
4251
0
        if self.items == 0 {
4252
0
            return None;
4253
0
        }
4254
0
4255
0
        let nxt = unsafe {
4256
0
            // SAFETY:
4257
0
            // 1. We check number of items to yield using `items` field.
4258
0
            // 2. The caller ensures that the table is alive and has not moved.
4259
0
            self.next_impl()
4260
0
        };
4261
0
4262
0
        debug_assert!(nxt.is_some());
4263
0
        self.items -= 1;
4264
0
4265
0
        nxt
4266
0
    }
4267
4268
    #[inline(always)]
4269
0
    fn size_hint(&self) -> (usize, Option<usize>) {
4270
0
        (self.items, Some(self.items))
4271
0
    }
4272
}
4273
4274
impl ExactSizeIterator for FullBucketsIndices {}
4275
impl FusedIterator for FullBucketsIndices {}
4276
4277
/// Iterator which consumes a table and returns elements.
4278
pub struct RawIntoIter<T, A: Allocator = Global> {
4279
    iter: RawIter<T>,
4280
    allocation: Option<(NonNull<u8>, Layout, A)>,
4281
    marker: PhantomData<T>,
4282
}
4283
4284
impl<T, A: Allocator> RawIntoIter<T, A> {
4285
    #[cfg_attr(feature = "inline-more", inline)]
4286
0
    pub fn iter(&self) -> RawIter<T> {
4287
0
        self.iter.clone()
4288
0
    }
4289
}
4290
4291
unsafe impl<T, A: Allocator> Send for RawIntoIter<T, A>
4292
where
4293
    T: Send,
4294
    A: Send,
4295
{
4296
}
4297
unsafe impl<T, A: Allocator> Sync for RawIntoIter<T, A>
4298
where
4299
    T: Sync,
4300
    A: Sync,
4301
{
4302
}
4303
4304
#[cfg(feature = "nightly")]
4305
unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawIntoIter<T, A> {
4306
    #[cfg_attr(feature = "inline-more", inline)]
4307
    fn drop(&mut self) {
4308
        unsafe {
4309
            // Drop all remaining elements
4310
            self.iter.drop_elements();
4311
4312
            // Free the table
4313
            if let Some((ptr, layout, ref alloc)) = self.allocation {
4314
                alloc.deallocate(ptr, layout);
4315
            }
4316
        }
4317
    }
4318
}
4319
#[cfg(not(feature = "nightly"))]
4320
impl<T, A: Allocator> Drop for RawIntoIter<T, A> {
4321
    #[cfg_attr(feature = "inline-more", inline)]
4322
0
    fn drop(&mut self) {
4323
0
        unsafe {
4324
0
            // Drop all remaining elements
4325
0
            self.iter.drop_elements();
4326
4327
            // Free the table
4328
0
            if let Some((ptr, layout, ref alloc)) = self.allocation {
4329
0
                alloc.deallocate(ptr, layout);
4330
0
            }
4331
        }
4332
0
    }
4333
}
4334
4335
impl<T, A: Allocator> Iterator for RawIntoIter<T, A> {
4336
    type Item = T;
4337
4338
    #[cfg_attr(feature = "inline-more", inline)]
4339
0
    fn next(&mut self) -> Option<T> {
4340
0
        unsafe { Some(self.iter.next()?.read()) }
4341
0
    }
4342
4343
    #[inline]
4344
0
    fn size_hint(&self) -> (usize, Option<usize>) {
4345
0
        self.iter.size_hint()
4346
0
    }
4347
}
4348
4349
impl<T, A: Allocator> ExactSizeIterator for RawIntoIter<T, A> {}
4350
impl<T, A: Allocator> FusedIterator for RawIntoIter<T, A> {}
4351
4352
/// Iterator which consumes elements without freeing the table storage.
4353
pub struct RawDrain<'a, T, A: Allocator = Global> {
4354
    iter: RawIter<T>,
4355
4356
    // The table is moved into the iterator for the duration of the drain. This
4357
    // ensures that an empty table is left if the drain iterator is leaked
4358
    // without dropping.
4359
    table: RawTableInner,
4360
    orig_table: NonNull<RawTableInner>,
4361
4362
    // We don't use a &'a mut RawTable<T> because we want RawDrain to be
4363
    // covariant over T.
4364
    marker: PhantomData<&'a RawTable<T, A>>,
4365
}
4366
4367
impl<T, A: Allocator> RawDrain<'_, T, A> {
4368
    #[cfg_attr(feature = "inline-more", inline)]
4369
0
    pub fn iter(&self) -> RawIter<T> {
4370
0
        self.iter.clone()
4371
0
    }
4372
}
4373
4374
unsafe impl<T, A: Allocator> Send for RawDrain<'_, T, A>
4375
where
4376
    T: Send,
4377
    A: Send,
4378
{
4379
}
4380
unsafe impl<T, A: Allocator> Sync for RawDrain<'_, T, A>
4381
where
4382
    T: Sync,
4383
    A: Sync,
4384
{
4385
}
4386
4387
impl<T, A: Allocator> Drop for RawDrain<'_, T, A> {
4388
    #[cfg_attr(feature = "inline-more", inline)]
4389
0
    fn drop(&mut self) {
4390
0
        unsafe {
4391
0
            // Drop all remaining elements. Note that this may panic.
4392
0
            self.iter.drop_elements();
4393
0
4394
0
            // Reset the contents of the table now that all elements have been
4395
0
            // dropped.
4396
0
            self.table.clear_no_drop();
4397
0
4398
0
            // Move the now empty table back to its original location.
4399
0
            self.orig_table
4400
0
                .as_ptr()
4401
0
                .copy_from_nonoverlapping(&self.table, 1);
4402
0
        }
4403
0
    }
Unexecuted instantiation: _RNvXsG_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawDrainTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEENtNtNtB1v_3ops4drop4Drop4dropB2w_
Unexecuted instantiation: _RNvXININtCsgkA6tlBCRmB_9hashbrown3rawsG_0ppEINtB5_8RawDrainppENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropB7_
4404
}
4405
4406
impl<T, A: Allocator> Iterator for RawDrain<'_, T, A> {
4407
    type Item = T;
4408
4409
    #[cfg_attr(feature = "inline-more", inline)]
4410
0
    fn next(&mut self) -> Option<T> {
4411
        unsafe {
4412
0
            let item = self.iter.next()?;
4413
0
            Some(item.read())
4414
        }
4415
0
    }
Unexecuted instantiation: _RNvXsH_NtCsgkA6tlBCRmB_9hashbrown3rawINtB5_8RawDrainTINtCs9xc8CxQ35gK_3lru6KeyRefAhj20_EINtNtNtCsbQ8arDwx5Xq_4core3ptr8non_null7NonNullINtBS_8LruEntryB1h_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementEEEENtNtNtNtB1v_4iter6traits8iterator8Iterator4nextB2w_
Unexecuted instantiation: _RNvXININtCsgkA6tlBCRmB_9hashbrown3rawsH_0ppEINtB5_8RawDrainppENtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits8iterator8Iterator4nextB7_
4416
4417
    #[inline]
4418
0
    fn size_hint(&self) -> (usize, Option<usize>) {
4419
0
        self.iter.size_hint()
4420
0
    }
4421
}
4422
4423
impl<T, A: Allocator> ExactSizeIterator for RawDrain<'_, T, A> {}
4424
impl<T, A: Allocator> FusedIterator for RawDrain<'_, T, A> {}
4425
4426
/// Iterator over occupied buckets that could match a given hash.
4427
///
4428
/// `RawTable` only stores 7 bits of the hash value, so this iterator may return
4429
/// items that have a hash value different than the one provided. You should
4430
/// always validate the returned values before using them.
4431
///
4432
/// For maximum flexibility this iterator is not bound by a lifetime, but you
4433
/// must observe several rules when using it:
4434
/// - You must not free the hash table while iterating (including via growing/shrinking).
4435
/// - It is fine to erase a bucket that has been yielded by the iterator.
4436
/// - Erasing a bucket that has not yet been yielded by the iterator may still
4437
///   result in the iterator yielding that bucket.
4438
/// - It is unspecified whether an element inserted after the iterator was
4439
///   created will be yielded by that iterator.
4440
/// - The order in which the iterator yields buckets is unspecified and may
4441
///   change in the future.
4442
pub struct RawIterHash<T> {
4443
    inner: RawIterHashInner,
4444
    _marker: PhantomData<T>,
4445
}
4446
4447
struct RawIterHashInner {
4448
    // See `RawTableInner`'s corresponding fields for details.
4449
    // We can't store a `*const RawTableInner` as it would get
4450
    // invalidated by the user calling `&mut` methods on `RawTable`.
4451
    bucket_mask: usize,
4452
    ctrl: NonNull<u8>,
4453
4454
    // The top 7 bits of the hash.
4455
    h2_hash: u8,
4456
4457
    // The sequence of groups to probe in the search.
4458
    probe_seq: ProbeSeq,
4459
4460
    group: Group,
4461
4462
    // The elements within the group with a matching h2-hash.
4463
    bitmask: BitMaskIter,
4464
}
4465
4466
impl<T> RawIterHash<T> {
4467
    #[cfg_attr(feature = "inline-more", inline)]
4468
    #[cfg(feature = "raw")]
4469
    unsafe fn new<A: Allocator>(table: &RawTable<T, A>, hash: u64) -> Self {
4470
        RawIterHash {
4471
            inner: RawIterHashInner::new(&table.table, hash),
4472
            _marker: PhantomData,
4473
        }
4474
    }
4475
}
4476
impl RawIterHashInner {
4477
    #[cfg_attr(feature = "inline-more", inline)]
4478
    #[cfg(feature = "raw")]
4479
    unsafe fn new(table: &RawTableInner, hash: u64) -> Self {
4480
        let h2_hash = h2(hash);
4481
        let probe_seq = table.probe_seq(hash);
4482
        let group = Group::load(table.ctrl(probe_seq.pos));
4483
        let bitmask = group.match_byte(h2_hash).into_iter();
4484
4485
        RawIterHashInner {
4486
            bucket_mask: table.bucket_mask,
4487
            ctrl: table.ctrl,
4488
            h2_hash,
4489
            probe_seq,
4490
            group,
4491
            bitmask,
4492
        }
4493
    }
4494
}
4495
4496
impl<T> Iterator for RawIterHash<T> {
4497
    type Item = Bucket<T>;
4498
4499
0
    fn next(&mut self) -> Option<Bucket<T>> {
4500
0
        unsafe {
4501
0
            match self.inner.next() {
4502
0
                Some(index) => {
4503
0
                    // Can't use `RawTable::bucket` here as we don't have
4504
0
                    // an actual `RawTable` reference to use.
4505
0
                    debug_assert!(index <= self.inner.bucket_mask);
4506
0
                    let bucket = Bucket::from_base_index(self.inner.ctrl.cast(), index);
4507
0
                    Some(bucket)
4508
                }
4509
0
                None => None,
4510
            }
4511
        }
4512
0
    }
4513
}
4514
4515
impl Iterator for RawIterHashInner {
4516
    type Item = usize;
4517
4518
0
    fn next(&mut self) -> Option<Self::Item> {
4519
        unsafe {
4520
            loop {
4521
0
                if let Some(bit) = self.bitmask.next() {
4522
0
                    let index = (self.probe_seq.pos + bit) & self.bucket_mask;
4523
0
                    return Some(index);
4524
0
                }
4525
0
                if likely(self.group.match_empty().any_bit_set()) {
4526
0
                    return None;
4527
0
                }
4528
0
                self.probe_seq.move_next(self.bucket_mask);
4529
0
4530
0
                // Can't use `RawTableInner::ctrl` here as we don't have
4531
0
                // an actual `RawTableInner` reference to use.
4532
0
                let index = self.probe_seq.pos;
4533
0
                debug_assert!(index < self.bucket_mask + 1 + Group::WIDTH);
4534
0
                let group_ctrl = self.ctrl.as_ptr().add(index);
4535
0
4536
0
                self.group = Group::load(group_ctrl);
4537
0
                self.bitmask = self.group.match_byte(self.h2_hash).into_iter();
4538
            }
4539
        }
4540
0
    }
4541
}
4542
4543
pub(crate) struct RawExtractIf<'a, T, A: Allocator> {
4544
    pub iter: RawIter<T>,
4545
    pub table: &'a mut RawTable<T, A>,
4546
}
4547
4548
impl<T, A: Allocator> RawExtractIf<'_, T, A> {
4549
    #[cfg_attr(feature = "inline-more", inline)]
4550
0
    pub(crate) fn next<F>(&mut self, mut f: F) -> Option<T>
4551
0
    where
4552
0
        F: FnMut(&mut T) -> bool,
4553
0
    {
4554
        unsafe {
4555
0
            for item in &mut self.iter {
4556
0
                if f(item.as_mut()) {
4557
0
                    return Some(self.table.remove(item).0);
4558
0
                }
4559
            }
4560
        }
4561
0
        None
4562
0
    }
4563
}
4564
4565
#[cfg(test)]
4566
mod test_map {
4567
    use super::*;
4568
4569
    fn rehash_in_place<T>(table: &mut RawTable<T>, hasher: impl Fn(&T) -> u64) {
4570
        unsafe {
4571
            table.table.rehash_in_place(
4572
                &|table, index| hasher(table.bucket::<T>(index).as_ref()),
4573
                mem::size_of::<T>(),
4574
                if mem::needs_drop::<T>() {
4575
                    Some(mem::transmute(ptr::drop_in_place::<T> as unsafe fn(*mut T)))
4576
                } else {
4577
                    None
4578
                },
4579
            );
4580
        }
4581
    }
4582
4583
    #[test]
4584
    fn rehash() {
4585
        let mut table = RawTable::new();
4586
        let hasher = |i: &u64| *i;
4587
        for i in 0..100 {
4588
            table.insert(i, i, hasher);
4589
        }
4590
4591
        for i in 0..100 {
4592
            unsafe {
4593
                assert_eq!(table.find(i, |x| *x == i).map(|b| b.read()), Some(i));
4594
            }
4595
            assert!(table.find(i + 100, |x| *x == i + 100).is_none());
4596
        }
4597
4598
        rehash_in_place(&mut table, hasher);
4599
4600
        for i in 0..100 {
4601
            unsafe {
4602
                assert_eq!(table.find(i, |x| *x == i).map(|b| b.read()), Some(i));
4603
            }
4604
            assert!(table.find(i + 100, |x| *x == i + 100).is_none());
4605
        }
4606
    }
4607
4608
    /// CHECKING THAT WE ARE NOT TRYING TO READ THE MEMORY OF
4609
    /// AN UNINITIALIZED TABLE DURING THE DROP
4610
    #[test]
4611
    fn test_drop_uninitialized() {
4612
        use ::alloc::vec::Vec;
4613
4614
        let table = unsafe {
4615
            // SAFETY: The `buckets` is power of two and we're not
4616
            // trying to actually use the returned RawTable.
4617
            RawTable::<(u64, Vec<i32>)>::new_uninitialized(Global, 8, Fallibility::Infallible)
4618
                .unwrap()
4619
        };
4620
        drop(table);
4621
    }
4622
4623
    /// CHECKING THAT WE DON'T TRY TO DROP DATA IF THE `ITEMS`
4624
    /// ARE ZERO, EVEN IF WE HAVE `FULL` CONTROL BYTES.
4625
    #[test]
4626
    fn test_drop_zero_items() {
4627
        use ::alloc::vec::Vec;
4628
        unsafe {
4629
            // SAFETY: The `buckets` is power of two and we're not
4630
            // trying to actually use the returned RawTable.
4631
            let table =
4632
                RawTable::<(u64, Vec<i32>)>::new_uninitialized(Global, 8, Fallibility::Infallible)
4633
                    .unwrap();
4634
4635
            // WE SIMULATE, AS IT WERE, A FULL TABLE.
4636
4637
            // SAFETY: We checked that the table is allocated and therefore the table already has
4638
            // `self.bucket_mask + 1 + Group::WIDTH` number of control bytes (see TableLayout::calculate_layout_for)
4639
            // so writing `table.table.num_ctrl_bytes() == bucket_mask + 1 + Group::WIDTH` bytes is safe.
4640
            table
4641
                .table
4642
                .ctrl(0)
4643
                .write_bytes(EMPTY, table.table.num_ctrl_bytes());
4644
4645
            // SAFETY: table.capacity() is guaranteed to be smaller than table.buckets()
4646
            table.table.ctrl(0).write_bytes(0, table.capacity());
4647
4648
            // Fix up the trailing control bytes. See the comments in set_ctrl
4649
            // for the handling of tables smaller than the group width.
4650
            if table.buckets() < Group::WIDTH {
4651
                // SAFETY: We have `self.bucket_mask + 1 + Group::WIDTH` number of control bytes,
4652
                // so copying `self.buckets() == self.bucket_mask + 1` bytes with offset equal to
4653
                // `Group::WIDTH` is safe
4654
                table
4655
                    .table
4656
                    .ctrl(0)
4657
                    .copy_to(table.table.ctrl(Group::WIDTH), table.table.buckets());
4658
            } else {
4659
                // SAFETY: We have `self.bucket_mask + 1 + Group::WIDTH` number of
4660
                // control bytes,so copying `Group::WIDTH` bytes with offset equal
4661
                // to `self.buckets() == self.bucket_mask + 1` is safe
4662
                table
4663
                    .table
4664
                    .ctrl(0)
4665
                    .copy_to(table.table.ctrl(table.table.buckets()), Group::WIDTH);
4666
            }
4667
            drop(table);
4668
        }
4669
    }
4670
4671
    /// CHECKING THAT WE DON'T TRY TO DROP DATA IF THE `ITEMS`
4672
    /// ARE ZERO, EVEN IF WE HAVE `FULL` CONTROL BYTES.
4673
    #[test]
4674
    fn test_catch_panic_clone_from() {
4675
        use ::alloc::sync::Arc;
4676
        use ::alloc::vec::Vec;
4677
        use allocator_api2::alloc::{AllocError, Allocator, Global};
4678
        use core::sync::atomic::{AtomicI8, Ordering};
4679
        use std::thread;
4680
4681
        struct MyAllocInner {
4682
            drop_count: Arc<AtomicI8>,
4683
        }
4684
4685
        #[derive(Clone)]
4686
        struct MyAlloc {
4687
            _inner: Arc<MyAllocInner>,
4688
        }
4689
4690
        impl Drop for MyAllocInner {
4691
            fn drop(&mut self) {
4692
                println!("MyAlloc freed.");
4693
                self.drop_count.fetch_sub(1, Ordering::SeqCst);
4694
            }
4695
        }
4696
4697
        unsafe impl Allocator for MyAlloc {
4698
            fn allocate(&self, layout: Layout) -> std::result::Result<NonNull<[u8]>, AllocError> {
4699
                let g = Global;
4700
                g.allocate(layout)
4701
            }
4702
4703
            unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
4704
                let g = Global;
4705
                g.deallocate(ptr, layout)
4706
            }
4707
        }
4708
4709
        const DISARMED: bool = false;
4710
        const ARMED: bool = true;
4711
4712
        struct CheckedCloneDrop {
4713
            panic_in_clone: bool,
4714
            dropped: bool,
4715
            need_drop: Vec<u64>,
4716
        }
4717
4718
        impl Clone for CheckedCloneDrop {
4719
            fn clone(&self) -> Self {
4720
                if self.panic_in_clone {
4721
                    panic!("panic in clone")
4722
                }
4723
                Self {
4724
                    panic_in_clone: self.panic_in_clone,
4725
                    dropped: self.dropped,
4726
                    need_drop: self.need_drop.clone(),
4727
                }
4728
            }
4729
        }
4730
4731
        impl Drop for CheckedCloneDrop {
4732
            fn drop(&mut self) {
4733
                if self.dropped {
4734
                    panic!("double drop");
4735
                }
4736
                self.dropped = true;
4737
            }
4738
        }
4739
4740
        let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
4741
4742
        let mut table = RawTable::new_in(MyAlloc {
4743
            _inner: Arc::new(MyAllocInner {
4744
                drop_count: dropped.clone(),
4745
            }),
4746
        });
4747
4748
        for (idx, panic_in_clone) in core::iter::repeat(DISARMED).take(7).enumerate() {
4749
            let idx = idx as u64;
4750
            table.insert(
4751
                idx,
4752
                (
4753
                    idx,
4754
                    CheckedCloneDrop {
4755
                        panic_in_clone,
4756
                        dropped: false,
4757
                        need_drop: vec![idx],
4758
                    },
4759
                ),
4760
                |(k, _)| *k,
4761
            );
4762
        }
4763
4764
        assert_eq!(table.len(), 7);
4765
4766
        thread::scope(|s| {
4767
            let result = s.spawn(|| {
4768
                let armed_flags = [
4769
                    DISARMED, DISARMED, ARMED, DISARMED, DISARMED, DISARMED, DISARMED,
4770
                ];
4771
                let mut scope_table = RawTable::new_in(MyAlloc {
4772
                    _inner: Arc::new(MyAllocInner {
4773
                        drop_count: dropped.clone(),
4774
                    }),
4775
                });
4776
                for (idx, &panic_in_clone) in armed_flags.iter().enumerate() {
4777
                    let idx = idx as u64;
4778
                    scope_table.insert(
4779
                        idx,
4780
                        (
4781
                            idx,
4782
                            CheckedCloneDrop {
4783
                                panic_in_clone,
4784
                                dropped: false,
4785
                                need_drop: vec![idx + 100],
4786
                            },
4787
                        ),
4788
                        |(k, _)| *k,
4789
                    );
4790
                }
4791
                table.clone_from(&scope_table);
4792
            });
4793
            assert!(result.join().is_err());
4794
        });
4795
4796
        // Let's check that all iterators work fine and do not return elements
4797
        // (especially `RawIterRange`, which does not depend on the number of
4798
        // elements in the table, but looks directly at the control bytes)
4799
        //
4800
        // SAFETY: We know for sure that `RawTable` will outlive
4801
        // the returned `RawIter / RawIterRange` iterator.
4802
        assert_eq!(table.len(), 0);
4803
        assert_eq!(unsafe { table.iter().count() }, 0);
4804
        assert_eq!(unsafe { table.iter().iter.count() }, 0);
4805
4806
        for idx in 0..table.buckets() {
4807
            let idx = idx as u64;
4808
            assert!(
4809
                table.find(idx, |(k, _)| *k == idx).is_none(),
4810
                "Index: {idx}"
4811
            );
4812
        }
4813
4814
        // All allocator clones should already be dropped.
4815
        assert_eq!(dropped.load(Ordering::SeqCst), 1);
4816
    }
4817
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/raw/sse2.rs
Line
Count
Source
1
use super::bitmask::BitMask;
2
use super::EMPTY;
3
use core::mem;
4
use core::num::NonZeroU16;
5
6
#[cfg(target_arch = "x86")]
7
use core::arch::x86;
8
#[cfg(target_arch = "x86_64")]
9
use core::arch::x86_64 as x86;
10
11
pub(crate) type BitMaskWord = u16;
12
pub(crate) type NonZeroBitMaskWord = NonZeroU16;
13
pub(crate) const BITMASK_STRIDE: usize = 1;
14
pub(crate) const BITMASK_MASK: BitMaskWord = 0xffff;
15
pub(crate) const BITMASK_ITER_MASK: BitMaskWord = !0;
16
17
/// Abstraction over a group of control bytes which can be scanned in
18
/// parallel.
19
///
20
/// This implementation uses a 128-bit SSE value.
21
#[derive(Copy, Clone)]
22
pub(crate) struct Group(x86::__m128i);
23
24
// FIXME: https://github.com/rust-lang/rust-clippy/issues/3859
25
#[allow(clippy::use_self)]
26
impl Group {
27
    /// Number of bytes in the group.
28
    pub(crate) const WIDTH: usize = mem::size_of::<Self>();
29
30
    /// Returns a full group of empty bytes, suitable for use as the initial
31
    /// value for an empty hash table.
32
    ///
33
    /// This is guaranteed to be aligned to the group size.
34
    #[inline]
35
    #[allow(clippy::items_after_statements)]
36
0
    pub(crate) const fn static_empty() -> &'static [u8; Group::WIDTH] {
37
        #[repr(C)]
38
        struct AlignedBytes {
39
            _align: [Group; 0],
40
            bytes: [u8; Group::WIDTH],
41
        }
42
        const ALIGNED_BYTES: AlignedBytes = AlignedBytes {
43
            _align: [],
44
            bytes: [EMPTY; Group::WIDTH],
45
        };
46
0
        &ALIGNED_BYTES.bytes
47
0
    }
48
49
    /// Loads a group of bytes starting at the given address.
50
    #[inline]
51
    #[allow(clippy::cast_ptr_alignment)] // unaligned load
52
0
    pub(crate) unsafe fn load(ptr: *const u8) -> Self {
53
0
        Group(x86::_mm_loadu_si128(ptr.cast()))
54
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group4loadCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group4loadB6_
55
56
    /// Loads a group of bytes starting at the given address, which must be
57
    /// aligned to `mem::align_of::<Group>()`.
58
    #[inline]
59
    #[allow(clippy::cast_ptr_alignment)]
60
0
    pub(crate) unsafe fn load_aligned(ptr: *const u8) -> Self {
61
0
        // FIXME: use align_offset once it stabilizes
62
0
        debug_assert_eq!(ptr as usize & (mem::align_of::<Self>() - 1), 0);
63
0
        Group(x86::_mm_load_si128(ptr.cast()))
64
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group12load_alignedCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group12load_alignedB6_
65
66
    /// Stores the group of bytes to the given address, which must be
67
    /// aligned to `mem::align_of::<Group>()`.
68
    #[inline]
69
    #[allow(clippy::cast_ptr_alignment)]
70
0
    pub(crate) unsafe fn store_aligned(self, ptr: *mut u8) {
71
0
        // FIXME: use align_offset once it stabilizes
72
0
        debug_assert_eq!(ptr as usize & (mem::align_of::<Self>() - 1), 0);
73
0
        x86::_mm_store_si128(ptr.cast(), self.0);
74
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group13store_alignedCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group13store_alignedB6_
75
76
    /// Returns a `BitMask` indicating all bytes in the group which have
77
    /// the given value.
78
    #[inline]
79
0
    pub(crate) fn match_byte(self, byte: u8) -> BitMask {
80
0
        #[allow(
81
0
            clippy::cast_possible_wrap, // byte: u8 as i8
82
0
            // byte: i32 as u16
83
0
            //   note: _mm_movemask_epi8 returns a 16-bit mask in a i32, the
84
0
            //   upper 16-bits of the i32 are zeroed:
85
0
            clippy::cast_sign_loss,
86
0
            clippy::cast_possible_truncation
87
0
        )]
88
0
        unsafe {
89
0
            let cmp = x86::_mm_cmpeq_epi8(self.0, x86::_mm_set1_epi8(byte as i8));
90
0
            BitMask(x86::_mm_movemask_epi8(cmp) as u16)
91
0
        }
92
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group10match_byteCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group10match_byteB6_
93
94
    /// Returns a `BitMask` indicating all bytes in the group which are
95
    /// `EMPTY`.
96
    #[inline]
97
0
    pub(crate) fn match_empty(self) -> BitMask {
98
0
        self.match_byte(EMPTY)
99
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group11match_emptyCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group11match_emptyB6_
100
101
    /// Returns a `BitMask` indicating all bytes in the group which are
102
    /// `EMPTY` or `DELETED`.
103
    #[inline]
104
0
    pub(crate) fn match_empty_or_deleted(self) -> BitMask {
105
0
        #[allow(
106
0
            // byte: i32 as u16
107
0
            //   note: _mm_movemask_epi8 returns a 16-bit mask in a i32, the
108
0
            //   upper 16-bits of the i32 are zeroed:
109
0
            clippy::cast_sign_loss,
110
0
            clippy::cast_possible_truncation
111
0
        )]
112
0
        unsafe {
113
0
            // A byte is EMPTY or DELETED iff the high bit is set
114
0
            BitMask(x86::_mm_movemask_epi8(self.0) as u16)
115
0
        }
116
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group22match_empty_or_deletedCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group22match_empty_or_deletedB6_
117
118
    /// Returns a `BitMask` indicating all bytes in the group which are full.
119
    #[inline]
120
0
    pub(crate) fn match_full(&self) -> BitMask {
121
0
        self.match_empty_or_deleted().invert()
122
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group10match_fullCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group10match_fullB6_
123
124
    /// Performs the following transformation on all bytes in the group:
125
    /// - `EMPTY => EMPTY`
126
    /// - `DELETED => EMPTY`
127
    /// - `FULL => DELETED`
128
    #[inline]
129
0
    pub(crate) fn convert_special_to_empty_and_full_to_deleted(self) -> Self {
130
0
        // Map high_bit = 1 (EMPTY or DELETED) to 1111_1111
131
0
        // and high_bit = 0 (FULL) to 1000_0000
132
0
        //
133
0
        // Here's this logic expanded to concrete values:
134
0
        //   let special = 0 > byte = 1111_1111 (true) or 0000_0000 (false)
135
0
        //   1111_1111 | 1000_0000 = 1111_1111
136
0
        //   0000_0000 | 1000_0000 = 1000_0000
137
0
        #[allow(
138
0
            clippy::cast_possible_wrap, // byte: 0x80_u8 as i8
139
0
        )]
140
0
        unsafe {
141
0
            let zero = x86::_mm_setzero_si128();
142
0
            let special = x86::_mm_cmpgt_epi8(zero, self.0);
143
0
            Group(x86::_mm_or_si128(
144
0
                special,
145
0
                x86::_mm_set1_epi8(0x80_u8 as i8),
146
0
            ))
147
0
        }
148
0
    }
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group44convert_special_to_empty_and_full_to_deletedCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMNtNtCsgkA6tlBCRmB_9hashbrown3raw4sse2NtB2_5Group44convert_special_to_empty_and_full_to_deletedB6_
149
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/scopeguard.rs
Line
Count
Source
1
// Extracted from the scopeguard crate
2
use core::{
3
    mem::ManuallyDrop,
4
    ops::{Deref, DerefMut},
5
    ptr,
6
};
7
8
pub struct ScopeGuard<T, F>
9
where
10
    F: FnMut(&mut T),
11
{
12
    dropfn: F,
13
    value: T,
14
}
15
16
#[inline]
17
0
pub fn guard<T, F>(value: T, dropfn: F) -> ScopeGuard<T, F>
18
0
where
19
0
    F: FnMut(&mut T),
20
0
{
21
0
    ScopeGuard { dropfn, value }
22
0
}
Unexecuted instantiation: _RINvNtCsgkA6tlBCRmB_9hashbrown10scopeguard5guardNtNtB4_3raw13RawTableInnerNCINvMsa_BM_BK_14prepare_resizeNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalE0ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvNtCsgkA6tlBCRmB_9hashbrown10scopeguard5guardQNtNtB4_3raw13RawTableInnerNCNvMsa_BN_BL_15rehash_in_place0ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvNtCsgkA6tlBCRmB_9hashbrown10scopeguard5guardppEB4_
23
24
impl<T, F> ScopeGuard<T, F>
25
where
26
    F: FnMut(&mut T),
27
{
28
    #[inline]
29
0
    pub fn into_inner(guard: Self) -> T {
30
0
        // Cannot move out of Drop-implementing types, so
31
0
        // ptr::read the value out of a ManuallyDrop<Self>
32
0
        // Don't use mem::forget as that might invalidate value
33
0
        let guard = ManuallyDrop::new(guard);
34
0
        unsafe {
35
0
            let value = ptr::read(&guard.value);
36
0
            // read the closure so that it is dropped
37
0
            let _ = ptr::read(&guard.dropfn);
38
0
            value
39
0
        }
40
0
    }
41
}
42
43
impl<T, F> Deref for ScopeGuard<T, F>
44
where
45
    F: FnMut(&mut T),
46
{
47
    type Target = T;
48
    #[inline]
49
0
    fn deref(&self) -> &T {
50
0
        &self.value
51
0
    }
Unexecuted instantiation: _RNvXs_NtCsgkA6tlBCRmB_9hashbrown10scopeguardINtB4_10ScopeGuardNtNtB6_3raw13RawTableInnerNCINvMsa_B10_BY_14prepare_resizeNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalE0ENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs_NtCsgkA6tlBCRmB_9hashbrown10scopeguardINtB4_10ScopeGuardQNtNtB6_3raw13RawTableInnerNCNvMsa_B11_BZ_15rehash_in_place0ENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtCsgkA6tlBCRmB_9hashbrown10scopeguards_0ppEINtB5_10ScopeGuardppENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefB7_
52
}
53
54
impl<T, F> DerefMut for ScopeGuard<T, F>
55
where
56
    F: FnMut(&mut T),
57
{
58
    #[inline]
59
0
    fn deref_mut(&mut self) -> &mut T {
60
0
        &mut self.value
61
0
    }
Unexecuted instantiation: _RNvXs0_NtCsgkA6tlBCRmB_9hashbrown10scopeguardINtB5_10ScopeGuardNtNtB7_3raw13RawTableInnerNCINvMsa_B11_BZ_14prepare_resizeNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalE0ENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs0_NtCsgkA6tlBCRmB_9hashbrown10scopeguardINtB5_10ScopeGuardQNtNtB7_3raw13RawTableInnerNCNvMsa_B12_B10_15rehash_in_place0ENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtCsgkA6tlBCRmB_9hashbrown10scopeguards0_0ppEINtB5_10ScopeGuardppENtNtNtCsbQ8arDwx5Xq_4core3ops5deref8DerefMut9deref_mutB7_
62
}
63
64
impl<T, F> Drop for ScopeGuard<T, F>
65
where
66
    F: FnMut(&mut T),
67
{
68
    #[inline]
69
0
    fn drop(&mut self) {
70
0
        (self.dropfn)(&mut self.value);
71
0
    }
Unexecuted instantiation: _RNvXs1_NtCsgkA6tlBCRmB_9hashbrown10scopeguardINtB5_10ScopeGuardNtNtB7_3raw13RawTableInnerNCINvMsa_B11_BZ_14prepare_resizeNtNtNtNtCsby83UglaBWc_14allocator_api26stable5alloc6global6GlobalE0ENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs1_NtCsgkA6tlBCRmB_9hashbrown10scopeguardINtB5_10ScopeGuardQNtNtB7_3raw13RawTableInnerNCNvMsa_B12_B10_15rehash_in_place0ENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs1_NtCsgkA6tlBCRmB_9hashbrown10scopeguardINtB5_10ScopeGuardQNtNtB7_3raw13RawTableInnerNCNvMsa_B12_B10_15rehash_in_place0ENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropB7_
72
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/set.rs
Line
Count
Source
1
#[cfg(feature = "raw")]
2
use crate::raw::RawTable;
3
use crate::{Equivalent, TryReserveError};
4
use alloc::borrow::ToOwned;
5
use core::fmt;
6
use core::hash::{BuildHasher, Hash};
7
use core::iter::{Chain, FusedIterator};
8
use core::ops::{BitAnd, BitOr, BitXor, Sub};
9
10
use super::map::{self, DefaultHashBuilder, HashMap, Keys};
11
use crate::raw::{Allocator, Global, RawExtractIf};
12
13
// Future Optimization (FIXME!)
14
// =============================
15
//
16
// Iteration over zero sized values is a noop. There is no need
17
// for `bucket.val` in the case of HashSet. I suppose we would need HKT
18
// to get rid of it properly.
19
20
/// A hash set implemented as a `HashMap` where the value is `()`.
21
///
22
/// As with the [`HashMap`] type, a `HashSet` requires that the elements
23
/// implement the [`Eq`] and [`Hash`] traits. This can frequently be achieved by
24
/// using `#[derive(PartialEq, Eq, Hash)]`. If you implement these yourself,
25
/// it is important that the following property holds:
26
///
27
/// ```text
28
/// k1 == k2 -> hash(k1) == hash(k2)
29
/// ```
30
///
31
/// In other words, if two keys are equal, their hashes must be equal.
32
///
33
///
34
/// It is a logic error for an item to be modified in such a way that the
35
/// item's hash, as determined by the [`Hash`] trait, or its equality, as
36
/// determined by the [`Eq`] trait, changes while it is in the set. This is
37
/// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or
38
/// unsafe code.
39
///
40
/// It is also a logic error for the [`Hash`] implementation of a key to panic.
41
/// This is generally only possible if the trait is implemented manually. If a
42
/// panic does occur then the contents of the `HashSet` may become corrupted and
43
/// some items may be dropped from the table.
44
///
45
/// # Examples
46
///
47
/// ```
48
/// use hashbrown::HashSet;
49
/// // Type inference lets us omit an explicit type signature (which
50
/// // would be `HashSet<String>` in this example).
51
/// let mut books = HashSet::new();
52
///
53
/// // Add some books.
54
/// books.insert("A Dance With Dragons".to_string());
55
/// books.insert("To Kill a Mockingbird".to_string());
56
/// books.insert("The Odyssey".to_string());
57
/// books.insert("The Great Gatsby".to_string());
58
///
59
/// // Check for a specific one.
60
/// if !books.contains("The Winds of Winter") {
61
///     println!("We have {} books, but The Winds of Winter ain't one.",
62
///              books.len());
63
/// }
64
///
65
/// // Remove a book.
66
/// books.remove("The Odyssey");
67
///
68
/// // Iterate over everything.
69
/// for book in &books {
70
///     println!("{}", book);
71
/// }
72
/// ```
73
///
74
/// The easiest way to use `HashSet` with a custom type is to derive
75
/// [`Eq`] and [`Hash`]. We must also derive [`PartialEq`]. This will in the
76
/// future be implied by [`Eq`].
77
///
78
/// ```
79
/// use hashbrown::HashSet;
80
/// #[derive(Hash, Eq, PartialEq, Debug)]
81
/// struct Viking {
82
///     name: String,
83
///     power: usize,
84
/// }
85
///
86
/// let mut vikings = HashSet::new();
87
///
88
/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
89
/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
90
/// vikings.insert(Viking { name: "Olaf".to_string(), power: 4 });
91
/// vikings.insert(Viking { name: "Harald".to_string(), power: 8 });
92
///
93
/// // Use derived implementation to print the vikings.
94
/// for x in &vikings {
95
///     println!("{:?}", x);
96
/// }
97
/// ```
98
///
99
/// A `HashSet` with fixed list of elements can be initialized from an array:
100
///
101
/// ```
102
/// use hashbrown::HashSet;
103
///
104
/// let viking_names: HashSet<&'static str> =
105
///     [ "Einar", "Olaf", "Harald" ].into_iter().collect();
106
/// // use the values stored in the set
107
/// ```
108
///
109
/// [`Cell`]: https://doc.rust-lang.org/std/cell/struct.Cell.html
110
/// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
111
/// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
112
/// [`HashMap`]: struct.HashMap.html
113
/// [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
114
/// [`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
115
pub struct HashSet<T, S = DefaultHashBuilder, A: Allocator = Global> {
116
    pub(crate) map: HashMap<T, (), S, A>,
117
}
118
119
impl<T: Clone, S: Clone, A: Allocator + Clone> Clone for HashSet<T, S, A> {
120
0
    fn clone(&self) -> Self {
121
0
        HashSet {
122
0
            map: self.map.clone(),
123
0
        }
124
0
    }
125
126
0
    fn clone_from(&mut self, source: &Self) {
127
0
        self.map.clone_from(&source.map);
128
0
    }
129
}
130
131
#[cfg(feature = "ahash")]
132
impl<T> HashSet<T, DefaultHashBuilder> {
133
    /// Creates an empty `HashSet`.
134
    ///
135
    /// The hash set is initially created with a capacity of 0, so it will not allocate until it
136
    /// is first inserted into.
137
    ///
138
    /// # HashDoS resistance
139
    ///
140
    /// The `hash_builder` normally use a fixed key by default and that does
141
    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
142
    /// Users who require HashDoS resistance should explicitly use
143
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
144
    /// as the hasher when creating a [`HashSet`], for example with
145
    /// [`with_hasher`](HashSet::with_hasher) method.
146
    ///
147
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
148
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
149
    ///
150
    /// # Examples
151
    ///
152
    /// ```
153
    /// use hashbrown::HashSet;
154
    /// let set: HashSet<i32> = HashSet::new();
155
    /// ```
156
    #[cfg_attr(feature = "inline-more", inline)]
157
0
    pub fn new() -> Self {
158
0
        Self {
159
0
            map: HashMap::new(),
160
0
        }
161
0
    }
162
163
    /// Creates an empty `HashSet` with the specified capacity.
164
    ///
165
    /// The hash set will be able to hold at least `capacity` elements without
166
    /// reallocating. If `capacity` is 0, the hash set will not allocate.
167
    ///
168
    /// # HashDoS resistance
169
    ///
170
    /// The `hash_builder` normally use a fixed key by default and that does
171
    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
172
    /// Users who require HashDoS resistance should explicitly use
173
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
174
    /// as the hasher when creating a [`HashSet`], for example with
175
    /// [`with_capacity_and_hasher`](HashSet::with_capacity_and_hasher) method.
176
    ///
177
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
178
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
179
    ///
180
    /// # Examples
181
    ///
182
    /// ```
183
    /// use hashbrown::HashSet;
184
    /// let set: HashSet<i32> = HashSet::with_capacity(10);
185
    /// assert!(set.capacity() >= 10);
186
    /// ```
187
    #[cfg_attr(feature = "inline-more", inline)]
188
0
    pub fn with_capacity(capacity: usize) -> Self {
189
0
        Self {
190
0
            map: HashMap::with_capacity(capacity),
191
0
        }
192
0
    }
193
}
194
195
#[cfg(feature = "ahash")]
196
impl<T: Hash + Eq, A: Allocator> HashSet<T, DefaultHashBuilder, A> {
197
    /// Creates an empty `HashSet`.
198
    ///
199
    /// The hash set is initially created with a capacity of 0, so it will not allocate until it
200
    /// is first inserted into.
201
    ///
202
    /// # HashDoS resistance
203
    ///
204
    /// The `hash_builder` normally use a fixed key by default and that does
205
    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
206
    /// Users who require HashDoS resistance should explicitly use
207
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
208
    /// as the hasher when creating a [`HashSet`], for example with
209
    /// [`with_hasher_in`](HashSet::with_hasher_in) method.
210
    ///
211
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
212
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
213
    ///
214
    /// # Examples
215
    ///
216
    /// ```
217
    /// use hashbrown::HashSet;
218
    /// let set: HashSet<i32> = HashSet::new();
219
    /// ```
220
    #[cfg_attr(feature = "inline-more", inline)]
221
0
    pub fn new_in(alloc: A) -> Self {
222
0
        Self {
223
0
            map: HashMap::new_in(alloc),
224
0
        }
225
0
    }
226
227
    /// Creates an empty `HashSet` with the specified capacity.
228
    ///
229
    /// The hash set will be able to hold at least `capacity` elements without
230
    /// reallocating. If `capacity` is 0, the hash set will not allocate.
231
    ///
232
    /// # HashDoS resistance
233
    ///
234
    /// The `hash_builder` normally use a fixed key by default and that does
235
    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
236
    /// Users who require HashDoS resistance should explicitly use
237
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
238
    /// as the hasher when creating a [`HashSet`], for example with
239
    /// [`with_capacity_and_hasher_in`](HashSet::with_capacity_and_hasher_in) method.
240
    ///
241
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
242
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
243
    ///
244
    /// # Examples
245
    ///
246
    /// ```
247
    /// use hashbrown::HashSet;
248
    /// let set: HashSet<i32> = HashSet::with_capacity(10);
249
    /// assert!(set.capacity() >= 10);
250
    /// ```
251
    #[cfg_attr(feature = "inline-more", inline)]
252
0
    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
253
0
        Self {
254
0
            map: HashMap::with_capacity_in(capacity, alloc),
255
0
        }
256
0
    }
257
}
258
259
impl<T, S, A: Allocator> HashSet<T, S, A> {
260
    /// Returns the number of elements the set can hold without reallocating.
261
    ///
262
    /// # Examples
263
    ///
264
    /// ```
265
    /// use hashbrown::HashSet;
266
    /// let set: HashSet<i32> = HashSet::with_capacity(100);
267
    /// assert!(set.capacity() >= 100);
268
    /// ```
269
    #[cfg_attr(feature = "inline-more", inline)]
270
0
    pub fn capacity(&self) -> usize {
271
0
        self.map.capacity()
272
0
    }
273
274
    /// An iterator visiting all elements in arbitrary order.
275
    /// The iterator element type is `&'a T`.
276
    ///
277
    /// # Examples
278
    ///
279
    /// ```
280
    /// use hashbrown::HashSet;
281
    /// let mut set = HashSet::new();
282
    /// set.insert("a");
283
    /// set.insert("b");
284
    ///
285
    /// // Will print in an arbitrary order.
286
    /// for x in set.iter() {
287
    ///     println!("{}", x);
288
    /// }
289
    /// ```
290
    #[cfg_attr(feature = "inline-more", inline)]
291
0
    pub fn iter(&self) -> Iter<'_, T> {
292
0
        Iter {
293
0
            iter: self.map.keys(),
294
0
        }
295
0
    }
296
297
    /// Returns the number of elements in the set.
298
    ///
299
    /// # Examples
300
    ///
301
    /// ```
302
    /// use hashbrown::HashSet;
303
    ///
304
    /// let mut v = HashSet::new();
305
    /// assert_eq!(v.len(), 0);
306
    /// v.insert(1);
307
    /// assert_eq!(v.len(), 1);
308
    /// ```
309
    #[cfg_attr(feature = "inline-more", inline)]
310
0
    pub fn len(&self) -> usize {
311
0
        self.map.len()
312
0
    }
313
314
    /// Returns `true` if the set contains no elements.
315
    ///
316
    /// # Examples
317
    ///
318
    /// ```
319
    /// use hashbrown::HashSet;
320
    ///
321
    /// let mut v = HashSet::new();
322
    /// assert!(v.is_empty());
323
    /// v.insert(1);
324
    /// assert!(!v.is_empty());
325
    /// ```
326
    #[cfg_attr(feature = "inline-more", inline)]
327
0
    pub fn is_empty(&self) -> bool {
328
0
        self.map.is_empty()
329
0
    }
330
331
    /// Clears the set, returning all elements in an iterator.
332
    ///
333
    /// # Examples
334
    ///
335
    /// ```
336
    /// use hashbrown::HashSet;
337
    ///
338
    /// let mut set: HashSet<_> = [1, 2, 3].into_iter().collect();
339
    /// assert!(!set.is_empty());
340
    ///
341
    /// // print 1, 2, 3 in an arbitrary order
342
    /// for i in set.drain() {
343
    ///     println!("{}", i);
344
    /// }
345
    ///
346
    /// assert!(set.is_empty());
347
    /// ```
348
    #[cfg_attr(feature = "inline-more", inline)]
349
0
    pub fn drain(&mut self) -> Drain<'_, T, A> {
350
0
        Drain {
351
0
            iter: self.map.drain(),
352
0
        }
353
0
    }
354
355
    /// Retains only the elements specified by the predicate.
356
    ///
357
    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
358
    ///
359
    /// # Examples
360
    ///
361
    /// ```
362
    /// use hashbrown::HashSet;
363
    ///
364
    /// let xs = [1,2,3,4,5,6];
365
    /// let mut set: HashSet<i32> = xs.into_iter().collect();
366
    /// set.retain(|&k| k % 2 == 0);
367
    /// assert_eq!(set.len(), 3);
368
    /// ```
369
0
    pub fn retain<F>(&mut self, mut f: F)
370
0
    where
371
0
        F: FnMut(&T) -> bool,
372
0
    {
373
0
        self.map.retain(|k, _| f(k));
374
0
    }
375
376
    /// Drains elements which are true under the given predicate,
377
    /// and returns an iterator over the removed items.
378
    ///
379
    /// In other words, move all elements `e` such that `f(&e)` returns `true` out
380
    /// into another iterator.
381
    ///
382
    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
383
    /// or the iteration short-circuits, then the remaining elements will be retained.
384
    /// Use [`retain()`] with a negated predicate if you do not need the returned iterator.
385
    ///
386
    /// [`retain()`]: HashSet::retain
387
    ///
388
    /// # Examples
389
    ///
390
    /// ```
391
    /// use hashbrown::HashSet;
392
    ///
393
    /// let mut set: HashSet<i32> = (0..8).collect();
394
    /// let drained: HashSet<i32> = set.extract_if(|v| v % 2 == 0).collect();
395
    ///
396
    /// let mut evens = drained.into_iter().collect::<Vec<_>>();
397
    /// let mut odds = set.into_iter().collect::<Vec<_>>();
398
    /// evens.sort();
399
    /// odds.sort();
400
    ///
401
    /// assert_eq!(evens, vec![0, 2, 4, 6]);
402
    /// assert_eq!(odds, vec![1, 3, 5, 7]);
403
    /// ```
404
    #[cfg_attr(feature = "inline-more", inline)]
405
0
    pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, T, F, A>
406
0
    where
407
0
        F: FnMut(&T) -> bool,
408
0
    {
409
0
        ExtractIf {
410
0
            f,
411
0
            inner: RawExtractIf {
412
0
                iter: unsafe { self.map.table.iter() },
413
0
                table: &mut self.map.table,
414
0
            },
415
0
        }
416
0
    }
417
418
    /// Clears the set, removing all values.
419
    ///
420
    /// # Examples
421
    ///
422
    /// ```
423
    /// use hashbrown::HashSet;
424
    ///
425
    /// let mut v = HashSet::new();
426
    /// v.insert(1);
427
    /// v.clear();
428
    /// assert!(v.is_empty());
429
    /// ```
430
    #[cfg_attr(feature = "inline-more", inline)]
431
0
    pub fn clear(&mut self) {
432
0
        self.map.clear();
433
0
    }
434
}
435
436
impl<T, S> HashSet<T, S, Global> {
437
    /// Creates a new empty hash set which will use the given hasher to hash
438
    /// keys.
439
    ///
440
    /// The hash set is initially created with a capacity of 0, so it will not
441
    /// allocate until it is first inserted into.
442
    ///
443
    /// # HashDoS resistance
444
    ///
445
    /// The `hash_builder` normally use a fixed key by default and that does
446
    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
447
    /// Users who require HashDoS resistance should explicitly use
448
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
449
    /// as the hasher when creating a [`HashSet`].
450
    ///
451
    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
452
    /// the HashSet to be useful, see its documentation for details.
453
    ///
454
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
455
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
456
    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
457
    ///
458
    /// # Examples
459
    ///
460
    /// ```
461
    /// use hashbrown::HashSet;
462
    /// use hashbrown::hash_map::DefaultHashBuilder;
463
    ///
464
    /// let s = DefaultHashBuilder::default();
465
    /// let mut set = HashSet::with_hasher(s);
466
    /// set.insert(2);
467
    /// ```
468
    #[cfg_attr(feature = "inline-more", inline)]
469
0
    pub const fn with_hasher(hasher: S) -> Self {
470
0
        Self {
471
0
            map: HashMap::with_hasher(hasher),
472
0
        }
473
0
    }
474
475
    /// Creates an empty `HashSet` with the specified capacity, using
476
    /// `hasher` to hash the keys.
477
    ///
478
    /// The hash set will be able to hold at least `capacity` elements without
479
    /// reallocating. If `capacity` is 0, the hash set will not allocate.
480
    ///
481
    /// # HashDoS resistance
482
    ///
483
    /// The `hash_builder` normally use a fixed key by default and that does
484
    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
485
    /// Users who require HashDoS resistance should explicitly use
486
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
487
    /// as the hasher when creating a [`HashSet`].
488
    ///
489
    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
490
    /// the HashSet to be useful, see its documentation for details.
491
    ///
492
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
493
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
494
    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
495
    ///
496
    /// # Examples
497
    ///
498
    /// ```
499
    /// use hashbrown::HashSet;
500
    /// use hashbrown::hash_map::DefaultHashBuilder;
501
    ///
502
    /// let s = DefaultHashBuilder::default();
503
    /// let mut set = HashSet::with_capacity_and_hasher(10, s);
504
    /// set.insert(1);
505
    /// ```
506
    #[cfg_attr(feature = "inline-more", inline)]
507
0
    pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
508
0
        Self {
509
0
            map: HashMap::with_capacity_and_hasher(capacity, hasher),
510
0
        }
511
0
    }
512
}
513
514
impl<T, S, A> HashSet<T, S, A>
515
where
516
    A: Allocator,
517
{
518
    /// Returns a reference to the underlying allocator.
519
    #[inline]
520
0
    pub fn allocator(&self) -> &A {
521
0
        self.map.allocator()
522
0
    }
523
524
    /// Creates a new empty hash set which will use the given hasher to hash
525
    /// keys.
526
    ///
527
    /// The hash set is initially created with a capacity of 0, so it will not
528
    /// allocate until it is first inserted into.
529
    ///
530
    /// # HashDoS resistance
531
    ///
532
    /// The `hash_builder` normally use a fixed key by default and that does
533
    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
534
    /// Users who require HashDoS resistance should explicitly use
535
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
536
    /// as the hasher when creating a [`HashSet`].
537
    ///
538
    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
539
    /// the HashSet to be useful, see its documentation for details.
540
    ///
541
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
542
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
543
    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
544
    ///
545
    /// # Examples
546
    ///
547
    /// ```
548
    /// use hashbrown::HashSet;
549
    /// use hashbrown::hash_map::DefaultHashBuilder;
550
    ///
551
    /// let s = DefaultHashBuilder::default();
552
    /// let mut set = HashSet::with_hasher(s);
553
    /// set.insert(2);
554
    /// ```
555
    #[cfg_attr(feature = "inline-more", inline)]
556
0
    pub const fn with_hasher_in(hasher: S, alloc: A) -> Self {
557
0
        Self {
558
0
            map: HashMap::with_hasher_in(hasher, alloc),
559
0
        }
560
0
    }
561
562
    /// Creates an empty `HashSet` with the specified capacity, using
563
    /// `hasher` to hash the keys.
564
    ///
565
    /// The hash set will be able to hold at least `capacity` elements without
566
    /// reallocating. If `capacity` is 0, the hash set will not allocate.
567
    ///
568
    /// # HashDoS resistance
569
    ///
570
    /// The `hash_builder` normally use a fixed key by default and that does
571
    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
572
    /// Users who require HashDoS resistance should explicitly use
573
    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
574
    /// as the hasher when creating a [`HashSet`].
575
    ///
576
    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
577
    /// the HashSet to be useful, see its documentation for details.
578
    ///
579
    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
580
    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
581
    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
582
    ///
583
    /// # Examples
584
    ///
585
    /// ```
586
    /// use hashbrown::HashSet;
587
    /// use hashbrown::hash_map::DefaultHashBuilder;
588
    ///
589
    /// let s = DefaultHashBuilder::default();
590
    /// let mut set = HashSet::with_capacity_and_hasher(10, s);
591
    /// set.insert(1);
592
    /// ```
593
    #[cfg_attr(feature = "inline-more", inline)]
594
0
    pub fn with_capacity_and_hasher_in(capacity: usize, hasher: S, alloc: A) -> Self {
595
0
        Self {
596
0
            map: HashMap::with_capacity_and_hasher_in(capacity, hasher, alloc),
597
0
        }
598
0
    }
599
600
    /// Returns a reference to the set's [`BuildHasher`].
601
    ///
602
    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
603
    ///
604
    /// # Examples
605
    ///
606
    /// ```
607
    /// use hashbrown::HashSet;
608
    /// use hashbrown::hash_map::DefaultHashBuilder;
609
    ///
610
    /// let hasher = DefaultHashBuilder::default();
611
    /// let set: HashSet<i32> = HashSet::with_hasher(hasher);
612
    /// let hasher: &DefaultHashBuilder = set.hasher();
613
    /// ```
614
    #[cfg_attr(feature = "inline-more", inline)]
615
0
    pub fn hasher(&self) -> &S {
616
0
        self.map.hasher()
617
0
    }
618
}
619
620
impl<T, S, A> HashSet<T, S, A>
621
where
622
    T: Eq + Hash,
623
    S: BuildHasher,
624
    A: Allocator,
625
{
626
    /// Reserves capacity for at least `additional` more elements to be inserted
627
    /// in the `HashSet`. The collection may reserve more space to avoid
628
    /// frequent reallocations.
629
    ///
630
    /// # Panics
631
    ///
632
    /// Panics if the new capacity exceeds [`isize::MAX`] bytes and [`abort`] the program
633
    /// in case of allocation error. Use [`try_reserve`](HashSet::try_reserve) instead
634
    /// if you want to handle memory allocation failure.
635
    ///
636
    /// [`isize::MAX`]: https://doc.rust-lang.org/std/primitive.isize.html
637
    /// [`abort`]: https://doc.rust-lang.org/alloc/alloc/fn.handle_alloc_error.html
638
    ///
639
    /// # Examples
640
    ///
641
    /// ```
642
    /// use hashbrown::HashSet;
643
    /// let mut set: HashSet<i32> = HashSet::new();
644
    /// set.reserve(10);
645
    /// assert!(set.capacity() >= 10);
646
    /// ```
647
    #[cfg_attr(feature = "inline-more", inline)]
648
0
    pub fn reserve(&mut self, additional: usize) {
649
0
        self.map.reserve(additional);
650
0
    }
651
652
    /// Tries to reserve capacity for at least `additional` more elements to be inserted
653
    /// in the given `HashSet<K,V>`. The collection may reserve more space to avoid
654
    /// frequent reallocations.
655
    ///
656
    /// # Errors
657
    ///
658
    /// If the capacity overflows, or the allocator reports a failure, then an error
659
    /// is returned.
660
    ///
661
    /// # Examples
662
    ///
663
    /// ```
664
    /// use hashbrown::HashSet;
665
    /// let mut set: HashSet<i32> = HashSet::new();
666
    /// set.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
667
    /// ```
668
    #[cfg_attr(feature = "inline-more", inline)]
669
0
    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
670
0
        self.map.try_reserve(additional)
671
0
    }
672
673
    /// Shrinks the capacity of the set as much as possible. It will drop
674
    /// down as much as possible while maintaining the internal rules
675
    /// and possibly leaving some space in accordance with the resize policy.
676
    ///
677
    /// # Examples
678
    ///
679
    /// ```
680
    /// use hashbrown::HashSet;
681
    ///
682
    /// let mut set = HashSet::with_capacity(100);
683
    /// set.insert(1);
684
    /// set.insert(2);
685
    /// assert!(set.capacity() >= 100);
686
    /// set.shrink_to_fit();
687
    /// assert!(set.capacity() >= 2);
688
    /// ```
689
    #[cfg_attr(feature = "inline-more", inline)]
690
0
    pub fn shrink_to_fit(&mut self) {
691
0
        self.map.shrink_to_fit();
692
0
    }
693
694
    /// Shrinks the capacity of the set with a lower limit. It will drop
695
    /// down no lower than the supplied limit while maintaining the internal rules
696
    /// and possibly leaving some space in accordance with the resize policy.
697
    ///
698
    /// Panics if the current capacity is smaller than the supplied
699
    /// minimum capacity.
700
    ///
701
    /// # Examples
702
    ///
703
    /// ```
704
    /// use hashbrown::HashSet;
705
    ///
706
    /// let mut set = HashSet::with_capacity(100);
707
    /// set.insert(1);
708
    /// set.insert(2);
709
    /// assert!(set.capacity() >= 100);
710
    /// set.shrink_to(10);
711
    /// assert!(set.capacity() >= 10);
712
    /// set.shrink_to(0);
713
    /// assert!(set.capacity() >= 2);
714
    /// ```
715
    #[cfg_attr(feature = "inline-more", inline)]
716
0
    pub fn shrink_to(&mut self, min_capacity: usize) {
717
0
        self.map.shrink_to(min_capacity);
718
0
    }
719
720
    /// Visits the values representing the difference,
721
    /// i.e., the values that are in `self` but not in `other`.
722
    ///
723
    /// # Examples
724
    ///
725
    /// ```
726
    /// use hashbrown::HashSet;
727
    /// let a: HashSet<_> = [1, 2, 3].into_iter().collect();
728
    /// let b: HashSet<_> = [4, 2, 3, 4].into_iter().collect();
729
    ///
730
    /// // Can be seen as `a - b`.
731
    /// for x in a.difference(&b) {
732
    ///     println!("{}", x); // Print 1
733
    /// }
734
    ///
735
    /// let diff: HashSet<_> = a.difference(&b).collect();
736
    /// assert_eq!(diff, [1].iter().collect());
737
    ///
738
    /// // Note that difference is not symmetric,
739
    /// // and `b - a` means something else:
740
    /// let diff: HashSet<_> = b.difference(&a).collect();
741
    /// assert_eq!(diff, [4].iter().collect());
742
    /// ```
743
    #[cfg_attr(feature = "inline-more", inline)]
744
0
    pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, T, S, A> {
745
0
        Difference {
746
0
            iter: self.iter(),
747
0
            other,
748
0
        }
749
0
    }
750
751
    /// Visits the values representing the symmetric difference,
752
    /// i.e., the values that are in `self` or in `other` but not in both.
753
    ///
754
    /// # Examples
755
    ///
756
    /// ```
757
    /// use hashbrown::HashSet;
758
    /// let a: HashSet<_> = [1, 2, 3].into_iter().collect();
759
    /// let b: HashSet<_> = [4, 2, 3, 4].into_iter().collect();
760
    ///
761
    /// // Print 1, 4 in arbitrary order.
762
    /// for x in a.symmetric_difference(&b) {
763
    ///     println!("{}", x);
764
    /// }
765
    ///
766
    /// let diff1: HashSet<_> = a.symmetric_difference(&b).collect();
767
    /// let diff2: HashSet<_> = b.symmetric_difference(&a).collect();
768
    ///
769
    /// assert_eq!(diff1, diff2);
770
    /// assert_eq!(diff1, [1, 4].iter().collect());
771
    /// ```
772
    #[cfg_attr(feature = "inline-more", inline)]
773
0
    pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, T, S, A> {
774
0
        SymmetricDifference {
775
0
            iter: self.difference(other).chain(other.difference(self)),
776
0
        }
777
0
    }
778
779
    /// Visits the values representing the intersection,
780
    /// i.e., the values that are both in `self` and `other`.
781
    ///
782
    /// # Examples
783
    ///
784
    /// ```
785
    /// use hashbrown::HashSet;
786
    /// let a: HashSet<_> = [1, 2, 3].into_iter().collect();
787
    /// let b: HashSet<_> = [4, 2, 3, 4].into_iter().collect();
788
    ///
789
    /// // Print 2, 3 in arbitrary order.
790
    /// for x in a.intersection(&b) {
791
    ///     println!("{}", x);
792
    /// }
793
    ///
794
    /// let intersection: HashSet<_> = a.intersection(&b).collect();
795
    /// assert_eq!(intersection, [2, 3].iter().collect());
796
    /// ```
797
    #[cfg_attr(feature = "inline-more", inline)]
798
0
    pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, T, S, A> {
799
0
        let (smaller, larger) = if self.len() <= other.len() {
800
0
            (self, other)
801
        } else {
802
0
            (other, self)
803
        };
804
0
        Intersection {
805
0
            iter: smaller.iter(),
806
0
            other: larger,
807
0
        }
808
0
    }
809
810
    /// Visits the values representing the union,
811
    /// i.e., all the values in `self` or `other`, without duplicates.
812
    ///
813
    /// # Examples
814
    ///
815
    /// ```
816
    /// use hashbrown::HashSet;
817
    /// let a: HashSet<_> = [1, 2, 3].into_iter().collect();
818
    /// let b: HashSet<_> = [4, 2, 3, 4].into_iter().collect();
819
    ///
820
    /// // Print 1, 2, 3, 4 in arbitrary order.
821
    /// for x in a.union(&b) {
822
    ///     println!("{}", x);
823
    /// }
824
    ///
825
    /// let union: HashSet<_> = a.union(&b).collect();
826
    /// assert_eq!(union, [1, 2, 3, 4].iter().collect());
827
    /// ```
828
    #[cfg_attr(feature = "inline-more", inline)]
829
0
    pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T, S, A> {
830
        // We'll iterate one set in full, and only the remaining difference from the other.
831
        // Use the smaller set for the difference in order to reduce hash lookups.
832
0
        let (smaller, larger) = if self.len() <= other.len() {
833
0
            (self, other)
834
        } else {
835
0
            (other, self)
836
        };
837
0
        Union {
838
0
            iter: larger.iter().chain(smaller.difference(larger)),
839
0
        }
840
0
    }
841
842
    /// Returns `true` if the set contains a value.
843
    ///
844
    /// The value may be any borrowed form of the set's value type, but
845
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
846
    /// the value type.
847
    ///
848
    /// # Examples
849
    ///
850
    /// ```
851
    /// use hashbrown::HashSet;
852
    ///
853
    /// let set: HashSet<_> = [1, 2, 3].into_iter().collect();
854
    /// assert_eq!(set.contains(&1), true);
855
    /// assert_eq!(set.contains(&4), false);
856
    /// ```
857
    ///
858
    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
859
    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
860
    #[cfg_attr(feature = "inline-more", inline)]
861
0
    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
862
0
    where
863
0
        Q: Hash + Equivalent<T>,
864
0
    {
865
0
        self.map.contains_key(value)
866
0
    }
867
868
    /// Returns a reference to the value in the set, if any, that is equal to the given value.
869
    ///
870
    /// The value may be any borrowed form of the set's value type, but
871
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
872
    /// the value type.
873
    ///
874
    /// # Examples
875
    ///
876
    /// ```
877
    /// use hashbrown::HashSet;
878
    ///
879
    /// let set: HashSet<_> = [1, 2, 3].into_iter().collect();
880
    /// assert_eq!(set.get(&2), Some(&2));
881
    /// assert_eq!(set.get(&4), None);
882
    /// ```
883
    ///
884
    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
885
    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
886
    #[cfg_attr(feature = "inline-more", inline)]
887
0
    pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
888
0
    where
889
0
        Q: Hash + Equivalent<T>,
890
0
    {
891
0
        // Avoid `Option::map` because it bloats LLVM IR.
892
0
        match self.map.get_key_value(value) {
893
0
            Some((k, _)) => Some(k),
894
0
            None => None,
895
        }
896
0
    }
897
898
    /// Inserts the given `value` into the set if it is not present, then
899
    /// returns a reference to the value in the set.
900
    ///
901
    /// # Examples
902
    ///
903
    /// ```
904
    /// use hashbrown::HashSet;
905
    ///
906
    /// let mut set: HashSet<_> = [1, 2, 3].into_iter().collect();
907
    /// assert_eq!(set.len(), 3);
908
    /// assert_eq!(set.get_or_insert(2), &2);
909
    /// assert_eq!(set.get_or_insert(100), &100);
910
    /// assert_eq!(set.len(), 4); // 100 was inserted
911
    /// ```
912
    #[cfg_attr(feature = "inline-more", inline)]
913
0
    pub fn get_or_insert(&mut self, value: T) -> &T {
914
0
        // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
915
0
        // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
916
0
        self.map
917
0
            .raw_entry_mut()
918
0
            .from_key(&value)
919
0
            .or_insert(value, ())
920
0
            .0
921
0
    }
922
923
    /// Inserts an owned copy of the given `value` into the set if it is not
924
    /// present, then returns a reference to the value in the set.
925
    ///
926
    /// # Examples
927
    ///
928
    /// ```
929
    /// use hashbrown::HashSet;
930
    ///
931
    /// let mut set: HashSet<String> = ["cat", "dog", "horse"]
932
    ///     .iter().map(|&pet| pet.to_owned()).collect();
933
    ///
934
    /// assert_eq!(set.len(), 3);
935
    /// for &pet in &["cat", "dog", "fish"] {
936
    ///     let value = set.get_or_insert_owned(pet);
937
    ///     assert_eq!(value, pet);
938
    /// }
939
    /// assert_eq!(set.len(), 4); // a new "fish" was inserted
940
    /// ```
941
    #[inline]
942
0
    pub fn get_or_insert_owned<Q: ?Sized>(&mut self, value: &Q) -> &T
943
0
    where
944
0
        Q: Hash + Equivalent<T> + ToOwned<Owned = T>,
945
0
    {
946
0
        // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
947
0
        // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
948
0
        self.map
949
0
            .raw_entry_mut()
950
0
            .from_key(value)
951
0
            .or_insert_with(|| (value.to_owned(), ()))
952
0
            .0
953
0
    }
954
955
    /// Inserts a value computed from `f` into the set if the given `value` is
956
    /// not present, then returns a reference to the value in the set.
957
    ///
958
    /// # Examples
959
    ///
960
    /// ```
961
    /// use hashbrown::HashSet;
962
    ///
963
    /// let mut set: HashSet<String> = ["cat", "dog", "horse"]
964
    ///     .iter().map(|&pet| pet.to_owned()).collect();
965
    ///
966
    /// assert_eq!(set.len(), 3);
967
    /// for &pet in &["cat", "dog", "fish"] {
968
    ///     let value = set.get_or_insert_with(pet, str::to_owned);
969
    ///     assert_eq!(value, pet);
970
    /// }
971
    /// assert_eq!(set.len(), 4); // a new "fish" was inserted
972
    /// ```
973
    #[cfg_attr(feature = "inline-more", inline)]
974
0
    pub fn get_or_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> &T
975
0
    where
976
0
        Q: Hash + Equivalent<T>,
977
0
        F: FnOnce(&Q) -> T,
978
0
    {
979
0
        // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
980
0
        // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
981
0
        self.map
982
0
            .raw_entry_mut()
983
0
            .from_key(value)
984
0
            .or_insert_with(|| (f(value), ()))
985
0
            .0
986
0
    }
987
988
    /// Gets the given value's corresponding entry in the set for in-place manipulation.
989
    ///
990
    /// # Examples
991
    ///
992
    /// ```
993
    /// use hashbrown::HashSet;
994
    /// use hashbrown::hash_set::Entry::*;
995
    ///
996
    /// let mut singles = HashSet::new();
997
    /// let mut dupes = HashSet::new();
998
    ///
999
    /// for ch in "a short treatise on fungi".chars() {
1000
    ///     if let Vacant(dupe_entry) = dupes.entry(ch) {
1001
    ///         // We haven't already seen a duplicate, so
1002
    ///         // check if we've at least seen it once.
1003
    ///         match singles.entry(ch) {
1004
    ///             Vacant(single_entry) => {
1005
    ///                 // We found a new character for the first time.
1006
    ///                 single_entry.insert()
1007
    ///             }
1008
    ///             Occupied(single_entry) => {
1009
    ///                 // We've already seen this once, "move" it to dupes.
1010
    ///                 single_entry.remove();
1011
    ///                 dupe_entry.insert();
1012
    ///             }
1013
    ///         }
1014
    ///     }
1015
    /// }
1016
    ///
1017
    /// assert!(!singles.contains(&'t') && dupes.contains(&'t'));
1018
    /// assert!(singles.contains(&'u') && !dupes.contains(&'u'));
1019
    /// assert!(!singles.contains(&'v') && !dupes.contains(&'v'));
1020
    /// ```
1021
    #[cfg_attr(feature = "inline-more", inline)]
1022
0
    pub fn entry(&mut self, value: T) -> Entry<'_, T, S, A> {
1023
0
        match self.map.entry(value) {
1024
0
            map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { inner: entry }),
1025
0
            map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { inner: entry }),
1026
        }
1027
0
    }
1028
1029
    /// Returns `true` if `self` has no elements in common with `other`.
1030
    /// This is equivalent to checking for an empty intersection.
1031
    ///
1032
    /// # Examples
1033
    ///
1034
    /// ```
1035
    /// use hashbrown::HashSet;
1036
    ///
1037
    /// let a: HashSet<_> = [1, 2, 3].into_iter().collect();
1038
    /// let mut b = HashSet::new();
1039
    ///
1040
    /// assert_eq!(a.is_disjoint(&b), true);
1041
    /// b.insert(4);
1042
    /// assert_eq!(a.is_disjoint(&b), true);
1043
    /// b.insert(1);
1044
    /// assert_eq!(a.is_disjoint(&b), false);
1045
    /// ```
1046
0
    pub fn is_disjoint(&self, other: &Self) -> bool {
1047
0
        self.iter().all(|v| !other.contains(v))
1048
0
    }
1049
1050
    /// Returns `true` if the set is a subset of another,
1051
    /// i.e., `other` contains at least all the values in `self`.
1052
    ///
1053
    /// # Examples
1054
    ///
1055
    /// ```
1056
    /// use hashbrown::HashSet;
1057
    ///
1058
    /// let sup: HashSet<_> = [1, 2, 3].into_iter().collect();
1059
    /// let mut set = HashSet::new();
1060
    ///
1061
    /// assert_eq!(set.is_subset(&sup), true);
1062
    /// set.insert(2);
1063
    /// assert_eq!(set.is_subset(&sup), true);
1064
    /// set.insert(4);
1065
    /// assert_eq!(set.is_subset(&sup), false);
1066
    /// ```
1067
0
    pub fn is_subset(&self, other: &Self) -> bool {
1068
0
        self.len() <= other.len() && self.iter().all(|v| other.contains(v))
1069
0
    }
1070
1071
    /// Returns `true` if the set is a superset of another,
1072
    /// i.e., `self` contains at least all the values in `other`.
1073
    ///
1074
    /// # Examples
1075
    ///
1076
    /// ```
1077
    /// use hashbrown::HashSet;
1078
    ///
1079
    /// let sub: HashSet<_> = [1, 2].into_iter().collect();
1080
    /// let mut set = HashSet::new();
1081
    ///
1082
    /// assert_eq!(set.is_superset(&sub), false);
1083
    ///
1084
    /// set.insert(0);
1085
    /// set.insert(1);
1086
    /// assert_eq!(set.is_superset(&sub), false);
1087
    ///
1088
    /// set.insert(2);
1089
    /// assert_eq!(set.is_superset(&sub), true);
1090
    /// ```
1091
    #[cfg_attr(feature = "inline-more", inline)]
1092
0
    pub fn is_superset(&self, other: &Self) -> bool {
1093
0
        other.is_subset(self)
1094
0
    }
1095
1096
    /// Adds a value to the set.
1097
    ///
1098
    /// If the set did not have this value present, `true` is returned.
1099
    ///
1100
    /// If the set did have this value present, `false` is returned.
1101
    ///
1102
    /// # Examples
1103
    ///
1104
    /// ```
1105
    /// use hashbrown::HashSet;
1106
    ///
1107
    /// let mut set = HashSet::new();
1108
    ///
1109
    /// assert_eq!(set.insert(2), true);
1110
    /// assert_eq!(set.insert(2), false);
1111
    /// assert_eq!(set.len(), 1);
1112
    /// ```
1113
    #[cfg_attr(feature = "inline-more", inline)]
1114
0
    pub fn insert(&mut self, value: T) -> bool {
1115
0
        self.map.insert(value, ()).is_none()
1116
0
    }
1117
1118
    /// Insert a value the set without checking if the value already exists in the set.
1119
    ///
1120
    /// Returns a reference to the value just inserted.
1121
    ///
1122
    /// This operation is safe if a value does not exist in the set.
1123
    ///
1124
    /// However, if a value exists in the set already, the behavior is unspecified:
1125
    /// this operation may panic, loop forever, or any following operation with the set
1126
    /// may panic, loop forever or return arbitrary result.
1127
    ///
1128
    /// That said, this operation (and following operations) are guaranteed to
1129
    /// not violate memory safety.
1130
    ///
1131
    /// This operation is faster than regular insert, because it does not perform
1132
    /// lookup before insertion.
1133
    ///
1134
    /// This operation is useful during initial population of the set.
1135
    /// For example, when constructing a set from another set, we know
1136
    /// that values are unique.
1137
    #[cfg_attr(feature = "inline-more", inline)]
1138
0
    pub fn insert_unique_unchecked(&mut self, value: T) -> &T {
1139
0
        self.map.insert_unique_unchecked(value, ()).0
1140
0
    }
1141
1142
    /// Adds a value to the set, replacing the existing value, if any, that is equal to the given
1143
    /// one. Returns the replaced value.
1144
    ///
1145
    /// # Examples
1146
    ///
1147
    /// ```
1148
    /// use hashbrown::HashSet;
1149
    ///
1150
    /// let mut set = HashSet::new();
1151
    /// set.insert(Vec::<i32>::new());
1152
    ///
1153
    /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 0);
1154
    /// set.replace(Vec::with_capacity(10));
1155
    /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 10);
1156
    /// ```
1157
    #[cfg_attr(feature = "inline-more", inline)]
1158
0
    pub fn replace(&mut self, value: T) -> Option<T> {
1159
0
        match self.map.entry(value) {
1160
0
            map::Entry::Occupied(occupied) => Some(occupied.replace_key()),
1161
0
            map::Entry::Vacant(vacant) => {
1162
0
                vacant.insert(());
1163
0
                None
1164
            }
1165
        }
1166
0
    }
1167
1168
    /// Removes a value from the set. Returns whether the value was
1169
    /// present in the set.
1170
    ///
1171
    /// The value may be any borrowed form of the set's value type, but
1172
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1173
    /// the value type.
1174
    ///
1175
    /// # Examples
1176
    ///
1177
    /// ```
1178
    /// use hashbrown::HashSet;
1179
    ///
1180
    /// let mut set = HashSet::new();
1181
    ///
1182
    /// set.insert(2);
1183
    /// assert_eq!(set.remove(&2), true);
1184
    /// assert_eq!(set.remove(&2), false);
1185
    /// ```
1186
    ///
1187
    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1188
    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1189
    #[cfg_attr(feature = "inline-more", inline)]
1190
0
    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
1191
0
    where
1192
0
        Q: Hash + Equivalent<T>,
1193
0
    {
1194
0
        self.map.remove(value).is_some()
1195
0
    }
1196
1197
    /// Removes and returns the value in the set, if any, that is equal to the given one.
1198
    ///
1199
    /// The value may be any borrowed form of the set's value type, but
1200
    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1201
    /// the value type.
1202
    ///
1203
    /// # Examples
1204
    ///
1205
    /// ```
1206
    /// use hashbrown::HashSet;
1207
    ///
1208
    /// let mut set: HashSet<_> = [1, 2, 3].into_iter().collect();
1209
    /// assert_eq!(set.take(&2), Some(2));
1210
    /// assert_eq!(set.take(&2), None);
1211
    /// ```
1212
    ///
1213
    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1214
    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1215
    #[cfg_attr(feature = "inline-more", inline)]
1216
0
    pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
1217
0
    where
1218
0
        Q: Hash + Equivalent<T>,
1219
0
    {
1220
0
        // Avoid `Option::map` because it bloats LLVM IR.
1221
0
        match self.map.remove_entry(value) {
1222
0
            Some((k, _)) => Some(k),
1223
0
            None => None,
1224
        }
1225
0
    }
1226
}
1227
1228
impl<T, S, A: Allocator> HashSet<T, S, A> {
1229
    /// Returns a reference to the [`RawTable`] used underneath [`HashSet`].
1230
    /// This function is only available if the `raw` feature of the crate is enabled.
1231
    ///
1232
    /// # Note
1233
    ///
1234
    /// Calling this function is safe, but using the raw hash table API may require
1235
    /// unsafe functions or blocks.
1236
    ///
1237
    /// `RawTable` API gives the lowest level of control under the set that can be useful
1238
    /// for extending the HashSet's API, but may lead to *[undefined behavior]*.
1239
    ///
1240
    /// [`HashSet`]: struct.HashSet.html
1241
    /// [`RawTable`]: crate::raw::RawTable
1242
    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1243
    #[cfg(feature = "raw")]
1244
    #[cfg_attr(feature = "inline-more", inline)]
1245
    pub fn raw_table(&self) -> &RawTable<(T, ()), A> {
1246
        self.map.raw_table()
1247
    }
1248
1249
    /// Returns a mutable reference to the [`RawTable`] used underneath [`HashSet`].
1250
    /// This function is only available if the `raw` feature of the crate is enabled.
1251
    ///
1252
    /// # Note
1253
    ///
1254
    /// Calling this function is safe, but using the raw hash table API may require
1255
    /// unsafe functions or blocks.
1256
    ///
1257
    /// `RawTable` API gives the lowest level of control under the set that can be useful
1258
    /// for extending the HashSet's API, but may lead to *[undefined behavior]*.
1259
    ///
1260
    /// [`HashSet`]: struct.HashSet.html
1261
    /// [`RawTable`]: crate::raw::RawTable
1262
    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1263
    #[cfg(feature = "raw")]
1264
    #[cfg_attr(feature = "inline-more", inline)]
1265
    pub fn raw_table_mut(&mut self) -> &mut RawTable<(T, ()), A> {
1266
        self.map.raw_table_mut()
1267
    }
1268
}
1269
1270
impl<T, S, A> PartialEq for HashSet<T, S, A>
1271
where
1272
    T: Eq + Hash,
1273
    S: BuildHasher,
1274
    A: Allocator,
1275
{
1276
0
    fn eq(&self, other: &Self) -> bool {
1277
0
        if self.len() != other.len() {
1278
0
            return false;
1279
0
        }
1280
0
1281
0
        self.iter().all(|key| other.contains(key))
1282
0
    }
1283
}
1284
1285
impl<T, S, A> Eq for HashSet<T, S, A>
1286
where
1287
    T: Eq + Hash,
1288
    S: BuildHasher,
1289
    A: Allocator,
1290
{
1291
}
1292
1293
impl<T, S, A> fmt::Debug for HashSet<T, S, A>
1294
where
1295
    T: fmt::Debug,
1296
    A: Allocator,
1297
{
1298
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1299
0
        f.debug_set().entries(self.iter()).finish()
1300
0
    }
1301
}
1302
1303
impl<T, S, A> From<HashMap<T, (), S, A>> for HashSet<T, S, A>
1304
where
1305
    A: Allocator,
1306
{
1307
0
    fn from(map: HashMap<T, (), S, A>) -> Self {
1308
0
        Self { map }
1309
0
    }
1310
}
1311
1312
impl<T, S, A> FromIterator<T> for HashSet<T, S, A>
1313
where
1314
    T: Eq + Hash,
1315
    S: BuildHasher + Default,
1316
    A: Default + Allocator,
1317
{
1318
    #[cfg_attr(feature = "inline-more", inline)]
1319
0
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1320
0
        let mut set = Self::with_hasher_in(Default::default(), Default::default());
1321
0
        set.extend(iter);
1322
0
        set
1323
0
    }
1324
}
1325
1326
// The default hasher is used to match the std implementation signature
1327
#[cfg(feature = "ahash")]
1328
impl<T, A, const N: usize> From<[T; N]> for HashSet<T, DefaultHashBuilder, A>
1329
where
1330
    T: Eq + Hash,
1331
    A: Default + Allocator,
1332
{
1333
    /// # Examples
1334
    ///
1335
    /// ```
1336
    /// use hashbrown::HashSet;
1337
    ///
1338
    /// let set1 = HashSet::from([1, 2, 3, 4]);
1339
    /// let set2: HashSet<_> = [1, 2, 3, 4].into();
1340
    /// assert_eq!(set1, set2);
1341
    /// ```
1342
0
    fn from(arr: [T; N]) -> Self {
1343
0
        arr.into_iter().collect()
1344
0
    }
1345
}
1346
1347
impl<T, S, A> Extend<T> for HashSet<T, S, A>
1348
where
1349
    T: Eq + Hash,
1350
    S: BuildHasher,
1351
    A: Allocator,
1352
{
1353
    #[cfg_attr(feature = "inline-more", inline)]
1354
0
    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1355
0
        self.map.extend(iter.into_iter().map(|k| (k, ())));
1356
0
    }
1357
1358
    #[inline]
1359
    #[cfg(feature = "nightly")]
1360
    fn extend_one(&mut self, k: T) {
1361
        self.map.insert(k, ());
1362
    }
1363
1364
    #[inline]
1365
    #[cfg(feature = "nightly")]
1366
    fn extend_reserve(&mut self, additional: usize) {
1367
        Extend::<(T, ())>::extend_reserve(&mut self.map, additional);
1368
    }
1369
}
1370
1371
impl<'a, T, S, A> Extend<&'a T> for HashSet<T, S, A>
1372
where
1373
    T: 'a + Eq + Hash + Copy,
1374
    S: BuildHasher,
1375
    A: Allocator,
1376
{
1377
    #[cfg_attr(feature = "inline-more", inline)]
1378
0
    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
1379
0
        self.extend(iter.into_iter().copied());
1380
0
    }
1381
1382
    #[inline]
1383
    #[cfg(feature = "nightly")]
1384
    fn extend_one(&mut self, k: &'a T) {
1385
        self.map.insert(*k, ());
1386
    }
1387
1388
    #[inline]
1389
    #[cfg(feature = "nightly")]
1390
    fn extend_reserve(&mut self, additional: usize) {
1391
        Extend::<(T, ())>::extend_reserve(&mut self.map, additional);
1392
    }
1393
}
1394
1395
impl<T, S, A> Default for HashSet<T, S, A>
1396
where
1397
    S: Default,
1398
    A: Default + Allocator,
1399
{
1400
    /// Creates an empty `HashSet<T, S>` with the `Default` value for the hasher.
1401
    #[cfg_attr(feature = "inline-more", inline)]
1402
0
    fn default() -> Self {
1403
0
        Self {
1404
0
            map: HashMap::default(),
1405
0
        }
1406
0
    }
1407
}
1408
1409
impl<T, S, A> BitOr<&HashSet<T, S, A>> for &HashSet<T, S, A>
1410
where
1411
    T: Eq + Hash + Clone,
1412
    S: BuildHasher + Default,
1413
    A: Allocator,
1414
{
1415
    type Output = HashSet<T, S>;
1416
1417
    /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.
1418
    ///
1419
    /// # Examples
1420
    ///
1421
    /// ```
1422
    /// use hashbrown::HashSet;
1423
    ///
1424
    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1425
    /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1426
    ///
1427
    /// let set = &a | &b;
1428
    ///
1429
    /// let mut i = 0;
1430
    /// let expected = [1, 2, 3, 4, 5];
1431
    /// for x in &set {
1432
    ///     assert!(expected.contains(x));
1433
    ///     i += 1;
1434
    /// }
1435
    /// assert_eq!(i, expected.len());
1436
    /// ```
1437
0
    fn bitor(self, rhs: &HashSet<T, S, A>) -> HashSet<T, S> {
1438
0
        self.union(rhs).cloned().collect()
1439
0
    }
1440
}
1441
1442
impl<T, S, A> BitAnd<&HashSet<T, S, A>> for &HashSet<T, S, A>
1443
where
1444
    T: Eq + Hash + Clone,
1445
    S: BuildHasher + Default,
1446
    A: Allocator,
1447
{
1448
    type Output = HashSet<T, S>;
1449
1450
    /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.
1451
    ///
1452
    /// # Examples
1453
    ///
1454
    /// ```
1455
    /// use hashbrown::HashSet;
1456
    ///
1457
    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1458
    /// let b: HashSet<_> = vec![2, 3, 4].into_iter().collect();
1459
    ///
1460
    /// let set = &a & &b;
1461
    ///
1462
    /// let mut i = 0;
1463
    /// let expected = [2, 3];
1464
    /// for x in &set {
1465
    ///     assert!(expected.contains(x));
1466
    ///     i += 1;
1467
    /// }
1468
    /// assert_eq!(i, expected.len());
1469
    /// ```
1470
0
    fn bitand(self, rhs: &HashSet<T, S, A>) -> HashSet<T, S> {
1471
0
        self.intersection(rhs).cloned().collect()
1472
0
    }
1473
}
1474
1475
impl<T, S> BitXor<&HashSet<T, S>> for &HashSet<T, S>
1476
where
1477
    T: Eq + Hash + Clone,
1478
    S: BuildHasher + Default,
1479
{
1480
    type Output = HashSet<T, S>;
1481
1482
    /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.
1483
    ///
1484
    /// # Examples
1485
    ///
1486
    /// ```
1487
    /// use hashbrown::HashSet;
1488
    ///
1489
    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1490
    /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1491
    ///
1492
    /// let set = &a ^ &b;
1493
    ///
1494
    /// let mut i = 0;
1495
    /// let expected = [1, 2, 4, 5];
1496
    /// for x in &set {
1497
    ///     assert!(expected.contains(x));
1498
    ///     i += 1;
1499
    /// }
1500
    /// assert_eq!(i, expected.len());
1501
    /// ```
1502
0
    fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1503
0
        self.symmetric_difference(rhs).cloned().collect()
1504
0
    }
1505
}
1506
1507
impl<T, S> Sub<&HashSet<T, S>> for &HashSet<T, S>
1508
where
1509
    T: Eq + Hash + Clone,
1510
    S: BuildHasher + Default,
1511
{
1512
    type Output = HashSet<T, S>;
1513
1514
    /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.
1515
    ///
1516
    /// # Examples
1517
    ///
1518
    /// ```
1519
    /// use hashbrown::HashSet;
1520
    ///
1521
    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1522
    /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1523
    ///
1524
    /// let set = &a - &b;
1525
    ///
1526
    /// let mut i = 0;
1527
    /// let expected = [1, 2];
1528
    /// for x in &set {
1529
    ///     assert!(expected.contains(x));
1530
    ///     i += 1;
1531
    /// }
1532
    /// assert_eq!(i, expected.len());
1533
    /// ```
1534
0
    fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1535
0
        self.difference(rhs).cloned().collect()
1536
0
    }
1537
}
1538
1539
/// An iterator over the items of a `HashSet`.
1540
///
1541
/// This `struct` is created by the [`iter`] method on [`HashSet`].
1542
/// See its documentation for more.
1543
///
1544
/// [`HashSet`]: struct.HashSet.html
1545
/// [`iter`]: struct.HashSet.html#method.iter
1546
pub struct Iter<'a, K> {
1547
    iter: Keys<'a, K, ()>,
1548
}
1549
1550
/// An owning iterator over the items of a `HashSet`.
1551
///
1552
/// This `struct` is created by the [`into_iter`] method on [`HashSet`]
1553
/// (provided by the `IntoIterator` trait). See its documentation for more.
1554
///
1555
/// [`HashSet`]: struct.HashSet.html
1556
/// [`into_iter`]: struct.HashSet.html#method.into_iter
1557
pub struct IntoIter<K, A: Allocator = Global> {
1558
    iter: map::IntoIter<K, (), A>,
1559
}
1560
1561
/// A draining iterator over the items of a `HashSet`.
1562
///
1563
/// This `struct` is created by the [`drain`] method on [`HashSet`].
1564
/// See its documentation for more.
1565
///
1566
/// [`HashSet`]: struct.HashSet.html
1567
/// [`drain`]: struct.HashSet.html#method.drain
1568
pub struct Drain<'a, K, A: Allocator = Global> {
1569
    iter: map::Drain<'a, K, (), A>,
1570
}
1571
1572
/// A draining iterator over entries of a `HashSet` which don't satisfy the predicate `f`.
1573
///
1574
/// This `struct` is created by the [`extract_if`] method on [`HashSet`]. See its
1575
/// documentation for more.
1576
///
1577
/// [`extract_if`]: struct.HashSet.html#method.extract_if
1578
/// [`HashSet`]: struct.HashSet.html
1579
#[must_use = "Iterators are lazy unless consumed"]
1580
pub struct ExtractIf<'a, K, F, A: Allocator = Global>
1581
where
1582
    F: FnMut(&K) -> bool,
1583
{
1584
    f: F,
1585
    inner: RawExtractIf<'a, (K, ()), A>,
1586
}
1587
1588
/// A lazy iterator producing elements in the intersection of `HashSet`s.
1589
///
1590
/// This `struct` is created by the [`intersection`] method on [`HashSet`].
1591
/// See its documentation for more.
1592
///
1593
/// [`HashSet`]: struct.HashSet.html
1594
/// [`intersection`]: struct.HashSet.html#method.intersection
1595
pub struct Intersection<'a, T, S, A: Allocator = Global> {
1596
    // iterator of the first set
1597
    iter: Iter<'a, T>,
1598
    // the second set
1599
    other: &'a HashSet<T, S, A>,
1600
}
1601
1602
/// A lazy iterator producing elements in the difference of `HashSet`s.
1603
///
1604
/// This `struct` is created by the [`difference`] method on [`HashSet`].
1605
/// See its documentation for more.
1606
///
1607
/// [`HashSet`]: struct.HashSet.html
1608
/// [`difference`]: struct.HashSet.html#method.difference
1609
pub struct Difference<'a, T, S, A: Allocator = Global> {
1610
    // iterator of the first set
1611
    iter: Iter<'a, T>,
1612
    // the second set
1613
    other: &'a HashSet<T, S, A>,
1614
}
1615
1616
/// A lazy iterator producing elements in the symmetric difference of `HashSet`s.
1617
///
1618
/// This `struct` is created by the [`symmetric_difference`] method on
1619
/// [`HashSet`]. See its documentation for more.
1620
///
1621
/// [`HashSet`]: struct.HashSet.html
1622
/// [`symmetric_difference`]: struct.HashSet.html#method.symmetric_difference
1623
pub struct SymmetricDifference<'a, T, S, A: Allocator = Global> {
1624
    iter: Chain<Difference<'a, T, S, A>, Difference<'a, T, S, A>>,
1625
}
1626
1627
/// A lazy iterator producing elements in the union of `HashSet`s.
1628
///
1629
/// This `struct` is created by the [`union`] method on [`HashSet`].
1630
/// See its documentation for more.
1631
///
1632
/// [`HashSet`]: struct.HashSet.html
1633
/// [`union`]: struct.HashSet.html#method.union
1634
pub struct Union<'a, T, S, A: Allocator = Global> {
1635
    iter: Chain<Iter<'a, T>, Difference<'a, T, S, A>>,
1636
}
1637
1638
impl<'a, T, S, A: Allocator> IntoIterator for &'a HashSet<T, S, A> {
1639
    type Item = &'a T;
1640
    type IntoIter = Iter<'a, T>;
1641
1642
    #[cfg_attr(feature = "inline-more", inline)]
1643
0
    fn into_iter(self) -> Iter<'a, T> {
1644
0
        self.iter()
1645
0
    }
1646
}
1647
1648
impl<T, S, A: Allocator> IntoIterator for HashSet<T, S, A> {
1649
    type Item = T;
1650
    type IntoIter = IntoIter<T, A>;
1651
1652
    /// Creates a consuming iterator, that is, one that moves each value out
1653
    /// of the set in arbitrary order. The set cannot be used after calling
1654
    /// this.
1655
    ///
1656
    /// # Examples
1657
    ///
1658
    /// ```
1659
    /// use hashbrown::HashSet;
1660
    /// let mut set = HashSet::new();
1661
    /// set.insert("a".to_string());
1662
    /// set.insert("b".to_string());
1663
    ///
1664
    /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
1665
    /// let v: Vec<String> = set.into_iter().collect();
1666
    ///
1667
    /// // Will print in an arbitrary order.
1668
    /// for x in &v {
1669
    ///     println!("{}", x);
1670
    /// }
1671
    /// ```
1672
    #[cfg_attr(feature = "inline-more", inline)]
1673
0
    fn into_iter(self) -> IntoIter<T, A> {
1674
0
        IntoIter {
1675
0
            iter: self.map.into_iter(),
1676
0
        }
1677
0
    }
1678
}
1679
1680
impl<K> Clone for Iter<'_, K> {
1681
    #[cfg_attr(feature = "inline-more", inline)]
1682
0
    fn clone(&self) -> Self {
1683
0
        Iter {
1684
0
            iter: self.iter.clone(),
1685
0
        }
1686
0
    }
1687
}
1688
impl<'a, K> Iterator for Iter<'a, K> {
1689
    type Item = &'a K;
1690
1691
    #[cfg_attr(feature = "inline-more", inline)]
1692
0
    fn next(&mut self) -> Option<&'a K> {
1693
0
        self.iter.next()
1694
0
    }
1695
    #[cfg_attr(feature = "inline-more", inline)]
1696
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1697
0
        self.iter.size_hint()
1698
0
    }
1699
    #[cfg_attr(feature = "inline-more", inline)]
1700
0
    fn fold<B, F>(self, init: B, f: F) -> B
1701
0
    where
1702
0
        Self: Sized,
1703
0
        F: FnMut(B, Self::Item) -> B,
1704
0
    {
1705
0
        self.iter.fold(init, f)
1706
0
    }
1707
}
1708
impl<'a, K> ExactSizeIterator for Iter<'a, K> {
1709
    #[cfg_attr(feature = "inline-more", inline)]
1710
0
    fn len(&self) -> usize {
1711
0
        self.iter.len()
1712
0
    }
1713
}
1714
impl<K> FusedIterator for Iter<'_, K> {}
1715
1716
impl<K: fmt::Debug> fmt::Debug for Iter<'_, K> {
1717
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1718
0
        f.debug_list().entries(self.clone()).finish()
1719
0
    }
1720
}
1721
1722
impl<K, A: Allocator> Iterator for IntoIter<K, A> {
1723
    type Item = K;
1724
1725
    #[cfg_attr(feature = "inline-more", inline)]
1726
0
    fn next(&mut self) -> Option<K> {
1727
0
        // Avoid `Option::map` because it bloats LLVM IR.
1728
0
        match self.iter.next() {
1729
0
            Some((k, _)) => Some(k),
1730
0
            None => None,
1731
        }
1732
0
    }
1733
    #[cfg_attr(feature = "inline-more", inline)]
1734
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1735
0
        self.iter.size_hint()
1736
0
    }
1737
    #[cfg_attr(feature = "inline-more", inline)]
1738
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
1739
0
    where
1740
0
        Self: Sized,
1741
0
        F: FnMut(B, Self::Item) -> B,
1742
0
    {
1743
0
        self.iter.fold(init, |acc, (k, ())| f(acc, k))
1744
0
    }
1745
}
1746
impl<K, A: Allocator> ExactSizeIterator for IntoIter<K, A> {
1747
    #[cfg_attr(feature = "inline-more", inline)]
1748
0
    fn len(&self) -> usize {
1749
0
        self.iter.len()
1750
0
    }
1751
}
1752
impl<K, A: Allocator> FusedIterator for IntoIter<K, A> {}
1753
1754
impl<K: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<K, A> {
1755
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1756
0
        let entries_iter = self.iter.iter().map(|(k, _)| k);
1757
0
        f.debug_list().entries(entries_iter).finish()
1758
0
    }
1759
}
1760
1761
impl<K, A: Allocator> Iterator for Drain<'_, K, A> {
1762
    type Item = K;
1763
1764
    #[cfg_attr(feature = "inline-more", inline)]
1765
0
    fn next(&mut self) -> Option<K> {
1766
0
        // Avoid `Option::map` because it bloats LLVM IR.
1767
0
        match self.iter.next() {
1768
0
            Some((k, _)) => Some(k),
1769
0
            None => None,
1770
        }
1771
0
    }
1772
    #[cfg_attr(feature = "inline-more", inline)]
1773
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1774
0
        self.iter.size_hint()
1775
0
    }
1776
    #[cfg_attr(feature = "inline-more", inline)]
1777
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
1778
0
    where
1779
0
        Self: Sized,
1780
0
        F: FnMut(B, Self::Item) -> B,
1781
0
    {
1782
0
        self.iter.fold(init, |acc, (k, ())| f(acc, k))
1783
0
    }
1784
}
1785
impl<K, A: Allocator> ExactSizeIterator for Drain<'_, K, A> {
1786
    #[cfg_attr(feature = "inline-more", inline)]
1787
0
    fn len(&self) -> usize {
1788
0
        self.iter.len()
1789
0
    }
1790
}
1791
impl<K, A: Allocator> FusedIterator for Drain<'_, K, A> {}
1792
1793
impl<K: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, K, A> {
1794
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1795
0
        let entries_iter = self.iter.iter().map(|(k, _)| k);
1796
0
        f.debug_list().entries(entries_iter).finish()
1797
0
    }
1798
}
1799
1800
impl<K, F, A: Allocator> Iterator for ExtractIf<'_, K, F, A>
1801
where
1802
    F: FnMut(&K) -> bool,
1803
{
1804
    type Item = K;
1805
1806
    #[cfg_attr(feature = "inline-more", inline)]
1807
0
    fn next(&mut self) -> Option<Self::Item> {
1808
0
        self.inner
1809
0
            .next(|&mut (ref k, ())| (self.f)(k))
1810
0
            .map(|(k, ())| k)
1811
0
    }
1812
1813
    #[inline]
1814
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1815
0
        (0, self.inner.iter.size_hint().1)
1816
0
    }
1817
}
1818
1819
impl<K, F, A: Allocator> FusedIterator for ExtractIf<'_, K, F, A> where F: FnMut(&K) -> bool {}
1820
1821
impl<T, S, A: Allocator> Clone for Intersection<'_, T, S, A> {
1822
    #[cfg_attr(feature = "inline-more", inline)]
1823
0
    fn clone(&self) -> Self {
1824
0
        Intersection {
1825
0
            iter: self.iter.clone(),
1826
0
            ..*self
1827
0
        }
1828
0
    }
1829
}
1830
1831
impl<'a, T, S, A> Iterator for Intersection<'a, T, S, A>
1832
where
1833
    T: Eq + Hash,
1834
    S: BuildHasher,
1835
    A: Allocator,
1836
{
1837
    type Item = &'a T;
1838
1839
    #[cfg_attr(feature = "inline-more", inline)]
1840
0
    fn next(&mut self) -> Option<&'a T> {
1841
        loop {
1842
0
            let elt = self.iter.next()?;
1843
0
            if self.other.contains(elt) {
1844
0
                return Some(elt);
1845
0
            }
1846
        }
1847
0
    }
1848
1849
    #[cfg_attr(feature = "inline-more", inline)]
1850
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1851
0
        let (_, upper) = self.iter.size_hint();
1852
0
        (0, upper)
1853
0
    }
1854
    #[cfg_attr(feature = "inline-more", inline)]
1855
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
1856
0
    where
1857
0
        Self: Sized,
1858
0
        F: FnMut(B, Self::Item) -> B,
1859
0
    {
1860
0
        self.iter.fold(init, |acc, elt| {
1861
0
            if self.other.contains(elt) {
1862
0
                f(acc, elt)
1863
            } else {
1864
0
                acc
1865
            }
1866
0
        })
1867
0
    }
1868
}
1869
1870
impl<T, S, A> fmt::Debug for Intersection<'_, T, S, A>
1871
where
1872
    T: fmt::Debug + Eq + Hash,
1873
    S: BuildHasher,
1874
    A: Allocator,
1875
{
1876
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1877
0
        f.debug_list().entries(self.clone()).finish()
1878
0
    }
1879
}
1880
1881
impl<T, S, A> FusedIterator for Intersection<'_, T, S, A>
1882
where
1883
    T: Eq + Hash,
1884
    S: BuildHasher,
1885
    A: Allocator,
1886
{
1887
}
1888
1889
impl<T, S, A: Allocator> Clone for Difference<'_, T, S, A> {
1890
    #[cfg_attr(feature = "inline-more", inline)]
1891
0
    fn clone(&self) -> Self {
1892
0
        Difference {
1893
0
            iter: self.iter.clone(),
1894
0
            ..*self
1895
0
        }
1896
0
    }
1897
}
1898
1899
impl<'a, T, S, A> Iterator for Difference<'a, T, S, A>
1900
where
1901
    T: Eq + Hash,
1902
    S: BuildHasher,
1903
    A: Allocator,
1904
{
1905
    type Item = &'a T;
1906
1907
    #[cfg_attr(feature = "inline-more", inline)]
1908
0
    fn next(&mut self) -> Option<&'a T> {
1909
        loop {
1910
0
            let elt = self.iter.next()?;
1911
0
            if !self.other.contains(elt) {
1912
0
                return Some(elt);
1913
0
            }
1914
        }
1915
0
    }
1916
1917
    #[cfg_attr(feature = "inline-more", inline)]
1918
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1919
0
        let (_, upper) = self.iter.size_hint();
1920
0
        (0, upper)
1921
0
    }
1922
    #[cfg_attr(feature = "inline-more", inline)]
1923
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
1924
0
    where
1925
0
        Self: Sized,
1926
0
        F: FnMut(B, Self::Item) -> B,
1927
0
    {
1928
0
        self.iter.fold(init, |acc, elt| {
1929
0
            if self.other.contains(elt) {
1930
0
                acc
1931
            } else {
1932
0
                f(acc, elt)
1933
            }
1934
0
        })
1935
0
    }
1936
}
1937
1938
impl<T, S, A> FusedIterator for Difference<'_, T, S, A>
1939
where
1940
    T: Eq + Hash,
1941
    S: BuildHasher,
1942
    A: Allocator,
1943
{
1944
}
1945
1946
impl<T, S, A> fmt::Debug for Difference<'_, T, S, A>
1947
where
1948
    T: fmt::Debug + Eq + Hash,
1949
    S: BuildHasher,
1950
    A: Allocator,
1951
{
1952
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1953
0
        f.debug_list().entries(self.clone()).finish()
1954
0
    }
1955
}
1956
1957
impl<T, S, A: Allocator> Clone for SymmetricDifference<'_, T, S, A> {
1958
    #[cfg_attr(feature = "inline-more", inline)]
1959
0
    fn clone(&self) -> Self {
1960
0
        SymmetricDifference {
1961
0
            iter: self.iter.clone(),
1962
0
        }
1963
0
    }
1964
}
1965
1966
impl<'a, T, S, A> Iterator for SymmetricDifference<'a, T, S, A>
1967
where
1968
    T: Eq + Hash,
1969
    S: BuildHasher,
1970
    A: Allocator,
1971
{
1972
    type Item = &'a T;
1973
1974
    #[cfg_attr(feature = "inline-more", inline)]
1975
0
    fn next(&mut self) -> Option<&'a T> {
1976
0
        self.iter.next()
1977
0
    }
1978
    #[cfg_attr(feature = "inline-more", inline)]
1979
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1980
0
        self.iter.size_hint()
1981
0
    }
1982
    #[cfg_attr(feature = "inline-more", inline)]
1983
0
    fn fold<B, F>(self, init: B, f: F) -> B
1984
0
    where
1985
0
        Self: Sized,
1986
0
        F: FnMut(B, Self::Item) -> B,
1987
0
    {
1988
0
        self.iter.fold(init, f)
1989
0
    }
1990
}
1991
1992
impl<T, S, A> FusedIterator for SymmetricDifference<'_, T, S, A>
1993
where
1994
    T: Eq + Hash,
1995
    S: BuildHasher,
1996
    A: Allocator,
1997
{
1998
}
1999
2000
impl<T, S, A> fmt::Debug for SymmetricDifference<'_, T, S, A>
2001
where
2002
    T: fmt::Debug + Eq + Hash,
2003
    S: BuildHasher,
2004
    A: Allocator,
2005
{
2006
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2007
0
        f.debug_list().entries(self.clone()).finish()
2008
0
    }
2009
}
2010
2011
impl<T, S, A: Allocator> Clone for Union<'_, T, S, A> {
2012
    #[cfg_attr(feature = "inline-more", inline)]
2013
0
    fn clone(&self) -> Self {
2014
0
        Union {
2015
0
            iter: self.iter.clone(),
2016
0
        }
2017
0
    }
2018
}
2019
2020
impl<T, S, A> FusedIterator for Union<'_, T, S, A>
2021
where
2022
    T: Eq + Hash,
2023
    S: BuildHasher,
2024
    A: Allocator,
2025
{
2026
}
2027
2028
impl<T, S, A> fmt::Debug for Union<'_, T, S, A>
2029
where
2030
    T: fmt::Debug + Eq + Hash,
2031
    S: BuildHasher,
2032
    A: Allocator,
2033
{
2034
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2035
0
        f.debug_list().entries(self.clone()).finish()
2036
0
    }
2037
}
2038
2039
impl<'a, T, S, A> Iterator for Union<'a, T, S, A>
2040
where
2041
    T: Eq + Hash,
2042
    S: BuildHasher,
2043
    A: Allocator,
2044
{
2045
    type Item = &'a T;
2046
2047
    #[cfg_attr(feature = "inline-more", inline)]
2048
0
    fn next(&mut self) -> Option<&'a T> {
2049
0
        self.iter.next()
2050
0
    }
2051
    #[cfg_attr(feature = "inline-more", inline)]
2052
0
    fn size_hint(&self) -> (usize, Option<usize>) {
2053
0
        self.iter.size_hint()
2054
0
    }
2055
    #[cfg_attr(feature = "inline-more", inline)]
2056
0
    fn fold<B, F>(self, init: B, f: F) -> B
2057
0
    where
2058
0
        Self: Sized,
2059
0
        F: FnMut(B, Self::Item) -> B,
2060
0
    {
2061
0
        self.iter.fold(init, f)
2062
0
    }
2063
}
2064
2065
/// A view into a single entry in a set, which may either be vacant or occupied.
2066
///
2067
/// This `enum` is constructed from the [`entry`] method on [`HashSet`].
2068
///
2069
/// [`HashSet`]: struct.HashSet.html
2070
/// [`entry`]: struct.HashSet.html#method.entry
2071
///
2072
/// # Examples
2073
///
2074
/// ```
2075
/// use hashbrown::hash_set::{Entry, HashSet, OccupiedEntry};
2076
///
2077
/// let mut set = HashSet::new();
2078
/// set.extend(["a", "b", "c"]);
2079
/// assert_eq!(set.len(), 3);
2080
///
2081
/// // Existing value (insert)
2082
/// let entry: Entry<_, _> = set.entry("a");
2083
/// let _raw_o: OccupiedEntry<_, _> = entry.insert();
2084
/// assert_eq!(set.len(), 3);
2085
/// // Nonexistent value (insert)
2086
/// set.entry("d").insert();
2087
///
2088
/// // Existing value (or_insert)
2089
/// set.entry("b").or_insert();
2090
/// // Nonexistent value (or_insert)
2091
/// set.entry("e").or_insert();
2092
///
2093
/// println!("Our HashSet: {:?}", set);
2094
///
2095
/// let mut vec: Vec<_> = set.iter().copied().collect();
2096
/// // The `Iter` iterator produces items in arbitrary order, so the
2097
/// // items must be sorted to test them against a sorted array.
2098
/// vec.sort_unstable();
2099
/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
2100
/// ```
2101
pub enum Entry<'a, T, S, A = Global>
2102
where
2103
    A: Allocator,
2104
{
2105
    /// An occupied entry.
2106
    ///
2107
    /// # Examples
2108
    ///
2109
    /// ```
2110
    /// use hashbrown::hash_set::{Entry, HashSet};
2111
    /// let mut set: HashSet<_> = ["a", "b"].into();
2112
    ///
2113
    /// match set.entry("a") {
2114
    ///     Entry::Vacant(_) => unreachable!(),
2115
    ///     Entry::Occupied(_) => { }
2116
    /// }
2117
    /// ```
2118
    Occupied(OccupiedEntry<'a, T, S, A>),
2119
2120
    /// A vacant entry.
2121
    ///
2122
    /// # Examples
2123
    ///
2124
    /// ```
2125
    /// use hashbrown::hash_set::{Entry, HashSet};
2126
    /// let mut set: HashSet<&str> = HashSet::new();
2127
    ///
2128
    /// match set.entry("a") {
2129
    ///     Entry::Occupied(_) => unreachable!(),
2130
    ///     Entry::Vacant(_) => { }
2131
    /// }
2132
    /// ```
2133
    Vacant(VacantEntry<'a, T, S, A>),
2134
}
2135
2136
impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for Entry<'_, T, S, A> {
2137
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2138
0
        match *self {
2139
0
            Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
2140
0
            Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
2141
        }
2142
0
    }
2143
}
2144
2145
/// A view into an occupied entry in a `HashSet`.
2146
/// It is part of the [`Entry`] enum.
2147
///
2148
/// [`Entry`]: enum.Entry.html
2149
///
2150
/// # Examples
2151
///
2152
/// ```
2153
/// use hashbrown::hash_set::{Entry, HashSet, OccupiedEntry};
2154
///
2155
/// let mut set = HashSet::new();
2156
/// set.extend(["a", "b", "c"]);
2157
///
2158
/// let _entry_o: OccupiedEntry<_, _> = set.entry("a").insert();
2159
/// assert_eq!(set.len(), 3);
2160
///
2161
/// // Existing key
2162
/// match set.entry("a") {
2163
///     Entry::Vacant(_) => unreachable!(),
2164
///     Entry::Occupied(view) => {
2165
///         assert_eq!(view.get(), &"a");
2166
///     }
2167
/// }
2168
///
2169
/// assert_eq!(set.len(), 3);
2170
///
2171
/// // Existing key (take)
2172
/// match set.entry("c") {
2173
///     Entry::Vacant(_) => unreachable!(),
2174
///     Entry::Occupied(view) => {
2175
///         assert_eq!(view.remove(), "c");
2176
///     }
2177
/// }
2178
/// assert_eq!(set.get(&"c"), None);
2179
/// assert_eq!(set.len(), 2);
2180
/// ```
2181
pub struct OccupiedEntry<'a, T, S, A: Allocator = Global> {
2182
    inner: map::OccupiedEntry<'a, T, (), S, A>,
2183
}
2184
2185
impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for OccupiedEntry<'_, T, S, A> {
2186
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2187
0
        f.debug_struct("OccupiedEntry")
2188
0
            .field("value", self.get())
2189
0
            .finish()
2190
0
    }
2191
}
2192
2193
/// A view into a vacant entry in a `HashSet`.
2194
/// It is part of the [`Entry`] enum.
2195
///
2196
/// [`Entry`]: enum.Entry.html
2197
///
2198
/// # Examples
2199
///
2200
/// ```
2201
/// use hashbrown::hash_set::{Entry, HashSet, VacantEntry};
2202
///
2203
/// let mut set = HashSet::<&str>::new();
2204
///
2205
/// let entry_v: VacantEntry<_, _> = match set.entry("a") {
2206
///     Entry::Vacant(view) => view,
2207
///     Entry::Occupied(_) => unreachable!(),
2208
/// };
2209
/// entry_v.insert();
2210
/// assert!(set.contains("a") && set.len() == 1);
2211
///
2212
/// // Nonexistent key (insert)
2213
/// match set.entry("b") {
2214
///     Entry::Vacant(view) => view.insert(),
2215
///     Entry::Occupied(_) => unreachable!(),
2216
/// }
2217
/// assert!(set.contains("b") && set.len() == 2);
2218
/// ```
2219
pub struct VacantEntry<'a, T, S, A: Allocator = Global> {
2220
    inner: map::VacantEntry<'a, T, (), S, A>,
2221
}
2222
2223
impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for VacantEntry<'_, T, S, A> {
2224
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2225
0
        f.debug_tuple("VacantEntry").field(self.get()).finish()
2226
0
    }
2227
}
2228
2229
impl<'a, T, S, A: Allocator> Entry<'a, T, S, A> {
2230
    /// Sets the value of the entry, and returns an OccupiedEntry.
2231
    ///
2232
    /// # Examples
2233
    ///
2234
    /// ```
2235
    /// use hashbrown::HashSet;
2236
    ///
2237
    /// let mut set: HashSet<&str> = HashSet::new();
2238
    /// let entry = set.entry("horseyland").insert();
2239
    ///
2240
    /// assert_eq!(entry.get(), &"horseyland");
2241
    /// ```
2242
    #[cfg_attr(feature = "inline-more", inline)]
2243
0
    pub fn insert(self) -> OccupiedEntry<'a, T, S, A>
2244
0
    where
2245
0
        T: Hash,
2246
0
        S: BuildHasher,
2247
0
    {
2248
0
        match self {
2249
0
            Entry::Occupied(entry) => entry,
2250
0
            Entry::Vacant(entry) => entry.insert_entry(),
2251
        }
2252
0
    }
2253
2254
    /// Ensures a value is in the entry by inserting if it was vacant.
2255
    ///
2256
    /// # Examples
2257
    ///
2258
    /// ```
2259
    /// use hashbrown::HashSet;
2260
    ///
2261
    /// let mut set: HashSet<&str> = HashSet::new();
2262
    ///
2263
    /// // nonexistent key
2264
    /// set.entry("poneyland").or_insert();
2265
    /// assert!(set.contains("poneyland"));
2266
    ///
2267
    /// // existing key
2268
    /// set.entry("poneyland").or_insert();
2269
    /// assert!(set.contains("poneyland"));
2270
    /// assert_eq!(set.len(), 1);
2271
    /// ```
2272
    #[cfg_attr(feature = "inline-more", inline)]
2273
0
    pub fn or_insert(self)
2274
0
    where
2275
0
        T: Hash,
2276
0
        S: BuildHasher,
2277
0
    {
2278
0
        if let Entry::Vacant(entry) = self {
2279
0
            entry.insert();
2280
0
        }
2281
0
    }
2282
2283
    /// Returns a reference to this entry's value.
2284
    ///
2285
    /// # Examples
2286
    ///
2287
    /// ```
2288
    /// use hashbrown::HashSet;
2289
    ///
2290
    /// let mut set: HashSet<&str> = HashSet::new();
2291
    /// set.entry("poneyland").or_insert();
2292
    /// // existing key
2293
    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2294
    /// // nonexistent key
2295
    /// assert_eq!(set.entry("horseland").get(), &"horseland");
2296
    /// ```
2297
    #[cfg_attr(feature = "inline-more", inline)]
2298
0
    pub fn get(&self) -> &T {
2299
0
        match *self {
2300
0
            Entry::Occupied(ref entry) => entry.get(),
2301
0
            Entry::Vacant(ref entry) => entry.get(),
2302
        }
2303
0
    }
2304
}
2305
2306
impl<T, S, A: Allocator> OccupiedEntry<'_, T, S, A> {
2307
    /// Gets a reference to the value in the entry.
2308
    ///
2309
    /// # Examples
2310
    ///
2311
    /// ```
2312
    /// use hashbrown::hash_set::{Entry, HashSet};
2313
    ///
2314
    /// let mut set: HashSet<&str> = HashSet::new();
2315
    /// set.entry("poneyland").or_insert();
2316
    ///
2317
    /// match set.entry("poneyland") {
2318
    ///     Entry::Vacant(_) => panic!(),
2319
    ///     Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
2320
    /// }
2321
    /// ```
2322
    #[cfg_attr(feature = "inline-more", inline)]
2323
0
    pub fn get(&self) -> &T {
2324
0
        self.inner.key()
2325
0
    }
2326
2327
    /// Takes the value out of the entry, and returns it.
2328
    /// Keeps the allocated memory for reuse.
2329
    ///
2330
    /// # Examples
2331
    ///
2332
    /// ```
2333
    /// use hashbrown::HashSet;
2334
    /// use hashbrown::hash_set::Entry;
2335
    ///
2336
    /// let mut set: HashSet<&str> = HashSet::new();
2337
    /// // The set is empty
2338
    /// assert!(set.is_empty() && set.capacity() == 0);
2339
    ///
2340
    /// set.entry("poneyland").or_insert();
2341
    /// let capacity_before_remove = set.capacity();
2342
    ///
2343
    /// if let Entry::Occupied(o) = set.entry("poneyland") {
2344
    ///     assert_eq!(o.remove(), "poneyland");
2345
    /// }
2346
    ///
2347
    /// assert_eq!(set.contains("poneyland"), false);
2348
    /// // Now set hold none elements but capacity is equal to the old one
2349
    /// assert!(set.len() == 0 && set.capacity() == capacity_before_remove);
2350
    /// ```
2351
    #[cfg_attr(feature = "inline-more", inline)]
2352
0
    pub fn remove(self) -> T {
2353
0
        self.inner.remove_entry().0
2354
0
    }
2355
2356
    /// Replaces the entry, returning the old value. The new value in the hash map will be
2357
    /// the value used to create this entry.
2358
    ///
2359
    /// # Panics
2360
    ///
2361
    /// Will panic if this OccupiedEntry was created through [`Entry::insert`].
2362
    ///
2363
    /// # Examples
2364
    ///
2365
    /// ```
2366
    ///  use hashbrown::hash_set::{Entry, HashSet};
2367
    ///  use std::rc::Rc;
2368
    ///
2369
    ///  let mut set: HashSet<Rc<String>> = HashSet::new();
2370
    ///  let key_one = Rc::new("Stringthing".to_string());
2371
    ///  let key_two = Rc::new("Stringthing".to_string());
2372
    ///
2373
    ///  set.insert(key_one.clone());
2374
    ///  assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
2375
    ///
2376
    ///  match set.entry(key_two.clone()) {
2377
    ///      Entry::Occupied(entry) => {
2378
    ///          let old_key: Rc<String> = entry.replace();
2379
    ///          assert!(Rc::ptr_eq(&key_one, &old_key));
2380
    ///      }
2381
    ///      Entry::Vacant(_) => panic!(),
2382
    ///  }
2383
    ///
2384
    ///  assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
2385
    ///  assert!(set.contains(&"Stringthing".to_owned()));
2386
    /// ```
2387
    #[cfg_attr(feature = "inline-more", inline)]
2388
0
    pub fn replace(self) -> T {
2389
0
        self.inner.replace_key()
2390
0
    }
2391
}
2392
2393
impl<'a, T, S, A: Allocator> VacantEntry<'a, T, S, A> {
2394
    /// Gets a reference to the value that would be used when inserting
2395
    /// through the `VacantEntry`.
2396
    ///
2397
    /// # Examples
2398
    ///
2399
    /// ```
2400
    /// use hashbrown::HashSet;
2401
    ///
2402
    /// let mut set: HashSet<&str> = HashSet::new();
2403
    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2404
    /// ```
2405
    #[cfg_attr(feature = "inline-more", inline)]
2406
0
    pub fn get(&self) -> &T {
2407
0
        self.inner.key()
2408
0
    }
2409
2410
    /// Take ownership of the value.
2411
    ///
2412
    /// # Examples
2413
    ///
2414
    /// ```
2415
    /// use hashbrown::hash_set::{Entry, HashSet};
2416
    ///
2417
    /// let mut set: HashSet<&str> = HashSet::new();
2418
    ///
2419
    /// match set.entry("poneyland") {
2420
    ///     Entry::Occupied(_) => panic!(),
2421
    ///     Entry::Vacant(v) => assert_eq!(v.into_value(), "poneyland"),
2422
    /// }
2423
    /// ```
2424
    #[cfg_attr(feature = "inline-more", inline)]
2425
0
    pub fn into_value(self) -> T {
2426
0
        self.inner.into_key()
2427
0
    }
2428
2429
    /// Sets the value of the entry with the VacantEntry's value.
2430
    ///
2431
    /// # Examples
2432
    ///
2433
    /// ```
2434
    /// use hashbrown::HashSet;
2435
    /// use hashbrown::hash_set::Entry;
2436
    ///
2437
    /// let mut set: HashSet<&str> = HashSet::new();
2438
    ///
2439
    /// if let Entry::Vacant(o) = set.entry("poneyland") {
2440
    ///     o.insert();
2441
    /// }
2442
    /// assert!(set.contains("poneyland"));
2443
    /// ```
2444
    #[cfg_attr(feature = "inline-more", inline)]
2445
0
    pub fn insert(self)
2446
0
    where
2447
0
        T: Hash,
2448
0
        S: BuildHasher,
2449
0
    {
2450
0
        self.inner.insert(());
2451
0
    }
2452
2453
    #[cfg_attr(feature = "inline-more", inline)]
2454
0
    fn insert_entry(self) -> OccupiedEntry<'a, T, S, A>
2455
0
    where
2456
0
        T: Hash,
2457
0
        S: BuildHasher,
2458
0
    {
2459
0
        OccupiedEntry {
2460
0
            inner: self.inner.insert_entry(()),
2461
0
        }
2462
0
    }
2463
}
2464
2465
#[allow(dead_code)]
2466
0
fn assert_covariance() {
2467
0
    fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> {
2468
0
        v
2469
0
    }
2470
0
    fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> {
2471
0
        v
2472
0
    }
2473
0
    fn into_iter<'new, A: Allocator>(v: IntoIter<&'static str, A>) -> IntoIter<&'new str, A> {
2474
0
        v
2475
0
    }
2476
0
    fn difference<'a, 'new, A: Allocator>(
2477
0
        v: Difference<'a, &'static str, DefaultHashBuilder, A>,
2478
0
    ) -> Difference<'a, &'new str, DefaultHashBuilder, A> {
2479
0
        v
2480
0
    }
2481
0
    fn symmetric_difference<'a, 'new, A: Allocator>(
2482
0
        v: SymmetricDifference<'a, &'static str, DefaultHashBuilder, A>,
2483
0
    ) -> SymmetricDifference<'a, &'new str, DefaultHashBuilder, A> {
2484
0
        v
2485
0
    }
2486
0
    fn intersection<'a, 'new, A: Allocator>(
2487
0
        v: Intersection<'a, &'static str, DefaultHashBuilder, A>,
2488
0
    ) -> Intersection<'a, &'new str, DefaultHashBuilder, A> {
2489
0
        v
2490
0
    }
2491
0
    fn union<'a, 'new, A: Allocator>(
2492
0
        v: Union<'a, &'static str, DefaultHashBuilder, A>,
2493
0
    ) -> Union<'a, &'new str, DefaultHashBuilder, A> {
2494
0
        v
2495
0
    }
2496
0
    fn drain<'new, A: Allocator>(d: Drain<'static, &'static str, A>) -> Drain<'new, &'new str, A> {
2497
0
        d
2498
0
    }
2499
0
}
2500
2501
#[cfg(test)]
2502
mod test_set {
2503
    use super::super::map::DefaultHashBuilder;
2504
    use super::HashSet;
2505
    use std::vec::Vec;
2506
2507
    #[test]
2508
    fn test_zero_capacities() {
2509
        type HS = HashSet<i32>;
2510
2511
        let s = HS::new();
2512
        assert_eq!(s.capacity(), 0);
2513
2514
        let s = HS::default();
2515
        assert_eq!(s.capacity(), 0);
2516
2517
        let s = HS::with_hasher(DefaultHashBuilder::default());
2518
        assert_eq!(s.capacity(), 0);
2519
2520
        let s = HS::with_capacity(0);
2521
        assert_eq!(s.capacity(), 0);
2522
2523
        let s = HS::with_capacity_and_hasher(0, DefaultHashBuilder::default());
2524
        assert_eq!(s.capacity(), 0);
2525
2526
        let mut s = HS::new();
2527
        s.insert(1);
2528
        s.insert(2);
2529
        s.remove(&1);
2530
        s.remove(&2);
2531
        s.shrink_to_fit();
2532
        assert_eq!(s.capacity(), 0);
2533
2534
        let mut s = HS::new();
2535
        s.reserve(0);
2536
        assert_eq!(s.capacity(), 0);
2537
    }
2538
2539
    #[test]
2540
    fn test_disjoint() {
2541
        let mut xs = HashSet::new();
2542
        let mut ys = HashSet::new();
2543
        assert!(xs.is_disjoint(&ys));
2544
        assert!(ys.is_disjoint(&xs));
2545
        assert!(xs.insert(5));
2546
        assert!(ys.insert(11));
2547
        assert!(xs.is_disjoint(&ys));
2548
        assert!(ys.is_disjoint(&xs));
2549
        assert!(xs.insert(7));
2550
        assert!(xs.insert(19));
2551
        assert!(xs.insert(4));
2552
        assert!(ys.insert(2));
2553
        assert!(ys.insert(-11));
2554
        assert!(xs.is_disjoint(&ys));
2555
        assert!(ys.is_disjoint(&xs));
2556
        assert!(ys.insert(7));
2557
        assert!(!xs.is_disjoint(&ys));
2558
        assert!(!ys.is_disjoint(&xs));
2559
    }
2560
2561
    #[test]
2562
    fn test_subset_and_superset() {
2563
        let mut a = HashSet::new();
2564
        assert!(a.insert(0));
2565
        assert!(a.insert(5));
2566
        assert!(a.insert(11));
2567
        assert!(a.insert(7));
2568
2569
        let mut b = HashSet::new();
2570
        assert!(b.insert(0));
2571
        assert!(b.insert(7));
2572
        assert!(b.insert(19));
2573
        assert!(b.insert(250));
2574
        assert!(b.insert(11));
2575
        assert!(b.insert(200));
2576
2577
        assert!(!a.is_subset(&b));
2578
        assert!(!a.is_superset(&b));
2579
        assert!(!b.is_subset(&a));
2580
        assert!(!b.is_superset(&a));
2581
2582
        assert!(b.insert(5));
2583
2584
        assert!(a.is_subset(&b));
2585
        assert!(!a.is_superset(&b));
2586
        assert!(!b.is_subset(&a));
2587
        assert!(b.is_superset(&a));
2588
    }
2589
2590
    #[test]
2591
    fn test_iterate() {
2592
        let mut a = HashSet::new();
2593
        for i in 0..32 {
2594
            assert!(a.insert(i));
2595
        }
2596
        let mut observed: u32 = 0;
2597
        for k in &a {
2598
            observed |= 1 << *k;
2599
        }
2600
        assert_eq!(observed, 0xFFFF_FFFF);
2601
    }
2602
2603
    #[test]
2604
    fn test_intersection() {
2605
        let mut a = HashSet::new();
2606
        let mut b = HashSet::new();
2607
2608
        assert!(a.insert(11));
2609
        assert!(a.insert(1));
2610
        assert!(a.insert(3));
2611
        assert!(a.insert(77));
2612
        assert!(a.insert(103));
2613
        assert!(a.insert(5));
2614
        assert!(a.insert(-5));
2615
2616
        assert!(b.insert(2));
2617
        assert!(b.insert(11));
2618
        assert!(b.insert(77));
2619
        assert!(b.insert(-9));
2620
        assert!(b.insert(-42));
2621
        assert!(b.insert(5));
2622
        assert!(b.insert(3));
2623
2624
        let mut i = 0;
2625
        let expected = [3, 5, 11, 77];
2626
        for x in a.intersection(&b) {
2627
            assert!(expected.contains(x));
2628
            i += 1;
2629
        }
2630
        assert_eq!(i, expected.len());
2631
    }
2632
2633
    #[test]
2634
    fn test_difference() {
2635
        let mut a = HashSet::new();
2636
        let mut b = HashSet::new();
2637
2638
        assert!(a.insert(1));
2639
        assert!(a.insert(3));
2640
        assert!(a.insert(5));
2641
        assert!(a.insert(9));
2642
        assert!(a.insert(11));
2643
2644
        assert!(b.insert(3));
2645
        assert!(b.insert(9));
2646
2647
        let mut i = 0;
2648
        let expected = [1, 5, 11];
2649
        for x in a.difference(&b) {
2650
            assert!(expected.contains(x));
2651
            i += 1;
2652
        }
2653
        assert_eq!(i, expected.len());
2654
    }
2655
2656
    #[test]
2657
    fn test_symmetric_difference() {
2658
        let mut a = HashSet::new();
2659
        let mut b = HashSet::new();
2660
2661
        assert!(a.insert(1));
2662
        assert!(a.insert(3));
2663
        assert!(a.insert(5));
2664
        assert!(a.insert(9));
2665
        assert!(a.insert(11));
2666
2667
        assert!(b.insert(-2));
2668
        assert!(b.insert(3));
2669
        assert!(b.insert(9));
2670
        assert!(b.insert(14));
2671
        assert!(b.insert(22));
2672
2673
        let mut i = 0;
2674
        let expected = [-2, 1, 5, 11, 14, 22];
2675
        for x in a.symmetric_difference(&b) {
2676
            assert!(expected.contains(x));
2677
            i += 1;
2678
        }
2679
        assert_eq!(i, expected.len());
2680
    }
2681
2682
    #[test]
2683
    fn test_union() {
2684
        let mut a = HashSet::new();
2685
        let mut b = HashSet::new();
2686
2687
        assert!(a.insert(1));
2688
        assert!(a.insert(3));
2689
        assert!(a.insert(5));
2690
        assert!(a.insert(9));
2691
        assert!(a.insert(11));
2692
        assert!(a.insert(16));
2693
        assert!(a.insert(19));
2694
        assert!(a.insert(24));
2695
2696
        assert!(b.insert(-2));
2697
        assert!(b.insert(1));
2698
        assert!(b.insert(5));
2699
        assert!(b.insert(9));
2700
        assert!(b.insert(13));
2701
        assert!(b.insert(19));
2702
2703
        let mut i = 0;
2704
        let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
2705
        for x in a.union(&b) {
2706
            assert!(expected.contains(x));
2707
            i += 1;
2708
        }
2709
        assert_eq!(i, expected.len());
2710
    }
2711
2712
    #[test]
2713
    fn test_from_map() {
2714
        let mut a = crate::HashMap::new();
2715
        a.insert(1, ());
2716
        a.insert(2, ());
2717
        a.insert(3, ());
2718
        a.insert(4, ());
2719
2720
        let a: HashSet<_> = a.into();
2721
2722
        assert_eq!(a.len(), 4);
2723
        assert!(a.contains(&1));
2724
        assert!(a.contains(&2));
2725
        assert!(a.contains(&3));
2726
        assert!(a.contains(&4));
2727
    }
2728
2729
    #[test]
2730
    fn test_from_iter() {
2731
        let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9];
2732
2733
        let set: HashSet<_> = xs.iter().copied().collect();
2734
2735
        for x in &xs {
2736
            assert!(set.contains(x));
2737
        }
2738
2739
        assert_eq!(set.iter().len(), xs.len() - 1);
2740
    }
2741
2742
    #[test]
2743
    fn test_move_iter() {
2744
        let hs = {
2745
            let mut hs = HashSet::new();
2746
2747
            hs.insert('a');
2748
            hs.insert('b');
2749
2750
            hs
2751
        };
2752
2753
        let v = hs.into_iter().collect::<Vec<char>>();
2754
        assert!(v == ['a', 'b'] || v == ['b', 'a']);
2755
    }
2756
2757
    #[test]
2758
    fn test_eq() {
2759
        // These constants once happened to expose a bug in insert().
2760
        // I'm keeping them around to prevent a regression.
2761
        let mut s1 = HashSet::new();
2762
2763
        s1.insert(1);
2764
        s1.insert(2);
2765
        s1.insert(3);
2766
2767
        let mut s2 = HashSet::new();
2768
2769
        s2.insert(1);
2770
        s2.insert(2);
2771
2772
        assert!(s1 != s2);
2773
2774
        s2.insert(3);
2775
2776
        assert_eq!(s1, s2);
2777
    }
2778
2779
    #[test]
2780
    fn test_show() {
2781
        let mut set = HashSet::new();
2782
        let empty = HashSet::<i32>::new();
2783
2784
        set.insert(1);
2785
        set.insert(2);
2786
2787
        let set_str = format!("{set:?}");
2788
2789
        assert!(set_str == "{1, 2}" || set_str == "{2, 1}");
2790
        assert_eq!(format!("{empty:?}"), "{}");
2791
    }
2792
2793
    #[test]
2794
    fn test_trivial_drain() {
2795
        let mut s = HashSet::<i32>::new();
2796
        for _ in s.drain() {}
2797
        assert!(s.is_empty());
2798
        drop(s);
2799
2800
        let mut s = HashSet::<i32>::new();
2801
        drop(s.drain());
2802
        assert!(s.is_empty());
2803
    }
2804
2805
    #[test]
2806
    fn test_drain() {
2807
        let mut s: HashSet<_> = (1..100).collect();
2808
2809
        // try this a bunch of times to make sure we don't screw up internal state.
2810
        for _ in 0..20 {
2811
            assert_eq!(s.len(), 99);
2812
2813
            {
2814
                let mut last_i = 0;
2815
                let mut d = s.drain();
2816
                for (i, x) in d.by_ref().take(50).enumerate() {
2817
                    last_i = i;
2818
                    assert!(x != 0);
2819
                }
2820
                assert_eq!(last_i, 49);
2821
            }
2822
2823
            if !s.is_empty() {
2824
                panic!("s should be empty!");
2825
            }
2826
2827
            // reset to try again.
2828
            s.extend(1..100);
2829
        }
2830
    }
2831
2832
    #[test]
2833
    fn test_replace() {
2834
        use core::hash;
2835
2836
        #[derive(Debug)]
2837
        #[allow(dead_code)]
2838
        struct Foo(&'static str, i32);
2839
2840
        impl PartialEq for Foo {
2841
            fn eq(&self, other: &Self) -> bool {
2842
                self.0 == other.0
2843
            }
2844
        }
2845
2846
        impl Eq for Foo {}
2847
2848
        impl hash::Hash for Foo {
2849
            fn hash<H: hash::Hasher>(&self, h: &mut H) {
2850
                self.0.hash(h);
2851
            }
2852
        }
2853
2854
        let mut s = HashSet::new();
2855
        assert_eq!(s.replace(Foo("a", 1)), None);
2856
        assert_eq!(s.len(), 1);
2857
        assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1)));
2858
        assert_eq!(s.len(), 1);
2859
2860
        let mut it = s.iter();
2861
        assert_eq!(it.next(), Some(&Foo("a", 2)));
2862
        assert_eq!(it.next(), None);
2863
    }
2864
2865
    #[test]
2866
    #[allow(clippy::needless_borrow)]
2867
    fn test_extend_ref() {
2868
        let mut a = HashSet::new();
2869
        a.insert(1);
2870
2871
        a.extend([2, 3, 4]);
2872
2873
        assert_eq!(a.len(), 4);
2874
        assert!(a.contains(&1));
2875
        assert!(a.contains(&2));
2876
        assert!(a.contains(&3));
2877
        assert!(a.contains(&4));
2878
2879
        let mut b = HashSet::new();
2880
        b.insert(5);
2881
        b.insert(6);
2882
2883
        a.extend(&b);
2884
2885
        assert_eq!(a.len(), 6);
2886
        assert!(a.contains(&1));
2887
        assert!(a.contains(&2));
2888
        assert!(a.contains(&3));
2889
        assert!(a.contains(&4));
2890
        assert!(a.contains(&5));
2891
        assert!(a.contains(&6));
2892
    }
2893
2894
    #[test]
2895
    fn test_retain() {
2896
        let xs = [1, 2, 3, 4, 5, 6];
2897
        let mut set: HashSet<i32> = xs.iter().copied().collect();
2898
        set.retain(|&k| k % 2 == 0);
2899
        assert_eq!(set.len(), 3);
2900
        assert!(set.contains(&2));
2901
        assert!(set.contains(&4));
2902
        assert!(set.contains(&6));
2903
    }
2904
2905
    #[test]
2906
    fn test_extract_if() {
2907
        {
2908
            let mut set: HashSet<i32> = (0..8).collect();
2909
            let drained = set.extract_if(|&k| k % 2 == 0);
2910
            let mut out = drained.collect::<Vec<_>>();
2911
            out.sort_unstable();
2912
            assert_eq!(vec![0, 2, 4, 6], out);
2913
            assert_eq!(set.len(), 4);
2914
        }
2915
        {
2916
            let mut set: HashSet<i32> = (0..8).collect();
2917
            set.extract_if(|&k| k % 2 == 0).for_each(drop);
2918
            assert_eq!(set.len(), 4, "Removes non-matching items on drop");
2919
        }
2920
    }
2921
2922
    #[test]
2923
    fn test_const_with_hasher() {
2924
        use core::hash::BuildHasher;
2925
        use std::collections::hash_map::DefaultHasher;
2926
2927
        #[derive(Clone)]
2928
        struct MyHasher;
2929
        impl BuildHasher for MyHasher {
2930
            type Hasher = DefaultHasher;
2931
2932
            fn build_hasher(&self) -> DefaultHasher {
2933
                DefaultHasher::new()
2934
            }
2935
        }
2936
2937
        const EMPTY_SET: HashSet<u32, MyHasher> = HashSet::with_hasher(MyHasher);
2938
2939
        let mut set = EMPTY_SET;
2940
        set.insert(19);
2941
        assert!(set.contains(&19));
2942
    }
2943
2944
    #[test]
2945
    fn rehash_in_place() {
2946
        let mut set = HashSet::new();
2947
2948
        for i in 0..224 {
2949
            set.insert(i);
2950
        }
2951
2952
        assert_eq!(
2953
            set.capacity(),
2954
            224,
2955
            "The set must be at or close to capacity to trigger a re hashing"
2956
        );
2957
2958
        for i in 100..1400 {
2959
            set.remove(&(i - 100));
2960
            set.insert(i);
2961
        }
2962
    }
2963
2964
    #[test]
2965
    fn collect() {
2966
        // At the time of writing, this hits the ZST case in from_base_index
2967
        // (and without the `map`, it does not).
2968
        let mut _set: HashSet<_> = (0..3).map(|_| ()).collect();
2969
    }
2970
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.5/src/table.rs
Line
Count
Source
1
use core::{fmt, iter::FusedIterator, marker::PhantomData};
2
3
use crate::{
4
    raw::{
5
        Allocator, Bucket, Global, InsertSlot, RawDrain, RawExtractIf, RawIntoIter, RawIter,
6
        RawTable,
7
    },
8
    TryReserveError,
9
};
10
11
/// Low-level hash table with explicit hashing.
12
///
13
/// The primary use case for this type over [`HashMap`] or [`HashSet`] is to
14
/// support types that do not implement the [`Hash`] and [`Eq`] traits, but
15
/// instead require additional data not contained in the key itself to compute a
16
/// hash and compare two elements for equality.
17
///
18
/// Examples of when this can be useful include:
19
/// - An `IndexMap` implementation where indices into a `Vec` are stored as
20
///   elements in a `HashTable<usize>`. Hashing and comparing the elements
21
///   requires indexing the associated `Vec` to get the actual value referred to
22
///   by the index.
23
/// - Avoiding re-computing a hash when it is already known.
24
/// - Mutating the key of an element in a way that doesn't affect its hash.
25
///
26
/// To achieve this, `HashTable` methods that search for an element in the table
27
/// require a hash value and equality function to be explicitly passed in as
28
/// arguments. The method will then iterate over the elements with the given
29
/// hash and call the equality function on each of them, until a match is found.
30
///
31
/// In most cases, a `HashTable` will not be exposed directly in an API. It will
32
/// instead be wrapped in a helper type which handles the work of calculating
33
/// hash values and comparing elements.
34
///
35
/// Due to its low-level nature, this type provides fewer guarantees than
36
/// [`HashMap`] and [`HashSet`]. Specifically, the API allows you to shoot
37
/// yourself in the foot by having multiple elements with identical keys in the
38
/// table. The table itself will still function correctly and lookups will
39
/// arbitrarily return one of the matching elements. However you should avoid
40
/// doing this because it changes the runtime of hash table operations from
41
/// `O(1)` to `O(k)` where `k` is the number of duplicate entries.
42
///
43
/// [`HashMap`]: super::HashMap
44
/// [`HashSet`]: super::HashSet
45
pub struct HashTable<T, A = Global>
46
where
47
    A: Allocator,
48
{
49
    pub(crate) raw: RawTable<T, A>,
50
}
51
52
impl<T> HashTable<T, Global> {
53
    /// Creates an empty `HashTable`.
54
    ///
55
    /// The hash table is initially created with a capacity of 0, so it will not allocate until it
56
    /// is first inserted into.
57
    ///
58
    /// # Examples
59
    ///
60
    /// ```
61
    /// use hashbrown::HashTable;
62
    /// let mut table: HashTable<&str> = HashTable::new();
63
    /// assert_eq!(table.len(), 0);
64
    /// assert_eq!(table.capacity(), 0);
65
    /// ```
66
0
    pub const fn new() -> Self {
67
0
        Self {
68
0
            raw: RawTable::new(),
69
0
        }
70
0
    }
71
72
    /// Creates an empty `HashTable` with the specified capacity.
73
    ///
74
    /// The hash table will be able to hold at least `capacity` elements without
75
    /// reallocating. If `capacity` is 0, the hash table will not allocate.
76
    ///
77
    /// # Examples
78
    ///
79
    /// ```
80
    /// use hashbrown::HashTable;
81
    /// let mut table: HashTable<&str> = HashTable::with_capacity(10);
82
    /// assert_eq!(table.len(), 0);
83
    /// assert!(table.capacity() >= 10);
84
    /// ```
85
0
    pub fn with_capacity(capacity: usize) -> Self {
86
0
        Self {
87
0
            raw: RawTable::with_capacity(capacity),
88
0
        }
89
0
    }
90
}
91
92
impl<T, A> HashTable<T, A>
93
where
94
    A: Allocator,
95
{
96
    /// Creates an empty `HashTable` using the given allocator.
97
    ///
98
    /// The hash table is initially created with a capacity of 0, so it will not allocate until it
99
    /// is first inserted into.
100
    ///
101
    /// # Examples
102
    ///
103
    /// ```
104
    /// # #[cfg(feature = "nightly")]
105
    /// # fn test() {
106
    /// use ahash::AHasher;
107
    /// use bumpalo::Bump;
108
    /// use hashbrown::HashTable;
109
    /// use std::hash::{BuildHasher, BuildHasherDefault};
110
    ///
111
    /// let bump = Bump::new();
112
    /// let mut table = HashTable::new_in(&bump);
113
    /// let hasher = BuildHasherDefault::<AHasher>::default();
114
    /// let hasher = |val: &_| hasher.hash_one(val);
115
    ///
116
    /// // The created HashTable holds none elements
117
    /// assert_eq!(table.len(), 0);
118
    ///
119
    /// // The created HashTable also doesn't allocate memory
120
    /// assert_eq!(table.capacity(), 0);
121
    ///
122
    /// // Now we insert element inside created HashTable
123
    /// table.insert_unique(hasher(&"One"), "One", hasher);
124
    /// // We can see that the HashTable holds 1 element
125
    /// assert_eq!(table.len(), 1);
126
    /// // And it also allocates some capacity
127
    /// assert!(table.capacity() > 1);
128
    /// # }
129
    /// # fn main() {
130
    /// #     #[cfg(feature = "nightly")]
131
    /// #     test()
132
    /// # }
133
    /// ```
134
0
    pub const fn new_in(alloc: A) -> Self {
135
0
        Self {
136
0
            raw: RawTable::new_in(alloc),
137
0
        }
138
0
    }
139
140
    /// Creates an empty `HashTable` with the specified capacity using the given allocator.
141
    ///
142
    /// The hash table will be able to hold at least `capacity` elements without
143
    /// reallocating. If `capacity` is 0, the hash table will not allocate.
144
    ///
145
    /// # Examples
146
    ///
147
    /// ```
148
    /// # #[cfg(feature = "nightly")]
149
    /// # fn test() {
150
    /// use ahash::AHasher;
151
    /// use bumpalo::Bump;
152
    /// use hashbrown::HashTable;
153
    /// use std::hash::{BuildHasher, BuildHasherDefault};
154
    ///
155
    /// let bump = Bump::new();
156
    /// let mut table = HashTable::with_capacity_in(5, &bump);
157
    /// let hasher = BuildHasherDefault::<AHasher>::default();
158
    /// let hasher = |val: &_| hasher.hash_one(val);
159
    ///
160
    /// // The created HashTable holds none elements
161
    /// assert_eq!(table.len(), 0);
162
    /// // But it can hold at least 5 elements without reallocating
163
    /// let empty_map_capacity = table.capacity();
164
    /// assert!(empty_map_capacity >= 5);
165
    ///
166
    /// // Now we insert some 5 elements inside created HashTable
167
    /// table.insert_unique(hasher(&"One"), "One", hasher);
168
    /// table.insert_unique(hasher(&"Two"), "Two", hasher);
169
    /// table.insert_unique(hasher(&"Three"), "Three", hasher);
170
    /// table.insert_unique(hasher(&"Four"), "Four", hasher);
171
    /// table.insert_unique(hasher(&"Five"), "Five", hasher);
172
    ///
173
    /// // We can see that the HashTable holds 5 elements
174
    /// assert_eq!(table.len(), 5);
175
    /// // But its capacity isn't changed
176
    /// assert_eq!(table.capacity(), empty_map_capacity)
177
    /// # }
178
    /// # fn main() {
179
    /// #     #[cfg(feature = "nightly")]
180
    /// #     test()
181
    /// # }
182
    /// ```
183
0
    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
184
0
        Self {
185
0
            raw: RawTable::with_capacity_in(capacity, alloc),
186
0
        }
187
0
    }
188
189
    /// Returns a reference to the underlying allocator.
190
0
    pub fn allocator(&self) -> &A {
191
0
        self.raw.allocator()
192
0
    }
193
194
    /// Returns a reference to an entry in the table with the given hash and
195
    /// which satisfies the equality function passed.
196
    ///
197
    /// This method will call `eq` for all entries with the given hash, but may
198
    /// also call it for entries with a different hash. `eq` should only return
199
    /// true for the desired entry, at which point the search is stopped.
200
    ///
201
    /// # Examples
202
    ///
203
    /// ```
204
    /// # #[cfg(feature = "nightly")]
205
    /// # fn test() {
206
    /// use ahash::AHasher;
207
    /// use hashbrown::HashTable;
208
    /// use std::hash::{BuildHasher, BuildHasherDefault};
209
    ///
210
    /// let mut table = HashTable::new();
211
    /// let hasher = BuildHasherDefault::<AHasher>::default();
212
    /// let hasher = |val: &_| hasher.hash_one(val);
213
    /// table.insert_unique(hasher(&1), 1, hasher);
214
    /// table.insert_unique(hasher(&2), 2, hasher);
215
    /// table.insert_unique(hasher(&3), 3, hasher);
216
    /// assert_eq!(table.find(hasher(&2), |&val| val == 2), Some(&2));
217
    /// assert_eq!(table.find(hasher(&4), |&val| val == 4), None);
218
    /// # }
219
    /// # fn main() {
220
    /// #     #[cfg(feature = "nightly")]
221
    /// #     test()
222
    /// # }
223
    /// ```
224
0
    pub fn find(&self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&T> {
225
0
        self.raw.get(hash, eq)
226
0
    }
227
228
    /// Returns a mutable reference to an entry in the table with the given hash
229
    /// and which satisfies the equality function passed.
230
    ///
231
    /// This method will call `eq` for all entries with the given hash, but may
232
    /// also call it for entries with a different hash. `eq` should only return
233
    /// true for the desired entry, at which point the search is stopped.
234
    ///
235
    /// When mutating an entry, you should ensure that it still retains the same
236
    /// hash value as when it was inserted, otherwise lookups of that entry may
237
    /// fail to find it.
238
    ///
239
    /// # Examples
240
    ///
241
    /// ```
242
    /// # #[cfg(feature = "nightly")]
243
    /// # fn test() {
244
    /// use ahash::AHasher;
245
    /// use hashbrown::HashTable;
246
    /// use std::hash::{BuildHasher, BuildHasherDefault};
247
    ///
248
    /// let mut table = HashTable::new();
249
    /// let hasher = BuildHasherDefault::<AHasher>::default();
250
    /// let hasher = |val: &_| hasher.hash_one(val);
251
    /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
252
    /// if let Some(val) = table.find_mut(hasher(&1), |val| val.0 == 1) {
253
    ///     val.1 = "b";
254
    /// }
255
    /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), Some(&(1, "b")));
256
    /// assert_eq!(table.find(hasher(&2), |val| val.0 == 2), None);
257
    /// # }
258
    /// # fn main() {
259
    /// #     #[cfg(feature = "nightly")]
260
    /// #     test()
261
    /// # }
262
    /// ```
263
0
    pub fn find_mut(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&mut T> {
264
0
        self.raw.get_mut(hash, eq)
265
0
    }
266
267
    /// Returns an `OccupiedEntry` for an entry in the table with the given hash
268
    /// and which satisfies the equality function passed.
269
    ///
270
    /// This can be used to remove the entry from the table. Call
271
    /// [`HashTable::entry`] instead if you wish to insert an entry if the
272
    /// lookup fails.
273
    ///
274
    /// This method will call `eq` for all entries with the given hash, but may
275
    /// also call it for entries with a different hash. `eq` should only return
276
    /// true for the desired entry, at which point the search is stopped.
277
    ///
278
    /// # Examples
279
    ///
280
    /// ```
281
    /// # #[cfg(feature = "nightly")]
282
    /// # fn test() {
283
    /// use ahash::AHasher;
284
    /// use hashbrown::HashTable;
285
    /// use std::hash::{BuildHasher, BuildHasherDefault};
286
    ///
287
    /// let mut table = HashTable::new();
288
    /// let hasher = BuildHasherDefault::<AHasher>::default();
289
    /// let hasher = |val: &_| hasher.hash_one(val);
290
    /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
291
    /// if let Ok(entry) = table.find_entry(hasher(&1), |val| val.0 == 1) {
292
    ///     entry.remove();
293
    /// }
294
    /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), None);
295
    /// # }
296
    /// # fn main() {
297
    /// #     #[cfg(feature = "nightly")]
298
    /// #     test()
299
    /// # }
300
    /// ```
301
    #[cfg_attr(feature = "inline-more", inline)]
302
0
    pub fn find_entry(
303
0
        &mut self,
304
0
        hash: u64,
305
0
        eq: impl FnMut(&T) -> bool,
306
0
    ) -> Result<OccupiedEntry<'_, T, A>, AbsentEntry<'_, T, A>> {
307
0
        match self.raw.find(hash, eq) {
308
0
            Some(bucket) => Ok(OccupiedEntry {
309
0
                hash,
310
0
                bucket,
311
0
                table: self,
312
0
            }),
313
0
            None => Err(AbsentEntry { table: self }),
314
        }
315
0
    }
316
317
    /// Returns an `Entry` for an entry in the table with the given hash
318
    /// and which satisfies the equality function passed.
319
    ///
320
    /// This can be used to remove the entry from the table, or insert a new
321
    /// entry with the given hash if one doesn't already exist.
322
    ///
323
    /// This method will call `eq` for all entries with the given hash, but may
324
    /// also call it for entries with a different hash. `eq` should only return
325
    /// true for the desired entry, at which point the search is stopped.
326
    ///
327
    /// This method may grow the table in preparation for an insertion. Call
328
    /// [`HashTable::find_entry`] if this is undesirable.
329
    ///
330
    /// `hasher` is called if entries need to be moved or copied to a new table.
331
    /// This must return the same hash value that each entry was inserted with.
332
    ///
333
    /// # Examples
334
    ///
335
    /// ```
336
    /// # #[cfg(feature = "nightly")]
337
    /// # fn test() {
338
    /// use ahash::AHasher;
339
    /// use hashbrown::hash_table::Entry;
340
    /// use hashbrown::HashTable;
341
    /// use std::hash::{BuildHasher, BuildHasherDefault};
342
    ///
343
    /// let mut table = HashTable::new();
344
    /// let hasher = BuildHasherDefault::<AHasher>::default();
345
    /// let hasher = |val: &_| hasher.hash_one(val);
346
    /// table.insert_unique(hasher(&1), (1, "a"), |val| hasher(&val.0));
347
    /// if let Entry::Occupied(entry) = table.entry(hasher(&1), |val| val.0 == 1, |val| hasher(&val.0))
348
    /// {
349
    ///     entry.remove();
350
    /// }
351
    /// if let Entry::Vacant(entry) = table.entry(hasher(&2), |val| val.0 == 2, |val| hasher(&val.0)) {
352
    ///     entry.insert((2, "b"));
353
    /// }
354
    /// assert_eq!(table.find(hasher(&1), |val| val.0 == 1), None);
355
    /// assert_eq!(table.find(hasher(&2), |val| val.0 == 2), Some(&(2, "b")));
356
    /// # }
357
    /// # fn main() {
358
    /// #     #[cfg(feature = "nightly")]
359
    /// #     test()
360
    /// # }
361
    /// ```
362
    #[cfg_attr(feature = "inline-more", inline)]
363
0
    pub fn entry(
364
0
        &mut self,
365
0
        hash: u64,
366
0
        eq: impl FnMut(&T) -> bool,
367
0
        hasher: impl Fn(&T) -> u64,
368
0
    ) -> Entry<'_, T, A> {
369
0
        match self.raw.find_or_find_insert_slot(hash, eq, hasher) {
370
0
            Ok(bucket) => Entry::Occupied(OccupiedEntry {
371
0
                hash,
372
0
                bucket,
373
0
                table: self,
374
0
            }),
375
0
            Err(insert_slot) => Entry::Vacant(VacantEntry {
376
0
                hash,
377
0
                insert_slot,
378
0
                table: self,
379
0
            }),
380
        }
381
0
    }
382
383
    /// Inserts an element into the `HashTable` with the given hash value, but
384
    /// without checking whether an equivalent element already exists within the
385
    /// table.
386
    ///
387
    /// `hasher` is called if entries need to be moved or copied to a new table.
388
    /// This must return the same hash value that each entry was inserted with.
389
    ///
390
    /// # Examples
391
    ///
392
    /// ```
393
    /// # #[cfg(feature = "nightly")]
394
    /// # fn test() {
395
    /// use ahash::AHasher;
396
    /// use hashbrown::HashTable;
397
    /// use std::hash::{BuildHasher, BuildHasherDefault};
398
    ///
399
    /// let mut v = HashTable::new();
400
    /// let hasher = BuildHasherDefault::<AHasher>::default();
401
    /// let hasher = |val: &_| hasher.hash_one(val);
402
    /// v.insert_unique(hasher(&1), 1, hasher);
403
    /// # }
404
    /// # fn main() {
405
    /// #     #[cfg(feature = "nightly")]
406
    /// #     test()
407
    /// # }
408
    /// ```
409
0
    pub fn insert_unique(
410
0
        &mut self,
411
0
        hash: u64,
412
0
        value: T,
413
0
        hasher: impl Fn(&T) -> u64,
414
0
    ) -> OccupiedEntry<'_, T, A> {
415
0
        let bucket = self.raw.insert(hash, value, hasher);
416
0
        OccupiedEntry {
417
0
            hash,
418
0
            bucket,
419
0
            table: self,
420
0
        }
421
0
    }
422
423
    /// Clears the table, removing all values.
424
    ///
425
    /// # Examples
426
    ///
427
    /// ```
428
    /// # #[cfg(feature = "nightly")]
429
    /// # fn test() {
430
    /// use ahash::AHasher;
431
    /// use hashbrown::HashTable;
432
    /// use std::hash::{BuildHasher, BuildHasherDefault};
433
    ///
434
    /// let mut v = HashTable::new();
435
    /// let hasher = BuildHasherDefault::<AHasher>::default();
436
    /// let hasher = |val: &_| hasher.hash_one(val);
437
    /// v.insert_unique(hasher(&1), 1, hasher);
438
    /// v.clear();
439
    /// assert!(v.is_empty());
440
    /// # }
441
    /// # fn main() {
442
    /// #     #[cfg(feature = "nightly")]
443
    /// #     test()
444
    /// # }
445
    /// ```
446
0
    pub fn clear(&mut self) {
447
0
        self.raw.clear();
448
0
    }
449
450
    /// Shrinks the capacity of the table as much as possible. It will drop
451
    /// down as much as possible while maintaining the internal rules
452
    /// and possibly leaving some space in accordance with the resize policy.
453
    ///
454
    /// `hasher` is called if entries need to be moved or copied to a new table.
455
    /// This must return the same hash value that each entry was inserted with.
456
    ///
457
    /// # Examples
458
    ///
459
    /// ```
460
    /// # #[cfg(feature = "nightly")]
461
    /// # fn test() {
462
    /// use ahash::AHasher;
463
    /// use hashbrown::HashTable;
464
    /// use std::hash::{BuildHasher, BuildHasherDefault};
465
    ///
466
    /// let mut table = HashTable::with_capacity(100);
467
    /// let hasher = BuildHasherDefault::<AHasher>::default();
468
    /// let hasher = |val: &_| hasher.hash_one(val);
469
    /// table.insert_unique(hasher(&1), 1, hasher);
470
    /// table.insert_unique(hasher(&2), 2, hasher);
471
    /// assert!(table.capacity() >= 100);
472
    /// table.shrink_to_fit(hasher);
473
    /// assert!(table.capacity() >= 2);
474
    /// # }
475
    /// # fn main() {
476
    /// #     #[cfg(feature = "nightly")]
477
    /// #     test()
478
    /// # }
479
    /// ```
480
0
    pub fn shrink_to_fit(&mut self, hasher: impl Fn(&T) -> u64) {
481
0
        self.raw.shrink_to(self.len(), hasher)
482
0
    }
483
484
    /// Shrinks the capacity of the table with a lower limit. It will drop
485
    /// down no lower than the supplied limit while maintaining the internal rules
486
    /// and possibly leaving some space in accordance with the resize policy.
487
    ///
488
    /// `hasher` is called if entries need to be moved or copied to a new table.
489
    /// This must return the same hash value that each entry was inserted with.
490
    ///
491
    /// Panics if the current capacity is smaller than the supplied
492
    /// minimum capacity.
493
    ///
494
    /// # Examples
495
    ///
496
    /// ```
497
    /// # #[cfg(feature = "nightly")]
498
    /// # fn test() {
499
    /// use ahash::AHasher;
500
    /// use hashbrown::HashTable;
501
    /// use std::hash::{BuildHasher, BuildHasherDefault};
502
    ///
503
    /// let mut table = HashTable::with_capacity(100);
504
    /// let hasher = BuildHasherDefault::<AHasher>::default();
505
    /// let hasher = |val: &_| hasher.hash_one(val);
506
    /// table.insert_unique(hasher(&1), 1, hasher);
507
    /// table.insert_unique(hasher(&2), 2, hasher);
508
    /// assert!(table.capacity() >= 100);
509
    /// table.shrink_to(10, hasher);
510
    /// assert!(table.capacity() >= 10);
511
    /// table.shrink_to(0, hasher);
512
    /// assert!(table.capacity() >= 2);
513
    /// # }
514
    /// # fn main() {
515
    /// #     #[cfg(feature = "nightly")]
516
    /// #     test()
517
    /// # }
518
    /// ```
519
0
    pub fn shrink_to(&mut self, min_capacity: usize, hasher: impl Fn(&T) -> u64) {
520
0
        self.raw.shrink_to(min_capacity, hasher);
521
0
    }
522
523
    /// Reserves capacity for at least `additional` more elements to be inserted
524
    /// in the `HashTable`. The collection may reserve more space to avoid
525
    /// frequent reallocations.
526
    ///
527
    /// `hasher` is called if entries need to be moved or copied to a new table.
528
    /// This must return the same hash value that each entry was inserted with.
529
    ///
530
    /// # Panics
531
    ///
532
    /// Panics if the new capacity exceeds [`isize::MAX`] bytes and [`abort`] the program
533
    /// in case of allocation error. Use [`try_reserve`](HashTable::try_reserve) instead
534
    /// if you want to handle memory allocation failure.
535
    ///
536
    /// [`isize::MAX`]: https://doc.rust-lang.org/std/primitive.isize.html
537
    /// [`abort`]: https://doc.rust-lang.org/alloc/alloc/fn.handle_alloc_error.html
538
    ///
539
    /// # Examples
540
    ///
541
    /// ```
542
    /// # #[cfg(feature = "nightly")]
543
    /// # fn test() {
544
    /// use ahash::AHasher;
545
    /// use hashbrown::HashTable;
546
    /// use std::hash::{BuildHasher, BuildHasherDefault};
547
    ///
548
    /// let mut table: HashTable<i32> = HashTable::new();
549
    /// let hasher = BuildHasherDefault::<AHasher>::default();
550
    /// let hasher = |val: &_| hasher.hash_one(val);
551
    /// table.reserve(10, hasher);
552
    /// assert!(table.capacity() >= 10);
553
    /// # }
554
    /// # fn main() {
555
    /// #     #[cfg(feature = "nightly")]
556
    /// #     test()
557
    /// # }
558
    /// ```
559
0
    pub fn reserve(&mut self, additional: usize, hasher: impl Fn(&T) -> u64) {
560
0
        self.raw.reserve(additional, hasher)
561
0
    }
562
563
    /// Tries to reserve capacity for at least `additional` more elements to be inserted
564
    /// in the given `HashTable`. The collection may reserve more space to avoid
565
    /// frequent reallocations.
566
    ///
567
    /// `hasher` is called if entries need to be moved or copied to a new table.
568
    /// This must return the same hash value that each entry was inserted with.
569
    ///
570
    /// # Errors
571
    ///
572
    /// If the capacity overflows, or the allocator reports a failure, then an error
573
    /// is returned.
574
    ///
575
    /// # Examples
576
    ///
577
    /// ```
578
    /// # #[cfg(feature = "nightly")]
579
    /// # fn test() {
580
    /// use ahash::AHasher;
581
    /// use hashbrown::HashTable;
582
    /// use std::hash::{BuildHasher, BuildHasherDefault};
583
    ///
584
    /// let mut table: HashTable<i32> = HashTable::new();
585
    /// let hasher = BuildHasherDefault::<AHasher>::default();
586
    /// let hasher = |val: &_| hasher.hash_one(val);
587
    /// table
588
    ///     .try_reserve(10, hasher)
589
    ///     .expect("why is the test harness OOMing on 10 bytes?");
590
    /// # }
591
    /// # fn main() {
592
    /// #     #[cfg(feature = "nightly")]
593
    /// #     test()
594
    /// # }
595
    /// ```
596
0
    pub fn try_reserve(
597
0
        &mut self,
598
0
        additional: usize,
599
0
        hasher: impl Fn(&T) -> u64,
600
0
    ) -> Result<(), TryReserveError> {
601
0
        self.raw.try_reserve(additional, hasher)
602
0
    }
603
604
    /// Returns the number of elements the table can hold without reallocating.
605
    ///
606
    /// # Examples
607
    ///
608
    /// ```
609
    /// use hashbrown::HashTable;
610
    /// let table: HashTable<i32> = HashTable::with_capacity(100);
611
    /// assert!(table.capacity() >= 100);
612
    /// ```
613
0
    pub fn capacity(&self) -> usize {
614
0
        self.raw.capacity()
615
0
    }
616
617
    /// Returns the number of elements in the table.
618
    ///
619
    /// # Examples
620
    ///
621
    /// ```
622
    /// # #[cfg(feature = "nightly")]
623
    /// # fn test() {
624
    /// use ahash::AHasher;
625
    /// use hashbrown::HashTable;
626
    /// use std::hash::{BuildHasher, BuildHasherDefault};
627
    ///
628
    /// let hasher = BuildHasherDefault::<AHasher>::default();
629
    /// let hasher = |val: &_| hasher.hash_one(val);
630
    /// let mut v = HashTable::new();
631
    /// assert_eq!(v.len(), 0);
632
    /// v.insert_unique(hasher(&1), 1, hasher);
633
    /// assert_eq!(v.len(), 1);
634
    /// # }
635
    /// # fn main() {
636
    /// #     #[cfg(feature = "nightly")]
637
    /// #     test()
638
    /// # }
639
    /// ```
640
0
    pub fn len(&self) -> usize {
641
0
        self.raw.len()
642
0
    }
643
644
    /// Returns `true` if the set contains no elements.
645
    ///
646
    /// # Examples
647
    ///
648
    /// ```
649
    /// # #[cfg(feature = "nightly")]
650
    /// # fn test() {
651
    /// use ahash::AHasher;
652
    /// use hashbrown::HashTable;
653
    /// use std::hash::{BuildHasher, BuildHasherDefault};
654
    ///
655
    /// let hasher = BuildHasherDefault::<AHasher>::default();
656
    /// let hasher = |val: &_| hasher.hash_one(val);
657
    /// let mut v = HashTable::new();
658
    /// assert!(v.is_empty());
659
    /// v.insert_unique(hasher(&1), 1, hasher);
660
    /// assert!(!v.is_empty());
661
    /// # }
662
    /// # fn main() {
663
    /// #     #[cfg(feature = "nightly")]
664
    /// #     test()
665
    /// # }
666
    /// ```
667
0
    pub fn is_empty(&self) -> bool {
668
0
        self.raw.is_empty()
669
0
    }
670
671
    /// An iterator visiting all elements in arbitrary order.
672
    /// The iterator element type is `&'a T`.
673
    ///
674
    /// # Examples
675
    ///
676
    /// ```
677
    /// # #[cfg(feature = "nightly")]
678
    /// # fn test() {
679
    /// use ahash::AHasher;
680
    /// use hashbrown::HashTable;
681
    /// use std::hash::{BuildHasher, BuildHasherDefault};
682
    ///
683
    /// let mut table = HashTable::new();
684
    /// let hasher = BuildHasherDefault::<AHasher>::default();
685
    /// let hasher = |val: &_| hasher.hash_one(val);
686
    /// table.insert_unique(hasher(&"a"), "b", hasher);
687
    /// table.insert_unique(hasher(&"b"), "b", hasher);
688
    ///
689
    /// // Will print in an arbitrary order.
690
    /// for x in table.iter() {
691
    ///     println!("{}", x);
692
    /// }
693
    /// # }
694
    /// # fn main() {
695
    /// #     #[cfg(feature = "nightly")]
696
    /// #     test()
697
    /// # }
698
    /// ```
699
0
    pub fn iter(&self) -> Iter<'_, T> {
700
0
        Iter {
701
0
            inner: unsafe { self.raw.iter() },
702
0
            marker: PhantomData,
703
0
        }
704
0
    }
705
706
    /// An iterator visiting all elements in arbitrary order,
707
    /// with mutable references to the elements.
708
    /// The iterator element type is `&'a mut T`.
709
    ///
710
    /// # Examples
711
    ///
712
    /// ```
713
    /// # #[cfg(feature = "nightly")]
714
    /// # fn test() {
715
    /// use ahash::AHasher;
716
    /// use hashbrown::HashTable;
717
    /// use std::hash::{BuildHasher, BuildHasherDefault};
718
    ///
719
    /// let mut table = HashTable::new();
720
    /// let hasher = BuildHasherDefault::<AHasher>::default();
721
    /// let hasher = |val: &_| hasher.hash_one(val);
722
    /// table.insert_unique(hasher(&1), 1, hasher);
723
    /// table.insert_unique(hasher(&2), 2, hasher);
724
    /// table.insert_unique(hasher(&3), 3, hasher);
725
    ///
726
    /// // Update all values
727
    /// for val in table.iter_mut() {
728
    ///     *val *= 2;
729
    /// }
730
    ///
731
    /// assert_eq!(table.len(), 3);
732
    /// let mut vec: Vec<i32> = Vec::new();
733
    ///
734
    /// for val in &table {
735
    ///     println!("val: {}", val);
736
    ///     vec.push(*val);
737
    /// }
738
    ///
739
    /// // The `Iter` iterator produces items in arbitrary order, so the
740
    /// // items must be sorted to test them against a sorted array.
741
    /// vec.sort_unstable();
742
    /// assert_eq!(vec, [2, 4, 6]);
743
    ///
744
    /// assert_eq!(table.len(), 3);
745
    /// # }
746
    /// # fn main() {
747
    /// #     #[cfg(feature = "nightly")]
748
    /// #     test()
749
    /// # }
750
    /// ```
751
0
    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
752
0
        IterMut {
753
0
            inner: unsafe { self.raw.iter() },
754
0
            marker: PhantomData,
755
0
        }
756
0
    }
757
758
    /// Retains only the elements specified by the predicate.
759
    ///
760
    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
761
    ///
762
    /// # Examples
763
    ///
764
    /// ```
765
    /// # #[cfg(feature = "nightly")]
766
    /// # fn test() {
767
    /// use ahash::AHasher;
768
    /// use hashbrown::HashTable;
769
    /// use std::hash::{BuildHasher, BuildHasherDefault};
770
    ///
771
    /// let mut table = HashTable::new();
772
    /// let hasher = BuildHasherDefault::<AHasher>::default();
773
    /// let hasher = |val: &_| hasher.hash_one(val);
774
    /// for x in 1..=6 {
775
    ///     table.insert_unique(hasher(&x), x, hasher);
776
    /// }
777
    /// table.retain(|&mut x| x % 2 == 0);
778
    /// assert_eq!(table.len(), 3);
779
    /// # }
780
    /// # fn main() {
781
    /// #     #[cfg(feature = "nightly")]
782
    /// #     test()
783
    /// # }
784
    /// ```
785
0
    pub fn retain(&mut self, mut f: impl FnMut(&mut T) -> bool) {
786
        // Here we only use `iter` as a temporary, preventing use-after-free
787
        unsafe {
788
0
            for item in self.raw.iter() {
789
0
                if !f(item.as_mut()) {
790
0
                    self.raw.erase(item);
791
0
                }
792
            }
793
        }
794
0
    }
795
796
    /// Clears the set, returning all elements in an iterator.
797
    ///
798
    /// # Examples
799
    ///
800
    /// ```
801
    /// # #[cfg(feature = "nightly")]
802
    /// # fn test() {
803
    /// use ahash::AHasher;
804
    /// use hashbrown::HashTable;
805
    /// use std::hash::{BuildHasher, BuildHasherDefault};
806
    ///
807
    /// let mut table = HashTable::new();
808
    /// let hasher = BuildHasherDefault::<AHasher>::default();
809
    /// let hasher = |val: &_| hasher.hash_one(val);
810
    /// for x in 1..=3 {
811
    ///     table.insert_unique(hasher(&x), x, hasher);
812
    /// }
813
    /// assert!(!table.is_empty());
814
    ///
815
    /// // print 1, 2, 3 in an arbitrary order
816
    /// for i in table.drain() {
817
    ///     println!("{}", i);
818
    /// }
819
    ///
820
    /// assert!(table.is_empty());
821
    /// # }
822
    /// # fn main() {
823
    /// #     #[cfg(feature = "nightly")]
824
    /// #     test()
825
    /// # }
826
    /// ```
827
0
    pub fn drain(&mut self) -> Drain<'_, T, A> {
828
0
        Drain {
829
0
            inner: self.raw.drain(),
830
0
        }
831
0
    }
832
833
    /// Drains elements which are true under the given predicate,
834
    /// and returns an iterator over the removed items.
835
    ///
836
    /// In other words, move all elements `e` such that `f(&e)` returns `true` out
837
    /// into another iterator.
838
    ///
839
    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
840
    /// or the iteration short-circuits, then the remaining elements will be retained.
841
    /// Use [`retain()`] with a negated predicate if you do not need the returned iterator.
842
    ///
843
    /// [`retain()`]: HashTable::retain
844
    ///
845
    /// # Examples
846
    ///
847
    /// ```
848
    /// # #[cfg(feature = "nightly")]
849
    /// # fn test() {
850
    /// use ahash::AHasher;
851
    /// use hashbrown::HashTable;
852
    /// use std::hash::{BuildHasher, BuildHasherDefault};
853
    ///
854
    /// let mut table = HashTable::new();
855
    /// let hasher = BuildHasherDefault::<AHasher>::default();
856
    /// let hasher = |val: &_| hasher.hash_one(val);
857
    /// for x in 0..8 {
858
    ///     table.insert_unique(hasher(&x), x, hasher);
859
    /// }
860
    /// let drained: Vec<i32> = table.extract_if(|&mut v| v % 2 == 0).collect();
861
    ///
862
    /// let mut evens = drained.into_iter().collect::<Vec<_>>();
863
    /// let mut odds = table.into_iter().collect::<Vec<_>>();
864
    /// evens.sort();
865
    /// odds.sort();
866
    ///
867
    /// assert_eq!(evens, vec![0, 2, 4, 6]);
868
    /// assert_eq!(odds, vec![1, 3, 5, 7]);
869
    /// # }
870
    /// # fn main() {
871
    /// #     #[cfg(feature = "nightly")]
872
    /// #     test()
873
    /// # }
874
    /// ```
875
0
    pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, T, F, A>
876
0
    where
877
0
        F: FnMut(&mut T) -> bool,
878
0
    {
879
0
        ExtractIf {
880
0
            f,
881
0
            inner: RawExtractIf {
882
0
                iter: unsafe { self.raw.iter() },
883
0
                table: &mut self.raw,
884
0
            },
885
0
        }
886
0
    }
887
888
    /// Attempts to get mutable references to `N` values in the map at once.
889
    ///
890
    /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
891
    /// the `i`th key to be looked up.
892
    ///
893
    /// Returns an array of length `N` with the results of each query. For soundness, at most one
894
    /// mutable reference will be returned to any value. `None` will be returned if any of the
895
    /// keys are duplicates or missing.
896
    ///
897
    /// # Examples
898
    ///
899
    /// ```
900
    /// # #[cfg(feature = "nightly")]
901
    /// # fn test() {
902
    /// use ahash::AHasher;
903
    /// use hashbrown::hash_table::Entry;
904
    /// use hashbrown::HashTable;
905
    /// use std::hash::{BuildHasher, BuildHasherDefault};
906
    ///
907
    /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
908
    /// let hasher = BuildHasherDefault::<AHasher>::default();
909
    /// let hasher = |val: &_| hasher.hash_one(val);
910
    /// for (k, v) in [
911
    ///     ("Bodleian Library", 1602),
912
    ///     ("Athenæum", 1807),
913
    ///     ("Herzogin-Anna-Amalia-Bibliothek", 1691),
914
    ///     ("Library of Congress", 1800),
915
    /// ] {
916
    ///     libraries.insert_unique(hasher(&k), (k, v), |(k, _)| hasher(&k));
917
    /// }
918
    ///
919
    /// let keys = ["Athenæum", "Library of Congress"];
920
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
921
    /// assert_eq!(
922
    ///     got,
923
    ///     Some([&mut ("Athenæum", 1807), &mut ("Library of Congress", 1800),]),
924
    /// );
925
    ///
926
    /// // Missing keys result in None
927
    /// let keys = ["Athenæum", "New York Public Library"];
928
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
929
    /// assert_eq!(got, None);
930
    ///
931
    /// // Duplicate keys result in None
932
    /// let keys = ["Athenæum", "Athenæum"];
933
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
934
    /// assert_eq!(got, None);
935
    /// # }
936
    /// # fn main() {
937
    /// #     #[cfg(feature = "nightly")]
938
    /// #     test()
939
    /// # }
940
    /// ```
941
0
    pub fn get_many_mut<const N: usize>(
942
0
        &mut self,
943
0
        hashes: [u64; N],
944
0
        eq: impl FnMut(usize, &T) -> bool,
945
0
    ) -> Option<[&'_ mut T; N]> {
946
0
        self.raw.get_many_mut(hashes, eq)
947
0
    }
948
949
    /// Attempts to get mutable references to `N` values in the map at once, without validating that
950
    /// the values are unique.
951
    ///
952
    /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
953
    /// the `i`th key to be looked up.
954
    ///
955
    /// Returns an array of length `N` with the results of each query. `None` will be returned if
956
    /// any of the keys are missing.
957
    ///
958
    /// For a safe alternative see [`get_many_mut`](`HashTable::get_many_mut`).
959
    ///
960
    /// # Safety
961
    ///
962
    /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
963
    /// references are not used.
964
    ///
965
    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
966
    ///
967
    /// # Examples
968
    ///
969
    /// ```
970
    /// # #[cfg(feature = "nightly")]
971
    /// # fn test() {
972
    /// use ahash::AHasher;
973
    /// use hashbrown::hash_table::Entry;
974
    /// use hashbrown::HashTable;
975
    /// use std::hash::{BuildHasher, BuildHasherDefault};
976
    ///
977
    /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
978
    /// let hasher = BuildHasherDefault::<AHasher>::default();
979
    /// let hasher = |val: &_| hasher.hash_one(val);
980
    /// for (k, v) in [
981
    ///     ("Bodleian Library", 1602),
982
    ///     ("Athenæum", 1807),
983
    ///     ("Herzogin-Anna-Amalia-Bibliothek", 1691),
984
    ///     ("Library of Congress", 1800),
985
    /// ] {
986
    ///     libraries.insert_unique(hasher(&k), (k, v), |(k, _)| hasher(&k));
987
    /// }
988
    ///
989
    /// let keys = ["Athenæum", "Library of Congress"];
990
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
991
    /// assert_eq!(
992
    ///     got,
993
    ///     Some([&mut ("Athenæum", 1807), &mut ("Library of Congress", 1800),]),
994
    /// );
995
    ///
996
    /// // Missing keys result in None
997
    /// let keys = ["Athenæum", "New York Public Library"];
998
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
999
    /// assert_eq!(got, None);
1000
    ///
1001
    /// // Duplicate keys result in None
1002
    /// let keys = ["Athenæum", "Athenæum"];
1003
    /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
1004
    /// assert_eq!(got, None);
1005
    /// # }
1006
    /// # fn main() {
1007
    /// #     #[cfg(feature = "nightly")]
1008
    /// #     test()
1009
    /// # }
1010
    /// ```
1011
0
    pub unsafe fn get_many_unchecked_mut<const N: usize>(
1012
0
        &mut self,
1013
0
        hashes: [u64; N],
1014
0
        eq: impl FnMut(usize, &T) -> bool,
1015
0
    ) -> Option<[&'_ mut T; N]> {
1016
0
        self.raw.get_many_unchecked_mut(hashes, eq)
1017
0
    }
1018
}
1019
1020
impl<T, A> IntoIterator for HashTable<T, A>
1021
where
1022
    A: Allocator,
1023
{
1024
    type Item = T;
1025
    type IntoIter = IntoIter<T, A>;
1026
1027
0
    fn into_iter(self) -> IntoIter<T, A> {
1028
0
        IntoIter {
1029
0
            inner: self.raw.into_iter(),
1030
0
        }
1031
0
    }
1032
}
1033
1034
impl<'a, T, A> IntoIterator for &'a HashTable<T, A>
1035
where
1036
    A: Allocator,
1037
{
1038
    type Item = &'a T;
1039
    type IntoIter = Iter<'a, T>;
1040
1041
0
    fn into_iter(self) -> Iter<'a, T> {
1042
0
        self.iter()
1043
0
    }
1044
}
1045
1046
impl<'a, T, A> IntoIterator for &'a mut HashTable<T, A>
1047
where
1048
    A: Allocator,
1049
{
1050
    type Item = &'a mut T;
1051
    type IntoIter = IterMut<'a, T>;
1052
1053
0
    fn into_iter(self) -> IterMut<'a, T> {
1054
0
        self.iter_mut()
1055
0
    }
1056
}
1057
1058
impl<T, A> Default for HashTable<T, A>
1059
where
1060
    A: Allocator + Default,
1061
{
1062
0
    fn default() -> Self {
1063
0
        Self {
1064
0
            raw: Default::default(),
1065
0
        }
1066
0
    }
1067
}
1068
1069
impl<T, A> Clone for HashTable<T, A>
1070
where
1071
    T: Clone,
1072
    A: Allocator + Clone,
1073
{
1074
0
    fn clone(&self) -> Self {
1075
0
        Self {
1076
0
            raw: self.raw.clone(),
1077
0
        }
1078
0
    }
1079
}
1080
1081
impl<T, A> fmt::Debug for HashTable<T, A>
1082
where
1083
    T: fmt::Debug,
1084
    A: Allocator,
1085
{
1086
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1087
0
        f.debug_set().entries(self.iter()).finish()
1088
0
    }
1089
}
1090
1091
/// A view into a single entry in a table, which may either be vacant or occupied.
1092
///
1093
/// This `enum` is constructed from the [`entry`] method on [`HashTable`].
1094
///
1095
/// [`HashTable`]: struct.HashTable.html
1096
/// [`entry`]: struct.HashTable.html#method.entry
1097
///
1098
/// # Examples
1099
///
1100
/// ```
1101
/// # #[cfg(feature = "nightly")]
1102
/// # fn test() {
1103
/// use ahash::AHasher;
1104
/// use hashbrown::hash_table::{Entry, HashTable, OccupiedEntry};
1105
/// use std::hash::{BuildHasher, BuildHasherDefault};
1106
///
1107
/// let mut table = HashTable::new();
1108
/// let hasher = BuildHasherDefault::<AHasher>::default();
1109
/// let hasher = |val: &_| hasher.hash_one(val);
1110
/// for x in ["a", "b", "c"] {
1111
///     table.insert_unique(hasher(&x), x, hasher);
1112
/// }
1113
/// assert_eq!(table.len(), 3);
1114
///
1115
/// // Existing value (insert)
1116
/// let entry: Entry<_> = table.entry(hasher(&"a"), |&x| x == "a", hasher);
1117
/// let _raw_o: OccupiedEntry<_, _> = entry.insert("a");
1118
/// assert_eq!(table.len(), 3);
1119
/// // Nonexistent value (insert)
1120
/// table.entry(hasher(&"d"), |&x| x == "d", hasher).insert("d");
1121
///
1122
/// // Existing value (or_insert)
1123
/// table
1124
///     .entry(hasher(&"b"), |&x| x == "b", hasher)
1125
///     .or_insert("b");
1126
/// // Nonexistent value (or_insert)
1127
/// table
1128
///     .entry(hasher(&"e"), |&x| x == "e", hasher)
1129
///     .or_insert("e");
1130
///
1131
/// println!("Our HashTable: {:?}", table);
1132
///
1133
/// let mut vec: Vec<_> = table.iter().copied().collect();
1134
/// // The `Iter` iterator produces items in arbitrary order, so the
1135
/// // items must be sorted to test them against a sorted array.
1136
/// vec.sort_unstable();
1137
/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
1138
/// # }
1139
/// # fn main() {
1140
/// #     #[cfg(feature = "nightly")]
1141
/// #     test()
1142
/// # }
1143
/// ```
1144
pub enum Entry<'a, T, A = Global>
1145
where
1146
    A: Allocator,
1147
{
1148
    /// An occupied entry.
1149
    ///
1150
    /// # Examples
1151
    ///
1152
    /// ```
1153
    /// # #[cfg(feature = "nightly")]
1154
    /// # fn test() {
1155
    /// use ahash::AHasher;
1156
    /// use hashbrown::hash_table::{Entry, HashTable, OccupiedEntry};
1157
    /// use std::hash::{BuildHasher, BuildHasherDefault};
1158
    ///
1159
    /// let mut table = HashTable::new();
1160
    /// let hasher = BuildHasherDefault::<AHasher>::default();
1161
    /// let hasher = |val: &_| hasher.hash_one(val);
1162
    /// for x in ["a", "b"] {
1163
    ///     table.insert_unique(hasher(&x), x, hasher);
1164
    /// }
1165
    ///
1166
    /// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
1167
    ///     Entry::Vacant(_) => unreachable!(),
1168
    ///     Entry::Occupied(_) => {}
1169
    /// }
1170
    /// # }
1171
    /// # fn main() {
1172
    /// #     #[cfg(feature = "nightly")]
1173
    /// #     test()
1174
    /// # }
1175
    /// ```
1176
    Occupied(OccupiedEntry<'a, T, A>),
1177
1178
    /// A vacant entry.
1179
    ///
1180
    /// # Examples
1181
    ///
1182
    /// ```
1183
    /// # #[cfg(feature = "nightly")]
1184
    /// # fn test() {
1185
    /// use ahash::AHasher;
1186
    /// use hashbrown::hash_table::{Entry, HashTable, OccupiedEntry};
1187
    /// use std::hash::{BuildHasher, BuildHasherDefault};
1188
    ///
1189
    /// let mut table = HashTable::<&str>::new();
1190
    /// let hasher = BuildHasherDefault::<AHasher>::default();
1191
    /// let hasher = |val: &_| hasher.hash_one(val);
1192
    ///
1193
    /// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
1194
    ///     Entry::Vacant(_) => {}
1195
    ///     Entry::Occupied(_) => unreachable!(),
1196
    /// }
1197
    /// # }
1198
    /// # fn main() {
1199
    /// #     #[cfg(feature = "nightly")]
1200
    /// #     test()
1201
    /// # }
1202
    /// ```
1203
    Vacant(VacantEntry<'a, T, A>),
1204
}
1205
1206
impl<T: fmt::Debug, A: Allocator> fmt::Debug for Entry<'_, T, A> {
1207
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1208
0
        match *self {
1209
0
            Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
1210
0
            Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
1211
        }
1212
0
    }
1213
}
1214
1215
impl<'a, T, A> Entry<'a, T, A>
1216
where
1217
    A: Allocator,
1218
{
1219
    /// Sets the value of the entry, replacing any existing value if there is
1220
    /// one, and returns an [`OccupiedEntry`].
1221
    ///
1222
    /// # Examples
1223
    ///
1224
    /// ```
1225
    /// # #[cfg(feature = "nightly")]
1226
    /// # fn test() {
1227
    /// use ahash::AHasher;
1228
    /// use hashbrown::HashTable;
1229
    /// use std::hash::{BuildHasher, BuildHasherDefault};
1230
    ///
1231
    /// let mut table: HashTable<&str> = HashTable::new();
1232
    /// let hasher = BuildHasherDefault::<AHasher>::default();
1233
    /// let hasher = |val: &_| hasher.hash_one(val);
1234
    ///
1235
    /// let entry = table
1236
    ///     .entry(hasher(&"horseyland"), |&x| x == "horseyland", hasher)
1237
    ///     .insert("horseyland");
1238
    ///
1239
    /// assert_eq!(entry.get(), &"horseyland");
1240
    /// # }
1241
    /// # fn main() {
1242
    /// #     #[cfg(feature = "nightly")]
1243
    /// #     test()
1244
    /// # }
1245
    /// ```
1246
0
    pub fn insert(self, value: T) -> OccupiedEntry<'a, T, A> {
1247
0
        match self {
1248
0
            Entry::Occupied(mut entry) => {
1249
0
                *entry.get_mut() = value;
1250
0
                entry
1251
            }
1252
0
            Entry::Vacant(entry) => entry.insert(value),
1253
        }
1254
0
    }
1255
1256
    /// Ensures a value is in the entry by inserting if it was vacant.
1257
    ///
1258
    /// Returns an [`OccupiedEntry`] pointing to the now-occupied entry.
1259
    ///
1260
    /// # Examples
1261
    ///
1262
    /// ```
1263
    /// # #[cfg(feature = "nightly")]
1264
    /// # fn test() {
1265
    /// use ahash::AHasher;
1266
    /// use hashbrown::HashTable;
1267
    /// use std::hash::{BuildHasher, BuildHasherDefault};
1268
    ///
1269
    /// let mut table: HashTable<&str> = HashTable::new();
1270
    /// let hasher = BuildHasherDefault::<AHasher>::default();
1271
    /// let hasher = |val: &_| hasher.hash_one(val);
1272
    ///
1273
    /// // nonexistent key
1274
    /// table
1275
    ///     .entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher)
1276
    ///     .or_insert("poneyland");
1277
    /// assert!(table
1278
    ///     .find(hasher(&"poneyland"), |&x| x == "poneyland")
1279
    ///     .is_some());
1280
    ///
1281
    /// // existing key
1282
    /// table
1283
    ///     .entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher)
1284
    ///     .or_insert("poneyland");
1285
    /// assert!(table
1286
    ///     .find(hasher(&"poneyland"), |&x| x == "poneyland")
1287
    ///     .is_some());
1288
    /// assert_eq!(table.len(), 1);
1289
    /// # }
1290
    /// # fn main() {
1291
    /// #     #[cfg(feature = "nightly")]
1292
    /// #     test()
1293
    /// # }
1294
    /// ```
1295
0
    pub fn or_insert(self, default: T) -> OccupiedEntry<'a, T, A> {
1296
0
        match self {
1297
0
            Entry::Occupied(entry) => entry,
1298
0
            Entry::Vacant(entry) => entry.insert(default),
1299
        }
1300
0
    }
1301
1302
    /// Ensures a value is in the entry by inserting the result of the default function if empty..
1303
    ///
1304
    /// Returns an [`OccupiedEntry`] pointing to the now-occupied entry.
1305
    ///
1306
    /// # Examples
1307
    ///
1308
    /// ```
1309
    /// # #[cfg(feature = "nightly")]
1310
    /// # fn test() {
1311
    /// use ahash::AHasher;
1312
    /// use hashbrown::HashTable;
1313
    /// use std::hash::{BuildHasher, BuildHasherDefault};
1314
    ///
1315
    /// let mut table: HashTable<String> = HashTable::new();
1316
    /// let hasher = BuildHasherDefault::<AHasher>::default();
1317
    /// let hasher = |val: &_| hasher.hash_one(val);
1318
    ///
1319
    /// table
1320
    ///     .entry(hasher("poneyland"), |x| x == "poneyland", |val| hasher(val))
1321
    ///     .or_insert_with(|| "poneyland".to_string());
1322
    ///
1323
    /// assert!(table
1324
    ///     .find(hasher(&"poneyland"), |x| x == "poneyland")
1325
    ///     .is_some());
1326
    /// # }
1327
    /// # fn main() {
1328
    /// #     #[cfg(feature = "nightly")]
1329
    /// #     test()
1330
    /// # }
1331
    /// ```
1332
0
    pub fn or_insert_with(self, default: impl FnOnce() -> T) -> OccupiedEntry<'a, T, A> {
1333
0
        match self {
1334
0
            Entry::Occupied(entry) => entry,
1335
0
            Entry::Vacant(entry) => entry.insert(default()),
1336
        }
1337
0
    }
1338
1339
    /// Provides in-place mutable access to an occupied entry before any
1340
    /// potential inserts into the table.
1341
    ///
1342
    /// # Examples
1343
    ///
1344
    /// ```
1345
    /// # #[cfg(feature = "nightly")]
1346
    /// # fn test() {
1347
    /// use ahash::AHasher;
1348
    /// use hashbrown::HashTable;
1349
    /// use std::hash::{BuildHasher, BuildHasherDefault};
1350
    ///
1351
    /// let mut table: HashTable<(&str, u32)> = HashTable::new();
1352
    /// let hasher = BuildHasherDefault::<AHasher>::default();
1353
    /// let hasher = |val: &_| hasher.hash_one(val);
1354
    ///
1355
    /// table
1356
    ///     .entry(
1357
    ///         hasher(&"poneyland"),
1358
    ///         |&(x, _)| x == "poneyland",
1359
    ///         |(k, _)| hasher(&k),
1360
    ///     )
1361
    ///     .and_modify(|(_, v)| *v += 1)
1362
    ///     .or_insert(("poneyland", 42));
1363
    /// assert_eq!(
1364
    ///     table.find(hasher(&"poneyland"), |&(k, _)| k == "poneyland"),
1365
    ///     Some(&("poneyland", 42))
1366
    /// );
1367
    ///
1368
    /// table
1369
    ///     .entry(
1370
    ///         hasher(&"poneyland"),
1371
    ///         |&(x, _)| x == "poneyland",
1372
    ///         |(k, _)| hasher(&k),
1373
    ///     )
1374
    ///     .and_modify(|(_, v)| *v += 1)
1375
    ///     .or_insert(("poneyland", 42));
1376
    /// assert_eq!(
1377
    ///     table.find(hasher(&"poneyland"), |&(k, _)| k == "poneyland"),
1378
    ///     Some(&("poneyland", 43))
1379
    /// );
1380
    /// # }
1381
    /// # fn main() {
1382
    /// #     #[cfg(feature = "nightly")]
1383
    /// #     test()
1384
    /// # }
1385
    /// ```
1386
0
    pub fn and_modify(self, f: impl FnOnce(&mut T)) -> Self {
1387
0
        match self {
1388
0
            Entry::Occupied(mut entry) => {
1389
0
                f(entry.get_mut());
1390
0
                Entry::Occupied(entry)
1391
            }
1392
0
            Entry::Vacant(entry) => Entry::Vacant(entry),
1393
        }
1394
0
    }
1395
}
1396
1397
/// A view into an occupied entry in a `HashTable`.
1398
/// It is part of the [`Entry`] enum.
1399
///
1400
/// [`Entry`]: enum.Entry.html
1401
///
1402
/// # Examples
1403
///
1404
/// ```
1405
/// # #[cfg(feature = "nightly")]
1406
/// # fn test() {
1407
/// use ahash::AHasher;
1408
/// use hashbrown::hash_table::{Entry, HashTable, OccupiedEntry};
1409
/// use std::hash::{BuildHasher, BuildHasherDefault};
1410
///
1411
/// let mut table = HashTable::new();
1412
/// let hasher = BuildHasherDefault::<AHasher>::default();
1413
/// let hasher = |val: &_| hasher.hash_one(val);
1414
/// for x in ["a", "b", "c"] {
1415
///     table.insert_unique(hasher(&x), x, hasher);
1416
/// }
1417
/// assert_eq!(table.len(), 3);
1418
///
1419
/// let _entry_o: OccupiedEntry<_, _> = table.find_entry(hasher(&"a"), |&x| x == "a").unwrap();
1420
/// assert_eq!(table.len(), 3);
1421
///
1422
/// // Existing key
1423
/// match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
1424
///     Entry::Vacant(_) => unreachable!(),
1425
///     Entry::Occupied(view) => {
1426
///         assert_eq!(view.get(), &"a");
1427
///     }
1428
/// }
1429
///
1430
/// assert_eq!(table.len(), 3);
1431
///
1432
/// // Existing key (take)
1433
/// match table.entry(hasher(&"c"), |&x| x == "c", hasher) {
1434
///     Entry::Vacant(_) => unreachable!(),
1435
///     Entry::Occupied(view) => {
1436
///         assert_eq!(view.remove().0, "c");
1437
///     }
1438
/// }
1439
/// assert_eq!(table.find(hasher(&"c"), |&x| x == "c"), None);
1440
/// assert_eq!(table.len(), 2);
1441
/// # }
1442
/// # fn main() {
1443
/// #     #[cfg(feature = "nightly")]
1444
/// #     test()
1445
/// # }
1446
/// ```
1447
pub struct OccupiedEntry<'a, T, A = Global>
1448
where
1449
    A: Allocator,
1450
{
1451
    hash: u64,
1452
    bucket: Bucket<T>,
1453
    table: &'a mut HashTable<T, A>,
1454
}
1455
1456
unsafe impl<T, A> Send for OccupiedEntry<'_, T, A>
1457
where
1458
    T: Send,
1459
    A: Send + Allocator,
1460
{
1461
}
1462
unsafe impl<T, A> Sync for OccupiedEntry<'_, T, A>
1463
where
1464
    T: Sync,
1465
    A: Sync + Allocator,
1466
{
1467
}
1468
1469
impl<T: fmt::Debug, A: Allocator> fmt::Debug for OccupiedEntry<'_, T, A> {
1470
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1471
0
        f.debug_struct("OccupiedEntry")
1472
0
            .field("value", self.get())
1473
0
            .finish()
1474
0
    }
1475
}
1476
1477
impl<'a, T, A> OccupiedEntry<'a, T, A>
1478
where
1479
    A: Allocator,
1480
{
1481
    /// Takes the value out of the entry, and returns it along with a
1482
    /// `VacantEntry` that can be used to insert another value with the same
1483
    /// hash as the one that was just removed.
1484
    ///
1485
    /// # Examples
1486
    ///
1487
    /// ```
1488
    /// # #[cfg(feature = "nightly")]
1489
    /// # fn test() {
1490
    /// use ahash::AHasher;
1491
    /// use hashbrown::hash_table::Entry;
1492
    /// use hashbrown::HashTable;
1493
    /// use std::hash::{BuildHasher, BuildHasherDefault};
1494
    ///
1495
    /// let mut table: HashTable<&str> = HashTable::new();
1496
    /// let hasher = BuildHasherDefault::<AHasher>::default();
1497
    /// let hasher = |val: &_| hasher.hash_one(val);
1498
    /// // The table is empty
1499
    /// assert!(table.is_empty() && table.capacity() == 0);
1500
    ///
1501
    /// table.insert_unique(hasher(&"poneyland"), "poneyland", hasher);
1502
    /// let capacity_before_remove = table.capacity();
1503
    ///
1504
    /// if let Entry::Occupied(o) = table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
1505
    ///     assert_eq!(o.remove().0, "poneyland");
1506
    /// }
1507
    ///
1508
    /// assert!(table
1509
    ///     .find(hasher(&"poneyland"), |&x| x == "poneyland")
1510
    ///     .is_none());
1511
    /// // Now table hold none elements but capacity is equal to the old one
1512
    /// assert!(table.len() == 0 && table.capacity() == capacity_before_remove);
1513
    /// # }
1514
    /// # fn main() {
1515
    /// #     #[cfg(feature = "nightly")]
1516
    /// #     test()
1517
    /// # }
1518
    /// ```
1519
    #[cfg_attr(feature = "inline-more", inline)]
1520
0
    pub fn remove(self) -> (T, VacantEntry<'a, T, A>) {
1521
0
        let (val, slot) = unsafe { self.table.raw.remove(self.bucket) };
1522
0
        (
1523
0
            val,
1524
0
            VacantEntry {
1525
0
                hash: self.hash,
1526
0
                insert_slot: slot,
1527
0
                table: self.table,
1528
0
            },
1529
0
        )
1530
0
    }
1531
1532
    /// Gets a reference to the value in the entry.
1533
    ///
1534
    /// # Examples
1535
    ///
1536
    /// ```
1537
    /// # #[cfg(feature = "nightly")]
1538
    /// # fn test() {
1539
    /// use ahash::AHasher;
1540
    /// use hashbrown::hash_table::Entry;
1541
    /// use hashbrown::HashTable;
1542
    /// use std::hash::{BuildHasher, BuildHasherDefault};
1543
    ///
1544
    /// let mut table: HashTable<&str> = HashTable::new();
1545
    /// let hasher = BuildHasherDefault::<AHasher>::default();
1546
    /// let hasher = |val: &_| hasher.hash_one(val);
1547
    /// table.insert_unique(hasher(&"poneyland"), "poneyland", hasher);
1548
    ///
1549
    /// match table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
1550
    ///     Entry::Vacant(_) => panic!(),
1551
    ///     Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
1552
    /// }
1553
    /// # }
1554
    /// # fn main() {
1555
    /// #     #[cfg(feature = "nightly")]
1556
    /// #     test()
1557
    /// # }
1558
    /// ```
1559
    #[inline]
1560
0
    pub fn get(&self) -> &T {
1561
0
        unsafe { self.bucket.as_ref() }
1562
0
    }
1563
1564
    /// Gets a mutable reference to the value in the entry.
1565
    ///
1566
    /// If you need a reference to the `OccupiedEntry` which may outlive the
1567
    /// destruction of the `Entry` value, see [`into_mut`].
1568
    ///
1569
    /// [`into_mut`]: #method.into_mut
1570
    ///
1571
    /// # Examples
1572
    ///
1573
    /// ```
1574
    /// # #[cfg(feature = "nightly")]
1575
    /// # fn test() {
1576
    /// use ahash::AHasher;
1577
    /// use hashbrown::hash_table::Entry;
1578
    /// use hashbrown::HashTable;
1579
    /// use std::hash::{BuildHasher, BuildHasherDefault};
1580
    ///
1581
    /// let mut table: HashTable<(&str, u32)> = HashTable::new();
1582
    /// let hasher = BuildHasherDefault::<AHasher>::default();
1583
    /// let hasher = |val: &_| hasher.hash_one(val);
1584
    /// table.insert_unique(hasher(&"poneyland"), ("poneyland", 12), |(k, _)| hasher(&k));
1585
    ///
1586
    /// assert_eq!(
1587
    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
1588
    ///     Some(&("poneyland", 12))
1589
    /// );
1590
    ///
1591
    /// if let Entry::Occupied(mut o) = table.entry(
1592
    ///     hasher(&"poneyland"),
1593
    ///     |&(x, _)| x == "poneyland",
1594
    ///     |(k, _)| hasher(&k),
1595
    /// ) {
1596
    ///     o.get_mut().1 += 10;
1597
    ///     assert_eq!(o.get().1, 22);
1598
    ///
1599
    ///     // We can use the same Entry multiple times.
1600
    ///     o.get_mut().1 += 2;
1601
    /// }
1602
    ///
1603
    /// assert_eq!(
1604
    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
1605
    ///     Some(&("poneyland", 24))
1606
    /// );
1607
    /// # }
1608
    /// # fn main() {
1609
    /// #     #[cfg(feature = "nightly")]
1610
    /// #     test()
1611
    /// # }
1612
    /// ```
1613
    #[inline]
1614
0
    pub fn get_mut(&mut self) -> &mut T {
1615
0
        unsafe { self.bucket.as_mut() }
1616
0
    }
1617
1618
    /// Converts the OccupiedEntry into a mutable reference to the value in the entry
1619
    /// with a lifetime bound to the table itself.
1620
    ///
1621
    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
1622
    ///
1623
    /// [`get_mut`]: #method.get_mut
1624
    ///
1625
    /// # Examples
1626
    ///
1627
    /// ```
1628
    /// # #[cfg(feature = "nightly")]
1629
    /// # fn test() {
1630
    /// use ahash::AHasher;
1631
    /// use hashbrown::hash_table::Entry;
1632
    /// use hashbrown::HashTable;
1633
    /// use std::hash::{BuildHasher, BuildHasherDefault};
1634
    ///
1635
    /// let mut table: HashTable<(&str, u32)> = HashTable::new();
1636
    /// let hasher = BuildHasherDefault::<AHasher>::default();
1637
    /// let hasher = |val: &_| hasher.hash_one(val);
1638
    /// table.insert_unique(hasher(&"poneyland"), ("poneyland", 12), |(k, _)| hasher(&k));
1639
    ///
1640
    /// assert_eq!(
1641
    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
1642
    ///     Some(&("poneyland", 12))
1643
    /// );
1644
    ///
1645
    /// let value: &mut (&str, u32);
1646
    /// match table.entry(
1647
    ///     hasher(&"poneyland"),
1648
    ///     |&(x, _)| x == "poneyland",
1649
    ///     |(k, _)| hasher(&k),
1650
    /// ) {
1651
    ///     Entry::Occupied(entry) => value = entry.into_mut(),
1652
    ///     Entry::Vacant(_) => panic!(),
1653
    /// }
1654
    /// value.1 += 10;
1655
    ///
1656
    /// assert_eq!(
1657
    ///     table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
1658
    ///     Some(&("poneyland", 22))
1659
    /// );
1660
    /// # }
1661
    /// # fn main() {
1662
    /// #     #[cfg(feature = "nightly")]
1663
    /// #     test()
1664
    /// # }
1665
    /// ```
1666
0
    pub fn into_mut(self) -> &'a mut T {
1667
0
        unsafe { self.bucket.as_mut() }
1668
0
    }
1669
1670
    /// Converts the OccupiedEntry into a mutable reference to the underlying
1671
    /// table.
1672
0
    pub fn into_table(self) -> &'a mut HashTable<T, A> {
1673
0
        self.table
1674
0
    }
1675
}
1676
1677
/// A view into a vacant entry in a `HashTable`.
1678
/// It is part of the [`Entry`] enum.
1679
///
1680
/// [`Entry`]: enum.Entry.html
1681
///
1682
/// # Examples
1683
///
1684
/// ```
1685
/// # #[cfg(feature = "nightly")]
1686
/// # fn test() {
1687
/// use ahash::AHasher;
1688
/// use hashbrown::hash_table::{Entry, HashTable, VacantEntry};
1689
/// use std::hash::{BuildHasher, BuildHasherDefault};
1690
///
1691
/// let mut table: HashTable<&str> = HashTable::new();
1692
/// let hasher = BuildHasherDefault::<AHasher>::default();
1693
/// let hasher = |val: &_| hasher.hash_one(val);
1694
///
1695
/// let entry_v: VacantEntry<_, _> = match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
1696
///     Entry::Vacant(view) => view,
1697
///     Entry::Occupied(_) => unreachable!(),
1698
/// };
1699
/// entry_v.insert("a");
1700
/// assert!(table.find(hasher(&"a"), |&x| x == "a").is_some() && table.len() == 1);
1701
///
1702
/// // Nonexistent key (insert)
1703
/// match table.entry(hasher(&"b"), |&x| x == "b", hasher) {
1704
///     Entry::Vacant(view) => {
1705
///         view.insert("b");
1706
///     }
1707
///     Entry::Occupied(_) => unreachable!(),
1708
/// }
1709
/// assert!(table.find(hasher(&"b"), |&x| x == "b").is_some() && table.len() == 2);
1710
/// # }
1711
/// # fn main() {
1712
/// #     #[cfg(feature = "nightly")]
1713
/// #     test()
1714
/// # }
1715
/// ```
1716
pub struct VacantEntry<'a, T, A = Global>
1717
where
1718
    A: Allocator,
1719
{
1720
    hash: u64,
1721
    insert_slot: InsertSlot,
1722
    table: &'a mut HashTable<T, A>,
1723
}
1724
1725
impl<T: fmt::Debug, A: Allocator> fmt::Debug for VacantEntry<'_, T, A> {
1726
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1727
0
        f.write_str("VacantEntry")
1728
0
    }
1729
}
1730
1731
impl<'a, T, A> VacantEntry<'a, T, A>
1732
where
1733
    A: Allocator,
1734
{
1735
    /// Inserts a new element into the table with the hash that was used to
1736
    /// obtain the `VacantEntry`.
1737
    ///
1738
    /// An `OccupiedEntry` is returned for the newly inserted element.
1739
    ///
1740
    /// # Examples
1741
    ///
1742
    /// ```
1743
    /// # #[cfg(feature = "nightly")]
1744
    /// # fn test() {
1745
    /// use ahash::AHasher;
1746
    /// use hashbrown::hash_table::Entry;
1747
    /// use hashbrown::HashTable;
1748
    /// use std::hash::{BuildHasher, BuildHasherDefault};
1749
    ///
1750
    /// let mut table: HashTable<&str> = HashTable::new();
1751
    /// let hasher = BuildHasherDefault::<AHasher>::default();
1752
    /// let hasher = |val: &_| hasher.hash_one(val);
1753
    ///
1754
    /// if let Entry::Vacant(o) = table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
1755
    ///     o.insert("poneyland");
1756
    /// }
1757
    /// assert_eq!(
1758
    ///     table.find(hasher(&"poneyland"), |&x| x == "poneyland"),
1759
    ///     Some(&"poneyland")
1760
    /// );
1761
    /// # }
1762
    /// # fn main() {
1763
    /// #     #[cfg(feature = "nightly")]
1764
    /// #     test()
1765
    /// # }
1766
    /// ```
1767
    #[inline]
1768
0
    pub fn insert(self, value: T) -> OccupiedEntry<'a, T, A> {
1769
0
        let bucket = unsafe {
1770
0
            self.table
1771
0
                .raw
1772
0
                .insert_in_slot(self.hash, self.insert_slot, value)
1773
0
        };
1774
0
        OccupiedEntry {
1775
0
            hash: self.hash,
1776
0
            bucket,
1777
0
            table: self.table,
1778
0
        }
1779
0
    }
1780
1781
    /// Converts the VacantEntry into a mutable reference to the underlying
1782
    /// table.
1783
0
    pub fn into_table(self) -> &'a mut HashTable<T, A> {
1784
0
        self.table
1785
0
    }
1786
}
1787
1788
/// Type representing the absence of an entry, as returned by [`HashTable::find_entry`].
1789
///
1790
/// This type only exists due to [limitations] in Rust's NLL borrow checker. In
1791
/// the future, `find_entry` will return an `Option<OccupiedEntry>` and this
1792
/// type will be removed.
1793
///
1794
/// [limitations]: https://smallcultfollowing.com/babysteps/blog/2018/06/15/mir-based-borrow-check-nll-status-update/#polonius
1795
///
1796
/// # Examples
1797
///
1798
/// ```
1799
/// # #[cfg(feature = "nightly")]
1800
/// # fn test() {
1801
/// use ahash::AHasher;
1802
/// use hashbrown::hash_table::{AbsentEntry, Entry, HashTable};
1803
/// use std::hash::{BuildHasher, BuildHasherDefault};
1804
///
1805
/// let mut table: HashTable<&str> = HashTable::new();
1806
/// let hasher = BuildHasherDefault::<AHasher>::default();
1807
/// let hasher = |val: &_| hasher.hash_one(val);
1808
///
1809
/// let entry_v: AbsentEntry<_, _> = table.find_entry(hasher(&"a"), |&x| x == "a").unwrap_err();
1810
/// entry_v
1811
///     .into_table()
1812
///     .insert_unique(hasher(&"a"), "a", hasher);
1813
/// assert!(table.find(hasher(&"a"), |&x| x == "a").is_some() && table.len() == 1);
1814
///
1815
/// // Nonexistent key (insert)
1816
/// match table.entry(hasher(&"b"), |&x| x == "b", hasher) {
1817
///     Entry::Vacant(view) => {
1818
///         view.insert("b");
1819
///     }
1820
///     Entry::Occupied(_) => unreachable!(),
1821
/// }
1822
/// assert!(table.find(hasher(&"b"), |&x| x == "b").is_some() && table.len() == 2);
1823
/// # }
1824
/// # fn main() {
1825
/// #     #[cfg(feature = "nightly")]
1826
/// #     test()
1827
/// # }
1828
/// ```
1829
pub struct AbsentEntry<'a, T, A = Global>
1830
where
1831
    A: Allocator,
1832
{
1833
    table: &'a mut HashTable<T, A>,
1834
}
1835
1836
impl<T: fmt::Debug, A: Allocator> fmt::Debug for AbsentEntry<'_, T, A> {
1837
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1838
0
        f.write_str("AbsentEntry")
1839
0
    }
1840
}
1841
1842
impl<'a, T, A> AbsentEntry<'a, T, A>
1843
where
1844
    A: Allocator,
1845
{
1846
    /// Converts the AbsentEntry into a mutable reference to the underlying
1847
    /// table.
1848
0
    pub fn into_table(self) -> &'a mut HashTable<T, A> {
1849
0
        self.table
1850
0
    }
1851
}
1852
1853
/// An iterator over the entries of a `HashTable` in arbitrary order.
1854
/// The iterator element type is `&'a T`.
1855
///
1856
/// This `struct` is created by the [`iter`] method on [`HashTable`]. See its
1857
/// documentation for more.
1858
///
1859
/// [`iter`]: struct.HashTable.html#method.iter
1860
/// [`HashTable`]: struct.HashTable.html
1861
pub struct Iter<'a, T> {
1862
    inner: RawIter<T>,
1863
    marker: PhantomData<&'a T>,
1864
}
1865
1866
impl<'a, T> Iterator for Iter<'a, T> {
1867
    type Item = &'a T;
1868
1869
0
    fn next(&mut self) -> Option<Self::Item> {
1870
0
        // Avoid `Option::map` because it bloats LLVM IR.
1871
0
        match self.inner.next() {
1872
0
            Some(bucket) => Some(unsafe { bucket.as_ref() }),
1873
0
            None => None,
1874
        }
1875
0
    }
1876
1877
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1878
0
        self.inner.size_hint()
1879
0
    }
1880
1881
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
1882
0
    where
1883
0
        Self: Sized,
1884
0
        F: FnMut(B, Self::Item) -> B,
1885
0
    {
1886
0
        self.inner
1887
0
            .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_ref()) })
1888
0
    }
1889
}
1890
1891
impl<T> ExactSizeIterator for Iter<'_, T> {
1892
0
    fn len(&self) -> usize {
1893
0
        self.inner.len()
1894
0
    }
1895
}
1896
1897
impl<T> FusedIterator for Iter<'_, T> {}
1898
1899
/// A mutable iterator over the entries of a `HashTable` in arbitrary order.
1900
/// The iterator element type is `&'a mut T`.
1901
///
1902
/// This `struct` is created by the [`iter_mut`] method on [`HashTable`]. See its
1903
/// documentation for more.
1904
///
1905
/// [`iter_mut`]: struct.HashTable.html#method.iter_mut
1906
/// [`HashTable`]: struct.HashTable.html
1907
pub struct IterMut<'a, T> {
1908
    inner: RawIter<T>,
1909
    marker: PhantomData<&'a mut T>,
1910
}
1911
1912
impl<'a, T> Iterator for IterMut<'a, T> {
1913
    type Item = &'a mut T;
1914
1915
0
    fn next(&mut self) -> Option<Self::Item> {
1916
0
        // Avoid `Option::map` because it bloats LLVM IR.
1917
0
        match self.inner.next() {
1918
0
            Some(bucket) => Some(unsafe { bucket.as_mut() }),
1919
0
            None => None,
1920
        }
1921
0
    }
1922
1923
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1924
0
        self.inner.size_hint()
1925
0
    }
1926
1927
0
    fn fold<B, F>(self, init: B, mut f: F) -> B
1928
0
    where
1929
0
        Self: Sized,
1930
0
        F: FnMut(B, Self::Item) -> B,
1931
0
    {
1932
0
        self.inner
1933
0
            .fold(init, |acc, bucket| unsafe { f(acc, bucket.as_mut()) })
1934
0
    }
1935
}
1936
1937
impl<T> ExactSizeIterator for IterMut<'_, T> {
1938
0
    fn len(&self) -> usize {
1939
0
        self.inner.len()
1940
0
    }
1941
}
1942
1943
impl<T> FusedIterator for IterMut<'_, T> {}
1944
1945
/// An owning iterator over the entries of a `HashTable` in arbitrary order.
1946
/// The iterator element type is `T`.
1947
///
1948
/// This `struct` is created by the [`into_iter`] method on [`HashTable`]
1949
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
1950
/// The table cannot be used after calling that method.
1951
///
1952
/// [`into_iter`]: struct.HashTable.html#method.into_iter
1953
/// [`HashTable`]: struct.HashTable.html
1954
/// [`IntoIterator`]: https://doc.rust-lang.org/core/iter/trait.IntoIterator.html
1955
pub struct IntoIter<T, A = Global>
1956
where
1957
    A: Allocator,
1958
{
1959
    inner: RawIntoIter<T, A>,
1960
}
1961
1962
impl<T, A> Iterator for IntoIter<T, A>
1963
where
1964
    A: Allocator,
1965
{
1966
    type Item = T;
1967
1968
0
    fn next(&mut self) -> Option<Self::Item> {
1969
0
        self.inner.next()
1970
0
    }
1971
1972
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1973
0
        self.inner.size_hint()
1974
0
    }
1975
1976
0
    fn fold<B, F>(self, init: B, f: F) -> B
1977
0
    where
1978
0
        Self: Sized,
1979
0
        F: FnMut(B, Self::Item) -> B,
1980
0
    {
1981
0
        self.inner.fold(init, f)
1982
0
    }
1983
}
1984
1985
impl<T, A> ExactSizeIterator for IntoIter<T, A>
1986
where
1987
    A: Allocator,
1988
{
1989
0
    fn len(&self) -> usize {
1990
0
        self.inner.len()
1991
0
    }
1992
}
1993
1994
impl<T, A> FusedIterator for IntoIter<T, A> where A: Allocator {}
1995
1996
/// A draining iterator over the items of a `HashTable`.
1997
///
1998
/// This `struct` is created by the [`drain`] method on [`HashTable`].
1999
/// See its documentation for more.
2000
///
2001
/// [`HashTable`]: struct.HashTable.html
2002
/// [`drain`]: struct.HashTable.html#method.drain
2003
pub struct Drain<'a, T, A: Allocator = Global> {
2004
    inner: RawDrain<'a, T, A>,
2005
}
2006
2007
impl<T, A: Allocator> Drain<'_, T, A> {
2008
    /// Returns a iterator of references over the remaining items.
2009
0
    fn iter(&self) -> Iter<'_, T> {
2010
0
        Iter {
2011
0
            inner: self.inner.iter(),
2012
0
            marker: PhantomData,
2013
0
        }
2014
0
    }
2015
}
2016
2017
impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
2018
    type Item = T;
2019
2020
0
    fn next(&mut self) -> Option<T> {
2021
0
        self.inner.next()
2022
0
    }
2023
0
    fn size_hint(&self) -> (usize, Option<usize>) {
2024
0
        self.inner.size_hint()
2025
0
    }
2026
}
2027
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
2028
0
    fn len(&self) -> usize {
2029
0
        self.inner.len()
2030
0
    }
2031
}
2032
impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
2033
2034
impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
2035
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2036
0
        f.debug_list().entries(self.iter()).finish()
2037
0
    }
2038
}
2039
2040
/// A draining iterator over entries of a `HashTable` which don't satisfy the predicate `f`.
2041
///
2042
/// This `struct` is created by [`HashTable::extract_if`]. See its
2043
/// documentation for more.
2044
#[must_use = "Iterators are lazy unless consumed"]
2045
pub struct ExtractIf<'a, T, F, A: Allocator = Global>
2046
where
2047
    F: FnMut(&mut T) -> bool,
2048
{
2049
    f: F,
2050
    inner: RawExtractIf<'a, T, A>,
2051
}
2052
2053
impl<T, F, A: Allocator> Iterator for ExtractIf<'_, T, F, A>
2054
where
2055
    F: FnMut(&mut T) -> bool,
2056
{
2057
    type Item = T;
2058
2059
    #[inline]
2060
0
    fn next(&mut self) -> Option<Self::Item> {
2061
0
        self.inner.next(|val| (self.f)(val))
2062
0
    }
2063
2064
    #[inline]
2065
0
    fn size_hint(&self) -> (usize, Option<usize>) {
2066
0
        (0, self.inner.iter.size_hint().1)
2067
0
    }
2068
}
2069
2070
impl<T, F, A: Allocator> FusedIterator for ExtractIf<'_, T, F, A> where F: FnMut(&mut T) -> bool {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hex-0.4.3/src/error.rs
Line
Count
Source
1
use core::fmt;
2
3
/// The error type for decoding a hex string into `Vec<u8>` or `[u8; N]`.
4
#[derive(Debug, Clone, Copy, PartialEq)]
5
pub enum FromHexError {
6
    /// An invalid character was found. Valid ones are: `0...9`, `a...f`
7
    /// or `A...F`.
8
    InvalidHexCharacter { c: char, index: usize },
9
10
    /// A hex string's length needs to be even, as two digits correspond to
11
    /// one byte.
12
    OddLength,
13
14
    /// If the hex string is decoded into a fixed sized container, such as an
15
    /// array, the hex string's length * 2 has to match the container's
16
    /// length.
17
    InvalidStringLength,
18
}
19
20
#[cfg(feature = "std")]
21
impl std::error::Error for FromHexError {}
22
23
impl fmt::Display for FromHexError {
24
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25
0
        match *self {
26
0
            FromHexError::InvalidHexCharacter { c, index } => {
27
0
                write!(f, "Invalid character {:?} at position {}", c, index)
28
            }
29
0
            FromHexError::OddLength => write!(f, "Odd number of digits"),
30
0
            FromHexError::InvalidStringLength => write!(f, "Invalid string length"),
31
        }
32
0
    }
33
}
34
35
#[cfg(test)]
36
// this feature flag is here to suppress unused
37
// warnings of `super::*` and `pretty_assertions::assert_eq`
38
#[cfg(feature = "alloc")]
39
mod tests {
40
    use super::*;
41
    #[cfg(feature = "alloc")]
42
    use alloc::string::ToString;
43
    use pretty_assertions::assert_eq;
44
45
    #[test]
46
    #[cfg(feature = "alloc")]
47
    fn test_display() {
48
        assert_eq!(
49
            FromHexError::InvalidHexCharacter { c: '\n', index: 5 }.to_string(),
50
            "Invalid character '\\n' at position 5"
51
        );
52
53
        assert_eq!(FromHexError::OddLength.to_string(), "Odd number of digits");
54
        assert_eq!(
55
            FromHexError::InvalidStringLength.to_string(),
56
            "Invalid string length"
57
        );
58
    }
59
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hex-0.4.3/src/lib.rs
Line
Count
Source
1
// Copyright (c) 2013-2014 The Rust Project Developers.
2
// Copyright (c) 2015-2020 The rust-hex Developers.
3
//
4
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7
// option. This file may not be copied, modified, or distributed
8
// except according to those terms.
9
//! Encoding and decoding hex strings.
10
//!
11
//! For most cases, you can simply use the [`decode`], [`encode`] and
12
//! [`encode_upper`] functions. If you need a bit more control, use the traits
13
//! [`ToHex`] and [`FromHex`] instead.
14
//!
15
//! # Example
16
//!
17
//! ```
18
//! # #[cfg(not(feature = "alloc"))]
19
//! # let mut output = [0; 0x18];
20
//! #
21
//! # #[cfg(not(feature = "alloc"))]
22
//! # hex::encode_to_slice(b"Hello world!", &mut output).unwrap();
23
//! #
24
//! # #[cfg(not(feature = "alloc"))]
25
//! # let hex_string = ::core::str::from_utf8(&output).unwrap();
26
//! #
27
//! # #[cfg(feature = "alloc")]
28
//! let hex_string = hex::encode("Hello world!");
29
//!
30
//! println!("{}", hex_string); // Prints "48656c6c6f20776f726c6421"
31
//!
32
//! # assert_eq!(hex_string, "48656c6c6f20776f726c6421");
33
//! ```
34
35
#![doc(html_root_url = "https://docs.rs/hex/0.4.3")]
36
#![cfg_attr(not(feature = "std"), no_std)]
37
#![cfg_attr(docsrs, feature(doc_cfg))]
38
#![allow(clippy::unreadable_literal)]
39
40
#[cfg(feature = "alloc")]
41
extern crate alloc;
42
#[cfg(feature = "alloc")]
43
use alloc::{string::String, vec::Vec};
44
45
use core::iter;
46
47
mod error;
48
pub use crate::error::FromHexError;
49
50
#[cfg(feature = "serde")]
51
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
52
pub mod serde;
53
#[cfg(feature = "serde")]
54
pub use crate::serde::deserialize;
55
#[cfg(all(feature = "alloc", feature = "serde"))]
56
pub use crate::serde::{serialize, serialize_upper};
57
58
/// Encoding values as hex string.
59
///
60
/// This trait is implemented for all `T` which implement `AsRef<[u8]>`. This
61
/// includes `String`, `str`, `Vec<u8>` and `[u8]`.
62
///
63
/// # Example
64
///
65
/// ```
66
/// use hex::ToHex;
67
///
68
/// println!("{}", "Hello world!".encode_hex::<String>());
69
/// # assert_eq!("Hello world!".encode_hex::<String>(), "48656c6c6f20776f726c6421".to_string());
70
/// ```
71
///
72
/// *Note*: instead of using this trait, you might want to use [`encode()`].
73
pub trait ToHex {
74
    /// Encode the hex strict representing `self` into the result. Lower case
75
    /// letters are used (e.g. `f9b4ca`)
76
    fn encode_hex<T: iter::FromIterator<char>>(&self) -> T;
77
78
    /// Encode the hex strict representing `self` into the result. Upper case
79
    /// letters are used (e.g. `F9B4CA`)
80
    fn encode_hex_upper<T: iter::FromIterator<char>>(&self) -> T;
81
}
82
83
const HEX_CHARS_LOWER: &[u8; 16] = b"0123456789abcdef";
84
const HEX_CHARS_UPPER: &[u8; 16] = b"0123456789ABCDEF";
85
86
struct BytesToHexChars<'a> {
87
    inner: ::core::slice::Iter<'a, u8>,
88
    table: &'static [u8; 16],
89
    next: Option<char>,
90
}
91
92
impl<'a> BytesToHexChars<'a> {
93
0
    fn new(inner: &'a [u8], table: &'static [u8; 16]) -> BytesToHexChars<'a> {
94
0
        BytesToHexChars {
95
0
            inner: inner.iter(),
96
0
            table,
97
0
            next: None,
98
0
        }
99
0
    }
Unexecuted instantiation: _RNvMCscasVpOptvTz_3hexNtB2_15BytesToHexChars3newCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMCscasVpOptvTz_3hexNtB2_15BytesToHexChars3newB2_
100
}
101
102
impl<'a> Iterator for BytesToHexChars<'a> {
103
    type Item = char;
104
105
0
    fn next(&mut self) -> Option<Self::Item> {
106
0
        match self.next.take() {
107
0
            Some(current) => Some(current),
108
0
            None => self.inner.next().map(|byte| {
109
0
                let current = self.table[(byte >> 4) as usize] as char;
110
0
                self.next = Some(self.table[(byte & 0x0F) as usize] as char);
111
0
                current
112
0
            }),
113
        }
114
0
    }
115
116
0
    fn size_hint(&self) -> (usize, Option<usize>) {
117
0
        let length = self.len();
118
0
        (length, Some(length))
119
0
    }
120
}
121
122
impl<'a> iter::ExactSizeIterator for BytesToHexChars<'a> {
123
0
    fn len(&self) -> usize {
124
0
        let mut length = self.inner.len() * 2;
125
0
        if self.next.is_some() {
126
0
            length += 1;
127
0
        }
128
0
        length
129
0
    }
130
}
131
132
#[inline]
133
0
fn encode_to_iter<T: iter::FromIterator<char>>(table: &'static [u8; 16], source: &[u8]) -> T {
134
0
    BytesToHexChars::new(source, table).collect()
135
0
}
Unexecuted instantiation: _RINvCscasVpOptvTz_3hex14encode_to_iterNtNtCsiBl6Lc3cFal_5alloc6string6StringECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvCscasVpOptvTz_3hex14encode_to_iterpEB2_
136
137
impl<T: AsRef<[u8]>> ToHex for T {
138
0
    fn encode_hex<U: iter::FromIterator<char>>(&self) -> U {
139
0
        encode_to_iter(HEX_CHARS_LOWER, self.as_ref())
140
0
    }
Unexecuted instantiation: _RINvXs1_CscasVpOptvTz_3hexAhj20_NtB6_5ToHex10encode_hexNtNtCsiBl6Lc3cFal_5alloc6string6StringECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXs1_CscasVpOptvTz_3hexAhj240_NtB6_5ToHex10encode_hexNtNtCsiBl6Lc3cFal_5alloc6string6StringECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXs1_CscasVpOptvTz_3hexAhj30_NtB6_5ToHex10encode_hexNtNtCsiBl6Lc3cFal_5alloc6string6StringECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXs1_CscasVpOptvTz_3hexAhj60_NtB6_5ToHex10encode_hexNtNtCsiBl6Lc3cFal_5alloc6string6StringECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXINICscasVpOptvTz_3hexs1_0pEpNtB6_5ToHex10encode_hexpEB6_
141
142
0
    fn encode_hex_upper<U: iter::FromIterator<char>>(&self) -> U {
143
0
        encode_to_iter(HEX_CHARS_UPPER, self.as_ref())
144
0
    }
145
}
146
147
/// Types that can be decoded from a hex string.
148
///
149
/// This trait is implemented for `Vec<u8>` and small `u8`-arrays.
150
///
151
/// # Example
152
///
153
/// ```
154
/// use core::str;
155
/// use hex::FromHex;
156
///
157
/// let buffer = <[u8; 12]>::from_hex("48656c6c6f20776f726c6421")?;
158
/// let string = str::from_utf8(&buffer).expect("invalid buffer length");
159
///
160
/// println!("{}", string); // prints "Hello world!"
161
/// # assert_eq!("Hello world!", string);
162
/// # Ok::<(), hex::FromHexError>(())
163
/// ```
164
pub trait FromHex: Sized {
165
    type Error;
166
167
    /// Creates an instance of type `Self` from the given hex string, or fails
168
    /// with a custom error type.
169
    ///
170
    /// Both, upper and lower case characters are valid and can even be
171
    /// mixed (e.g. `f9b4ca`, `F9B4CA` and `f9B4Ca` are all valid strings).
172
    fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error>;
173
}
174
175
0
fn val(c: u8, idx: usize) -> Result<u8, FromHexError> {
176
0
    match c {
177
0
        b'A'..=b'F' => Ok(c - b'A' + 10),
178
0
        b'a'..=b'f' => Ok(c - b'a' + 10),
179
0
        b'0'..=b'9' => Ok(c - b'0'),
180
0
        _ => Err(FromHexError::InvalidHexCharacter {
181
0
            c: c as char,
182
0
            index: idx,
183
0
        }),
184
    }
185
0
}
186
187
#[cfg(feature = "alloc")]
188
impl FromHex for Vec<u8> {
189
    type Error = FromHexError;
190
191
0
    fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
192
0
        let hex = hex.as_ref();
193
0
        if hex.len() % 2 != 0 {
194
0
            return Err(FromHexError::OddLength);
195
0
        }
196
0
197
0
        hex.chunks(2)
198
0
            .enumerate()
199
0
            .map(|(i, pair)| Ok(val(pair[0], 2 * i)? << 4 | val(pair[1], 2 * i + 1)?))
200
0
            .collect()
201
0
    }
202
}
203
204
// Helper macro to implement the trait for a few fixed sized arrays. Once Rust
205
// has type level integers, this should be removed.
206
macro_rules! from_hex_array_impl {
207
    ($($len:expr)+) => {$(
208
        impl FromHex for [u8; $len] {
209
            type Error = FromHexError;
210
211
0
            fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
212
0
                let mut out = [0_u8; $len];
213
0
                decode_to_slice(hex, &mut out as &mut [u8])?;
214
0
                Ok(out)
215
0
            }
Unexecuted instantiation: _RINvXs3_CscasVpOptvTz_3hexAhj1_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXs4_CscasVpOptvTz_3hexAhj2_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXs5_CscasVpOptvTz_3hexAhj3_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXs6_CscasVpOptvTz_3hexAhj4_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXs7_CscasVpOptvTz_3hexAhj5_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXs8_CscasVpOptvTz_3hexAhj6_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXs9_CscasVpOptvTz_3hexAhj7_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsa_CscasVpOptvTz_3hexAhj8_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsb_CscasVpOptvTz_3hexAhj9_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsc_CscasVpOptvTz_3hexAhja_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsd_CscasVpOptvTz_3hexAhjb_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXse_CscasVpOptvTz_3hexAhjc_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsf_CscasVpOptvTz_3hexAhjd_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsg_CscasVpOptvTz_3hexAhje_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsh_CscasVpOptvTz_3hexAhjf_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsi_CscasVpOptvTz_3hexAhj10_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsj_CscasVpOptvTz_3hexAhj11_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsk_CscasVpOptvTz_3hexAhj12_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsl_CscasVpOptvTz_3hexAhj13_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsm_CscasVpOptvTz_3hexAhj14_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsn_CscasVpOptvTz_3hexAhj15_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXso_CscasVpOptvTz_3hexAhj16_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsp_CscasVpOptvTz_3hexAhj17_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsq_CscasVpOptvTz_3hexAhj18_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsr_CscasVpOptvTz_3hexAhj19_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXss_CscasVpOptvTz_3hexAhj1a_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXst_CscasVpOptvTz_3hexAhj1b_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsu_CscasVpOptvTz_3hexAhj1c_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsv_CscasVpOptvTz_3hexAhj1d_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsw_CscasVpOptvTz_3hexAhj1e_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsx_CscasVpOptvTz_3hexAhj1f_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsy_CscasVpOptvTz_3hexAhj20_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsz_CscasVpOptvTz_3hexAhj21_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsA_CscasVpOptvTz_3hexAhj22_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsB_CscasVpOptvTz_3hexAhj23_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsC_CscasVpOptvTz_3hexAhj24_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsD_CscasVpOptvTz_3hexAhj25_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsE_CscasVpOptvTz_3hexAhj26_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsF_CscasVpOptvTz_3hexAhj27_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsG_CscasVpOptvTz_3hexAhj28_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsH_CscasVpOptvTz_3hexAhj29_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsI_CscasVpOptvTz_3hexAhj2a_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsJ_CscasVpOptvTz_3hexAhj2b_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsK_CscasVpOptvTz_3hexAhj2c_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsL_CscasVpOptvTz_3hexAhj2d_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsM_CscasVpOptvTz_3hexAhj2e_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsN_CscasVpOptvTz_3hexAhj2f_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsO_CscasVpOptvTz_3hexAhj30_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsP_CscasVpOptvTz_3hexAhj31_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsQ_CscasVpOptvTz_3hexAhj32_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsR_CscasVpOptvTz_3hexAhj33_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsS_CscasVpOptvTz_3hexAhj34_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsT_CscasVpOptvTz_3hexAhj35_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsU_CscasVpOptvTz_3hexAhj36_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsV_CscasVpOptvTz_3hexAhj37_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsW_CscasVpOptvTz_3hexAhj38_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsX_CscasVpOptvTz_3hexAhj39_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsY_CscasVpOptvTz_3hexAhj3a_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXsZ_CscasVpOptvTz_3hexAhj3b_NtB6_7FromHex8from_hexpEB6_
Unexecuted instantiation: _RINvXs10_CscasVpOptvTz_3hexAhj3c_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs11_CscasVpOptvTz_3hexAhj3d_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs12_CscasVpOptvTz_3hexAhj3e_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs13_CscasVpOptvTz_3hexAhj3f_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs14_CscasVpOptvTz_3hexAhj40_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs15_CscasVpOptvTz_3hexAhj41_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs16_CscasVpOptvTz_3hexAhj42_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs17_CscasVpOptvTz_3hexAhj43_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs18_CscasVpOptvTz_3hexAhj44_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs19_CscasVpOptvTz_3hexAhj45_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1a_CscasVpOptvTz_3hexAhj46_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1b_CscasVpOptvTz_3hexAhj47_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1c_CscasVpOptvTz_3hexAhj48_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1d_CscasVpOptvTz_3hexAhj49_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1e_CscasVpOptvTz_3hexAhj4a_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1f_CscasVpOptvTz_3hexAhj4b_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1g_CscasVpOptvTz_3hexAhj4c_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1h_CscasVpOptvTz_3hexAhj4d_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1i_CscasVpOptvTz_3hexAhj4e_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1j_CscasVpOptvTz_3hexAhj4f_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1k_CscasVpOptvTz_3hexAhj50_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1l_CscasVpOptvTz_3hexAhj51_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1m_CscasVpOptvTz_3hexAhj52_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1n_CscasVpOptvTz_3hexAhj53_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1o_CscasVpOptvTz_3hexAhj54_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1p_CscasVpOptvTz_3hexAhj55_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1q_CscasVpOptvTz_3hexAhj56_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1r_CscasVpOptvTz_3hexAhj57_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1s_CscasVpOptvTz_3hexAhj58_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1t_CscasVpOptvTz_3hexAhj59_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1u_CscasVpOptvTz_3hexAhj5a_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1v_CscasVpOptvTz_3hexAhj5b_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1w_CscasVpOptvTz_3hexAhj5c_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1x_CscasVpOptvTz_3hexAhj5d_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1y_CscasVpOptvTz_3hexAhj5e_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1z_CscasVpOptvTz_3hexAhj5f_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1A_CscasVpOptvTz_3hexAhj60_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1B_CscasVpOptvTz_3hexAhj61_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1C_CscasVpOptvTz_3hexAhj62_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1D_CscasVpOptvTz_3hexAhj63_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1E_CscasVpOptvTz_3hexAhj64_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1F_CscasVpOptvTz_3hexAhj65_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1G_CscasVpOptvTz_3hexAhj66_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1H_CscasVpOptvTz_3hexAhj67_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1I_CscasVpOptvTz_3hexAhj68_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1J_CscasVpOptvTz_3hexAhj69_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1K_CscasVpOptvTz_3hexAhj6a_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1L_CscasVpOptvTz_3hexAhj6b_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1M_CscasVpOptvTz_3hexAhj6c_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1N_CscasVpOptvTz_3hexAhj6d_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1O_CscasVpOptvTz_3hexAhj6e_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1P_CscasVpOptvTz_3hexAhj6f_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1Q_CscasVpOptvTz_3hexAhj70_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1R_CscasVpOptvTz_3hexAhj71_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1S_CscasVpOptvTz_3hexAhj72_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1T_CscasVpOptvTz_3hexAhj73_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1U_CscasVpOptvTz_3hexAhj74_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1V_CscasVpOptvTz_3hexAhj75_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1W_CscasVpOptvTz_3hexAhj76_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1X_CscasVpOptvTz_3hexAhj77_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1Y_CscasVpOptvTz_3hexAhj78_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs1Z_CscasVpOptvTz_3hexAhj79_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs20_CscasVpOptvTz_3hexAhj7a_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs21_CscasVpOptvTz_3hexAhj7b_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs22_CscasVpOptvTz_3hexAhj7c_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs23_CscasVpOptvTz_3hexAhj7d_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs24_CscasVpOptvTz_3hexAhj7e_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs25_CscasVpOptvTz_3hexAhj7f_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs26_CscasVpOptvTz_3hexAhj80_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs27_CscasVpOptvTz_3hexAhja0_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs28_CscasVpOptvTz_3hexAhjc0_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs29_CscasVpOptvTz_3hexAhjc8_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2a_CscasVpOptvTz_3hexAhje0_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2b_CscasVpOptvTz_3hexAhj100_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2c_CscasVpOptvTz_3hexAhj180_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2d_CscasVpOptvTz_3hexAhj200_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2e_CscasVpOptvTz_3hexAhj300_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2f_CscasVpOptvTz_3hexAhj400_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2g_CscasVpOptvTz_3hexAhj800_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2h_CscasVpOptvTz_3hexAhj1000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2i_CscasVpOptvTz_3hexAhj2000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2j_CscasVpOptvTz_3hexAhj4000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2k_CscasVpOptvTz_3hexAhj8000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2l_CscasVpOptvTz_3hexAhj10000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2m_CscasVpOptvTz_3hexAhj20000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2n_CscasVpOptvTz_3hexAhj40000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2o_CscasVpOptvTz_3hexAhj80000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2p_CscasVpOptvTz_3hexAhj100000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2q_CscasVpOptvTz_3hexAhj200000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2r_CscasVpOptvTz_3hexAhj400000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2s_CscasVpOptvTz_3hexAhj800000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2t_CscasVpOptvTz_3hexAhj1000000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2u_CscasVpOptvTz_3hexAhj2000000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2v_CscasVpOptvTz_3hexAhj4000000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2w_CscasVpOptvTz_3hexAhj8000000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2x_CscasVpOptvTz_3hexAhj10000000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2y_CscasVpOptvTz_3hexAhj20000000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2z_CscasVpOptvTz_3hexAhj40000000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2A_CscasVpOptvTz_3hexAhj80000000_NtB7_7FromHex8from_hexpEB7_
Unexecuted instantiation: _RINvXs2B_CscasVpOptvTz_3hexAhj100000000_NtB7_7FromHex8from_hexpEB7_
216
        }
217
    )+}
218
}
219
220
from_hex_array_impl! {
221
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
222
    17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
223
    33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
224
    49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
225
    65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
226
    81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
227
    97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
228
    113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
229
    160 192 200 224 256 384 512 768 1024 2048 4096 8192 16384 32768
230
}
231
232
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
233
from_hex_array_impl! {
234
    65536 131072 262144 524288 1048576 2097152 4194304 8388608
235
    16777216 33554432 67108864 134217728 268435456 536870912
236
    1073741824 2147483648
237
}
238
239
#[cfg(target_pointer_width = "64")]
240
from_hex_array_impl! {
241
    4294967296
242
}
243
244
/// Encodes `data` as hex string using lowercase characters.
245
///
246
/// Lowercase characters are used (e.g. `f9b4ca`). The resulting string's
247
/// length is always even, each byte in `data` is always encoded using two hex
248
/// digits. Thus, the resulting string contains exactly twice as many bytes as
249
/// the input data.
250
///
251
/// # Example
252
///
253
/// ```
254
/// assert_eq!(hex::encode("Hello world!"), "48656c6c6f20776f726c6421");
255
/// assert_eq!(hex::encode(vec![1, 2, 3, 15, 16]), "0102030f10");
256
/// ```
257
#[must_use]
258
#[cfg(feature = "alloc")]
259
0
pub fn encode<T: AsRef<[u8]>>(data: T) -> String {
260
0
    data.encode_hex()
261
0
}
Unexecuted instantiation: _RINvCscasVpOptvTz_3hex6encodeAhj20_ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvCscasVpOptvTz_3hex6encodeAhj240_ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvCscasVpOptvTz_3hex6encodeAhj30_ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvCscasVpOptvTz_3hex6encodeAhj60_ECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvCscasVpOptvTz_3hex6encodepEB2_
262
263
/// Encodes `data` as hex string using uppercase characters.
264
///
265
/// Apart from the characters' casing, this works exactly like `encode()`.
266
///
267
/// # Example
268
///
269
/// ```
270
/// assert_eq!(hex::encode_upper("Hello world!"), "48656C6C6F20776F726C6421");
271
/// assert_eq!(hex::encode_upper(vec![1, 2, 3, 15, 16]), "0102030F10");
272
/// ```
273
#[must_use]
274
#[cfg(feature = "alloc")]
275
0
pub fn encode_upper<T: AsRef<[u8]>>(data: T) -> String {
276
0
    data.encode_hex_upper()
277
0
}
278
279
/// Decodes a hex string into raw bytes.
280
///
281
/// Both, upper and lower case characters are valid in the input string and can
282
/// even be mixed (e.g. `f9b4ca`, `F9B4CA` and `f9B4Ca` are all valid strings).
283
///
284
/// # Example
285
///
286
/// ```
287
/// assert_eq!(
288
///     hex::decode("48656c6c6f20776f726c6421"),
289
///     Ok("Hello world!".to_owned().into_bytes())
290
/// );
291
///
292
/// assert_eq!(hex::decode("123"), Err(hex::FromHexError::OddLength));
293
/// assert!(hex::decode("foo").is_err());
294
/// ```
295
#[cfg(feature = "alloc")]
296
0
pub fn decode<T: AsRef<[u8]>>(data: T) -> Result<Vec<u8>, FromHexError> {
297
0
    FromHex::from_hex(data)
298
0
}
299
300
/// Decode a hex string into a mutable bytes slice.
301
///
302
/// Both, upper and lower case characters are valid in the input string and can
303
/// even be mixed (e.g. `f9b4ca`, `F9B4CA` and `f9B4Ca` are all valid strings).
304
///
305
/// # Example
306
///
307
/// ```
308
/// let mut bytes = [0u8; 4];
309
/// assert_eq!(hex::decode_to_slice("6b697769", &mut bytes as &mut [u8]), Ok(()));
310
/// assert_eq!(&bytes, b"kiwi");
311
/// ```
312
0
pub fn decode_to_slice<T: AsRef<[u8]>>(data: T, out: &mut [u8]) -> Result<(), FromHexError> {
313
0
    let data = data.as_ref();
314
0
315
0
    if data.len() % 2 != 0 {
316
0
        return Err(FromHexError::OddLength);
317
0
    }
318
0
    if data.len() / 2 != out.len() {
319
0
        return Err(FromHexError::InvalidStringLength);
320
0
    }
321
322
0
    for (i, byte) in out.iter_mut().enumerate() {
323
0
        *byte = val(data[2 * i], 2 * i)? << 4 | val(data[2 * i + 1], 2 * i + 1)?;
324
    }
325
326
0
    Ok(())
327
0
}
328
329
// generates an iterator like this
330
// (0, 1)
331
// (2, 3)
332
// (4, 5)
333
// (6, 7)
334
// ...
335
#[inline]
336
0
fn generate_iter(len: usize) -> impl Iterator<Item = (usize, usize)> {
337
0
    (0..len).step_by(2).zip((0..len).skip(1).step_by(2))
338
0
}
339
340
// the inverse of `val`.
341
#[inline]
342
#[must_use]
343
0
fn byte2hex(byte: u8, table: &[u8; 16]) -> (u8, u8) {
344
0
    let high = table[((byte & 0xf0) >> 4) as usize];
345
0
    let low = table[(byte & 0x0f) as usize];
346
0
347
0
    (high, low)
348
0
}
349
350
/// Encodes some bytes into a mutable slice of bytes.
351
///
352
/// The output buffer, has to be able to hold at least `input.len() * 2` bytes,
353
/// otherwise this function will return an error.
354
///
355
/// # Example
356
///
357
/// ```
358
/// # use hex::FromHexError;
359
/// # fn main() -> Result<(), FromHexError> {
360
/// let mut bytes = [0u8; 4 * 2];
361
///
362
/// hex::encode_to_slice(b"kiwi", &mut bytes)?;
363
/// assert_eq!(&bytes, b"6b697769");
364
/// # Ok(())
365
/// # }
366
/// ```
367
0
pub fn encode_to_slice<T: AsRef<[u8]>>(input: T, output: &mut [u8]) -> Result<(), FromHexError> {
368
0
    if input.as_ref().len() * 2 != output.len() {
369
0
        return Err(FromHexError::InvalidStringLength);
370
0
    }
371
372
0
    for (byte, (i, j)) in input
373
0
        .as_ref()
374
0
        .iter()
375
0
        .zip(generate_iter(input.as_ref().len() * 2))
376
0
    {
377
0
        let (high, low) = byte2hex(*byte, HEX_CHARS_LOWER);
378
0
        output[i] = high;
379
0
        output[j] = low;
380
0
    }
381
382
0
    Ok(())
383
0
}
384
385
#[cfg(test)]
386
mod test {
387
    use super::*;
388
    #[cfg(feature = "alloc")]
389
    use alloc::string::ToString;
390
    use pretty_assertions::assert_eq;
391
392
    #[test]
393
    #[cfg(feature = "alloc")]
394
    fn test_gen_iter() {
395
        let result = vec![(0, 1), (2, 3)];
396
397
        assert_eq!(generate_iter(5).collect::<Vec<_>>(), result);
398
    }
399
400
    #[test]
401
    fn test_encode_to_slice() {
402
        let mut output_1 = [0; 4 * 2];
403
        encode_to_slice(b"kiwi", &mut output_1).unwrap();
404
        assert_eq!(&output_1, b"6b697769");
405
406
        let mut output_2 = [0; 5 * 2];
407
        encode_to_slice(b"kiwis", &mut output_2).unwrap();
408
        assert_eq!(&output_2, b"6b69776973");
409
410
        let mut output_3 = [0; 100];
411
412
        assert_eq!(
413
            encode_to_slice(b"kiwis", &mut output_3),
414
            Err(FromHexError::InvalidStringLength)
415
        );
416
    }
417
418
    #[test]
419
    fn test_decode_to_slice() {
420
        let mut output_1 = [0; 4];
421
        decode_to_slice(b"6b697769", &mut output_1).unwrap();
422
        assert_eq!(&output_1, b"kiwi");
423
424
        let mut output_2 = [0; 5];
425
        decode_to_slice(b"6b69776973", &mut output_2).unwrap();
426
        assert_eq!(&output_2, b"kiwis");
427
428
        let mut output_3 = [0; 4];
429
430
        assert_eq!(
431
            decode_to_slice(b"6", &mut output_3),
432
            Err(FromHexError::OddLength)
433
        );
434
    }
435
436
    #[test]
437
    #[cfg(feature = "alloc")]
438
    fn test_encode() {
439
        assert_eq!(encode("foobar"), "666f6f626172");
440
    }
441
442
    #[test]
443
    #[cfg(feature = "alloc")]
444
    fn test_decode() {
445
        assert_eq!(
446
            decode("666f6f626172"),
447
            Ok(String::from("foobar").into_bytes())
448
        );
449
    }
450
451
    #[test]
452
    #[cfg(feature = "alloc")]
453
    pub fn test_from_hex_okay_str() {
454
        assert_eq!(Vec::from_hex("666f6f626172").unwrap(), b"foobar");
455
        assert_eq!(Vec::from_hex("666F6F626172").unwrap(), b"foobar");
456
    }
457
458
    #[test]
459
    #[cfg(feature = "alloc")]
460
    pub fn test_from_hex_okay_bytes() {
461
        assert_eq!(Vec::from_hex(b"666f6f626172").unwrap(), b"foobar");
462
        assert_eq!(Vec::from_hex(b"666F6F626172").unwrap(), b"foobar");
463
    }
464
465
    #[test]
466
    #[cfg(feature = "alloc")]
467
    pub fn test_invalid_length() {
468
        assert_eq!(Vec::from_hex("1").unwrap_err(), FromHexError::OddLength);
469
        assert_eq!(
470
            Vec::from_hex("666f6f6261721").unwrap_err(),
471
            FromHexError::OddLength
472
        );
473
    }
474
475
    #[test]
476
    #[cfg(feature = "alloc")]
477
    pub fn test_invalid_char() {
478
        assert_eq!(
479
            Vec::from_hex("66ag").unwrap_err(),
480
            FromHexError::InvalidHexCharacter { c: 'g', index: 3 }
481
        );
482
    }
483
484
    #[test]
485
    #[cfg(feature = "alloc")]
486
    pub fn test_empty() {
487
        assert_eq!(Vec::from_hex("").unwrap(), b"");
488
    }
489
490
    #[test]
491
    #[cfg(feature = "alloc")]
492
    pub fn test_from_hex_whitespace() {
493
        assert_eq!(
494
            Vec::from_hex("666f 6f62617").unwrap_err(),
495
            FromHexError::InvalidHexCharacter { c: ' ', index: 4 }
496
        );
497
    }
498
499
    #[test]
500
    pub fn test_from_hex_array() {
501
        assert_eq!(
502
            <[u8; 6] as FromHex>::from_hex("666f6f626172"),
503
            Ok([0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72])
504
        );
505
506
        assert_eq!(
507
            <[u8; 5] as FromHex>::from_hex("666f6f626172"),
508
            Err(FromHexError::InvalidStringLength)
509
        );
510
    }
511
512
    #[test]
513
    #[cfg(feature = "alloc")]
514
    fn test_to_hex() {
515
        assert_eq!(
516
            [0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72].encode_hex::<String>(),
517
            "666f6f626172".to_string(),
518
        );
519
520
        assert_eq!(
521
            [0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72].encode_hex_upper::<String>(),
522
            "666F6F626172".to_string(),
523
        );
524
    }
525
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hex-literal-0.4.1/src/lib.rs
Line
Count
Source
1
#![doc = include_str!("../README.md")]
2
#![no_std]
3
#![doc(
4
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
5
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
6
)]
7
8
0
const fn next_hex_char(string: &[u8], mut pos: usize) -> Option<(u8, usize)> {
9
0
    while pos < string.len() {
10
0
        let raw_val = string[pos];
11
0
        pos += 1;
12
0
        let val = match raw_val {
13
0
            b'0'..=b'9' => raw_val - 48,
14
0
            b'A'..=b'F' => raw_val - 55,
15
0
            b'a'..=b'f' => raw_val - 87,
16
0
            b' ' | b'\r' | b'\n' | b'\t' => continue,
17
0
            0..=127 => panic!("Encountered invalid ASCII character"),
18
0
            _ => panic!("Encountered non-ASCII character"),
19
        };
20
0
        return Some((val, pos));
21
    }
22
0
    None
23
0
}
24
25
0
const fn next_byte(string: &[u8], pos: usize) -> Option<(u8, usize)> {
26
0
    let (half1, pos) = match next_hex_char(string, pos) {
27
0
        Some(v) => v,
28
0
        None => return None,
29
    };
30
0
    let (half2, pos) = match next_hex_char(string, pos) {
31
0
        Some(v) => v,
32
0
        None => panic!("Odd number of hex characters"),
33
    };
34
0
    Some(((half1 << 4) + half2, pos))
35
0
}
36
37
/// Compute length of a byte array which will be decoded from the strings.
38
///
39
/// This function is an implementation detail and SHOULD NOT be called directly!
40
#[doc(hidden)]
41
0
pub const fn len(strings: &[&[u8]]) -> usize {
42
0
    let mut i = 0;
43
0
    let mut len = 0;
44
0
    while i < strings.len() {
45
0
        let mut pos = 0;
46
0
        while let Some((_, new_pos)) = next_byte(strings[i], pos) {
47
0
            len += 1;
48
0
            pos = new_pos;
49
0
        }
50
0
        i += 1;
51
    }
52
0
    len
53
0
}
54
55
/// Decode hex strings into a byte array of pre-computed length.
56
///
57
/// This function is an implementation detail and SHOULD NOT be called directly!
58
#[doc(hidden)]
59
0
pub const fn decode<const LEN: usize>(strings: &[&[u8]]) -> [u8; LEN] {
60
0
    let mut i = 0;
61
0
    let mut buf = [0u8; LEN];
62
0
    let mut buf_pos = 0;
63
0
    while i < strings.len() {
64
0
        let mut pos = 0;
65
0
        while let Some((byte, new_pos)) = next_byte(strings[i], pos) {
66
0
            buf[buf_pos] = byte;
67
0
            buf_pos += 1;
68
0
            pos = new_pos;
69
0
        }
70
0
        i += 1;
71
    }
72
0
    if LEN != buf_pos {
73
0
        panic!("Length mismatch. Please report this bug.");
74
0
    }
75
0
    buf
76
0
}
77
78
/// Macro for converting sequence of string literals containing hex-encoded data
79
/// into an array of bytes.
80
#[macro_export]
81
macro_rules! hex {
82
    ($($s:literal)*) => {{
83
        const STRINGS: &[&'static [u8]] = &[$($s.as_bytes(),)*];
84
        const LEN: usize = $crate::len(STRINGS);
85
        const RES: [u8; LEN] = $crate::decode(STRINGS);
86
        RES
87
    }};
88
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hkdf-0.12.4/src/errors.rs
Line
Count
Source
1
use core::fmt;
2
3
/// Error that is returned when supplied pseudorandom key (PRK) is not long enough.
4
#[derive(Copy, Clone, Debug)]
5
pub struct InvalidPrkLength;
6
7
impl fmt::Display for InvalidPrkLength {
8
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
9
0
        f.write_str("invalid pseudorandom key length, too short")
10
0
    }
11
}
12
13
#[cfg(feature = "std")]
14
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
15
impl ::std::error::Error for InvalidPrkLength {}
16
17
/// Structure for InvalidLength, used for output error handling.
18
#[derive(Copy, Clone, Debug)]
19
pub struct InvalidLength;
20
21
impl fmt::Display for InvalidLength {
22
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
23
0
        f.write_str("invalid number of blocks, too large output")
24
0
    }
25
}
26
27
#[cfg(feature = "std")]
28
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
29
impl ::std::error::Error for InvalidLength {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hkdf-0.12.4/src/lib.rs
Line
Count
Source
1
//! An implementation of HKDF, the [HMAC-based Extract-and-Expand Key Derivation Function][1].
2
//!
3
//! # Usage
4
//!
5
//! The most common way to use HKDF is as follows: you provide the Initial Key
6
//! Material (IKM) and an optional salt, then you expand it (perhaps multiple times)
7
//! into some Output Key Material (OKM) bound to an "info" context string.
8
//!
9
//! There are two usage options for the salt:
10
//!
11
//! - [`None`] or static for domain separation in a private setting
12
//! -  guaranteed to be uniformly-distributed and unique in a public setting
13
//!
14
//! Other non fitting data should be added to the `IKM` or `info`.
15
//!
16
//! ```rust
17
//! use sha2::Sha256;
18
//! use hkdf::Hkdf;
19
//! use hex_literal::hex;
20
//!
21
//! let ikm = hex!("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
22
//! let salt = hex!("000102030405060708090a0b0c");
23
//! let info = hex!("f0f1f2f3f4f5f6f7f8f9");
24
//!
25
//! let hk = Hkdf::<Sha256>::new(Some(&salt[..]), &ikm);
26
//! let mut okm = [0u8; 42];
27
//! hk.expand(&info, &mut okm)
28
//!     .expect("42 is a valid length for Sha256 to output");
29
//!
30
//! let expected = hex!("
31
//!     3cb25f25faacd57a90434f64d0362f2a
32
//!     2d2d0a90cf1a5a4c5db02d56ecc4c5bf
33
//!     34007208d5b887185865
34
//! ");
35
//! assert_eq!(okm[..], expected[..]);
36
//! ```
37
//!
38
//! Normally the PRK (Pseudo-Random Key) remains hidden within the HKDF
39
//! object, but if you need to access it, use [`Hkdf::extract`] instead of
40
//! [`Hkdf::new`].
41
//!
42
//! ```rust
43
//! # use sha2::Sha256;
44
//! # use hkdf::Hkdf;
45
//! # use hex_literal::hex;
46
//! # let ikm = hex!("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
47
//! # let salt = hex!("000102030405060708090a0b0c");
48
//!
49
//! let (prk, hk) = Hkdf::<Sha256>::extract(Some(&salt[..]), &ikm);
50
//! let expected = hex!("
51
//!     077709362c2e32df0ddc3f0dc47bba63
52
//!     90b6c73bb50f9c3122ec844ad7c2b3e5
53
//! ");
54
//! assert_eq!(prk[..], expected[..]);
55
//! ```
56
//!
57
//! If you already have a strong key to work from (uniformly-distributed and
58
//! long enough), you can save a tiny amount of time by skipping the extract
59
//! step. In this case, you pass a Pseudo-Random Key (PRK) into the
60
//! [`Hkdf::from_prk`] constructor, then use the resulting [`Hkdf`] object
61
//! as usual.
62
//!
63
//! ```rust
64
//! # use sha2::Sha256;
65
//! # use hkdf::Hkdf;
66
//! # use hex_literal::hex;
67
//! # let salt = hex!("000102030405060708090a0b0c");
68
//! # let info = hex!("f0f1f2f3f4f5f6f7f8f9");
69
//! let prk = hex!("
70
//!     077709362c2e32df0ddc3f0dc47bba63
71
//!     90b6c73bb50f9c3122ec844ad7c2b3e5
72
//! ");
73
//!
74
//! let hk = Hkdf::<Sha256>::from_prk(&prk).expect("PRK should be large enough");
75
//! let mut okm = [0u8; 42];
76
//! hk.expand(&info, &mut okm)
77
//!     .expect("42 is a valid length for Sha256 to output");
78
//!
79
//! let expected = hex!("
80
//!     3cb25f25faacd57a90434f64d0362f2a
81
//!     2d2d0a90cf1a5a4c5db02d56ecc4c5bf
82
//!     34007208d5b887185865
83
//! ");
84
//! assert_eq!(okm[..], expected[..]);
85
//! ```
86
//!
87
//! [1]: https://tools.ietf.org/html/rfc5869
88
89
#![no_std]
90
#![doc(
91
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
92
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
93
)]
94
#![cfg_attr(docsrs, feature(doc_cfg))]
95
#![forbid(unsafe_code)]
96
#![warn(missing_docs, rust_2018_idioms)]
97
98
#[cfg(feature = "std")]
99
extern crate std;
100
101
pub use hmac;
102
103
use core::fmt;
104
use core::marker::PhantomData;
105
use hmac::digest::{
106
    crypto_common::AlgorithmName, generic_array::typenum::Unsigned, Output, OutputSizeUser,
107
};
108
use hmac::{Hmac, SimpleHmac};
109
110
mod errors;
111
mod sealed;
112
113
pub use errors::{InvalidLength, InvalidPrkLength};
114
115
/// [`HkdfExtract`] variant which uses [`SimpleHmac`] for underlying HMAC
116
/// implementation.
117
pub type SimpleHkdfExtract<H> = HkdfExtract<H, SimpleHmac<H>>;
118
/// [`Hkdf`] variant which uses [`SimpleHmac`] for underlying HMAC
119
/// implementation.
120
pub type SimpleHkdf<H> = Hkdf<H, SimpleHmac<H>>;
121
122
/// Structure representing the streaming context of an HKDF-Extract operation
123
/// ```rust
124
/// # use hkdf::{Hkdf, HkdfExtract};
125
/// # use sha2::Sha256;
126
/// let mut extract_ctx = HkdfExtract::<Sha256>::new(Some(b"mysalt"));
127
/// extract_ctx.input_ikm(b"hello");
128
/// extract_ctx.input_ikm(b" world");
129
/// let (streamed_res, _) = extract_ctx.finalize();
130
///
131
/// let (oneshot_res, _) = Hkdf::<Sha256>::extract(Some(b"mysalt"), b"hello world");
132
/// assert_eq!(streamed_res, oneshot_res);
133
/// ```
134
#[derive(Clone)]
135
pub struct HkdfExtract<H, I = Hmac<H>>
136
where
137
    H: OutputSizeUser,
138
    I: HmacImpl<H>,
139
{
140
    hmac: I,
141
    _pd: PhantomData<H>,
142
}
143
144
impl<H, I> HkdfExtract<H, I>
145
where
146
    H: OutputSizeUser,
147
    I: HmacImpl<H>,
148
{
149
    /// Initiates the HKDF-Extract context with the given optional salt
150
0
    pub fn new(salt: Option<&[u8]>) -> Self {
151
0
        let default_salt = Output::<H>::default();
152
0
        let salt = salt.unwrap_or(&default_salt);
153
0
        Self {
154
0
            hmac: I::new_from_slice(salt),
155
0
            _pd: PhantomData,
156
0
        }
157
0
    }
Unexecuted instantiation: _RNvMCsa0LBMWDZ1jV_4hkdfINtB2_11HkdfExtractINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBJ_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB34_IB34_IB34_IB34_IB34_NtB36_5UTermNtNtB38_3bit2B1ENtB4h_2B0EB4v_EB4v_EB4v_EB4v_ENtB2m_9OidSha256EEE3newCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMCsa0LBMWDZ1jV_4hkdfINtB2_11HkdfExtractppE3newB2_
158
159
    /// Feeds in additional input key material to the HKDF-Extract context
160
0
    pub fn input_ikm(&mut self, ikm: &[u8]) {
161
0
        self.hmac.update(ikm);
162
0
    }
Unexecuted instantiation: _RNvMCsa0LBMWDZ1jV_4hkdfINtB2_11HkdfExtractINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBJ_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB34_IB34_IB34_IB34_IB34_NtB36_5UTermNtNtB38_3bit2B1ENtB4h_2B0EB4v_EB4v_EB4v_EB4v_ENtB2m_9OidSha256EEE9input_ikmCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMCsa0LBMWDZ1jV_4hkdfINtB2_11HkdfExtractppE9input_ikmB2_
163
164
    /// Completes the HKDF-Extract operation, returning both the generated pseudorandom key and
165
    /// `Hkdf` struct for expanding.
166
0
    pub fn finalize(self) -> (Output<H>, Hkdf<H, I>) {
167
0
        let prk = self.hmac.finalize();
168
0
        let hkdf = Hkdf::from_prk(&prk).expect("PRK size is correct");
169
0
        (prk, hkdf)
170
0
    }
Unexecuted instantiation: _RNvMCsa0LBMWDZ1jV_4hkdfINtB2_11HkdfExtractINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBJ_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB34_IB34_IB34_IB34_IB34_NtB36_5UTermNtNtB38_3bit2B1ENtB4h_2B0EB4v_EB4v_EB4v_EB4v_ENtB2m_9OidSha256EEE8finalizeCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMCsa0LBMWDZ1jV_4hkdfINtB2_11HkdfExtractppE8finalizeB2_
171
}
172
173
impl<H, I> fmt::Debug for HkdfExtract<H, I>
174
where
175
    H: OutputSizeUser,
176
    I: HmacImpl<H>,
177
    I::Core: AlgorithmName,
178
{
179
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180
0
        f.write_str("HkdfExtract<")?;
181
0
        <I::Core as AlgorithmName>::write_alg_name(f)?;
182
0
        f.write_str("> { ... }")
183
0
    }
184
}
185
186
/// Structure representing the HKDF, capable of HKDF-Expand and HKDF-Extract operations.
187
/// Recommendations for the correct usage of the parameters can be found in the
188
/// [crate root](index.html#usage).
189
#[derive(Clone)]
190
pub struct Hkdf<H: OutputSizeUser, I: HmacImpl<H> = Hmac<H>> {
191
    hmac: I::Core,
192
    _pd: PhantomData<H>,
193
}
194
195
impl<H: OutputSizeUser, I: HmacImpl<H>> Hkdf<H, I> {
196
    /// Convenience method for [`extract`][Hkdf::extract] when the generated
197
    /// pseudorandom key can be ignored and only HKDF-Expand operation is needed. This is the most
198
    /// common constructor.
199
0
    pub fn new(salt: Option<&[u8]>, ikm: &[u8]) -> Self {
200
0
        let (_, hkdf) = Self::extract(salt, ikm);
201
0
        hkdf
202
0
    }
203
204
    /// Create `Hkdf` from an already cryptographically strong pseudorandom key
205
    /// as per section 3.3 from RFC5869.
206
0
    pub fn from_prk(prk: &[u8]) -> Result<Self, InvalidPrkLength> {
207
0
        // section 2.3 specifies that prk must be "at least HashLen octets"
208
0
        if prk.len() < <H as OutputSizeUser>::OutputSize::to_usize() {
209
0
            return Err(InvalidPrkLength);
210
0
        }
211
0
        Ok(Self {
212
0
            hmac: I::new_core(prk),
213
0
            _pd: PhantomData,
214
0
        })
215
0
    }
Unexecuted instantiation: _RNvMs0_Csa0LBMWDZ1jV_4hkdfINtB5_4HkdfINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBE_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2Z_IB2Z_IB2Z_IB2Z_IB2Z_NtB31_5UTermNtNtB33_3bit2B1ENtB4c_2B0EB4q_EB4q_EB4q_EB4q_ENtB2h_9OidSha256EEE8from_prkCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs0_Csa0LBMWDZ1jV_4hkdfINtB5_4HkdfppE8from_prkB5_
216
217
    /// The RFC5869 HKDF-Extract operation returning both the generated
218
    /// pseudorandom key and `Hkdf` struct for expanding.
219
0
    pub fn extract(salt: Option<&[u8]>, ikm: &[u8]) -> (Output<H>, Self) {
220
0
        let mut extract_ctx = HkdfExtract::new(salt);
221
0
        extract_ctx.input_ikm(ikm);
222
0
        extract_ctx.finalize()
223
0
    }
224
225
    /// The RFC5869 HKDF-Expand operation. This is equivalent to calling
226
    /// [`expand`][Hkdf::extract] with the `info` argument set equal to the
227
    /// concatenation of all the elements of `info_components`.
228
0
    pub fn expand_multi_info(
229
0
        &self,
230
0
        info_components: &[&[u8]],
231
0
        okm: &mut [u8],
232
0
    ) -> Result<(), InvalidLength> {
233
0
        let mut prev: Option<Output<H>> = None;
234
0
235
0
        let chunk_len = <H as OutputSizeUser>::OutputSize::USIZE;
236
0
        if okm.len() > chunk_len * 255 {
237
0
            return Err(InvalidLength);
238
0
        }
239
240
0
        for (block_n, block) in okm.chunks_mut(chunk_len).enumerate() {
241
0
            let mut hmac = I::from_core(&self.hmac);
242
243
0
            if let Some(ref prev) = prev {
244
0
                hmac.update(prev)
245
0
            };
246
247
            // Feed in the info components in sequence. This is equivalent to feeding in the
248
            // concatenation of all the info components
249
0
            for info in info_components {
250
0
                hmac.update(info);
251
0
            }
252
253
0
            hmac.update(&[block_n as u8 + 1]);
254
0
255
0
            let output = hmac.finalize();
256
0
257
0
            let block_len = block.len();
258
0
            block.copy_from_slice(&output[..block_len]);
259
0
260
0
            prev = Some(output);
261
        }
262
263
0
        Ok(())
264
0
    }
Unexecuted instantiation: _RNvMs0_Csa0LBMWDZ1jV_4hkdfINtB5_4HkdfINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBE_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2Z_IB2Z_IB2Z_IB2Z_IB2Z_NtB31_5UTermNtNtB33_3bit2B1ENtB4c_2B0EB4q_EB4q_EB4q_EB4q_ENtB2h_9OidSha256EEE17expand_multi_infoCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs0_Csa0LBMWDZ1jV_4hkdfINtB5_4HkdfppE17expand_multi_infoB5_
265
266
    /// The RFC5869 HKDF-Expand operation
267
    ///
268
    /// If you don't have any `info` to pass, use an empty slice.
269
0
    pub fn expand(&self, info: &[u8], okm: &mut [u8]) -> Result<(), InvalidLength> {
270
0
        self.expand_multi_info(&[info], okm)
271
0
    }
Unexecuted instantiation: _RNvMs0_Csa0LBMWDZ1jV_4hkdfINtB5_4HkdfINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBE_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2Z_IB2Z_IB2Z_IB2Z_IB2Z_NtB31_5UTermNtNtB33_3bit2B1ENtB4c_2B0EB4q_EB4q_EB4q_EB4q_ENtB2h_9OidSha256EEE6expandCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvMs0_Csa0LBMWDZ1jV_4hkdfINtB5_4HkdfppE6expandB5_
272
}
273
274
impl<H, I> fmt::Debug for Hkdf<H, I>
275
where
276
    H: OutputSizeUser,
277
    I: HmacImpl<H>,
278
    I::Core: AlgorithmName,
279
{
280
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281
0
        f.write_str("Hkdf<")?;
282
0
        <I::Core as AlgorithmName>::write_alg_name(f)?;
283
0
        f.write_str("> { ... }")
284
0
    }
285
}
286
287
/// Sealed trait implemented for [`Hmac`] and [`SimpleHmac`].
288
pub trait HmacImpl<H: OutputSizeUser>: sealed::Sealed<H> {}
289
290
impl<H: OutputSizeUser, T: sealed::Sealed<H>> HmacImpl<H> for T {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hkdf-0.12.4/src/sealed.rs
Line
Count
Source
1
use hmac::digest::{
2
    block_buffer::Eager,
3
    core_api::{
4
        BlockSizeUser, BufferKindUser, CoreProxy, CoreWrapper, FixedOutputCore, OutputSizeUser,
5
        UpdateCore,
6
    },
7
    generic_array::typenum::{IsLess, Le, NonZero, U256},
8
    Digest, FixedOutput, HashMarker, KeyInit, Output, Update,
9
};
10
use hmac::{Hmac, HmacCore, SimpleHmac};
11
12
pub trait Sealed<H: OutputSizeUser> {
13
    type Core: Clone;
14
15
    fn new_from_slice(key: &[u8]) -> Self;
16
17
    fn new_core(key: &[u8]) -> Self::Core;
18
19
    fn from_core(core: &Self::Core) -> Self;
20
21
    fn update(&mut self, data: &[u8]);
22
23
    fn finalize(self) -> Output<H>;
24
}
25
26
impl<H> Sealed<H> for Hmac<H>
27
where
28
    H: CoreProxy + OutputSizeUser,
29
    H::Core: HashMarker
30
        + UpdateCore
31
        + FixedOutputCore
32
        + BufferKindUser<BufferKind = Eager>
33
        + Default
34
        + Clone,
35
    <H::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
36
    Le<<H::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
37
{
38
    type Core = HmacCore<H>;
39
40
    #[inline(always)]
41
0
    fn new_from_slice(key: &[u8]) -> Self {
42
0
        KeyInit::new_from_slice(key).expect("HMAC can take a key of any size")
43
0
    }
Unexecuted instantiation: _RNvXNtCsa0LBMWDZ1jV_4hkdf6sealedINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIBv_INtNtBz_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3B_IB3B_IB3B_IB3B_IB3B_NtB3D_5UTermNtNtB3F_3bit2B1ENtB4O_2B0EB52_EB52_EB52_EB52_ENtB2T_9OidSha256EEEEINtB2_6SealedB23_E14new_from_sliceCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtCsa0LBMWDZ1jV_4hkdf6sealed0pEINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCorepEEINtB5_6SealedpE14new_from_sliceB7_
44
45
    #[inline(always)]
46
0
    fn new_core(key: &[u8]) -> Self::Core {
47
0
        HmacCore::new_from_slice(key).expect("HMAC can take a key of any size")
48
0
    }
Unexecuted instantiation: _RNvXNtCsa0LBMWDZ1jV_4hkdf6sealedINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIBv_INtNtBz_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3B_IB3B_IB3B_IB3B_IB3B_NtB3D_5UTermNtNtB3F_3bit2B1ENtB4O_2B0EB52_EB52_EB52_EB52_ENtB2T_9OidSha256EEEEINtB2_6SealedB23_E8new_coreCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtCsa0LBMWDZ1jV_4hkdf6sealed0pEINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCorepEEINtB5_6SealedpE8new_coreB7_
49
50
    #[inline(always)]
51
0
    fn from_core(core: &Self::Core) -> Self {
52
0
        CoreWrapper::from_core(core.clone())
53
0
    }
Unexecuted instantiation: _RNvXNtCsa0LBMWDZ1jV_4hkdf6sealedINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIBv_INtNtBz_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3B_IB3B_IB3B_IB3B_IB3B_NtB3D_5UTermNtNtB3F_3bit2B1ENtB4O_2B0EB52_EB52_EB52_EB52_ENtB2T_9OidSha256EEEEINtB2_6SealedB23_E9from_coreCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtCsa0LBMWDZ1jV_4hkdf6sealed0pEINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCorepEEINtB5_6SealedpE9from_coreB7_
54
55
    #[inline(always)]
56
0
    fn update(&mut self, data: &[u8]) {
57
0
        Update::update(self, data);
58
0
    }
Unexecuted instantiation: _RNvXNtCsa0LBMWDZ1jV_4hkdf6sealedINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIBv_INtNtBz_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3B_IB3B_IB3B_IB3B_IB3B_NtB3D_5UTermNtNtB3F_3bit2B1ENtB4O_2B0EB52_EB52_EB52_EB52_ENtB2T_9OidSha256EEEEINtB2_6SealedB23_E6updateCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtCsa0LBMWDZ1jV_4hkdf6sealed0pEINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCorepEEINtB5_6SealedpE6updateB7_
59
60
    #[inline(always)]
61
0
    fn finalize(self) -> Output<H> {
62
0
        // Output<H> and Output<H::Core> are always equal to each other,
63
0
        // but we can not prove it at type level
64
0
        Output::<H>::clone_from_slice(&self.finalize_fixed())
65
0
    }
Unexecuted instantiation: _RNvXNtCsa0LBMWDZ1jV_4hkdf6sealedINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCoreIBv_INtNtBz_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3B_IB3B_IB3B_IB3B_IB3B_NtB3D_5UTermNtNtB3F_3bit2B1ENtB4O_2B0EB52_EB52_EB52_EB52_ENtB2T_9OidSha256EEEEINtB2_6SealedB23_E8finalizeCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtCsa0LBMWDZ1jV_4hkdf6sealed0pEINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtCsgFTejnltRzv_4hmac5optim8HmacCorepEEINtB5_6SealedpE8finalizeB7_
66
}
67
68
impl<H: Digest + BlockSizeUser + Clone> Sealed<H> for SimpleHmac<H> {
69
    type Core = Self;
70
71
    #[inline(always)]
72
0
    fn new_from_slice(key: &[u8]) -> Self {
73
0
        KeyInit::new_from_slice(key).expect("HMAC can take a key of any size")
74
0
    }
75
76
    #[inline(always)]
77
0
    fn new_core(key: &[u8]) -> Self::Core {
78
0
        KeyInit::new_from_slice(key).expect("HMAC can take a key of any size")
79
0
    }
80
81
    #[inline(always)]
82
0
    fn from_core(core: &Self::Core) -> Self {
83
0
        core.clone()
84
0
    }
85
86
    #[inline(always)]
87
0
    fn update(&mut self, data: &[u8]) {
88
0
        Update::update(self, data);
89
0
    }
90
91
    #[inline(always)]
92
0
    fn finalize(self) -> Output<H> {
93
0
        // Output<H> and Output<H::Core> are always equal to each other,
94
0
        // but we can not prove it at type level
95
0
        Output::<H>::clone_from_slice(&self.finalize_fixed())
96
0
    }
97
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hmac-0.12.1/src/lib.rs
Line
Count
Source
1
//! Generic implementation of Hash-based Message Authentication Code (HMAC).
2
//!
3
//! To use it you will need a cryptographic hash function implementation which
4
//! implements the [`digest`] crate traits. You can find compatible crates
5
//! (e.g. [`sha2`]) in the [`RustCrypto/hashes`] repository.
6
//!
7
//! This crate provides two HMAC implementation [`Hmac`] and [`SimpleHmac`].
8
//! The first one is a buffered wrapper around block-level [`HmacCore`].
9
//! Internally it uses efficient state representation, but works only with
10
//! hash functions which expose block-level API and consume blocks eagerly
11
//! (e.g. it will not work with the BLAKE2 family of  hash functions).
12
//! On the other hand, [`SimpleHmac`] is a bit less efficient memory-wise,
13
//! but works with all hash functions which implement the [`Digest`] trait.
14
//!
15
//! # Examples
16
//! Let us demonstrate how to use HMAC using the SHA-256 hash function.
17
//!
18
//! In the following examples [`Hmac`] is interchangeable with [`SimpleHmac`].
19
//!
20
//! To get authentication code:
21
//!
22
//! ```rust
23
//! use sha2::Sha256;
24
//! use hmac::{Hmac, Mac};
25
//! use hex_literal::hex;
26
//!
27
//! // Create alias for HMAC-SHA256
28
//! type HmacSha256 = Hmac<Sha256>;
29
//!
30
//! let mut mac = HmacSha256::new_from_slice(b"my secret and secure key")
31
//!     .expect("HMAC can take key of any size");
32
//! mac.update(b"input message");
33
//!
34
//! // `result` has type `CtOutput` which is a thin wrapper around array of
35
//! // bytes for providing constant time equality check
36
//! let result = mac.finalize();
37
//! // To get underlying array use `into_bytes`, but be careful, since
38
//! // incorrect use of the code value may permit timing attacks which defeats
39
//! // the security provided by the `CtOutput`
40
//! let code_bytes = result.into_bytes();
41
//! let expected = hex!("
42
//!     97d2a569059bbcd8ead4444ff99071f4
43
//!     c01d005bcefe0d3567e1be628e5fdcd9
44
//! ");
45
//! assert_eq!(code_bytes[..], expected[..]);
46
//! ```
47
//!
48
//! To verify the message:
49
//!
50
//! ```rust
51
//! # use sha2::Sha256;
52
//! # use hmac::{Hmac, Mac};
53
//! # use hex_literal::hex;
54
//! # type HmacSha256 = Hmac<Sha256>;
55
//! let mut mac = HmacSha256::new_from_slice(b"my secret and secure key")
56
//!     .expect("HMAC can take key of any size");
57
//!
58
//! mac.update(b"input message");
59
//!
60
//! let code_bytes = hex!("
61
//!     97d2a569059bbcd8ead4444ff99071f4
62
//!     c01d005bcefe0d3567e1be628e5fdcd9
63
//! ");
64
//! // `verify_slice` will return `Ok(())` if code is correct, `Err(MacError)` otherwise
65
//! mac.verify_slice(&code_bytes[..]).unwrap();
66
//! ```
67
//!
68
//! # Block and input sizes
69
//! Usually it is assumed that block size is larger than output size. Due to the
70
//! generic nature of the implementation, this edge case must be handled as well
71
//! to remove potential panic. This is done by truncating hash output to the hash
72
//! block size if needed.
73
//!
74
//! [`digest`]: https://docs.rs/digest
75
//! [`sha2`]: https://docs.rs/sha2
76
//! [`RustCrypto/hashes`]: https://github.com/RustCrypto/hashes
77
78
#![no_std]
79
#![doc(
80
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg",
81
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/26acc39f/logo.svg",
82
    html_root_url = "https://docs.rs/hmac/0.12.1"
83
)]
84
#![forbid(unsafe_code)]
85
#![cfg_attr(docsrs, feature(doc_cfg))]
86
#![warn(missing_docs, rust_2018_idioms)]
87
88
#[cfg(feature = "std")]
89
extern crate std;
90
91
pub use digest;
92
pub use digest::Mac;
93
94
use digest::{
95
    core_api::{Block, BlockSizeUser},
96
    Digest,
97
};
98
99
mod optim;
100
mod simple;
101
102
pub use optim::{Hmac, HmacCore};
103
pub use simple::SimpleHmac;
104
105
const IPAD: u8 = 0x36;
106
const OPAD: u8 = 0x5C;
107
108
0
fn get_der_key<D: Digest + BlockSizeUser>(key: &[u8]) -> Block<D> {
109
0
    let mut der_key = Block::<D>::default();
110
0
    // The key that HMAC processes must be the same as the block size of the
111
0
    // underlying hash function. If the provided key is smaller than that,
112
0
    // we just pad it with zeros. If its larger, we hash it and then pad it
113
0
    // with zeros.
114
0
    if key.len() <= der_key.len() {
115
0
        der_key[..key.len()].copy_from_slice(key);
116
0
    } else {
117
0
        let hash = D::digest(key);
118
0
        // All commonly used hash functions have block size bigger
119
0
        // than output hash size, but to be extra rigorous we
120
0
        // handle the potential uncommon cases as well.
121
0
        // The condition is calcualted at compile time, so this
122
0
        // branch gets removed from the final binary.
123
0
        if hash.len() <= der_key.len() {
124
0
            der_key[..hash.len()].copy_from_slice(&hash);
125
0
        } else {
126
0
            let n = der_key.len();
127
0
            der_key.copy_from_slice(&hash[..n]);
128
0
        }
129
    }
130
0
    der_key
131
0
}
Unexecuted instantiation: _RINvCsgFTejnltRzv_4hmac11get_der_keyINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBD_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB2Y_IB2Y_IB2Y_IB2Y_IB2Y_NtB30_5UTermNtNtB32_3bit2B1ENtB4b_2B0EB4p_EB4p_EB4p_EB4p_ENtB2g_9OidSha256EEECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvCsgFTejnltRzv_4hmac11get_der_keypEB2_
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hmac-0.12.1/src/optim.rs
Line
Count
Source
1
use super::{get_der_key, IPAD, OPAD};
2
use core::{fmt, slice};
3
#[cfg(feature = "reset")]
4
use digest::Reset;
5
use digest::{
6
    block_buffer::Eager,
7
    core_api::{
8
        AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreProxy, CoreWrapper,
9
        FixedOutputCore, OutputSizeUser, UpdateCore,
10
    },
11
    crypto_common::{Key, KeySizeUser},
12
    generic_array::typenum::{IsLess, Le, NonZero, U256},
13
    HashMarker, InvalidLength, KeyInit, MacMarker, Output,
14
};
15
16
/// Generic HMAC instance.
17
pub type Hmac<D> = CoreWrapper<HmacCore<D>>;
18
19
/// Generic core HMAC instance, which operates over blocks.
20
pub struct HmacCore<D>
21
where
22
    D: CoreProxy,
23
    D::Core: HashMarker
24
        + UpdateCore
25
        + FixedOutputCore
26
        + BufferKindUser<BufferKind = Eager>
27
        + Default
28
        + Clone,
29
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
30
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
31
{
32
    digest: D::Core,
33
    opad_digest: D::Core,
34
    #[cfg(feature = "reset")]
35
    ipad_digest: D::Core,
36
}
37
38
impl<D> Clone for HmacCore<D>
39
where
40
    D: CoreProxy,
41
    D::Core: HashMarker
42
        + UpdateCore
43
        + FixedOutputCore
44
        + BufferKindUser<BufferKind = Eager>
45
        + Default
46
        + Clone,
47
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
48
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
49
{
50
0
    fn clone(&self) -> Self {
51
0
        Self {
52
0
            digest: self.digest.clone(),
53
0
            opad_digest: self.opad_digest.clone(),
54
0
            #[cfg(feature = "reset")]
55
0
            ipad_digest: self.ipad_digest.clone(),
56
0
        }
57
0
    }
Unexecuted instantiation: _RNvXNtCsgFTejnltRzv_4hmac5optimINtB2_8HmacCoreINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBN_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB38_IB38_IB38_IB38_IB38_NtB3a_5UTermNtNtB3c_3bit2B1ENtB4l_2B0EB4z_EB4z_EB4z_EB4z_ENtB2q_9OidSha256EEENtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtCsgFTejnltRzv_4hmac5optim0pEINtB5_8HmacCorepENtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
58
}
59
60
impl<D> MacMarker for HmacCore<D>
61
where
62
    D: CoreProxy,
63
    D::Core: HashMarker
64
        + UpdateCore
65
        + FixedOutputCore
66
        + BufferKindUser<BufferKind = Eager>
67
        + Default
68
        + Clone,
69
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
70
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
71
{
72
}
73
74
impl<D> BufferKindUser for HmacCore<D>
75
where
76
    D: CoreProxy,
77
    D::Core: HashMarker
78
        + UpdateCore
79
        + FixedOutputCore
80
        + BufferKindUser<BufferKind = Eager>
81
        + Default
82
        + Clone,
83
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
84
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
85
{
86
    type BufferKind = Eager;
87
}
88
89
impl<D> KeySizeUser for HmacCore<D>
90
where
91
    D: CoreProxy,
92
    D::Core: HashMarker
93
        + UpdateCore
94
        + FixedOutputCore
95
        + BufferKindUser<BufferKind = Eager>
96
        + Default
97
        + Clone,
98
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
99
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
100
{
101
    type KeySize = <<D as CoreProxy>::Core as BlockSizeUser>::BlockSize;
102
}
103
104
impl<D> BlockSizeUser for HmacCore<D>
105
where
106
    D: CoreProxy,
107
    D::Core: HashMarker
108
        + UpdateCore
109
        + FixedOutputCore
110
        + BufferKindUser<BufferKind = Eager>
111
        + Default
112
        + Clone,
113
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
114
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
115
{
116
    type BlockSize = <<D as CoreProxy>::Core as BlockSizeUser>::BlockSize;
117
}
118
119
impl<D> OutputSizeUser for HmacCore<D>
120
where
121
    D: CoreProxy,
122
    D::Core: HashMarker
123
        + UpdateCore
124
        + FixedOutputCore
125
        + BufferKindUser<BufferKind = Eager>
126
        + Default
127
        + Clone,
128
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
129
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
130
{
131
    type OutputSize = <<D as CoreProxy>::Core as OutputSizeUser>::OutputSize;
132
}
133
134
impl<D> KeyInit for HmacCore<D>
135
where
136
    D: CoreProxy,
137
    D::Core: HashMarker
138
        + UpdateCore
139
        + FixedOutputCore
140
        + BufferKindUser<BufferKind = Eager>
141
        + Default
142
        + Clone,
143
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
144
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
145
{
146
    #[inline(always)]
147
0
    fn new(key: &Key<Self>) -> Self {
148
0
        Self::new_from_slice(key.as_slice()).unwrap()
149
0
    }
150
151
    #[inline(always)]
152
0
    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
153
0
        let mut buf = get_der_key::<CoreWrapper<D::Core>>(key);
154
0
        for b in buf.iter_mut() {
155
0
            *b ^= IPAD;
156
0
        }
157
0
        let mut digest = D::Core::default();
158
0
        digest.update_blocks(slice::from_ref(&buf));
159
160
0
        for b in buf.iter_mut() {
161
0
            *b ^= IPAD ^ OPAD;
162
0
        }
163
164
0
        let mut opad_digest = D::Core::default();
165
0
        opad_digest.update_blocks(slice::from_ref(&buf));
166
0
167
0
        Ok(Self {
168
0
            #[cfg(feature = "reset")]
169
0
            ipad_digest: digest.clone(),
170
0
            opad_digest,
171
0
            digest,
172
0
        })
173
0
    }
Unexecuted instantiation: _RNvXs4_NtCsgFTejnltRzv_4hmac5optimINtB5_8HmacCoreINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBQ_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3b_IB3b_IB3b_IB3b_IB3b_NtB3d_5UTermNtNtB3f_3bit2B1ENtB4o_2B0EB4C_EB4C_EB4C_EB4C_ENtB2t_9OidSha256EEENtCslUxhuGmkrsg_13crypto_common7KeyInit14new_from_sliceCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtCsgFTejnltRzv_4hmac5optims4_0pEINtB5_8HmacCorepENtCslUxhuGmkrsg_13crypto_common7KeyInit14new_from_sliceB7_
174
}
175
176
impl<D> UpdateCore for HmacCore<D>
177
where
178
    D: CoreProxy,
179
    D::Core: HashMarker
180
        + UpdateCore
181
        + FixedOutputCore
182
        + BufferKindUser<BufferKind = Eager>
183
        + Default
184
        + Clone,
185
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
186
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
187
{
188
    #[inline(always)]
189
0
    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
190
0
        self.digest.update_blocks(blocks);
191
0
    }
Unexecuted instantiation: _RNvXs5_NtCsgFTejnltRzv_4hmac5optimINtB5_8HmacCoreINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBQ_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3b_IB3b_IB3b_IB3b_IB3b_NtB3d_5UTermNtNtB3f_3bit2B1ENtB4o_2B0EB4C_EB4C_EB4C_EB4C_ENtB2t_9OidSha256EEENtBQ_10UpdateCore13update_blocksCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtCsgFTejnltRzv_4hmac5optims5_0pEINtB5_8HmacCorepENtNtCsfSiVvAzsu9K_6digest8core_api10UpdateCore13update_blocksB7_
192
}
193
194
impl<D> FixedOutputCore for HmacCore<D>
195
where
196
    D: CoreProxy,
197
    D::Core: HashMarker
198
        + UpdateCore
199
        + FixedOutputCore
200
        + BufferKindUser<BufferKind = Eager>
201
        + Default
202
        + Clone,
203
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
204
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
205
{
206
    #[inline(always)]
207
0
    fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
208
0
        let mut hash = Output::<D::Core>::default();
209
0
        self.digest.finalize_fixed_core(buffer, &mut hash);
210
0
        // finalize_fixed_core should reset the buffer as well, but
211
0
        // to be extra safe we reset it explicitly again.
212
0
        buffer.reset();
213
0
        #[cfg(not(feature = "reset"))]
214
0
        let h = &mut self.opad_digest;
215
0
        #[cfg(feature = "reset")]
216
0
        let mut h = self.opad_digest.clone();
217
0
        buffer.digest_blocks(&hash, |b| h.update_blocks(b));
Unexecuted instantiation: _RNCNvXs6_NtCsgFTejnltRzv_4hmac5optimINtB7_8HmacCoreINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBS_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3d_IB3d_IB3d_IB3d_IB3d_NtB3f_5UTermNtNtB3h_3bit2B1ENtB4q_2B0EB4E_EB4E_EB4E_EB4E_ENtB2v_9OidSha256EEENtBS_15FixedOutputCore19finalize_fixed_core0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCNvXININtCsgFTejnltRzv_4hmac5optims6_0pEINtB7_8HmacCorepENtNtCsfSiVvAzsu9K_6digest8core_api15FixedOutputCore19finalize_fixed_core0B9_
218
0
        h.finalize_fixed_core(buffer, out);
219
0
    }
Unexecuted instantiation: _RNvXs6_NtCsgFTejnltRzv_4hmac5optimINtB5_8HmacCoreINtNtNtCsfSiVvAzsu9K_6digest8core_api7wrapper11CoreWrapperINtNtBQ_11ct_variable21CtVariableCoreWrapperNtNtCs23lnNM1woOA_4sha28core_api13Sha256VarCoreINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB3b_IB3b_IB3b_IB3b_IB3b_NtB3d_5UTermNtNtB3f_3bit2B1ENtB4o_2B0EB4C_EB4C_EB4C_EB4C_ENtB2t_9OidSha256EEENtBQ_15FixedOutputCore19finalize_fixed_coreCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXININtCsgFTejnltRzv_4hmac5optims6_0pEINtB5_8HmacCorepENtNtCsfSiVvAzsu9K_6digest8core_api15FixedOutputCore19finalize_fixed_coreB7_
220
}
221
222
#[cfg(feature = "reset")]
223
#[cfg_attr(docsrs, doc(cfg(feature = "reset")))]
224
impl<D> Reset for HmacCore<D>
225
where
226
    D: CoreProxy,
227
    D::Core: HashMarker
228
        + UpdateCore
229
        + FixedOutputCore
230
        + BufferKindUser<BufferKind = Eager>
231
        + Default
232
        + Clone,
233
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
234
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
235
{
236
    #[inline(always)]
237
0
    fn reset(&mut self) {
238
0
        self.digest = self.ipad_digest.clone();
239
0
    }
240
}
241
242
impl<D> AlgorithmName for HmacCore<D>
243
where
244
    D: CoreProxy,
245
    D::Core: HashMarker
246
        + AlgorithmName
247
        + UpdateCore
248
        + FixedOutputCore
249
        + BufferKindUser<BufferKind = Eager>
250
        + Default
251
        + Clone,
252
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
253
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
254
{
255
0
    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
256
0
        f.write_str("Hmac<")?;
257
0
        <D::Core as AlgorithmName>::write_alg_name(f)?;
258
0
        f.write_str(">")
259
0
    }
260
}
261
262
impl<D> fmt::Debug for HmacCore<D>
263
where
264
    D: CoreProxy,
265
    D::Core: HashMarker
266
        + AlgorithmName
267
        + UpdateCore
268
        + FixedOutputCore
269
        + BufferKindUser<BufferKind = Eager>
270
        + Default
271
        + Clone,
272
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
273
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
274
{
275
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276
0
        f.write_str("HmacCore<")?;
277
0
        <D::Core as AlgorithmName>::write_alg_name(f)?;
278
0
        f.write_str("> { ... }")
279
0
    }
280
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hmac-0.12.1/src/simple.rs
Line
Count
Source
1
use super::{get_der_key, IPAD, OPAD};
2
use core::fmt;
3
use digest::{
4
    crypto_common::{Block, BlockSizeUser, InvalidLength, Key, KeySizeUser},
5
    Digest, FixedOutput, KeyInit, MacMarker, Output, OutputSizeUser, Update,
6
};
7
#[cfg(feature = "reset")]
8
use digest::{FixedOutputReset, Reset};
9
10
/// Simplified HMAC instance able to operate over hash functions
11
/// which do not expose block-level API and hash functions which
12
/// process blocks lazily (e.g. BLAKE2).
13
#[derive(Clone)]
14
pub struct SimpleHmac<D: Digest + BlockSizeUser> {
15
    digest: D,
16
    opad_key: Block<D>,
17
    #[cfg(feature = "reset")]
18
    ipad_key: Block<D>,
19
}
20
21
impl<D: Digest + BlockSizeUser> KeySizeUser for SimpleHmac<D> {
22
    type KeySize = D::BlockSize;
23
}
24
25
impl<D: Digest + BlockSizeUser> MacMarker for SimpleHmac<D> {}
26
27
impl<D: Digest + BlockSizeUser> KeyInit for SimpleHmac<D> {
28
0
    fn new(key: &Key<Self>) -> Self {
29
0
        Self::new_from_slice(key.as_slice()).unwrap()
30
0
    }
31
32
    #[inline]
33
0
    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
34
0
        let der_key = get_der_key::<D>(key);
35
0
        let mut ipad_key = der_key.clone();
36
0
        for b in ipad_key.iter_mut() {
37
0
            *b ^= IPAD;
38
0
        }
39
0
        let mut digest = D::new();
40
0
        digest.update(&ipad_key);
41
0
42
0
        let mut opad_key = der_key;
43
0
        for b in opad_key.iter_mut() {
44
0
            *b ^= OPAD;
45
0
        }
46
47
0
        Ok(Self {
48
0
            digest,
49
0
            opad_key,
50
0
            #[cfg(feature = "reset")]
51
0
            ipad_key,
52
0
        })
53
0
    }
54
}
55
56
impl<D: Digest + BlockSizeUser> Update for SimpleHmac<D> {
57
    #[inline(always)]
58
0
    fn update(&mut self, data: &[u8]) {
59
0
        self.digest.update(data);
60
0
    }
61
}
62
63
impl<D: Digest + BlockSizeUser> OutputSizeUser for SimpleHmac<D> {
64
    type OutputSize = D::OutputSize;
65
}
66
67
impl<D: Digest + BlockSizeUser> FixedOutput for SimpleHmac<D> {
68
0
    fn finalize_into(self, out: &mut Output<Self>) {
69
0
        let mut h = D::new();
70
0
        h.update(&self.opad_key);
71
0
        h.update(&self.digest.finalize());
72
0
        h.finalize_into(out);
73
0
    }
74
}
75
76
impl<D: Digest + BlockSizeUser + fmt::Debug> fmt::Debug for SimpleHmac<D> {
77
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78
0
        f.debug_struct("SimpleHmac")
79
0
            .field("digest", &self.digest)
80
0
            // TODO: replace with `finish_non_exhaustive` on MSRV
81
0
            // bump to 1.53
82
0
            .field("..", &"..")
83
0
            .finish()
84
0
    }
85
}
86
87
#[cfg(feature = "reset")]
88
#[cfg_attr(docsrs, doc(cfg(feature = "reset")))]
89
impl<D: Digest + BlockSizeUser + Reset> Reset for SimpleHmac<D> {
90
0
    fn reset(&mut self) {
91
0
        Reset::reset(&mut self.digest);
92
0
        self.digest.update(&self.ipad_key);
93
0
    }
94
}
95
96
#[cfg(feature = "reset")]
97
#[cfg_attr(docsrs, doc(cfg(feature = "reset")))]
98
impl<D: Digest + BlockSizeUser + FixedOutputReset> FixedOutputReset for SimpleHmac<D> {
99
0
    fn finalize_into_reset(&mut self, out: &mut Output<Self>) {
100
0
        let mut h = D::new();
101
0
        Update::update(&mut h, &self.opad_key);
102
0
        Update::update(&mut h, &self.digest.finalize_reset());
103
0
        Update::update(&mut self.digest, &self.ipad_key);
104
0
        Digest::finalize_into(h, out);
105
0
    }
106
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/arithmetic/affine.rs
Line
Count
Source
1
//! Affine points
2
3
#![allow(clippy::op_ref)]
4
5
use super::{FieldElement, ProjectivePoint, CURVE_EQUATION_B};
6
use crate::{CompressedPoint, EncodedPoint, FieldBytes, PublicKey, Scalar, Secp256k1};
7
use core::ops::{Mul, Neg};
8
use elliptic_curve::{
9
    group::{prime::PrimeCurveAffine, GroupEncoding},
10
    point::{AffineCoordinates, DecompactPoint, DecompressPoint},
11
    sec1::{self, FromEncodedPoint, ToEncodedPoint},
12
    subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
13
    zeroize::DefaultIsZeroes,
14
    Error, Result,
15
};
16
17
#[cfg(feature = "serde")]
18
use serdect::serde::{de, ser, Deserialize, Serialize};
19
20
/// secp256k1 curve point expressed in affine coordinates.
21
///
22
/// # `serde` support
23
///
24
/// When the `serde` feature of this crate is enabled, the `Serialize` and
25
/// `Deserialize` traits are impl'd for this type.
26
///
27
/// The serialization uses the [SEC1] `Elliptic-Curve-Point-to-Octet-String`
28
/// encoding, serialized as binary.
29
///
30
/// When serialized with a text-based format, the SEC1 representation is
31
/// subsequently hex encoded.
32
///
33
/// [SEC1]: https://www.secg.org/sec1-v2.pdf
34
#[derive(Clone, Copy, Debug)]
35
pub struct AffinePoint {
36
    /// x-coordinate
37
    pub(crate) x: FieldElement,
38
39
    /// y-coordinate
40
    pub(crate) y: FieldElement,
41
42
    /// Is this point the point at infinity? 0 = no, 1 = yes
43
    ///
44
    /// This is a proxy for [`Choice`], but uses `u8` instead to permit `const`
45
    /// constructors for `IDENTITY` and `GENERATOR`.
46
    pub(super) infinity: u8,
47
}
48
49
impl AffinePoint {
50
    /// Additive identity of the group: the point at infinity.
51
    pub const IDENTITY: Self = Self {
52
        x: FieldElement::ZERO,
53
        y: FieldElement::ZERO,
54
        infinity: 1,
55
    };
56
57
    /// Base point of secp256k1.
58
    ///
59
    /// ```text
60
    /// Gₓ = 79be667e f9dcbbac 55a06295 ce870b07 029bfcdb 2dce28d9 59f2815b 16f81798
61
    /// Gᵧ = 483ada77 26a3c465 5da4fbfc 0e1108a8 fd17b448 a6855419 9c47d08f fb10d4b8
62
    /// ```
63
    pub const GENERATOR: Self = Self {
64
        x: FieldElement::from_bytes_unchecked(&[
65
            0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87,
66
            0x0b, 0x07, 0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, 0x59, 0xf2, 0x81, 0x5b,
67
            0x16, 0xf8, 0x17, 0x98,
68
        ]),
69
        y: FieldElement::from_bytes_unchecked(&[
70
            0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc, 0x0e, 0x11,
71
            0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f,
72
            0xfb, 0x10, 0xd4, 0xb8,
73
        ]),
74
        infinity: 0,
75
    };
76
}
77
78
impl AffinePoint {
79
    /// Create a new [`AffinePoint`] with the given coordinates.
80
1.78k
    pub(crate) const fn new(x: FieldElement, y: FieldElement) -> Self {
81
1.78k
        Self { x, y, infinity: 0 }
82
1.78k
    }
83
}
84
85
impl PrimeCurveAffine for AffinePoint {
86
    type Scalar = Scalar;
87
    type Curve = ProjectivePoint;
88
89
    /// Returns the identity of the group: the point at infinity.
90
0
    fn identity() -> Self {
91
0
        Self::IDENTITY
92
0
    }
93
94
    /// Returns the base point of secp256k1.
95
0
    fn generator() -> Self {
96
0
        Self::GENERATOR
97
0
    }
98
99
    /// Is this point the identity point?
100
523
    fn is_identity(&self) -> Choice {
101
523
        Choice::from(self.infinity)
102
523
    }
103
104
    /// Convert to curve representation.
105
0
    fn to_curve(&self) -> ProjectivePoint {
106
0
        ProjectivePoint::from(*self)
107
0
    }
108
}
109
110
impl AffineCoordinates for AffinePoint {
111
    type FieldRepr = FieldBytes;
112
113
523
    fn x(&self) -> FieldBytes {
114
523
        self.x.to_bytes()
115
523
    }
116
117
0
    fn y_is_odd(&self) -> Choice {
118
0
        self.y.normalize().is_odd()
119
0
    }
120
}
121
122
impl ConditionallySelectable for AffinePoint {
123
1.79k
    fn conditional_select(a: &AffinePoint, b: &AffinePoint, choice: Choice) -> AffinePoint {
124
1.79k
        AffinePoint {
125
1.79k
            x: FieldElement::conditional_select(&a.x, &b.x, choice),
126
1.79k
            y: FieldElement::conditional_select(&a.y, &b.y, choice),
127
1.79k
            infinity: u8::conditional_select(&a.infinity, &b.infinity, choice),
128
1.79k
        }
129
1.79k
    }
130
}
131
132
impl ConstantTimeEq for AffinePoint {
133
0
    fn ct_eq(&self, other: &AffinePoint) -> Choice {
134
0
        (self.x.negate(1) + &other.x).normalizes_to_zero()
135
0
            & (self.y.negate(1) + &other.y).normalizes_to_zero()
136
0
            & self.infinity.ct_eq(&other.infinity)
137
0
    }
138
}
139
140
impl Default for AffinePoint {
141
1.27k
    fn default() -> Self {
142
1.27k
        Self::IDENTITY
143
1.27k
    }
_RNvXs4_NtNtCsjewTDwKBbyD_4k25610arithmetic6affineNtB5_11AffinePointNtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs4RkbDk9WRL5_5clvmr
Line
Count
Source
141
1.27k
    fn default() -> Self {
142
1.27k
        Self::IDENTITY
143
1.27k
    }
Unexecuted instantiation: _RNvXs4_NtNtCsjewTDwKBbyD_4k25610arithmetic6affineNtB5_11AffinePointNtNtCsbQ8arDwx5Xq_4core7default7Default7defaultB9_
144
}
145
146
impl DefaultIsZeroes for AffinePoint {}
147
148
impl PartialEq for AffinePoint {
149
0
    fn eq(&self, other: &AffinePoint) -> bool {
150
0
        self.ct_eq(other).into()
151
0
    }
152
}
153
154
impl Eq for AffinePoint {}
155
156
impl Mul<Scalar> for AffinePoint {
157
    type Output = ProjectivePoint;
158
159
0
    fn mul(self, scalar: Scalar) -> ProjectivePoint {
160
0
        ProjectivePoint::from(self) * scalar
161
0
    }
162
}
163
164
impl Mul<&Scalar> for AffinePoint {
165
    type Output = ProjectivePoint;
166
167
0
    fn mul(self, scalar: &Scalar) -> ProjectivePoint {
168
0
        ProjectivePoint::from(self) * scalar
169
0
    }
170
}
171
172
impl Neg for AffinePoint {
173
    type Output = AffinePoint;
174
175
0
    fn neg(self) -> Self::Output {
176
0
        AffinePoint {
177
0
            x: self.x,
178
0
            y: self.y.negate(1).normalize_weak(),
179
0
            infinity: self.infinity,
180
0
        }
181
0
    }
182
}
183
184
impl DecompressPoint<Secp256k1> for AffinePoint {
185
735
    fn decompress(x_bytes: &FieldBytes, y_is_odd: Choice) -> CtOption<Self> {
186
735
        FieldElement::from_bytes(x_bytes).and_then(|x| {
187
735
            let alpha = (x * &x * &x) + &CURVE_EQUATION_B;
188
735
            let beta = alpha.sqrt();
189
735
190
735
            beta.map(|beta| {
191
735
                let beta = beta.normalize(); // Need to normalize for is_odd() to be consistent
192
735
                let y = FieldElement::conditional_select(
193
735
                    &beta.negate(1),
194
735
                    &beta,
195
735
                    beta.is_odd().ct_eq(&y_is_odd),
196
735
                );
197
735
198
735
                Self::new(x, y.normalize())
199
735
            })
200
735
        })
201
735
    }
202
}
203
204
/// Decompaction using Taproot conventions as described in [BIP 340].
205
///
206
/// [BIP 340]: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
207
impl DecompactPoint<Secp256k1> for AffinePoint {
208
10
    fn decompact(x_bytes: &FieldBytes) -> CtOption<Self> {
209
10
        Self::decompress(x_bytes, Choice::from(0))
210
10
    }
211
}
212
213
impl GroupEncoding for AffinePoint {
214
    type Repr = CompressedPoint;
215
216
0
    fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
217
0
        EncodedPoint::from_bytes(bytes)
218
0
            .map(|point| CtOption::new(point, Choice::from(1)))
219
0
            .unwrap_or_else(|_| {
220
0
                // SEC1 identity encoding is technically 1-byte 0x00, but the
221
0
                // `GroupEncoding` API requires a fixed-width `Repr`
222
0
                let is_identity = bytes.ct_eq(&Self::Repr::default());
223
0
                CtOption::new(EncodedPoint::identity(), is_identity)
224
0
            })
225
0
            .and_then(|point| Self::from_encoded_point(&point))
226
0
    }
227
228
0
    fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
229
0
        // No unchecked conversion possible for compressed points
230
0
        Self::from_bytes(bytes)
231
0
    }
232
233
0
    fn to_bytes(&self) -> Self::Repr {
234
0
        let encoded = self.to_encoded_point(true);
235
0
        let mut result = CompressedPoint::default();
236
0
        result[..encoded.len()].copy_from_slice(encoded.as_bytes());
237
0
        result
238
0
    }
239
}
240
241
impl FromEncodedPoint<Secp256k1> for AffinePoint {
242
    /// Attempts to parse the given [`EncodedPoint`] as an SEC1-encoded [`AffinePoint`].
243
    ///
244
    /// # Returns
245
    ///
246
    /// `None` value if `encoded_point` is not on the secp256k1 curve.
247
1.27k
    fn from_encoded_point(encoded_point: &EncodedPoint) -> CtOption<Self> {
248
1.27k
        match encoded_point.coordinates() {
249
10
            sec1::Coordinates::Identity => CtOption::new(Self::IDENTITY, 1.into()),
250
10
            sec1::Coordinates::Compact { x } => Self::decompact(x),
251
725
            sec1::Coordinates::Compressed { x, y_is_odd } => {
252
725
                AffinePoint::decompress(x, Choice::from(y_is_odd as u8))
253
            }
254
528
            sec1::Coordinates::Uncompressed { x, y } => {
255
528
                let x = FieldElement::from_bytes(x);
256
528
                let y = FieldElement::from_bytes(y);
257
528
258
528
                x.and_then(|x| {
259
528
                    y.and_then(|y| {
260
528
                        // Check that the point is on the curve
261
528
                        let lhs = (y * &y).negate(1);
262
528
                        let rhs = x * &x * &x + &CURVE_EQUATION_B;
263
528
                        let point = Self::new(x, y);
264
528
                        CtOption::new(point, (lhs + &rhs).normalizes_to_zero())
265
528
                    })
266
528
                })
267
            }
268
        }
269
1.27k
    }
270
}
271
272
impl ToEncodedPoint<Secp256k1> for AffinePoint {
273
0
    fn to_encoded_point(&self, compress: bool) -> EncodedPoint {
274
0
        EncodedPoint::conditional_select(
275
0
            &EncodedPoint::from_affine_coordinates(
276
0
                &self.x.to_bytes(),
277
0
                &self.y.to_bytes(),
278
0
                compress,
279
0
            ),
280
0
            &EncodedPoint::identity(),
281
0
            self.is_identity(),
282
0
        )
283
0
    }
284
}
285
286
impl TryFrom<EncodedPoint> for AffinePoint {
287
    type Error = Error;
288
289
0
    fn try_from(point: EncodedPoint) -> Result<AffinePoint> {
290
0
        AffinePoint::try_from(&point)
291
0
    }
292
}
293
294
impl TryFrom<&EncodedPoint> for AffinePoint {
295
    type Error = Error;
296
297
0
    fn try_from(point: &EncodedPoint) -> Result<AffinePoint> {
298
0
        Option::from(AffinePoint::from_encoded_point(point)).ok_or(Error)
299
0
    }
300
}
301
302
impl From<AffinePoint> for EncodedPoint {
303
0
    fn from(affine_point: AffinePoint) -> EncodedPoint {
304
0
        EncodedPoint::from(&affine_point)
305
0
    }
306
}
307
308
impl From<&AffinePoint> for EncodedPoint {
309
0
    fn from(affine_point: &AffinePoint) -> EncodedPoint {
310
0
        affine_point.to_encoded_point(true)
311
0
    }
312
}
313
314
impl From<PublicKey> for AffinePoint {
315
0
    fn from(public_key: PublicKey) -> AffinePoint {
316
0
        *public_key.as_affine()
317
0
    }
318
}
319
320
impl From<&PublicKey> for AffinePoint {
321
0
    fn from(public_key: &PublicKey) -> AffinePoint {
322
0
        AffinePoint::from(*public_key)
323
0
    }
324
}
325
326
impl TryFrom<AffinePoint> for PublicKey {
327
    type Error = Error;
328
329
0
    fn try_from(affine_point: AffinePoint) -> Result<PublicKey> {
330
0
        PublicKey::from_affine(affine_point)
331
0
    }
332
}
333
334
impl TryFrom<&AffinePoint> for PublicKey {
335
    type Error = Error;
336
337
0
    fn try_from(affine_point: &AffinePoint) -> Result<PublicKey> {
338
0
        PublicKey::try_from(*affine_point)
339
0
    }
340
}
341
342
#[cfg(feature = "serde")]
343
impl Serialize for AffinePoint {
344
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
345
    where
346
        S: ser::Serializer,
347
    {
348
        self.to_encoded_point(true).serialize(serializer)
349
    }
350
}
351
352
#[cfg(feature = "serde")]
353
impl<'de> Deserialize<'de> for AffinePoint {
354
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
355
    where
356
        D: de::Deserializer<'de>,
357
    {
358
        EncodedPoint::deserialize(deserializer)?
359
            .try_into()
360
            .map_err(de::Error::custom)
361
    }
362
}
363
364
#[cfg(test)]
365
mod tests {
366
    use super::AffinePoint;
367
    use crate::EncodedPoint;
368
    use elliptic_curve::{
369
        group::{prime::PrimeCurveAffine, GroupEncoding},
370
        sec1::{FromEncodedPoint, ToEncodedPoint},
371
    };
372
    use hex_literal::hex;
373
374
    const UNCOMPRESSED_BASEPOINT: &[u8] = &hex!(
375
        "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
376
         483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"
377
    );
378
    const COMPRESSED_BASEPOINT: &[u8] =
379
        &hex!("0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798");
380
381
    #[test]
382
    fn uncompressed_round_trip() {
383
        let pubkey = EncodedPoint::from_bytes(UNCOMPRESSED_BASEPOINT).unwrap();
384
        let res: EncodedPoint = AffinePoint::from_encoded_point(&pubkey)
385
            .unwrap()
386
            .to_encoded_point(false);
387
388
        assert_eq!(res, pubkey);
389
    }
390
391
    #[test]
392
    fn compressed_round_trip() {
393
        let pubkey = EncodedPoint::from_bytes(COMPRESSED_BASEPOINT).unwrap();
394
        let res: EncodedPoint = AffinePoint::from_encoded_point(&pubkey)
395
            .unwrap()
396
            .to_encoded_point(true);
397
398
        assert_eq!(res, pubkey);
399
    }
400
401
    #[test]
402
    fn uncompressed_to_compressed() {
403
        let encoded = EncodedPoint::from_bytes(UNCOMPRESSED_BASEPOINT).unwrap();
404
405
        let res = AffinePoint::from_encoded_point(&encoded)
406
            .unwrap()
407
            .to_encoded_point(true);
408
409
        assert_eq!(res.as_bytes(), COMPRESSED_BASEPOINT);
410
    }
411
412
    #[test]
413
    fn compressed_to_uncompressed() {
414
        let encoded = EncodedPoint::from_bytes(COMPRESSED_BASEPOINT).unwrap();
415
416
        let res = AffinePoint::from_encoded_point(&encoded)
417
            .unwrap()
418
            .to_encoded_point(false);
419
420
        assert_eq!(res.as_bytes(), UNCOMPRESSED_BASEPOINT);
421
    }
422
423
    #[test]
424
    fn affine_negation() {
425
        let basepoint = AffinePoint::GENERATOR;
426
        assert_eq!((-(-basepoint)), basepoint);
427
    }
428
429
    #[test]
430
    fn identity_encoding() {
431
        // This is technically an invalid SEC1 encoding, but is preferable to panicking.
432
        assert_eq!([0; 33], AffinePoint::IDENTITY.to_bytes().as_slice());
433
        assert!(bool::from(
434
            AffinePoint::from_bytes(&AffinePoint::IDENTITY.to_bytes())
435
                .unwrap()
436
                .is_identity()
437
        ))
438
    }
439
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/arithmetic/field.rs
Line
Count
Source
1
//! Field arithmetic modulo p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
2
3
#![allow(clippy::assign_op_pattern, clippy::op_ref)]
4
5
use cfg_if::cfg_if;
6
7
cfg_if! {
8
    if #[cfg(target_pointer_width = "32")] {
9
        mod field_10x26;
10
    } else if #[cfg(target_pointer_width = "64")] {
11
        mod field_5x52;
12
    } else {
13
        compile_error!("unsupported target word size (i.e. target_pointer_width)");
14
    }
15
}
16
17
cfg_if! {
18
    if #[cfg(debug_assertions)] {
19
        mod field_impl;
20
        use field_impl::FieldElementImpl;
21
    } else {
22
        cfg_if! {
23
            if #[cfg(target_pointer_width = "32")] {
24
                use field_10x26::FieldElement10x26 as FieldElementImpl;
25
            } else if #[cfg(target_pointer_width = "64")] {
26
                use field_5x52::FieldElement5x52 as FieldElementImpl;
27
            } else {
28
                compile_error!("unsupported target word size (i.e. target_pointer_width)");
29
            }
30
        }
31
    }
32
}
33
34
use crate::FieldBytes;
35
use core::{
36
    iter::{Product, Sum},
37
    ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
38
};
39
use elliptic_curve::{
40
    ff::{self, Field, PrimeField},
41
    ops::Invert,
42
    rand_core::RngCore,
43
    subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
44
    zeroize::DefaultIsZeroes,
45
};
46
47
#[cfg(test)]
48
use num_bigint::{BigUint, ToBigUint};
49
50
/// An element in the finite field used for curve coordinates.
51
#[derive(Clone, Copy, Debug)]
52
pub struct FieldElement(FieldElementImpl);
53
54
impl FieldElement {
55
    /// Zero element.
56
    pub const ZERO: Self = Self(FieldElementImpl::ZERO);
57
58
    /// Multiplicative identity.
59
    pub const ONE: Self = Self(FieldElementImpl::ONE);
60
61
    /// Determine if this `FieldElement` is zero.
62
    ///
63
    /// # Returns
64
    ///
65
    /// If zero, return `Choice(1)`.  Otherwise, return `Choice(0)`.
66
0
    pub fn is_zero(&self) -> Choice {
67
0
        self.0.is_zero()
68
0
    }
69
70
    /// Determine if this `FieldElement` is even in the SEC1 sense: `self mod 2 == 0`.
71
    ///
72
    /// # Returns
73
    ///
74
    /// If even, return `Choice(1)`.  Otherwise, return `Choice(0)`.
75
0
    pub fn is_even(&self) -> Choice {
76
0
        !self.0.is_odd()
77
0
    }
78
79
    /// Determine if this `FieldElement` is odd in the SEC1 sense: `self mod 2 == 1`.
80
    ///
81
    /// # Returns
82
    ///
83
    /// If odd, return `Choice(1)`.  Otherwise, return `Choice(0)`.
84
735
    pub fn is_odd(&self) -> Choice {
85
735
        self.0.is_odd()
86
735
    }
87
88
    /// Attempts to parse the given byte array as an SEC1-encoded field element.
89
    /// Does not check the result for being in the correct range.
90
0
    pub(crate) const fn from_bytes_unchecked(bytes: &[u8; 32]) -> Self {
91
0
        Self(FieldElementImpl::from_bytes_unchecked(bytes))
92
0
    }
93
94
    /// Attempts to parse the given byte array as an SEC1-encoded field element.
95
    ///
96
    /// Returns None if the byte array does not contain a big-endian integer in the range
97
    /// [0, p).
98
1.79k
    pub fn from_bytes(bytes: &FieldBytes) -> CtOption<Self> {
99
1.79k
        FieldElementImpl::from_bytes(bytes).map(Self)
100
1.79k
    }
101
102
    /// Convert a `u64` to a field element.
103
0
    pub const fn from_u64(w: u64) -> Self {
104
0
        Self(FieldElementImpl::from_u64(w))
105
0
    }
106
107
    /// Returns the SEC1 encoding of this field element.
108
523
    pub fn to_bytes(self) -> FieldBytes {
109
523
        self.0.normalize().to_bytes()
110
523
    }
111
112
    /// Returns -self, treating it as a value of given magnitude.
113
    /// The provided magnitude must be equal or greater than the actual magnitude of `self`.
114
558k
    pub fn negate(&self, magnitude: u32) -> Self {
115
558k
        Self(self.0.negate(magnitude))
116
558k
    }
117
118
    /// Fully normalizes the field element.
119
    /// Brings the magnitude to 1 and modulo reduces the value.
120
2.51k
    pub fn normalize(&self) -> Self {
121
2.51k
        Self(self.0.normalize())
122
2.51k
    }
123
124
    /// Weakly normalizes the field element.
125
    /// Brings the magnitude to 1, but does not guarantee the value to be less than the modulus.
126
1.07M
    pub fn normalize_weak(&self) -> Self {
127
1.07M
        Self(self.0.normalize_weak())
128
1.07M
    }
129
130
    /// Checks if the field element becomes zero if normalized.
131
1.78k
    pub fn normalizes_to_zero(&self) -> Choice {
132
1.78k
        self.0.normalizes_to_zero()
133
1.78k
    }
134
135
    /// Multiplies by a single-limb integer.
136
    /// Multiplies the magnitude by the same value.
137
384k
    pub fn mul_single(&self, rhs: u32) -> Self {
138
384k
        Self(self.0.mul_single(rhs))
139
384k
    }
140
141
    /// Returns 2*self.
142
    /// Doubles the magnitude.
143
1.00M
    pub fn double(&self) -> Self {
144
1.00M
        Self(self.0.add(&(self.0)))
145
1.00M
    }
146
147
    /// Returns self * rhs mod p
148
    /// Brings the magnitude to 1 (but doesn't normalize the result).
149
    /// The magnitudes of arguments should be <= 8.
150
0
    pub fn mul(&self, rhs: &Self) -> Self {
151
0
        Self(self.0.mul(&(rhs.0)))
152
0
    }
153
154
    /// Returns self * self.
155
    ///
156
    /// Brings the magnitude to 1 (but doesn't normalize the result).
157
    /// The magnitudes of arguments should be <= 8.
158
453k
    pub fn square(&self) -> Self {
159
453k
        Self(self.0.square())
160
453k
    }
161
162
    /// Raises the scalar to the power `2^k`
163
18.1k
    fn pow2k(&self, k: usize) -> Self {
164
18.1k
        let mut x = *self;
165
319k
        for _j in 0..k {
166
319k
            x = x.square();
167
319k
        }
168
18.1k
        x
169
18.1k
    }
170
171
    /// Returns the multiplicative inverse of self, if self is non-zero.
172
    /// The result has magnitude 1, but is not normalized.
173
523
    pub fn invert(&self) -> CtOption<Self> {
174
523
        // The binary representation of (p - 2) has 5 blocks of 1s, with lengths in
175
523
        // { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block:
176
523
        // [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
177
523
178
523
        let x2 = self.pow2k(1).mul(self);
179
523
        let x3 = x2.pow2k(1).mul(self);
180
523
        let x6 = x3.pow2k(3).mul(&x3);
181
523
        let x9 = x6.pow2k(3).mul(&x3);
182
523
        let x11 = x9.pow2k(2).mul(&x2);
183
523
        let x22 = x11.pow2k(11).mul(&x11);
184
523
        let x44 = x22.pow2k(22).mul(&x22);
185
523
        let x88 = x44.pow2k(44).mul(&x44);
186
523
        let x176 = x88.pow2k(88).mul(&x88);
187
523
        let x220 = x176.pow2k(44).mul(&x44);
188
523
        let x223 = x220.pow2k(3).mul(&x3);
189
523
190
523
        // The final result is then assembled using a sliding window over the blocks.
191
523
        let res = x223
192
523
            .pow2k(23)
193
523
            .mul(&x22)
194
523
            .pow2k(5)
195
523
            .mul(self)
196
523
            .pow2k(3)
197
523
            .mul(&x2)
198
523
            .pow2k(2)
199
523
            .mul(self);
200
523
201
523
        CtOption::new(res, !self.normalizes_to_zero())
202
523
    }
203
204
    /// Returns the square root of self mod p, or `None` if no square root exists.
205
    /// The result has magnitude 1, but is not normalized.
206
735
    pub fn sqrt(&self) -> CtOption<Self> {
207
735
        /*
208
735
        Given that p is congruent to 3 mod 4, we can compute the square root of
209
735
        a mod p as the (p+1)/4'th power of a.
210
735
211
735
        As (p+1)/4 is an even number, it will have the same result for a and for
212
735
        (-a). Only one of these two numbers actually has a square root however,
213
735
        so we test at the end by squaring and comparing to the input.
214
735
        Also because (p+1)/4 is an even number, the computed square root is
215
735
        itself always a square (a ** ((p+1)/4) is the square of a ** ((p+1)/8)).
216
735
        */
217
735
218
735
        // The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in
219
735
        // { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block:
220
735
        // 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
221
735
222
735
        let x2 = self.pow2k(1).mul(self);
223
735
        let x3 = x2.pow2k(1).mul(self);
224
735
        let x6 = x3.pow2k(3).mul(&x3);
225
735
        let x9 = x6.pow2k(3).mul(&x3);
226
735
        let x11 = x9.pow2k(2).mul(&x2);
227
735
        let x22 = x11.pow2k(11).mul(&x11);
228
735
        let x44 = x22.pow2k(22).mul(&x22);
229
735
        let x88 = x44.pow2k(44).mul(&x44);
230
735
        let x176 = x88.pow2k(88).mul(&x88);
231
735
        let x220 = x176.pow2k(44).mul(&x44);
232
735
        let x223 = x220.pow2k(3).mul(&x3);
233
735
234
735
        // The final result is then assembled using a sliding window over the blocks.
235
735
        let res = x223.pow2k(23).mul(&x22).pow2k(6).mul(&x2).pow2k(2);
236
735
237
735
        let is_root = (res.mul(&res).negate(1) + self).normalizes_to_zero();
238
735
239
735
        // Only return Some if it's the square root.
240
735
        CtOption::new(res, is_root)
241
735
    }
242
243
    #[cfg(test)]
244
    pub fn modulus_as_biguint() -> BigUint {
245
        Self::ONE.negate(1).to_biguint().unwrap() + 1.to_biguint().unwrap()
246
    }
247
}
248
249
impl Invert for FieldElement {
250
    type Output = CtOption<Self>;
251
252
0
    fn invert(&self) -> CtOption<Self> {
253
0
        self.invert()
254
0
    }
255
}
256
257
impl Field for FieldElement {
258
    const ZERO: Self = Self::ZERO;
259
    const ONE: Self = Self::ONE;
260
261
0
    fn random(mut rng: impl RngCore) -> Self {
262
0
        let mut bytes = FieldBytes::default();
263
264
        loop {
265
0
            rng.fill_bytes(&mut bytes);
266
0
            if let Some(fe) = Self::from_bytes(&bytes).into() {
267
0
                return fe;
268
0
            }
269
        }
270
0
    }
271
272
    #[must_use]
273
0
    fn square(&self) -> Self {
274
0
        self.square()
275
0
    }
276
277
    #[must_use]
278
0
    fn double(&self) -> Self {
279
0
        self.double()
280
0
    }
281
282
0
    fn invert(&self) -> CtOption<Self> {
283
0
        self.invert()
284
0
    }
285
286
0
    fn sqrt(&self) -> CtOption<Self> {
287
0
        self.sqrt()
288
0
    }
289
290
0
    fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
291
0
        ff::helpers::sqrt_ratio_generic(num, div)
292
0
    }
293
}
294
295
impl PrimeField for FieldElement {
296
    type Repr = FieldBytes;
297
298
    const MODULUS: &'static str =
299
        "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f";
300
    const NUM_BITS: u32 = 256;
301
    const CAPACITY: u32 = 255;
302
    const TWO_INV: Self = Self(FieldElementImpl::from_bytes_unchecked(&[
303
        0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
304
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff,
305
        0xfe, 0x18,
306
    ]));
307
    const MULTIPLICATIVE_GENERATOR: Self = Self::from_u64(3);
308
    const S: u32 = 1;
309
    const ROOT_OF_UNITY: Self = Self(FieldElementImpl::from_bytes_unchecked(&[
310
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
311
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
312
        0xfc, 0x2e,
313
    ]));
314
    const ROOT_OF_UNITY_INV: Self = Self(FieldElementImpl::from_bytes_unchecked(&[
315
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
316
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
317
        0xfc, 0x2e,
318
    ]));
319
    const DELTA: Self = Self::from_u64(9);
320
321
0
    fn from_repr(repr: Self::Repr) -> CtOption<Self> {
322
0
        Self::from_bytes(&repr)
323
0
    }
324
325
0
    fn to_repr(&self) -> Self::Repr {
326
0
        self.to_bytes()
327
0
    }
328
329
0
    fn is_odd(&self) -> Choice {
330
0
        self.is_odd()
331
0
    }
332
}
333
334
impl ConditionallySelectable for FieldElement {
335
    #[inline(always)]
336
1.87M
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
337
1.87M
        Self(FieldElementImpl::conditional_select(&(a.0), &(b.0), choice))
338
1.87M
    }
339
}
340
341
impl ConstantTimeEq for FieldElement {
342
0
    fn ct_eq(&self, other: &Self) -> Choice {
343
0
        self.0.ct_eq(&(other.0))
344
0
    }
345
}
346
347
impl Default for FieldElement {
348
3.04k
    fn default() -> Self {
349
3.04k
        Self::ZERO
350
3.04k
    }
351
}
352
353
impl DefaultIsZeroes for FieldElement {}
354
355
impl Eq for FieldElement {}
356
357
impl From<u64> for FieldElement {
358
0
    fn from(k: u64) -> Self {
359
0
        Self(FieldElementImpl::from_u64(k))
360
0
    }
361
}
362
363
impl PartialEq for FieldElement {
364
0
    fn eq(&self, other: &Self) -> bool {
365
0
        self.0.ct_eq(&(other.0)).into()
366
0
    }
367
}
368
369
impl Add<FieldElement> for FieldElement {
370
    type Output = FieldElement;
371
372
0
    fn add(self, other: FieldElement) -> FieldElement {
373
0
        FieldElement(self.0.add(&(other.0)))
374
0
    }
375
}
376
377
impl Add<&FieldElement> for FieldElement {
378
    type Output = FieldElement;
379
380
2.16M
    fn add(self, other: &FieldElement) -> FieldElement {
381
2.16M
        FieldElement(self.0.add(&(other.0)))
382
2.16M
    }
383
}
384
385
impl Add<&FieldElement> for &FieldElement {
386
    type Output = FieldElement;
387
388
0
    fn add(self, other: &FieldElement) -> FieldElement {
389
0
        FieldElement(self.0.add(&(other.0)))
390
0
    }
391
}
392
393
impl AddAssign<FieldElement> for FieldElement {
394
0
    fn add_assign(&mut self, other: FieldElement) {
395
0
        *self = *self + &other;
396
0
    }
397
}
398
399
impl AddAssign<&FieldElement> for FieldElement {
400
0
    fn add_assign(&mut self, other: &FieldElement) {
401
0
        *self = *self + other;
402
0
    }
403
}
404
405
impl Sub<FieldElement> for FieldElement {
406
    type Output = FieldElement;
407
408
0
    fn sub(self, other: FieldElement) -> FieldElement {
409
0
        self + -other
410
0
    }
411
}
412
413
impl Sub<&FieldElement> for FieldElement {
414
    type Output = FieldElement;
415
416
0
    fn sub(self, other: &FieldElement) -> FieldElement {
417
0
        self + -other
418
0
    }
419
}
420
421
impl SubAssign<FieldElement> for FieldElement {
422
0
    fn sub_assign(&mut self, other: FieldElement) {
423
0
        *self = *self + -other;
424
0
    }
425
}
426
427
impl SubAssign<&FieldElement> for FieldElement {
428
0
    fn sub_assign(&mut self, other: &FieldElement) {
429
0
        *self = *self + -other;
430
0
    }
431
}
432
433
impl Mul<FieldElement> for FieldElement {
434
    type Output = FieldElement;
435
436
0
    fn mul(self, other: FieldElement) -> FieldElement {
437
0
        FieldElement(self.0.mul(&(other.0)))
438
0
    }
439
}
440
441
impl Mul<&FieldElement> for FieldElement {
442
    type Output = FieldElement;
443
444
    #[inline(always)]
445
1.42M
    fn mul(self, other: &FieldElement) -> FieldElement {
446
1.42M
        FieldElement(self.0.mul(&(other.0)))
447
1.42M
    }
448
}
449
450
impl Mul<&FieldElement> for &FieldElement {
451
    type Output = FieldElement;
452
453
0
    fn mul(self, other: &FieldElement) -> FieldElement {
454
0
        FieldElement(self.0.mul(&(other.0)))
455
0
    }
456
}
457
458
impl MulAssign<FieldElement> for FieldElement {
459
0
    fn mul_assign(&mut self, rhs: FieldElement) {
460
0
        *self = *self * &rhs;
461
0
    }
462
}
463
464
impl MulAssign<&FieldElement> for FieldElement {
465
0
    fn mul_assign(&mut self, rhs: &FieldElement) {
466
0
        *self = *self * rhs;
467
0
    }
468
}
469
470
impl Neg for FieldElement {
471
    type Output = FieldElement;
472
473
0
    fn neg(self) -> FieldElement {
474
0
        self.negate(1)
475
0
    }
476
}
477
478
impl Neg for &FieldElement {
479
    type Output = FieldElement;
480
481
0
    fn neg(self) -> FieldElement {
482
0
        self.negate(1)
483
0
    }
484
}
485
486
impl Sum for FieldElement {
487
0
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
488
0
        iter.reduce(core::ops::Add::add).unwrap_or(Self::ZERO)
489
0
    }
490
}
491
492
impl<'a> Sum<&'a FieldElement> for FieldElement {
493
    #[inline]
494
0
    fn sum<I: Iterator<Item = &'a FieldElement>>(iter: I) -> Self {
495
0
        iter.copied().sum()
496
0
    }
497
}
498
499
impl Product for FieldElement {
500
0
    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
501
0
        iter.reduce(core::ops::Mul::mul).unwrap_or(Self::ONE)
502
0
    }
503
}
504
505
impl<'a> Product<&'a FieldElement> for FieldElement {
506
0
    fn product<I: Iterator<Item = &'a FieldElement>>(iter: I) -> Self {
507
0
        iter.copied().product()
508
0
    }
509
}
510
511
#[cfg(test)]
512
mod tests {
513
    use elliptic_curve::ff::{Field, PrimeField};
514
    use elliptic_curve::ops::BatchInvert;
515
    use num_bigint::{BigUint, ToBigUint};
516
    use proptest::prelude::*;
517
    use rand_core::OsRng;
518
519
    use super::FieldElement;
520
    use crate::{
521
        arithmetic::dev::{biguint_to_bytes, bytes_to_biguint},
522
        test_vectors::field::DBL_TEST_VECTORS,
523
        FieldBytes,
524
    };
525
526
    #[cfg(feature = "alloc")]
527
    use alloc::vec::Vec;
528
529
    impl From<&BigUint> for FieldElement {
530
        fn from(x: &BigUint) -> Self {
531
            let bytes = biguint_to_bytes(x);
532
            Self::from_bytes(&bytes.into()).unwrap()
533
        }
534
    }
535
536
    impl ToBigUint for FieldElement {
537
        fn to_biguint(&self) -> Option<BigUint> {
538
            Some(bytes_to_biguint(self.to_bytes().as_ref()))
539
        }
540
    }
541
542
    /// t = (modulus - 1) >> S
543
    const T: [u64; 4] = [
544
        0xffffffff7ffffe17,
545
        0xffffffffffffffff,
546
        0xffffffffffffffff,
547
        0x7fffffffffffffff,
548
    ];
549
550
    #[test]
551
    fn two_inv_constant() {
552
        assert_eq!(
553
            (FieldElement::from(2u64) * FieldElement::TWO_INV).normalize(),
554
            FieldElement::ONE
555
        );
556
    }
557
558
    #[test]
559
    fn root_of_unity_constant() {
560
        // ROOT_OF_UNITY^{2^s} mod m == 1
561
        assert_eq!(
562
            FieldElement::ROOT_OF_UNITY
563
                .pow_vartime(&[1u64 << FieldElement::S, 0, 0, 0])
564
                .normalize(),
565
            FieldElement::ONE
566
        );
567
568
        // MULTIPLICATIVE_GENERATOR^{t} mod m == ROOT_OF_UNITY
569
        assert_eq!(
570
            FieldElement::MULTIPLICATIVE_GENERATOR
571
                .pow_vartime(&T)
572
                .normalize(),
573
            FieldElement::ROOT_OF_UNITY
574
        )
575
    }
576
577
    #[test]
578
    fn root_of_unity_inv_constant() {
579
        assert_eq!(
580
            (FieldElement::ROOT_OF_UNITY * FieldElement::ROOT_OF_UNITY_INV).normalize(),
581
            FieldElement::ONE
582
        );
583
    }
584
585
    #[test]
586
    fn delta_constant() {
587
        // DELTA^{t} mod m == 1
588
        assert_eq!(
589
            FieldElement::DELTA.pow_vartime(&T).normalize(),
590
            FieldElement::ONE
591
        );
592
    }
593
594
    #[test]
595
    fn zero_is_additive_identity() {
596
        let zero = FieldElement::ZERO;
597
        let one = FieldElement::ONE;
598
        assert_eq!((zero + &zero).normalize(), zero);
599
        assert_eq!((one + &zero).normalize(), one);
600
    }
601
602
    #[test]
603
    fn one_is_multiplicative_identity() {
604
        let one = FieldElement::ONE;
605
        assert_eq!((one * &one).normalize(), one);
606
    }
607
608
    #[test]
609
    fn from_bytes() {
610
        assert_eq!(
611
            FieldElement::from_bytes(&FieldBytes::default()).unwrap(),
612
            FieldElement::ZERO
613
        );
614
        assert_eq!(
615
            FieldElement::from_bytes(
616
                &[
617
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
618
                    0, 0, 0, 0, 0, 1
619
                ]
620
                .into()
621
            )
622
            .unwrap(),
623
            FieldElement::ONE
624
        );
625
        assert!(bool::from(
626
            FieldElement::from_bytes(&[0xff; 32].into()).is_none()
627
        ));
628
    }
629
630
    #[test]
631
    fn to_bytes() {
632
        assert_eq!(FieldElement::ZERO.to_bytes(), [0; 32].into());
633
        assert_eq!(
634
            FieldElement::ONE.to_bytes(),
635
            [
636
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
637
                0, 0, 0, 1
638
            ]
639
            .into()
640
        );
641
    }
642
643
    #[test]
644
    fn repeated_add() {
645
        let mut r = FieldElement::ONE;
646
        for i in 0..DBL_TEST_VECTORS.len() {
647
            assert_eq!(r.to_bytes(), DBL_TEST_VECTORS[i].into());
648
            r = (r + &r).normalize();
649
        }
650
    }
651
652
    #[test]
653
    fn repeated_double() {
654
        let mut r = FieldElement::ONE;
655
        for i in 0..DBL_TEST_VECTORS.len() {
656
            assert_eq!(r.to_bytes(), DBL_TEST_VECTORS[i].into());
657
            r = r.double().normalize();
658
        }
659
    }
660
661
    #[test]
662
    fn repeated_mul() {
663
        let mut r = FieldElement::ONE;
664
        let two = r + &r;
665
        for i in 0..DBL_TEST_VECTORS.len() {
666
            assert_eq!(r.normalize().to_bytes(), DBL_TEST_VECTORS[i].into());
667
            r = r * &two;
668
        }
669
    }
670
671
    #[test]
672
    fn negation() {
673
        let two = FieldElement::ONE.double();
674
        let neg_two = two.negate(2);
675
        assert_eq!((two + &neg_two).normalize(), FieldElement::ZERO);
676
        assert_eq!(neg_two.negate(3).normalize(), two.normalize());
677
    }
678
679
    #[test]
680
    fn invert() {
681
        assert!(bool::from(FieldElement::ZERO.invert().is_none()));
682
683
        let one = FieldElement::ONE;
684
        assert_eq!(one.invert().unwrap().normalize(), one);
685
686
        let two = one + &one;
687
        let inv_two = two.invert().unwrap();
688
        assert_eq!((two * &inv_two).normalize(), one);
689
    }
690
691
    #[test]
692
    fn batch_invert_array() {
693
        let k: FieldElement = FieldElement::random(&mut OsRng);
694
        let l: FieldElement = FieldElement::random(&mut OsRng);
695
696
        let expected = [k.invert().unwrap(), l.invert().unwrap()];
697
        assert_eq!(
698
            <FieldElement as BatchInvert<_>>::batch_invert(&[k, l]).unwrap(),
699
            expected
700
        );
701
    }
702
703
    #[test]
704
    #[cfg(feature = "alloc")]
705
    fn batch_invert() {
706
        let k: FieldElement = FieldElement::random(&mut OsRng);
707
        let l: FieldElement = FieldElement::random(&mut OsRng);
708
709
        let expected = vec![k.invert().unwrap(), l.invert().unwrap()];
710
        let field_elements = vec![k, l];
711
        let res: Vec<_> =
712
            <FieldElement as BatchInvert<_>>::batch_invert(field_elements.as_slice()).unwrap();
713
        assert_eq!(res, expected);
714
    }
715
716
    #[test]
717
    fn sqrt() {
718
        let one = FieldElement::ONE;
719
        let two = one + &one;
720
        let four = two.square();
721
        assert_eq!(four.sqrt().unwrap().normalize(), two.normalize());
722
    }
723
724
    #[test]
725
    #[cfg_attr(
726
        debug_assertions,
727
        should_panic(expected = "assertion failed: self.normalized")
728
    )]
729
    fn unnormalized_is_odd() {
730
        // This is a regression test for https://github.com/RustCrypto/elliptic-curves/issues/529
731
        // where `is_odd()` in debug mode force-normalized its argument
732
        // instead of checking that it is already normalized.
733
        // As a result, in release (where normalization didn't happen) `is_odd()`
734
        // could return an incorrect value.
735
736
        let x = FieldElement::from_bytes_unchecked(&[
737
            61, 128, 156, 189, 241, 12, 174, 4, 80, 52, 238, 78, 188, 251, 9, 188, 95, 115, 38, 6,
738
            212, 168, 175, 174, 211, 232, 208, 14, 182, 45, 59, 122,
739
        ]);
740
        // Produces an unnormalized FieldElement with magnitude 1
741
        // (we cannot create one directly).
742
        let y = x.sqrt().unwrap();
743
744
        // This is fine.
745
        assert!(y.normalize().is_odd().unwrap_u8() == 0);
746
747
        // This panics since `y` is not normalized.
748
        let _result = y.is_odd();
749
    }
750
751
    prop_compose! {
752
        fn field_element()(bytes in any::<[u8; 32]>()) -> FieldElement {
753
            let mut res = bytes_to_biguint(&bytes);
754
            let m = FieldElement::modulus_as_biguint();
755
            // Modulus is 256 bit long, same as the maximum `res`,
756
            // so this is guaranteed to land us in the correct range.
757
            if res >= m {
758
                res -= m;
759
            }
760
            FieldElement::from(&res)
761
        }
762
    }
763
764
    proptest! {
765
766
        #[test]
767
        fn fuzzy_add(
768
            a in field_element(),
769
            b in field_element()
770
        ) {
771
            let a_bi = a.to_biguint().unwrap();
772
            let b_bi = b.to_biguint().unwrap();
773
            let res_bi = (&a_bi + &b_bi) % FieldElement::modulus_as_biguint();
774
            let res_ref = FieldElement::from(&res_bi);
775
            let res_test = (&a + &b).normalize();
776
            assert_eq!(res_test, res_ref);
777
        }
778
779
        #[test]
780
        fn fuzzy_mul(
781
            a in field_element(),
782
            b in field_element()
783
        ) {
784
            let a_bi = a.to_biguint().unwrap();
785
            let b_bi = b.to_biguint().unwrap();
786
            let res_bi = (&a_bi * &b_bi) % FieldElement::modulus_as_biguint();
787
            let res_ref = FieldElement::from(&res_bi);
788
            let res_test = (&a * &b).normalize();
789
            assert_eq!(res_test, res_ref);
790
        }
791
792
        #[test]
793
        fn fuzzy_square(
794
            a in field_element()
795
        ) {
796
            let a_bi = a.to_biguint().unwrap();
797
            let res_bi = (&a_bi * &a_bi) % FieldElement::modulus_as_biguint();
798
            let res_ref = FieldElement::from(&res_bi);
799
            let res_test = a.square().normalize();
800
            assert_eq!(res_test, res_ref);
801
        }
802
803
        #[test]
804
        fn fuzzy_negate(
805
            a in field_element()
806
        ) {
807
            let m = FieldElement::modulus_as_biguint();
808
            let a_bi = a.to_biguint().unwrap();
809
            let res_bi = (&m - &a_bi) % &m;
810
            let res_ref = FieldElement::from(&res_bi);
811
            let res_test = a.negate(1).normalize();
812
            assert_eq!(res_test, res_ref);
813
        }
814
815
        #[test]
816
        fn fuzzy_sqrt(
817
            a in field_element()
818
        ) {
819
            let m = FieldElement::modulus_as_biguint();
820
            let a_bi = a.to_biguint().unwrap();
821
            let sqr_bi = (&a_bi * &a_bi) % &m;
822
            let sqr = FieldElement::from(&sqr_bi);
823
824
            let res_ref1 = a;
825
            let possible_sqrt = (&m - &a_bi) % &m;
826
            let res_ref2 = FieldElement::from(&possible_sqrt);
827
            let res_test = sqr.sqrt().unwrap().normalize();
828
            // FIXME: is there a rule which square root is returned?
829
            assert!(res_test == res_ref1 || res_test == res_ref2);
830
        }
831
832
        #[test]
833
        fn fuzzy_invert(
834
            a in field_element()
835
        ) {
836
            let a = if bool::from(a.is_zero()) { FieldElement::ONE } else { a };
837
            let a_bi = a.to_biguint().unwrap();
838
            let inv = a.invert().unwrap().normalize();
839
            let inv_bi = inv.to_biguint().unwrap();
840
            let m = FieldElement::modulus_as_biguint();
841
            assert_eq!((&inv_bi * &a_bi) % &m, 1.to_biguint().unwrap());
842
        }
843
    }
844
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/arithmetic/field/field_5x52.rs
Line
Count
Source
1
//! Field element modulo the curve internal modulus using 64-bit limbs.
2
//! Inspired by the implementation in <https://github.com/bitcoin-core/secp256k1>
3
4
use crate::FieldBytes;
5
use elliptic_curve::{
6
    subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
7
    zeroize::Zeroize,
8
};
9
10
/// Scalars modulo SECP256k1 modulus (2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1).
11
/// Uses 5 64-bit limbs (little-endian), where in the normalized form
12
/// first 4 contain 52 bits of the value each, and the last one contains 48 bits.
13
/// CurveArithmetic operations can be done without modulo reduction for some time,
14
/// using the remaining overflow bits.
15
#[derive(Clone, Copy, Debug)]
16
pub struct FieldElement5x52(pub(crate) [u64; 5]);
17
18
impl FieldElement5x52 {
19
    /// Zero element.
20
    pub const ZERO: Self = Self([0, 0, 0, 0, 0]);
21
22
    /// Multiplicative identity.
23
    pub const ONE: Self = Self([1, 0, 0, 0, 0]);
24
25
    /// Attempts to parse the given byte array as an SEC1-encoded field element.
26
    /// Does not check the result for being in the correct range.
27
1.79k
    pub(crate) const fn from_bytes_unchecked(bytes: &[u8; 32]) -> Self {
28
1.79k
        let w0 = (bytes[31] as u64)
29
1.79k
            | ((bytes[30] as u64) << 8)
30
1.79k
            | ((bytes[29] as u64) << 16)
31
1.79k
            | ((bytes[28] as u64) << 24)
32
1.79k
            | ((bytes[27] as u64) << 32)
33
1.79k
            | ((bytes[26] as u64) << 40)
34
1.79k
            | (((bytes[25] & 0xFu8) as u64) << 48);
35
1.79k
36
1.79k
        let w1 = ((bytes[25] >> 4) as u64)
37
1.79k
            | ((bytes[24] as u64) << 4)
38
1.79k
            | ((bytes[23] as u64) << 12)
39
1.79k
            | ((bytes[22] as u64) << 20)
40
1.79k
            | ((bytes[21] as u64) << 28)
41
1.79k
            | ((bytes[20] as u64) << 36)
42
1.79k
            | ((bytes[19] as u64) << 44);
43
1.79k
44
1.79k
        let w2 = (bytes[18] as u64)
45
1.79k
            | ((bytes[17] as u64) << 8)
46
1.79k
            | ((bytes[16] as u64) << 16)
47
1.79k
            | ((bytes[15] as u64) << 24)
48
1.79k
            | ((bytes[14] as u64) << 32)
49
1.79k
            | ((bytes[13] as u64) << 40)
50
1.79k
            | (((bytes[12] & 0xFu8) as u64) << 48);
51
1.79k
52
1.79k
        let w3 = ((bytes[12] >> 4) as u64)
53
1.79k
            | ((bytes[11] as u64) << 4)
54
1.79k
            | ((bytes[10] as u64) << 12)
55
1.79k
            | ((bytes[9] as u64) << 20)
56
1.79k
            | ((bytes[8] as u64) << 28)
57
1.79k
            | ((bytes[7] as u64) << 36)
58
1.79k
            | ((bytes[6] as u64) << 44);
59
1.79k
60
1.79k
        let w4 = (bytes[5] as u64)
61
1.79k
            | ((bytes[4] as u64) << 8)
62
1.79k
            | ((bytes[3] as u64) << 16)
63
1.79k
            | ((bytes[2] as u64) << 24)
64
1.79k
            | ((bytes[1] as u64) << 32)
65
1.79k
            | ((bytes[0] as u64) << 40);
66
1.79k
67
1.79k
        Self([w0, w1, w2, w3, w4])
68
1.79k
    }
69
70
    /// Attempts to parse the given byte array as an SEC1-encoded field element.
71
    ///
72
    /// Returns None if the byte array does not contain a big-endian integer in the range
73
    /// [0, p).
74
    #[inline]
75
1.79k
    pub fn from_bytes(bytes: &FieldBytes) -> CtOption<Self> {
76
1.79k
        let res = Self::from_bytes_unchecked(bytes.as_ref());
77
1.79k
        let overflow = res.get_overflow();
78
1.79k
        CtOption::new(res, !overflow)
79
1.79k
    }
80
81
0
    pub const fn from_u64(val: u64) -> Self {
82
0
        let w0 = val & 0xFFFFFFFFFFFFF;
83
0
        let w1 = val >> 52;
84
0
        Self([w0, w1, 0, 0, 0])
85
0
    }
86
87
    /// Returns the SEC1 encoding of this field element.
88
523
    pub fn to_bytes(self) -> FieldBytes {
89
523
        let mut ret = FieldBytes::default();
90
523
        ret[0] = (self.0[4] >> 40) as u8;
91
523
        ret[1] = (self.0[4] >> 32) as u8;
92
523
        ret[2] = (self.0[4] >> 24) as u8;
93
523
        ret[3] = (self.0[4] >> 16) as u8;
94
523
        ret[4] = (self.0[4] >> 8) as u8;
95
523
        ret[5] = self.0[4] as u8;
96
523
        ret[6] = (self.0[3] >> 44) as u8;
97
523
        ret[7] = (self.0[3] >> 36) as u8;
98
523
        ret[8] = (self.0[3] >> 28) as u8;
99
523
        ret[9] = (self.0[3] >> 20) as u8;
100
523
        ret[10] = (self.0[3] >> 12) as u8;
101
523
        ret[11] = (self.0[3] >> 4) as u8;
102
523
        ret[12] = ((self.0[2] >> 48) as u8 & 0xFu8) | ((self.0[3] as u8 & 0xFu8) << 4);
103
523
        ret[13] = (self.0[2] >> 40) as u8;
104
523
        ret[14] = (self.0[2] >> 32) as u8;
105
523
        ret[15] = (self.0[2] >> 24) as u8;
106
523
        ret[16] = (self.0[2] >> 16) as u8;
107
523
        ret[17] = (self.0[2] >> 8) as u8;
108
523
        ret[18] = self.0[2] as u8;
109
523
        ret[19] = (self.0[1] >> 44) as u8;
110
523
        ret[20] = (self.0[1] >> 36) as u8;
111
523
        ret[21] = (self.0[1] >> 28) as u8;
112
523
        ret[22] = (self.0[1] >> 20) as u8;
113
523
        ret[23] = (self.0[1] >> 12) as u8;
114
523
        ret[24] = (self.0[1] >> 4) as u8;
115
523
        ret[25] = ((self.0[0] >> 48) as u8 & 0xFu8) | ((self.0[1] as u8 & 0xFu8) << 4);
116
523
        ret[26] = (self.0[0] >> 40) as u8;
117
523
        ret[27] = (self.0[0] >> 32) as u8;
118
523
        ret[28] = (self.0[0] >> 24) as u8;
119
523
        ret[29] = (self.0[0] >> 16) as u8;
120
523
        ret[30] = (self.0[0] >> 8) as u8;
121
523
        ret[31] = self.0[0] as u8;
122
523
        ret
123
523
    }
124
125
    /// Adds `x * (2^256 - modulus)`.
126
1.08M
    fn add_modulus_correction(&self, x: u64) -> Self {
127
1.08M
        // add (2^256 - modulus) * x to the first limb
128
1.08M
        let t0 = self.0[0] + x * 0x1000003D1u64;
129
1.08M
130
1.08M
        // Propagate excess bits up the limbs
131
1.08M
        let t1 = self.0[1] + (t0 >> 52);
132
1.08M
        let t0 = t0 & 0xFFFFFFFFFFFFFu64;
133
1.08M
134
1.08M
        let t2 = self.0[2] + (t1 >> 52);
135
1.08M
        let t1 = t1 & 0xFFFFFFFFFFFFFu64;
136
1.08M
137
1.08M
        let t3 = self.0[3] + (t2 >> 52);
138
1.08M
        let t2 = t2 & 0xFFFFFFFFFFFFFu64;
139
1.08M
140
1.08M
        let t4 = self.0[4] + (t3 >> 52);
141
1.08M
        let t3 = t3 & 0xFFFFFFFFFFFFFu64;
142
1.08M
143
1.08M
        Self([t0, t1, t2, t3, t4])
144
1.08M
    }
145
146
    /// Subtracts the overflow in the last limb and return it with the new field element.
147
    /// Equivalent to subtracting a multiple of 2^256.
148
1.08M
    fn subtract_modulus_approximation(&self) -> (Self, u64) {
149
1.08M
        let x = self.0[4] >> 48;
150
1.08M
        let t4 = self.0[4] & 0x0FFFFFFFFFFFFu64; // equivalent to self -= 2^256 * x
151
1.08M
        (Self([self.0[0], self.0[1], self.0[2], self.0[3], t4]), x)
152
1.08M
    }
153
154
    /// Checks if the field element is greater or equal to the modulus.
155
4.83k
    fn get_overflow(&self) -> Choice {
156
4.83k
        let m = self.0[1] & self.0[2] & self.0[3];
157
4.83k
        let x = (self.0[4] >> 48 != 0)
158
4.83k
            | ((self.0[4] == 0x0FFFFFFFFFFFFu64)
159
4.83k
                & (m == 0xFFFFFFFFFFFFFu64)
160
4.83k
                & (self.0[0] >= 0xFFFFEFFFFFC2Fu64));
161
4.83k
        Choice::from(x as u8)
162
4.83k
    }
163
164
    /// Brings the field element's magnitude to 1, but does not necessarily normalize it.
165
1.08M
    pub fn normalize_weak(&self) -> Self {
166
1.08M
        // Reduce t4 at the start so there will be at most a single carry from the first pass
167
1.08M
        let (t, x) = self.subtract_modulus_approximation();
168
1.08M
169
1.08M
        // The first pass ensures the magnitude is 1, ...
170
1.08M
        let res = t.add_modulus_correction(x);
171
1.08M
172
1.08M
        // ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element)
173
1.08M
        debug_assert!(res.0[4] >> 49 == 0);
174
175
1.08M
        res
176
1.08M
    }
177
178
    /// Fully normalizes the field element.
179
    /// That is, first four limbs are at most 52 bit large, the last limb is at most 48 bit large,
180
    /// and the value is less than the modulus.
181
3.03k
    pub fn normalize(&self) -> Self {
182
3.03k
        let res = self.normalize_weak();
183
3.03k
184
3.03k
        // At most a single final reduction is needed;
185
3.03k
        // check if the value is >= the field characteristic
186
3.03k
        let overflow = res.get_overflow();
187
3.03k
188
3.03k
        // Apply the final reduction (for constant-time behaviour, we do it always)
189
3.03k
        let res_corrected = res.add_modulus_correction(1u64);
190
3.03k
        // Mask off the possible multiple of 2^256 from the final reduction
191
3.03k
        let (res_corrected, x) = res_corrected.subtract_modulus_approximation();
192
3.03k
193
3.03k
        // If the last limb didn't carry to bit 48 already,
194
3.03k
        // then it should have after any final reduction
195
3.03k
        debug_assert!(x == (overflow.unwrap_u8() as u64));
196
197
3.03k
        Self::conditional_select(&res, &res_corrected, overflow)
198
3.03k
    }
199
200
    /// Checks if the field element becomes zero if normalized.
201
1.78k
    pub fn normalizes_to_zero(&self) -> Choice {
202
1.78k
        let res = self.normalize_weak();
203
1.78k
204
1.78k
        let t0 = res.0[0];
205
1.78k
        let t1 = res.0[1];
206
1.78k
        let t2 = res.0[2];
207
1.78k
        let t3 = res.0[3];
208
1.78k
        let t4 = res.0[4];
209
1.78k
210
1.78k
        // z0 tracks a possible raw value of 0, z1 tracks a possible raw value of the modulus
211
1.78k
        let z0 = t0 | t1 | t2 | t3 | t4;
212
1.78k
        let z1 = (t0 ^ 0x1000003D0u64) & t1 & t2 & t3 & (t4 ^ 0xF000000000000u64);
213
1.78k
214
1.78k
        Choice::from(((z0 == 0) | (z1 == 0xFFFFFFFFFFFFFu64)) as u8)
215
1.78k
    }
216
217
    /// Determine if this `FieldElement5x52` is zero.
218
    ///
219
    /// # Returns
220
    ///
221
    /// If zero, return `Choice(1)`.  Otherwise, return `Choice(0)`.
222
0
    pub fn is_zero(&self) -> Choice {
223
0
        Choice::from(((self.0[0] | self.0[1] | self.0[2] | self.0[3] | self.0[4]) == 0) as u8)
224
0
    }
225
226
    /// Determine if this `FieldElement5x52` is odd in the SEC1 sense: `self mod 2 == 1`.
227
    ///
228
    /// # Returns
229
    ///
230
    /// If odd, return `Choice(1)`.  Otherwise, return `Choice(0)`.
231
735
    pub fn is_odd(&self) -> Choice {
232
735
        (self.0[0] as u8 & 1).into()
233
735
    }
234
235
    /// The maximum number `m` for which `0xFFFFFFFFFFFFF * 2 * (m + 1) < 2^64`
236
    #[cfg(debug_assertions)]
237
8.21M
    pub const fn max_magnitude() -> u32 {
238
8.21M
        2047u32
239
8.21M
    }
240
241
    /// Returns -self, treating it as a value of given magnitude.
242
    /// The provided magnitude must be equal or greater than the actual magnitude of `self`.
243
    /// Raises the magnitude by 1.
244
558k
    pub const fn negate(&self, magnitude: u32) -> Self {
245
558k
        let m = (magnitude + 1) as u64;
246
558k
        let r0 = 0xFFFFEFFFFFC2Fu64 * 2 * m - self.0[0];
247
558k
        let r1 = 0xFFFFFFFFFFFFFu64 * 2 * m - self.0[1];
248
558k
        let r2 = 0xFFFFFFFFFFFFFu64 * 2 * m - self.0[2];
249
558k
        let r3 = 0xFFFFFFFFFFFFFu64 * 2 * m - self.0[3];
250
558k
        let r4 = 0x0FFFFFFFFFFFFu64 * 2 * m - self.0[4];
251
558k
        Self([r0, r1, r2, r3, r4])
252
558k
    }
253
254
    /// Returns self + rhs mod p.
255
    /// Sums the magnitudes.
256
3.16M
    pub const fn add(&self, rhs: &Self) -> Self {
257
3.16M
        Self([
258
3.16M
            self.0[0] + rhs.0[0],
259
3.16M
            self.0[1] + rhs.0[1],
260
3.16M
            self.0[2] + rhs.0[2],
261
3.16M
            self.0[3] + rhs.0[3],
262
3.16M
            self.0[4] + rhs.0[4],
263
3.16M
        ])
264
3.16M
    }
265
266
    /// Multiplies by a single-limb integer.
267
    /// Multiplies the magnitude by the same value.
268
384k
    pub const fn mul_single(&self, rhs: u32) -> Self {
269
384k
        let rhs_u64 = rhs as u64;
270
384k
        Self([
271
384k
            self.0[0] * rhs_u64,
272
384k
            self.0[1] * rhs_u64,
273
384k
            self.0[2] * rhs_u64,
274
384k
            self.0[3] * rhs_u64,
275
384k
            self.0[4] * rhs_u64,
276
384k
        ])
277
384k
    }
278
279
    #[inline(always)]
280
1.88M
    fn mul_inner(&self, rhs: &Self) -> Self {
281
1.88M
        /*
282
1.88M
        `square()` is just `mul()` with equal arguments. Rust compiler is smart enough
283
1.88M
        to do all the necessary optimizations for this case, but it needs to have this information
284
1.88M
        inside a function. If a function is just *called* with the same arguments,
285
1.88M
        this information cannot be used, so the function must be inlined while using the same arguments.
286
1.88M
287
1.88M
        Now `mul()` is quite long and therefore expensive to inline. So we have an inner (inlined)
288
1.88M
        function, that is used inside `mul()` and `square()`, and when it is used with the same
289
1.88M
        arguments in `square()`, compiler is able to use that fact after inlining.
290
1.88M
        */
291
1.88M
292
1.88M
        let a0 = self.0[0] as u128;
293
1.88M
        let a1 = self.0[1] as u128;
294
1.88M
        let a2 = self.0[2] as u128;
295
1.88M
        let a3 = self.0[3] as u128;
296
1.88M
        let a4 = self.0[4] as u128;
297
1.88M
        let b0 = rhs.0[0] as u128;
298
1.88M
        let b1 = rhs.0[1] as u128;
299
1.88M
        let b2 = rhs.0[2] as u128;
300
1.88M
        let b3 = rhs.0[3] as u128;
301
1.88M
        let b4 = rhs.0[4] as u128;
302
1.88M
        let m = 0xFFFFFFFFFFFFFu128;
303
1.88M
        let r = 0x1000003D10u128;
304
1.88M
305
1.88M
        debug_assert!(a0 >> 56 == 0);
306
1.88M
        debug_assert!(a1 >> 56 == 0);
307
1.88M
        debug_assert!(a2 >> 56 == 0);
308
1.88M
        debug_assert!(a3 >> 56 == 0);
309
1.88M
        debug_assert!(a4 >> 52 == 0);
310
311
1.88M
        debug_assert!(b0 >> 56 == 0);
312
1.88M
        debug_assert!(b1 >> 56 == 0);
313
1.88M
        debug_assert!(b2 >> 56 == 0);
314
1.88M
        debug_assert!(b3 >> 56 == 0);
315
1.88M
        debug_assert!(b4 >> 52 == 0);
316
317
        // [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n.
318
        // for 0 <= x <= 4, px is a shorthand for sum(a[i]*b[x-i], i=0..x).
319
        // for 4 <= x <= 8, px is a shorthand for sum(a[i]*b[x-i], i=(x-4)..4)
320
        // Note that [x 0 0 0 0 0] = [x*r].
321
322
1.88M
        let mut d = a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
323
1.88M
        debug_assert!(d >> 114 == 0);
324
        // [d 0 0 0] = [p3 0 0 0]
325
1.88M
        let mut c = a4 * b4;
326
1.88M
        debug_assert!(c >> 112 == 0);
327
        // [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0]
328
1.88M
        d += (c & m) * r;
329
1.88M
        c >>= 52;
330
1.88M
        debug_assert!(d >> 115 == 0);
331
1.88M
        debug_assert!(c >> 60 == 0);
332
1.88M
        let c64 = c as u64;
333
1.88M
        // [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0]
334
1.88M
        let t3 = (d & m) as u64;
335
1.88M
        d >>= 52;
336
1.88M
        debug_assert!(t3 >> 52 == 0);
337
1.88M
        debug_assert!(d >> 63 == 0);
338
1.88M
        let d64 = d as u64;
339
1.88M
        // [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0]
340
1.88M
341
1.88M
        d = d64 as u128 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
342
1.88M
        debug_assert!(d >> 115 == 0);
343
        // [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0]
344
1.88M
        d += c64 as u128 * r;
345
1.88M
        debug_assert!(d >> 116 == 0);
346
        // [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0]
347
1.88M
        let t4 = (d & m) as u64;
348
1.88M
        d >>= 52;
349
1.88M
        debug_assert!(t4 >> 52 == 0);
350
1.88M
        debug_assert!(d >> 64 == 0);
351
1.88M
        let d64 = d as u64;
352
1.88M
        // [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0]
353
1.88M
        let tx = t4 >> 48;
354
1.88M
        let t4 = t4 & ((m as u64) >> 4);
355
1.88M
        debug_assert!(tx >> 4 == 0);
356
1.88M
        debug_assert!(t4 >> 48 == 0);
357
        // [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0]
358
359
1.88M
        c = a0 * b0;
360
1.88M
        debug_assert!(c >> 112 == 0);
361
        // [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0]
362
1.88M
        d = d64 as u128 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1;
363
1.88M
        debug_assert!(d >> 115 == 0);
364
        // [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0]
365
1.88M
        let u0 = (d & m) as u64;
366
1.88M
        d >>= 52;
367
1.88M
        debug_assert!(u0 >> 52 == 0);
368
1.88M
        debug_assert!(d >> 63 == 0);
369
1.88M
        let d64 = d as u64;
370
1.88M
        // [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0]
371
1.88M
        // [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0]
372
1.88M
        let u0 = (u0 << 4) | tx;
373
1.88M
        debug_assert!(u0 >> 56 == 0);
374
        // [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0]
375
1.88M
        c += u0 as u128 * ((r as u64) >> 4) as u128;
376
1.88M
        debug_assert!(c >> 115 == 0);
377
        // [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0]
378
1.88M
        let r0 = (c & m) as u64;
379
1.88M
        c >>= 52;
380
1.88M
        debug_assert!(r0 >> 52 == 0);
381
1.88M
        debug_assert!(c >> 61 == 0);
382
1.88M
        let c64 = c as u64;
383
1.88M
        // [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0]
384
1.88M
385
1.88M
        c = c64 as u128 + a0 * b1 + a1 * b0;
386
1.88M
        debug_assert!(c >> 114 == 0);
387
        // [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0]
388
1.88M
        d = d64 as u128 + a2 * b4 + a3 * b3 + a4 * b2;
389
1.88M
        debug_assert!(d >> 114 == 0);
390
        // [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0]
391
1.88M
        c += (d & m) * r;
392
1.88M
        d >>= 52;
393
1.88M
        debug_assert!(c >> 115 == 0);
394
1.88M
        debug_assert!(d >> 62 == 0);
395
1.88M
        let d64 = d as u64;
396
1.88M
        // [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0]
397
1.88M
        let r1 = (c & m) as u64;
398
1.88M
        c >>= 52;
399
1.88M
        debug_assert!(r1 >> 52 == 0);
400
1.88M
        debug_assert!(c >> 63 == 0);
401
1.88M
        let c64 = c as u64;
402
1.88M
        // [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0]
403
1.88M
404
1.88M
        c = c64 as u128 + a0 * b2 + a1 * b1 + a2 * b0;
405
1.88M
        debug_assert!(c >> 114 == 0);
406
        // [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0]
407
1.88M
        d = d64 as u128 + a3 * b4 + a4 * b3;
408
1.88M
        debug_assert!(d >> 114 == 0);
409
        // [d 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0]
410
1.88M
        c += (d & m) * r;
411
1.88M
        d >>= 52;
412
1.88M
        debug_assert!(c >> 115 == 0);
413
1.88M
        debug_assert!(d >> 62 == 0);
414
1.88M
        let d64 = d as u64;
415
1.88M
        // [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0]
416
1.88M
417
1.88M
        // [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0]
418
1.88M
        let r2 = (c & m) as u64;
419
1.88M
        c >>= 52;
420
1.88M
        debug_assert!(r2 >> 52 == 0);
421
1.88M
        debug_assert!(c >> 63 == 0);
422
1.88M
        let c64 = c as u64;
423
1.88M
        // [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0]
424
1.88M
        c = c64 as u128 + (d64 as u128) * r + t3 as u128;
425
1.88M
        debug_assert!(c >> 100 == 0);
426
        // [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0]
427
1.88M
        let r3 = (c & m) as u64;
428
1.88M
        c >>= 52;
429
1.88M
        debug_assert!(r3 >> 52 == 0);
430
1.88M
        debug_assert!(c >> 48 == 0);
431
1.88M
        let c64 = c as u64;
432
1.88M
        // [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0]
433
1.88M
        c = c64 as u128 + t4 as u128;
434
1.88M
        debug_assert!(c >> 49 == 0);
435
        // [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0]
436
1.88M
        let r4 = c as u64;
437
1.88M
        debug_assert!(r4 >> 49 == 0);
438
        // [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0]
439
440
1.88M
        Self([r0, r1, r2, r3, r4])
441
1.88M
    }
442
443
    /// Returns self * rhs mod p
444
    /// Brings the magnitude to 1 (but doesn't normalize the result).
445
    /// The magnitudes of arguments should be <= 8.
446
    #[inline(always)]
447
1.42M
    pub fn mul(&self, rhs: &Self) -> Self {
448
1.42M
        self.mul_inner(rhs)
449
1.42M
    }
450
451
    /// Returns self * self
452
    /// Brings the magnitude to 1 (but doesn't normalize the result).
453
    /// The magnitudes of arguments should be <= 8.
454
453k
    pub fn square(&self) -> Self {
455
453k
        self.mul_inner(self)
456
453k
    }
457
}
458
459
impl Default for FieldElement5x52 {
460
1.79k
    fn default() -> Self {
461
1.79k
        Self::ZERO
462
1.79k
    }
463
}
464
465
impl ConditionallySelectable for FieldElement5x52 {
466
    #[inline(always)]
467
1.88M
    fn conditional_select(
468
1.88M
        a: &FieldElement5x52,
469
1.88M
        b: &FieldElement5x52,
470
1.88M
        choice: Choice,
471
1.88M
    ) -> FieldElement5x52 {
472
1.88M
        FieldElement5x52([
473
1.88M
            u64::conditional_select(&a.0[0], &b.0[0], choice),
474
1.88M
            u64::conditional_select(&a.0[1], &b.0[1], choice),
475
1.88M
            u64::conditional_select(&a.0[2], &b.0[2], choice),
476
1.88M
            u64::conditional_select(&a.0[3], &b.0[3], choice),
477
1.88M
            u64::conditional_select(&a.0[4], &b.0[4], choice),
478
1.88M
        ])
479
1.88M
    }
480
}
481
482
impl ConstantTimeEq for FieldElement5x52 {
483
0
    fn ct_eq(&self, other: &Self) -> Choice {
484
0
        self.0[0].ct_eq(&other.0[0])
485
0
            & self.0[1].ct_eq(&other.0[1])
486
0
            & self.0[2].ct_eq(&other.0[2])
487
0
            & self.0[3].ct_eq(&other.0[3])
488
0
            & self.0[4].ct_eq(&other.0[4])
489
0
    }
490
}
491
492
impl Zeroize for FieldElement5x52 {
493
0
    fn zeroize(&mut self) {
494
0
        self.0.zeroize();
495
0
    }
496
}
497
498
#[cfg(test)]
499
mod tests {
500
    use super::FieldElement5x52;
501
502
    #[test]
503
    fn overflow_check_after_weak_normalize() {
504
        // A regression test for a missing condition in `get_overflow()`.
505
        // The condition was only missing in the 32-bit case,
506
        // but we're adding a 64-bit testcase nevertheless.
507
        //
508
        // In `normalize()`, after the `normalize_weak()` call,
509
        // the excess bit from the limb 0 is propagated all the way to the last limb.
510
        // This constitutes an overflow, since the last bit becomes equal to (1 << 22),
511
        // that is 23 bits in total.
512
        // When `get_overflow()` is called afterwards, this was not detected,
513
        // since the corresponding condition (checking for the last limb being > 22 bits)
514
        // was missing.
515
        // This resulted in a debug assert firing later.
516
        //
517
        // This is essentially 2^256
518
        let z = FieldElement5x52([
519
            (1 << 52), // an excess bit here
520
            // the remaining full-sized limbs are at top normalized capacity
521
            (1 << 52) - 1,
522
            (1 << 52) - 1,
523
            (1 << 52) - 1,
524
            // the last limb is also at top normalized capacity
525
            (1 << 48) - 1,
526
        ]);
527
528
        // Used to fail here (debug_assert firing because overflow happened at an unexpected place):
529
        let z_normalized = z.normalize();
530
531
        // Properly normalized result, just to be sure
532
        // The initial number is 2^256, so the result is 0x1000003d1
533
        let z_reference = FieldElement5x52([0x1000003d1, 0, 0, 0, 0]);
534
535
        assert_eq!(z_normalized.0, z_reference.0);
536
    }
537
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/arithmetic/field/field_impl.rs
Line
Count
Source
1
//! A debug layer for lazy-reduction field elements making sure
2
//! they are not misused. Ensures the correct normalization and checks magnitudes in operations.
3
//! Only enabled when `debug_assertions` feature is on.
4
5
use crate::FieldBytes;
6
use elliptic_curve::{
7
    subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
8
    zeroize::Zeroize,
9
};
10
11
#[cfg(target_pointer_width = "32")]
12
use super::field_10x26::FieldElement10x26 as FieldElementUnsafeImpl;
13
14
#[cfg(target_pointer_width = "64")]
15
use super::field_5x52::FieldElement5x52 as FieldElementUnsafeImpl;
16
17
#[derive(Clone, Copy, Debug)]
18
pub struct FieldElementImpl {
19
    value: FieldElementUnsafeImpl,
20
    magnitude: u32,
21
    normalized: bool,
22
}
23
24
impl FieldElementImpl {
25
    /// Zero element.
26
    pub const ZERO: Self = Self {
27
        value: FieldElementUnsafeImpl::ZERO,
28
        magnitude: 1,
29
        normalized: true,
30
    };
31
32
    /// Multiplicative identity.
33
    pub const ONE: Self = Self {
34
        value: FieldElementUnsafeImpl::ONE,
35
        magnitude: 1,
36
        normalized: true,
37
    };
38
39
4.83k
    const fn new_normalized(value: &FieldElementUnsafeImpl) -> Self {
40
4.83k
        Self {
41
4.83k
            value: *value,
42
4.83k
            magnitude: 1,
43
4.83k
            normalized: true,
44
4.83k
        }
45
4.83k
    }
46
47
2.95M
    const fn new_weak_normalized(value: &FieldElementUnsafeImpl) -> Self {
48
2.95M
        Self {
49
2.95M
            value: *value,
50
2.95M
            magnitude: 1,
51
2.95M
            normalized: false,
52
2.95M
        }
53
2.95M
    }
54
55
4.10M
    fn new(value: &FieldElementUnsafeImpl, magnitude: u32) -> Self {
56
4.10M
        debug_assert!(magnitude <= FieldElementUnsafeImpl::max_magnitude());
57
4.10M
        Self {
58
4.10M
            value: *value,
59
4.10M
            magnitude,
60
4.10M
            normalized: false,
61
4.10M
        }
62
4.10M
    }
63
64
0
    pub(crate) const fn from_bytes_unchecked(bytes: &[u8; 32]) -> Self {
65
0
        let value = FieldElementUnsafeImpl::from_bytes_unchecked(bytes);
66
0
        Self::new_normalized(&value)
67
0
    }
68
69
0
    pub(crate) const fn from_u64(val: u64) -> Self {
70
0
        Self::new_normalized(&FieldElementUnsafeImpl::from_u64(val))
71
0
    }
72
73
1.79k
    pub fn from_bytes(bytes: &FieldBytes) -> CtOption<Self> {
74
1.79k
        let value = FieldElementUnsafeImpl::from_bytes(bytes);
75
1.79k
        CtOption::map(value, |x| Self::new_normalized(&x))
76
1.79k
    }
77
78
523
    pub fn to_bytes(self) -> FieldBytes {
79
523
        debug_assert!(self.normalized);
80
523
        self.value.to_bytes()
81
523
    }
82
83
1.07M
    pub fn normalize_weak(&self) -> Self {
84
1.07M
        Self::new_weak_normalized(&self.value.normalize_weak())
85
1.07M
    }
86
87
3.03k
    pub fn normalize(&self) -> Self {
88
3.03k
        Self::new_normalized(&self.value.normalize())
89
3.03k
    }
90
91
1.78k
    pub fn normalizes_to_zero(&self) -> Choice {
92
1.78k
        self.value.normalizes_to_zero()
93
1.78k
    }
94
95
0
    pub fn is_zero(&self) -> Choice {
96
0
        debug_assert!(self.normalized);
97
0
        self.value.is_zero()
98
0
    }
99
100
735
    pub fn is_odd(&self) -> Choice {
101
735
        debug_assert!(self.normalized);
102
735
        self.value.is_odd()
103
735
    }
104
105
558k
    pub fn negate(&self, magnitude: u32) -> Self {
106
558k
        debug_assert!(self.magnitude <= magnitude);
107
558k
        let new_magnitude = magnitude + 1;
108
558k
        debug_assert!(new_magnitude <= FieldElementUnsafeImpl::max_magnitude());
109
558k
        Self::new(&(self.value.negate(magnitude)), new_magnitude)
110
558k
    }
111
112
3.16M
    pub fn add(&self, rhs: &Self) -> Self {
113
3.16M
        let new_magnitude = self.magnitude + rhs.magnitude;
114
3.16M
        debug_assert!(new_magnitude <= FieldElementUnsafeImpl::max_magnitude());
115
3.16M
        Self::new(&(self.value.add(&(rhs.value))), new_magnitude)
116
3.16M
    }
117
118
384k
    pub fn mul_single(&self, rhs: u32) -> Self {
119
384k
        let new_magnitude = self.magnitude * rhs;
120
384k
        debug_assert!(new_magnitude <= FieldElementUnsafeImpl::max_magnitude());
121
384k
        Self::new(&(self.value.mul_single(rhs)), new_magnitude)
122
384k
    }
123
124
    /// Returns self * rhs mod p
125
1.42M
    pub fn mul(&self, rhs: &Self) -> Self {
126
1.42M
        debug_assert!(self.magnitude <= 8);
127
1.42M
        debug_assert!(rhs.magnitude <= 8);
128
1.42M
        Self::new_weak_normalized(&(self.value.mul(&(rhs.value))))
129
1.42M
    }
130
131
    /// Returns self * self mod p
132
453k
    pub fn square(&self) -> Self {
133
453k
        debug_assert!(self.magnitude <= 8);
134
453k
        Self::new_weak_normalized(&(self.value.square()))
135
453k
    }
136
}
137
138
impl Default for FieldElementImpl {
139
1.79k
    fn default() -> Self {
140
1.79k
        Self::ZERO
141
1.79k
    }
142
}
143
144
impl ConditionallySelectable for FieldElementImpl {
145
    #[inline(always)]
146
1.88M
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
147
        // 1. It's debug only, so it shouldn't present a security risk
148
        // 2. Being normalized does is independent from the field element value;
149
        //    elements must be normalized explicitly.
150
1.88M
        let new_normalized = if bool::from(choice) {
151
302k
            b.normalized
152
        } else {
153
1.57M
            a.normalized
154
        };
155
1.88M
        Self {
156
1.88M
            value: FieldElementUnsafeImpl::conditional_select(&(a.value), &(b.value), choice),
157
1.88M
            magnitude: u32::conditional_select(&(a.magnitude), &(b.magnitude), choice),
158
1.88M
            normalized: new_normalized,
159
1.88M
        }
160
1.88M
    }
161
}
162
163
impl ConstantTimeEq for FieldElementImpl {
164
0
    fn ct_eq(&self, other: &Self) -> Choice {
165
0
        self.value.ct_eq(&(other.value))
166
0
            & self.magnitude.ct_eq(&(other.magnitude))
167
0
            // See the comment in `conditional_select()`
168
0
            & Choice::from((self.normalized == other.normalized) as u8)
169
0
    }
170
}
171
172
impl Zeroize for FieldElementImpl {
173
0
    fn zeroize(&mut self) {
174
0
        self.value.zeroize();
175
0
        self.magnitude.zeroize();
176
0
        self.normalized.zeroize();
177
0
    }
178
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/arithmetic/mul.rs
Line
Count
Source
1
//! From libsecp256k1:
2
//!
3
//! The Secp256k1 curve has an endomorphism, where lambda * (x, y) = (beta * x, y), where
4
//! lambda is {0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a,
5
//!         0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78,0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72}
6
//!
7
//! "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm
8
//! (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1
9
//! and k2 have a small size.
10
//! It relies on constants a1, b1, a2, b2. These constants for the value of lambda above are:
11
//!
12
//! - a1 =      {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15}
13
//! - b1 =     -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3}
14
//! - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8}
15
//! - b2 =      {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15}
16
//!
17
//! The algorithm then computes c1 = round(b1 * k / n) and c2 = round(b2 * k / n), and gives
18
//! k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and
19
//! compute k1 as k - k2 * lambda, avoiding the need for constants a1 and a2.
20
//!
21
//! g1, g2 are precomputed constants used to replace division with a rounded multiplication
22
//! when decomposing the scalar for an endomorphism-based point multiplication.
23
//!
24
//! The possibility of using precomputed estimates is mentioned in "Guide to Elliptic Curve
25
//! Cryptography" (Hankerson, Menezes, Vanstone) in section 3.5.
26
//!
27
//! The derivation is described in the paper "Efficient Software Implementation of Public-Key
28
//! Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez),
29
//! Section 4.3 (here we use a somewhat higher-precision estimate):
30
//! d = a1*b2 - b1*a2
31
//! g1 = round((2^384)*b2/d)
32
//! g2 = round((2^384)*(-b1)/d)
33
//!
34
//! (Note that 'd' is also equal to the curve order here because `[a1,b1]` and `[a2,b2]` are found
35
//! as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda').
36
37
#[cfg(all(
38
    feature = "precomputed-tables",
39
    not(any(feature = "critical-section", feature = "std"))
40
))]
41
compile_error!("`precomputed-tables` feature requires either `critical-section` or `std`");
42
43
use crate::arithmetic::{
44
    scalar::{Scalar, WideScalar},
45
    ProjectivePoint,
46
};
47
48
use core::ops::{Mul, MulAssign};
49
use elliptic_curve::ops::LinearCombinationExt as LinearCombination;
50
use elliptic_curve::{
51
    ops::MulByGenerator,
52
    scalar::IsHigh,
53
    subtle::{Choice, ConditionallySelectable, ConstantTimeEq},
54
};
55
56
#[cfg(feature = "precomputed-tables")]
57
use once_cell::sync::Lazy;
58
59
/// Lookup table containing precomputed values `[p, 2p, 3p, ..., 8p]`
60
#[derive(Copy, Clone, Default)]
61
struct LookupTable([ProjectivePoint; 8]);
62
63
impl From<&ProjectivePoint> for LookupTable {
64
2.09k
    fn from(p: &ProjectivePoint) -> Self {
65
2.09k
        let mut points = [*p; 8];
66
16.7k
        for j in 0..7 {
67
14.6k
            points[j + 1] = p + &points[j];
68
14.6k
        }
69
2.09k
        LookupTable(points)
70
2.09k
    }
71
}
72
73
impl LookupTable {
74
    /// Given -8 <= x <= 8, returns x * p in constant time.
75
69.0k
    fn select(&self, x: i8) -> ProjectivePoint {
76
69.0k
        debug_assert!(x >= -8);
77
69.0k
        debug_assert!(x <= 8);
78
79
        // Compute xabs = |x|
80
69.0k
        let xmask = x >> 7;
81
69.0k
        let xabs = (x + xmask) ^ xmask;
82
69.0k
83
69.0k
        // Get an array element in constant time
84
69.0k
        let mut t = ProjectivePoint::IDENTITY;
85
621k
        for j in 1..9 {
86
552k
            let c = (xabs as u8).ct_eq(&(j as u8));
87
552k
            t.conditional_assign(&self.0[j - 1], c);
88
552k
        }
89
        // Now t == |x| * p.
90
91
69.0k
        let neg_mask = Choice::from((xmask & 1) as u8);
92
69.0k
        t.conditional_assign(&-t, neg_mask);
93
69.0k
        // Now t == x * p.
94
69.0k
95
69.0k
        t
96
69.0k
    }
97
}
98
99
const MINUS_LAMBDA: Scalar = Scalar::from_bytes_unchecked(&[
100
    0xac, 0x9c, 0x52, 0xb3, 0x3f, 0xa3, 0xcf, 0x1f, 0x5a, 0xd9, 0xe3, 0xfd, 0x77, 0xed, 0x9b, 0xa4,
101
    0xa8, 0x80, 0xb9, 0xfc, 0x8e, 0xc7, 0x39, 0xc2, 0xe0, 0xcf, 0xc8, 0x10, 0xb5, 0x12, 0x83, 0xcf,
102
]);
103
104
const MINUS_B1: Scalar = Scalar::from_bytes_unchecked(&[
105
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106
    0xe4, 0x43, 0x7e, 0xd6, 0x01, 0x0e, 0x88, 0x28, 0x6f, 0x54, 0x7f, 0xa9, 0x0a, 0xbf, 0xe4, 0xc3,
107
]);
108
109
const MINUS_B2: Scalar = Scalar::from_bytes_unchecked(&[
110
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
111
    0x8a, 0x28, 0x0a, 0xc5, 0x07, 0x74, 0x34, 0x6d, 0xd7, 0x65, 0xcd, 0xa8, 0x3d, 0xb1, 0x56, 0x2c,
112
]);
113
114
const G1: Scalar = Scalar::from_bytes_unchecked(&[
115
    0x30, 0x86, 0xd2, 0x21, 0xa7, 0xd4, 0x6b, 0xcd, 0xe8, 0x6c, 0x90, 0xe4, 0x92, 0x84, 0xeb, 0x15,
116
    0x3d, 0xaa, 0x8a, 0x14, 0x71, 0xe8, 0xca, 0x7f, 0xe8, 0x93, 0x20, 0x9a, 0x45, 0xdb, 0xb0, 0x31,
117
]);
118
119
const G2: Scalar = Scalar::from_bytes_unchecked(&[
120
    0xe4, 0x43, 0x7e, 0xd6, 0x01, 0x0e, 0x88, 0x28, 0x6f, 0x54, 0x7f, 0xa9, 0x0a, 0xbf, 0xe4, 0xc4,
121
    0x22, 0x12, 0x08, 0xac, 0x9d, 0xf5, 0x06, 0xc6, 0x15, 0x71, 0xb4, 0xae, 0x8a, 0xc4, 0x7f, 0x71,
122
]);
123
124
/*
125
 * Proof for decompose_scalar's bounds.
126
 *
127
 * Let
128
 *  - epsilon1 = 2^256 * |g1/2^384 - b2/d|
129
 *  - epsilon2 = 2^256 * |g2/2^384 - (-b1)/d|
130
 *  - c1 = round(k*g1/2^384)
131
 *  - c2 = round(k*g2/2^384)
132
 *
133
 * Lemma 1: |c1 - k*b2/d| < 2^-1 + epsilon1
134
 *
135
 *    |c1 - k*b2/d|
136
 *  =
137
 *    |c1 - k*g1/2^384 + k*g1/2^384 - k*b2/d|
138
 * <=   {triangle inequality}
139
 *    |c1 - k*g1/2^384| + |k*g1/2^384 - k*b2/d|
140
 *  =
141
 *    |c1 - k*g1/2^384| + k*|g1/2^384 - b2/d|
142
 * <    {rounding in c1 and 0 <= k < 2^256}
143
 *    2^-1 + 2^256 * |g1/2^384 - b2/d|
144
 *  =   {definition of epsilon1}
145
 *    2^-1 + epsilon1
146
 *
147
 * Lemma 2: |c2 - k*(-b1)/d| < 2^-1 + epsilon2
148
 *
149
 *    |c2 - k*(-b1)/d|
150
 *  =
151
 *    |c2 - k*g2/2^384 + k*g2/2^384 - k*(-b1)/d|
152
 * <=   {triangle inequality}
153
 *    |c2 - k*g2/2^384| + |k*g2/2^384 - k*(-b1)/d|
154
 *  =
155
 *    |c2 - k*g2/2^384| + k*|g2/2^384 - (-b1)/d|
156
 * <    {rounding in c2 and 0 <= k < 2^256}
157
 *    2^-1 + 2^256 * |g2/2^384 - (-b1)/d|
158
 *  =   {definition of epsilon2}
159
 *    2^-1 + epsilon2
160
 *
161
 * Let
162
 *  - k1 = k - c1*a1 - c2*a2
163
 *  - k2 = - c1*b1 - c2*b2
164
 *
165
 * Lemma 3: |k1| < (a1 + a2 + 1)/2 < 2^128
166
 *
167
 *    |k1|
168
 *  =   {definition of k1}
169
 *    |k - c1*a1 - c2*a2|
170
 *  =   {(a1*b2 - b1*a2)/n = 1}
171
 *    |k*(a1*b2 - b1*a2)/n - c1*a1 - c2*a2|
172
 *  =
173
 *    |a1*(k*b2/n - c1) + a2*(k*(-b1)/n - c2)|
174
 * <=   {triangle inequality}
175
 *    a1*|k*b2/n - c1| + a2*|k*(-b1)/n - c2|
176
 * <    {Lemma 1 and Lemma 2}
177
 *    a1*(2^-1 + epslion1) + a2*(2^-1 + epsilon2)
178
 * <    {rounding up to an integer}
179
 *    (a1 + a2 + 1)/2
180
 * <    {rounding up to a power of 2}
181
 *    2^128
182
 *
183
 * Lemma 4: |k2| < (-b1 + b2)/2 + 1 < 2^128
184
 *
185
 *    |k2|
186
 *  =   {definition of k2}
187
 *    |- c1*a1 - c2*a2|
188
 *  =   {(b1*b2 - b1*b2)/n = 0}
189
 *    |k*(b1*b2 - b1*b2)/n - c1*b1 - c2*b2|
190
 *  =
191
 *    |b1*(k*b2/n - c1) + b2*(k*(-b1)/n - c2)|
192
 * <=   {triangle inequality}
193
 *    (-b1)*|k*b2/n - c1| + b2*|k*(-b1)/n - c2|
194
 * <    {Lemma 1 and Lemma 2}
195
 *    (-b1)*(2^-1 + epslion1) + b2*(2^-1 + epsilon2)
196
 * <    {rounding up to an integer}
197
 *    (-b1 + b2)/2 + 1
198
 * <    {rounding up to a power of 2}
199
 *    2^128
200
 *
201
 * Let
202
 *  - r2 = k2 mod n
203
 *  - r1 = k - r2*lambda mod n.
204
 *
205
 * Notice that r1 is defined such that r1 + r2 * lambda == k (mod n).
206
 *
207
 * Lemma 5: r1 == k1 mod n.
208
 *
209
 *    r1
210
 * ==   {definition of r1 and r2}
211
 *    k - k2*lambda
212
 * ==   {definition of k2}
213
 *    k - (- c1*b1 - c2*b2)*lambda
214
 * ==
215
 *    k + c1*b1*lambda + c2*b2*lambda
216
 * ==  {a1 + b1*lambda == 0 mod n and a2 + b2*lambda == 0 mod n}
217
 *    k - c1*a1 - c2*a2
218
 * ==  {definition of k1}
219
 *    k1
220
 *
221
 * From Lemma 3, Lemma 4, Lemma 5 and the definition of r2, we can conclude that
222
 *
223
 *  - either r1 < 2^128 or -r1 mod n < 2^128
224
 *  - either r2 < 2^128 or -r2 mod n < 2^128.
225
 *
226
 * Q.E.D.
227
 */
228
229
/// Find r1 and r2 given k, such that r1 + r2 * lambda == k mod n.
230
1.04k
fn decompose_scalar(k: &Scalar) -> (Scalar, Scalar) {
231
1.04k
    // these _vartime calls are constant time since the shift amount is constant
232
1.04k
    let c1 = WideScalar::mul_shift_vartime(k, &G1, 384) * MINUS_B1;
233
1.04k
    let c2 = WideScalar::mul_shift_vartime(k, &G2, 384) * MINUS_B2;
234
1.04k
    let r2 = c1 + c2;
235
1.04k
    let r1 = k + r2 * MINUS_LAMBDA;
236
1.04k
237
1.04k
    (r1, r2)
238
1.04k
}
239
240
// This needs to be an object to have Default implemented for it
241
// (required because it's used in static_map later)
242
// Otherwise we could just have a function returning an array.
243
#[derive(Copy, Clone)]
244
struct Radix16Decomposition<const D: usize>([i8; D]);
245
246
impl<const D: usize> Radix16Decomposition<D> {
247
    /// Returns an object containing a decomposition
248
    /// `[a_0, ..., a_D]` such that `sum(a_j * 2^(j * 4)) == x`,
249
    /// and `-8 <= a_j <= 7`.
250
    /// Assumes `x < 2^(4*(D-1))`.
251
2.09k
    fn new(x: &Scalar) -> Self {
252
2.09k
        debug_assert!((x >> (4 * (D - 1))).is_zero().unwrap_u8() == 1);
253
254
        // The resulting decomposition can be negative, so, despite the limit on `x`,
255
        // we need an additional byte to store the carry.
256
2.09k
        let mut output = [0i8; D];
257
2.09k
258
2.09k
        // Step 1: change radix.
259
2.09k
        // Convert from radix 256 (bytes) to radix 16 (nibbles)
260
2.09k
        let bytes = x.to_bytes();
261
33.4k
        for i in 0..(D - 1) / 2 {
262
33.4k
            output[2 * i] = (bytes[31 - i] & 0xf) as i8;
263
33.4k
            output[2 * i + 1] = ((bytes[31 - i] >> 4) & 0xf) as i8;
264
33.4k
        }
265
266
        // Step 2: recenter coefficients from [0,16) to [-8,8)
267
66.9k
        for i in 0..(D - 1) {
268
66.9k
            let carry = (output[i] + 8) >> 4;
269
66.9k
            output[i] -= carry << 4;
270
66.9k
            output[i + 1] += carry;
271
66.9k
        }
272
273
2.09k
        Self(output)
274
2.09k
    }
_RNvMs0_NtNtCsjewTDwKBbyD_4k25610arithmetic3mulINtB5_20Radix16DecompositionKj21_E3newB9_
Line
Count
Source
251
2.09k
    fn new(x: &Scalar) -> Self {
252
2.09k
        debug_assert!((x >> (4 * (D - 1))).is_zero().unwrap_u8() == 1);
253
254
        // The resulting decomposition can be negative, so, despite the limit on `x`,
255
        // we need an additional byte to store the carry.
256
2.09k
        let mut output = [0i8; D];
257
2.09k
258
2.09k
        // Step 1: change radix.
259
2.09k
        // Convert from radix 256 (bytes) to radix 16 (nibbles)
260
2.09k
        let bytes = x.to_bytes();
261
33.4k
        for i in 0..(D - 1) / 2 {
262
33.4k
            output[2 * i] = (bytes[31 - i] & 0xf) as i8;
263
33.4k
            output[2 * i + 1] = ((bytes[31 - i] >> 4) & 0xf) as i8;
264
33.4k
        }
265
266
        // Step 2: recenter coefficients from [0,16) to [-8,8)
267
66.9k
        for i in 0..(D - 1) {
268
66.9k
            let carry = (output[i] + 8) >> 4;
269
66.9k
            output[i] -= carry << 4;
270
66.9k
            output[i + 1] += carry;
271
66.9k
        }
272
273
2.09k
        Self(output)
274
2.09k
    }
Unexecuted instantiation: _RNvMs0_NtNtCsjewTDwKBbyD_4k25610arithmetic3mulINtB5_20Radix16DecompositionKj41_E3newB9_
275
}
276
277
impl<const D: usize> Default for Radix16Decomposition<D> {
278
1.04k
    fn default() -> Self {
279
1.04k
        Self([0i8; D])
280
1.04k
    }
281
}
282
283
impl<const N: usize> LinearCombination<[(ProjectivePoint, Scalar); N]> for ProjectivePoint {
284
523
    fn lincomb_ext(points_and_scalars: &[(ProjectivePoint, Scalar); N]) -> Self {
285
523
        let mut tables = [(LookupTable::default(), LookupTable::default()); N];
286
523
        let mut digits = [(
287
523
            Radix16Decomposition::<33>::default(),
288
523
            Radix16Decomposition::<33>::default(),
289
523
        ); N];
290
523
291
523
        lincomb(points_and_scalars, &mut tables, &mut digits)
292
523
    }
Unexecuted instantiation: _RNvXs2_NtNtCsjewTDwKBbyD_4k25610arithmetic3mulNtNtB7_10projective15ProjectivePointINtNtCs8yVsO3EKNkV_14elliptic_curve3ops20LinearCombinationExtATBI_NtNtB7_6scalar6ScalarEj1_E11lincomb_extB9_
_RNvXs2_NtNtCsjewTDwKBbyD_4k25610arithmetic3mulNtNtB7_10projective15ProjectivePointINtNtCs8yVsO3EKNkV_14elliptic_curve3ops20LinearCombinationExtATBI_NtNtB7_6scalar6ScalarEj2_E11lincomb_extB9_
Line
Count
Source
284
523
    fn lincomb_ext(points_and_scalars: &[(ProjectivePoint, Scalar); N]) -> Self {
285
523
        let mut tables = [(LookupTable::default(), LookupTable::default()); N];
286
523
        let mut digits = [(
287
523
            Radix16Decomposition::<33>::default(),
288
523
            Radix16Decomposition::<33>::default(),
289
523
        ); N];
290
523
291
523
        lincomb(points_and_scalars, &mut tables, &mut digits)
292
523
    }
293
}
294
295
#[cfg(feature = "alloc")]
296
impl LinearCombination<[(ProjectivePoint, Scalar)]> for ProjectivePoint {
297
0
    fn lincomb_ext(points_and_scalars: &[(ProjectivePoint, Scalar)]) -> Self {
298
0
        let mut tables =
299
0
            vec![(LookupTable::default(), LookupTable::default()); points_and_scalars.len()];
300
0
        let mut digits = vec![
301
0
            (
302
0
                Radix16Decomposition::<33>::default(),
303
0
                Radix16Decomposition::<33>::default(),
304
0
            );
305
0
            points_and_scalars.len()
306
0
        ];
307
0
308
0
        lincomb(points_and_scalars, &mut tables, &mut digits)
309
0
    }
310
}
311
312
523
fn lincomb(
313
523
    xks: &[(ProjectivePoint, Scalar)],
314
523
    tables: &mut [(LookupTable, LookupTable)],
315
523
    digits: &mut [(Radix16Decomposition<33>, Radix16Decomposition<33>)],
316
523
) -> ProjectivePoint {
317
1.04k
    xks.iter().enumerate().for_each(|(i, (x, k))| {
318
1.04k
        let (r1, r2) = decompose_scalar(k);
319
1.04k
        let x_beta = x.endomorphism();
320
1.04k
        let (r1_sign, r2_sign) = (r1.is_high(), r2.is_high());
321
1.04k
322
1.04k
        let (r1_c, r2_c) = (
323
1.04k
            Scalar::conditional_select(&r1, &-r1, r1_sign),
324
1.04k
            Scalar::conditional_select(&r2, &-r2, r2_sign),
325
1.04k
        );
326
1.04k
327
1.04k
        tables[i] = (
328
1.04k
            LookupTable::from(&ProjectivePoint::conditional_select(x, &-*x, r1_sign)),
329
1.04k
            LookupTable::from(&ProjectivePoint::conditional_select(
330
1.04k
                &x_beta, &-x_beta, r2_sign,
331
1.04k
            )),
332
1.04k
        );
333
1.04k
334
1.04k
        digits[i] = (
335
1.04k
            Radix16Decomposition::<33>::new(&r1_c),
336
1.04k
            Radix16Decomposition::<33>::new(&r2_c),
337
1.04k
        )
338
1.04k
    });
339
523
340
523
    let mut acc = ProjectivePoint::IDENTITY;
341
1.04k
    for component in 0..xks.len() {
342
1.04k
        let (digit1, digit2) = digits[component];
343
1.04k
        let (table1, table2) = tables[component];
344
1.04k
345
1.04k
        acc += &table1.select(digit1.0[32]);
346
1.04k
        acc += &table2.select(digit2.0[32]);
347
1.04k
    }
348
349
16.7k
    for i in (0..32).rev() {
350
83.6k
        for _j in 0..4 {
351
66.9k
            acc = acc.double();
352
66.9k
        }
353
354
33.4k
        for component in 0..xks.len() {
355
33.4k
            let (digit1, digit2) = digits[component];
356
33.4k
            let (table1, table2) = tables[component];
357
33.4k
358
33.4k
            acc += &table1.select(digit1.0[i]);
359
33.4k
            acc += &table2.select(digit2.0[i]);
360
33.4k
        }
361
    }
362
523
    acc
363
523
}
364
365
/// Lazily computed basepoint table.
366
#[cfg(feature = "precomputed-tables")]
367
static GEN_LOOKUP_TABLE: Lazy<[LookupTable; 33]> = Lazy::new(precompute_gen_lookup_table);
368
369
#[cfg(feature = "precomputed-tables")]
370
0
fn precompute_gen_lookup_table() -> [LookupTable; 33] {
371
0
    let mut gen = ProjectivePoint::GENERATOR;
372
0
    let mut res = [LookupTable::default(); 33];
373
374
0
    for i in 0..33 {
375
0
        res[i] = LookupTable::from(&gen);
376
        // We are storing tables spaced by two radix steps,
377
        // to decrease the size of the precomputed data.
378
0
        for _ in 0..8 {
379
0
            gen = gen.double();
380
0
        }
381
    }
382
0
    res
383
0
}
384
385
impl MulByGenerator for ProjectivePoint {
386
    /// Calculates `k * G`, where `G` is the generator.
387
    #[cfg(not(feature = "precomputed-tables"))]
388
    fn mul_by_generator(k: &Scalar) -> ProjectivePoint {
389
        ProjectivePoint::GENERATOR * k
390
    }
391
392
    /// Calculates `k * G`, where `G` is the generator.
393
    #[cfg(feature = "precomputed-tables")]
394
0
    fn mul_by_generator(k: &Scalar) -> ProjectivePoint {
395
0
        let digits = Radix16Decomposition::<65>::new(k);
396
0
        let table = *GEN_LOOKUP_TABLE;
397
0
        let mut acc = table[32].select(digits.0[64]);
398
0
        let mut acc2 = ProjectivePoint::IDENTITY;
399
0
        for i in (0..32).rev() {
400
0
            acc2 += &table[i].select(digits.0[i * 2 + 1]);
401
0
            acc += &table[i].select(digits.0[i * 2]);
402
0
        }
403
        // This is the price of halving the precomputed table size (from 60kb to 30kb)
404
        // The performance hit is minor, about 3%.
405
0
        for _ in 0..4 {
406
0
            acc2 = acc2.double();
407
0
        }
408
0
        acc + acc2
409
0
    }
410
}
411
412
#[inline(always)]
413
0
fn mul(x: &ProjectivePoint, k: &Scalar) -> ProjectivePoint {
414
0
    ProjectivePoint::lincomb_ext(&[(*x, *k)])
415
0
}
416
417
impl Mul<Scalar> for ProjectivePoint {
418
    type Output = ProjectivePoint;
419
420
0
    fn mul(self, other: Scalar) -> ProjectivePoint {
421
0
        mul(&self, &other)
422
0
    }
423
}
424
425
impl Mul<&Scalar> for &ProjectivePoint {
426
    type Output = ProjectivePoint;
427
428
0
    fn mul(self, other: &Scalar) -> ProjectivePoint {
429
0
        mul(self, other)
430
0
    }
431
}
432
433
impl Mul<&Scalar> for ProjectivePoint {
434
    type Output = ProjectivePoint;
435
436
0
    fn mul(self, other: &Scalar) -> ProjectivePoint {
437
0
        mul(&self, other)
438
0
    }
439
}
440
441
impl MulAssign<Scalar> for ProjectivePoint {
442
0
    fn mul_assign(&mut self, rhs: Scalar) {
443
0
        *self = mul(self, &rhs);
444
0
    }
445
}
446
447
impl MulAssign<&Scalar> for ProjectivePoint {
448
0
    fn mul_assign(&mut self, rhs: &Scalar) {
449
0
        *self = mul(self, rhs);
450
0
    }
451
}
452
453
#[cfg(test)]
454
mod tests {
455
    use super::*;
456
    use crate::arithmetic::{ProjectivePoint, Scalar};
457
    use elliptic_curve::{
458
        ops::{LinearCombination as _, MulByGenerator},
459
        rand_core::OsRng,
460
        Field, Group,
461
    };
462
463
    #[test]
464
    fn test_lincomb() {
465
        let x = ProjectivePoint::random(&mut OsRng);
466
        let y = ProjectivePoint::random(&mut OsRng);
467
        let k = Scalar::random(&mut OsRng);
468
        let l = Scalar::random(&mut OsRng);
469
470
        let reference = &x * &k + &y * &l;
471
        let test = ProjectivePoint::lincomb(&x, &k, &y, &l);
472
        assert_eq!(reference, test);
473
    }
474
475
    #[test]
476
    fn test_mul_by_generator() {
477
        let k = Scalar::random(&mut OsRng);
478
        let reference = &ProjectivePoint::GENERATOR * &k;
479
        let test = ProjectivePoint::mul_by_generator(&k);
480
        assert_eq!(reference, test);
481
    }
482
483
    #[cfg(feature = "alloc")]
484
    #[test]
485
    fn test_lincomb_slice() {
486
        let x = ProjectivePoint::random(&mut OsRng);
487
        let y = ProjectivePoint::random(&mut OsRng);
488
        let k = Scalar::random(&mut OsRng);
489
        let l = Scalar::random(&mut OsRng);
490
491
        let reference = &x * &k + &y * &l;
492
        let points_and_scalars = vec![(x, k), (y, l)];
493
494
        let test = ProjectivePoint::lincomb_ext(points_and_scalars.as_slice());
495
        assert_eq!(reference, test);
496
    }
497
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/arithmetic/projective.rs
Line
Count
Source
1
//! Projective points
2
3
#![allow(clippy::op_ref)]
4
5
use super::{AffinePoint, FieldElement, Scalar, CURVE_EQUATION_B_SINGLE};
6
use crate::{CompressedPoint, EncodedPoint, PublicKey, Secp256k1};
7
use core::{
8
    iter::Sum,
9
    ops::{Add, AddAssign, Neg, Sub, SubAssign},
10
};
11
use elliptic_curve::ops::BatchInvert;
12
use elliptic_curve::{
13
    group::{
14
        ff::Field,
15
        prime::{PrimeCurve, PrimeCurveAffine, PrimeGroup},
16
        Curve, Group, GroupEncoding,
17
    },
18
    rand_core::RngCore,
19
    sec1::{FromEncodedPoint, ToEncodedPoint},
20
    subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
21
    zeroize::DefaultIsZeroes,
22
    BatchNormalize, Error, Result,
23
};
24
25
#[cfg(feature = "alloc")]
26
use alloc::vec::Vec;
27
28
#[rustfmt::skip]
29
const ENDOMORPHISM_BETA: FieldElement = FieldElement::from_bytes_unchecked(&[
30
    0x7a, 0xe9, 0x6a, 0x2b, 0x65, 0x7c, 0x07, 0x10,
31
    0x6e, 0x64, 0x47, 0x9e, 0xac, 0x34, 0x34, 0xe9,
32
    0x9c, 0xf0, 0x49, 0x75, 0x12, 0xf5, 0x89, 0x95,
33
    0xc1, 0x39, 0x6c, 0x28, 0x71, 0x95, 0x01, 0xee,
34
]);
35
36
/// A point on the secp256k1 curve in projective coordinates.
37
#[derive(Clone, Copy, Debug)]
38
pub struct ProjectivePoint {
39
    x: FieldElement,
40
    y: FieldElement,
41
    pub(super) z: FieldElement,
42
}
43
44
impl ProjectivePoint {
45
    /// Additive identity of the group: the point at infinity.
46
    pub const IDENTITY: Self = Self {
47
        x: FieldElement::ZERO,
48
        y: FieldElement::ONE,
49
        z: FieldElement::ZERO,
50
    };
51
52
    /// Base point of secp256k1.
53
    pub const GENERATOR: Self = Self {
54
        x: AffinePoint::GENERATOR.x,
55
        y: AffinePoint::GENERATOR.y,
56
        z: FieldElement::ONE,
57
    };
58
59
    /// Returns the additive identity of SECP256k1, also known as the "neutral element" or
60
    /// "point at infinity".
61
    #[deprecated(since = "0.10.2", note = "use `ProjectivePoint::IDENTITY` instead")]
62
0
    pub const fn identity() -> ProjectivePoint {
63
0
        Self::IDENTITY
64
0
    }
65
66
    /// Returns the base point of SECP256k1.
67
    #[deprecated(since = "0.10.2", note = "use `ProjectivePoint::GENERATOR` instead")]
68
0
    pub fn generator() -> ProjectivePoint {
69
0
        Self::GENERATOR
70
0
    }
71
72
    /// Returns the affine representation of this point.
73
523
    pub fn to_affine(&self) -> AffinePoint {
74
523
        self.z
75
523
            .invert()
76
523
            .map(|zinv| self.to_affine_internal(zinv))
77
523
            .unwrap_or_else(|| AffinePoint::IDENTITY)
78
523
    }
79
80
523
    pub(super) fn to_affine_internal(self, zinv: FieldElement) -> AffinePoint {
81
523
        let x = self.x * &zinv;
82
523
        let y = self.y * &zinv;
83
523
        AffinePoint::new(x.normalize(), y.normalize())
84
523
    }
85
86
    /// Returns `-self`.
87
71.1k
    fn neg(&self) -> ProjectivePoint {
88
71.1k
        ProjectivePoint {
89
71.1k
            x: self.x,
90
71.1k
            y: self.y.negate(1).normalize_weak(),
91
71.1k
            z: self.z,
92
71.1k
        }
93
71.1k
    }
94
95
    /// Returns `self + other`.
96
83.6k
    fn add(&self, other: &ProjectivePoint) -> ProjectivePoint {
97
83.6k
        // We implement the complete addition formula from Renes-Costello-Batina 2015
98
83.6k
        // (https://eprint.iacr.org/2015/1060 Algorithm 7).
99
83.6k
100
83.6k
        let xx = self.x * &other.x;
101
83.6k
        let yy = self.y * &other.y;
102
83.6k
        let zz = self.z * &other.z;
103
83.6k
104
83.6k
        let n_xx_yy = (xx + &yy).negate(2);
105
83.6k
        let n_yy_zz = (yy + &zz).negate(2);
106
83.6k
        let n_xx_zz = (xx + &zz).negate(2);
107
83.6k
        let xy_pairs = ((self.x + &self.y) * &(other.x + &other.y)) + &n_xx_yy;
108
83.6k
        let yz_pairs = ((self.y + &self.z) * &(other.y + &other.z)) + &n_yy_zz;
109
83.6k
        let xz_pairs = ((self.x + &self.z) * &(other.x + &other.z)) + &n_xx_zz;
110
83.6k
111
83.6k
        let bzz = zz.mul_single(CURVE_EQUATION_B_SINGLE);
112
83.6k
        let bzz3 = (bzz.double() + &bzz).normalize_weak();
113
83.6k
114
83.6k
        let yy_m_bzz3 = yy + &bzz3.negate(1);
115
83.6k
        let yy_p_bzz3 = yy + &bzz3;
116
83.6k
117
83.6k
        let byz = &yz_pairs
118
83.6k
            .mul_single(CURVE_EQUATION_B_SINGLE)
119
83.6k
            .normalize_weak();
120
83.6k
        let byz3 = (byz.double() + byz).normalize_weak();
121
83.6k
122
83.6k
        let xx3 = xx.double() + &xx;
123
83.6k
        let bxx9 = (xx3.double() + &xx3)
124
83.6k
            .normalize_weak()
125
83.6k
            .mul_single(CURVE_EQUATION_B_SINGLE)
126
83.6k
            .normalize_weak();
127
83.6k
128
83.6k
        let new_x = ((xy_pairs * &yy_m_bzz3) + &(byz3 * &xz_pairs).negate(1)).normalize_weak(); // m1
129
83.6k
        let new_y = ((yy_p_bzz3 * &yy_m_bzz3) + &(bxx9 * &xz_pairs)).normalize_weak();
130
83.6k
        let new_z = ((yz_pairs * &yy_p_bzz3) + &(xx3 * &xy_pairs)).normalize_weak();
131
83.6k
132
83.6k
        ProjectivePoint {
133
83.6k
            x: new_x,
134
83.6k
            y: new_y,
135
83.6k
            z: new_z,
136
83.6k
        }
137
83.6k
    }
138
139
    /// Returns `self + other`.
140
0
    fn add_mixed(&self, other: &AffinePoint) -> ProjectivePoint {
141
0
        // We implement the complete addition formula from Renes-Costello-Batina 2015
142
0
        // (https://eprint.iacr.org/2015/1060 Algorithm 8).
143
0
144
0
        let xx = self.x * &other.x;
145
0
        let yy = self.y * &other.y;
146
0
        let xy_pairs = ((self.x + &self.y) * &(other.x + &other.y)) + &(xx + &yy).negate(2);
147
0
        let yz_pairs = (other.y * &self.z) + &self.y;
148
0
        let xz_pairs = (other.x * &self.z) + &self.x;
149
0
150
0
        let bzz = &self.z.mul_single(CURVE_EQUATION_B_SINGLE);
151
0
        let bzz3 = (bzz.double() + bzz).normalize_weak();
152
0
153
0
        let yy_m_bzz3 = yy + &bzz3.negate(1);
154
0
        let yy_p_bzz3 = yy + &bzz3;
155
0
156
0
        let byz = &yz_pairs
157
0
            .mul_single(CURVE_EQUATION_B_SINGLE)
158
0
            .normalize_weak();
159
0
        let byz3 = (byz.double() + byz).normalize_weak();
160
0
161
0
        let xx3 = xx.double() + &xx;
162
0
        let bxx9 = &(xx3.double() + &xx3)
163
0
            .normalize_weak()
164
0
            .mul_single(CURVE_EQUATION_B_SINGLE)
165
0
            .normalize_weak();
166
0
167
0
        let mut ret = ProjectivePoint {
168
0
            x: ((xy_pairs * &yy_m_bzz3) + &(byz3 * &xz_pairs).negate(1)).normalize_weak(),
169
0
            y: ((yy_p_bzz3 * &yy_m_bzz3) + &(bxx9 * &xz_pairs)).normalize_weak(),
170
0
            z: ((yz_pairs * &yy_p_bzz3) + &(xx3 * &xy_pairs)).normalize_weak(),
171
0
        };
172
0
        ret.conditional_assign(self, other.is_identity());
173
0
        ret
174
0
    }
175
176
    /// Doubles this point.
177
    #[inline]
178
66.9k
    pub fn double(&self) -> ProjectivePoint {
179
66.9k
        // We implement the complete addition formula from Renes-Costello-Batina 2015
180
66.9k
        // (https://eprint.iacr.org/2015/1060 Algorithm 9).
181
66.9k
182
66.9k
        let yy = self.y.square();
183
66.9k
        let zz = self.z.square();
184
66.9k
        let xy2 = (self.x * &self.y).double();
185
66.9k
186
66.9k
        let bzz = &zz.mul_single(CURVE_EQUATION_B_SINGLE);
187
66.9k
        let bzz3 = (bzz.double() + bzz).normalize_weak();
188
66.9k
        let bzz9 = (bzz3.double() + &bzz3).normalize_weak();
189
66.9k
190
66.9k
        let yy_m_bzz9 = yy + &bzz9.negate(1);
191
66.9k
        let yy_p_bzz3 = yy + &bzz3;
192
66.9k
193
66.9k
        let yy_zz = yy * &zz;
194
66.9k
        let yy_zz8 = yy_zz.double().double().double();
195
66.9k
        let t = (yy_zz8.double() + &yy_zz8)
196
66.9k
            .normalize_weak()
197
66.9k
            .mul_single(CURVE_EQUATION_B_SINGLE);
198
66.9k
199
66.9k
        ProjectivePoint {
200
66.9k
            x: xy2 * &yy_m_bzz9,
201
66.9k
            y: ((yy_m_bzz9 * &yy_p_bzz3) + &t).normalize_weak(),
202
66.9k
            z: ((yy * &self.y) * &self.z)
203
66.9k
                .double()
204
66.9k
                .double()
205
66.9k
                .double()
206
66.9k
                .normalize_weak(),
207
66.9k
        }
208
66.9k
    }
209
210
    /// Returns `self - other`.
211
0
    fn sub(&self, other: &ProjectivePoint) -> ProjectivePoint {
212
0
        self.add(&other.neg())
213
0
    }
214
215
    /// Returns `self - other`.
216
0
    fn sub_mixed(&self, other: &AffinePoint) -> ProjectivePoint {
217
0
        self.add_mixed(&other.neg())
218
0
    }
219
220
    /// Calculates SECP256k1 endomorphism: `self * lambda`.
221
1.04k
    pub fn endomorphism(&self) -> Self {
222
1.04k
        Self {
223
1.04k
            x: self.x * &ENDOMORPHISM_BETA,
224
1.04k
            y: self.y,
225
1.04k
            z: self.z,
226
1.04k
        }
227
1.04k
    }
228
229
    /// Check whether `self` is equal to an affine point.
230
    ///
231
    /// This is a lot faster than first converting `self` to an `AffinePoint` and then doing the
232
    /// comparison. It is a little bit faster than converting `other` to a `ProjectivePoint` first.
233
0
    pub fn eq_affine(&self, other: &AffinePoint) -> Choice {
234
0
        // For understanding of this algorithm see Projective equality comment. It's the same except
235
0
        // that we know z = 1 for rhs and we have to check identity as a separate case.
236
0
        let both_identity = self.is_identity() & other.is_identity();
237
0
        let rhs_identity = other.is_identity();
238
0
        let rhs_x = &other.x * &self.z;
239
0
        let x_eq = rhs_x.negate(1).add(&self.x).normalizes_to_zero();
240
0
241
0
        let rhs_y = &other.y * &self.z;
242
0
        let y_eq = rhs_y.negate(1).add(&self.y).normalizes_to_zero();
243
0
244
0
        both_identity | (!rhs_identity & x_eq & y_eq)
245
0
    }
246
}
247
248
impl From<AffinePoint> for ProjectivePoint {
249
523
    fn from(p: AffinePoint) -> Self {
250
523
        let projective = ProjectivePoint {
251
523
            x: p.x,
252
523
            y: p.y,
253
523
            z: FieldElement::ONE,
254
523
        };
255
523
        Self::conditional_select(&projective, &Self::IDENTITY, p.is_identity())
256
523
    }
257
}
258
259
impl<const N: usize> BatchNormalize<[ProjectivePoint; N]> for ProjectivePoint {
260
    type Output = [Self::AffineRepr; N];
261
262
    #[inline]
263
0
    fn batch_normalize(points: &[Self; N]) -> [Self::AffineRepr; N] {
264
0
        let mut zs = [FieldElement::ONE; N];
265
0
        let mut affine_points = [AffinePoint::IDENTITY; N];
266
0
        batch_normalize_generic(points, &mut zs, &mut affine_points);
267
0
        affine_points
268
0
    }
269
}
270
271
#[cfg(feature = "alloc")]
272
impl BatchNormalize<[ProjectivePoint]> for ProjectivePoint {
273
    type Output = Vec<Self::AffineRepr>;
274
275
    #[inline]
276
0
    fn batch_normalize(points: &[Self]) -> Vec<Self::AffineRepr> {
277
0
        let mut zs = vec![FieldElement::ONE; points.len()];
278
0
        let mut affine_points = vec![AffinePoint::IDENTITY; points.len()];
279
0
        batch_normalize_generic(points, zs.as_mut_slice(), &mut affine_points);
280
0
        affine_points
281
0
    }
282
}
283
284
0
fn batch_normalize_generic<P, Z, O>(points: &P, zs: &mut Z, out: &mut O)
285
0
where
286
0
    FieldElement: BatchInvert<Z>,
287
0
    P: AsRef<[ProjectivePoint]> + ?Sized,
288
0
    Z: AsMut<[FieldElement]> + ?Sized,
289
0
    O: AsMut<[AffinePoint]> + ?Sized,
290
0
{
291
0
    let points = points.as_ref();
292
0
    let out = out.as_mut();
293
294
0
    for i in 0..points.len() {
295
0
        // Even a single zero value will fail inversion for the entire batch.
296
0
        // Put a dummy value (above `FieldElement::ONE`) so inversion succeeds
297
0
        // and treat that case specially later-on.
298
0
        zs.as_mut()[i].conditional_assign(&points[i].z, !points[i].z.ct_eq(&FieldElement::ZERO));
299
0
    }
300
301
    // This is safe to unwrap since we assured that all elements are non-zero
302
0
    let zs_inverses = <FieldElement as BatchInvert<Z>>::batch_invert(zs).unwrap();
303
304
0
    for i in 0..out.len() {
305
0
        // If the `z` coordinate is non-zero, we can use it to invert;
306
0
        // otherwise it defaults to the `IDENTITY` value.
307
0
        out[i] = AffinePoint::conditional_select(
308
0
            &points[i].to_affine_internal(zs_inverses.as_ref()[i]),
309
0
            &AffinePoint::IDENTITY,
310
0
            points[i].z.ct_eq(&FieldElement::ZERO),
311
0
        );
312
0
    }
313
0
}
Unexecuted instantiation: _RINvNtNtCsjewTDwKBbyD_4k25610arithmetic10projective23batch_normalize_genericSNtB2_15ProjectivePointSNtNtB4_5field12FieldElementINtNtCsiBl6Lc3cFal_5alloc3vec3VecNtNtB4_6affine11AffinePointEEB6_
Unexecuted instantiation: _RINvNtNtCsjewTDwKBbyD_4k25610arithmetic10projective23batch_normalize_genericSNtB2_15ProjectivePointSNtNtB4_5field12FieldElementSNtNtB4_6affine11AffinePointEB6_
314
315
impl From<&AffinePoint> for ProjectivePoint {
316
523
    fn from(p: &AffinePoint) -> Self {
317
523
        Self::from(*p)
318
523
    }
319
}
320
321
impl From<ProjectivePoint> for AffinePoint {
322
0
    fn from(p: ProjectivePoint) -> AffinePoint {
323
0
        p.to_affine()
324
0
    }
325
}
326
327
impl From<&ProjectivePoint> for AffinePoint {
328
0
    fn from(p: &ProjectivePoint) -> AffinePoint {
329
0
        p.to_affine()
330
0
    }
331
}
332
333
impl FromEncodedPoint<Secp256k1> for ProjectivePoint {
334
0
    fn from_encoded_point(p: &EncodedPoint) -> CtOption<Self> {
335
0
        AffinePoint::from_encoded_point(p).map(ProjectivePoint::from)
336
0
    }
337
}
338
339
impl ToEncodedPoint<Secp256k1> for ProjectivePoint {
340
0
    fn to_encoded_point(&self, compress: bool) -> EncodedPoint {
341
0
        self.to_affine().to_encoded_point(compress)
342
0
    }
343
}
344
345
impl ConditionallySelectable for ProjectivePoint {
346
623k
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
347
623k
        ProjectivePoint {
348
623k
            x: FieldElement::conditional_select(&a.x, &b.x, choice),
349
623k
            y: FieldElement::conditional_select(&a.y, &b.y, choice),
350
623k
            z: FieldElement::conditional_select(&a.z, &b.z, choice),
351
623k
        }
352
623k
    }
353
}
354
355
impl ConstantTimeEq for ProjectivePoint {
356
0
    fn ct_eq(&self, other: &Self) -> Choice {
357
0
        // If both points are not equal to inifinity then they are in the form:
358
0
        //
359
0
        // lhs: (x₁z₁, y₁z₁, z₁), rhs: (x₂z₂, y₂z₂, z₂) where z₁ ≠ 0 and z₂ ≠ 0.
360
0
        // we want to know if x₁ == x₂ and y₁ == y₂
361
0
        // So we multiply the x and y by the opposing z to get:
362
0
        // lhs: (x₁z₁z₂, y₁z₁z₂) rhs: (x₂z₁z₂, y₂z₁z₂)
363
0
        // and check lhs == rhs which implies x₁ == x₂ and y₁ == y₂.
364
0
        //
365
0
        // If one point is infinity it is always in the form (0, y, 0). Note that the above
366
0
        // algorithm still works here. If They are both infinity then they'll both evaluate to (0,0).
367
0
        // If for example the first point is infinity then the above will evaluate to (z₂ * 0, z₂ *
368
0
        // y₂) = (0, z₂y₂) for the first point and (0 * x₂z₂, 0 * y₂z₂) = (0, 0) for the second.
369
0
        //
370
0
        // Since z₂y₂ will never be 0 they will not be equal in this case either.
371
0
        let lhs_x = self.x * &other.z;
372
0
        let rhs_x = other.x * &self.z;
373
0
        let x_eq = rhs_x.negate(1).add(&lhs_x).normalizes_to_zero();
374
0
375
0
        let lhs_y = self.y * &other.z;
376
0
        let rhs_y = other.y * &self.z;
377
0
        let y_eq = rhs_y.negate(1).add(&lhs_y).normalizes_to_zero();
378
0
        x_eq & y_eq
379
0
    }
380
}
381
382
impl PartialEq for ProjectivePoint {
383
0
    fn eq(&self, other: &Self) -> bool {
384
0
        self.ct_eq(other).into()
385
0
    }
386
}
387
388
impl PartialEq<AffinePoint> for ProjectivePoint {
389
0
    fn eq(&self, other: &AffinePoint) -> bool {
390
0
        self.eq_affine(other).into()
391
0
    }
392
}
393
394
impl PartialEq<ProjectivePoint> for AffinePoint {
395
0
    fn eq(&self, other: &ProjectivePoint) -> bool {
396
0
        other.eq_affine(self).into()
397
0
    }
398
}
399
400
impl Eq for ProjectivePoint {}
401
402
impl Group for ProjectivePoint {
403
    type Scalar = Scalar;
404
405
0
    fn random(mut rng: impl RngCore) -> Self {
406
0
        Self::GENERATOR * Scalar::random(&mut rng)
407
0
    }
408
409
0
    fn identity() -> Self {
410
0
        Self::IDENTITY
411
0
    }
412
413
523
    fn generator() -> Self {
414
523
        Self::GENERATOR
415
523
    }
416
417
0
    fn is_identity(&self) -> Choice {
418
0
        self.z.normalizes_to_zero()
419
0
    }
420
421
    #[must_use]
422
0
    fn double(&self) -> Self {
423
0
        Self::double(self)
424
0
    }
425
}
426
427
impl GroupEncoding for ProjectivePoint {
428
    type Repr = CompressedPoint;
429
430
0
    fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
431
0
        <AffinePoint as GroupEncoding>::from_bytes(bytes).map(Into::into)
432
0
    }
433
434
0
    fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
435
0
        // No unchecked conversion possible for compressed points
436
0
        Self::from_bytes(bytes)
437
0
    }
438
439
0
    fn to_bytes(&self) -> Self::Repr {
440
0
        self.to_affine().to_bytes()
441
0
    }
442
}
443
444
impl PrimeGroup for ProjectivePoint {}
445
446
impl Curve for ProjectivePoint {
447
    type AffineRepr = AffinePoint;
448
449
523
    fn to_affine(&self) -> AffinePoint {
450
523
        ProjectivePoint::to_affine(self)
451
523
    }
452
453
    #[cfg(feature = "alloc")]
454
    #[inline]
455
0
    fn batch_normalize(projective: &[Self], affine: &mut [Self::AffineRepr]) {
456
0
        assert_eq!(projective.len(), affine.len());
457
0
        let mut zs = vec![FieldElement::ONE; projective.len()];
458
0
        batch_normalize_generic(projective, zs.as_mut_slice(), affine);
459
0
    }
460
}
461
462
impl PrimeCurve for ProjectivePoint {
463
    type Affine = AffinePoint;
464
}
465
466
impl Default for ProjectivePoint {
467
8.36k
    fn default() -> Self {
468
8.36k
        Self::IDENTITY
469
8.36k
    }
470
}
471
472
impl DefaultIsZeroes for ProjectivePoint {}
473
474
impl Add<&ProjectivePoint> for &ProjectivePoint {
475
    type Output = ProjectivePoint;
476
477
14.6k
    fn add(self, other: &ProjectivePoint) -> ProjectivePoint {
478
14.6k
        ProjectivePoint::add(self, other)
479
14.6k
    }
480
}
481
482
impl Add<ProjectivePoint> for ProjectivePoint {
483
    type Output = ProjectivePoint;
484
485
0
    fn add(self, other: ProjectivePoint) -> ProjectivePoint {
486
0
        ProjectivePoint::add(&self, &other)
487
0
    }
488
}
489
490
impl Add<&ProjectivePoint> for ProjectivePoint {
491
    type Output = ProjectivePoint;
492
493
0
    fn add(self, other: &ProjectivePoint) -> ProjectivePoint {
494
0
        ProjectivePoint::add(&self, other)
495
0
    }
496
}
497
498
impl AddAssign<ProjectivePoint> for ProjectivePoint {
499
0
    fn add_assign(&mut self, rhs: ProjectivePoint) {
500
0
        *self = ProjectivePoint::add(self, &rhs);
501
0
    }
502
}
503
504
impl AddAssign<&ProjectivePoint> for ProjectivePoint {
505
69.0k
    fn add_assign(&mut self, rhs: &ProjectivePoint) {
506
69.0k
        *self = ProjectivePoint::add(self, rhs);
507
69.0k
    }
508
}
509
510
impl Add<AffinePoint> for ProjectivePoint {
511
    type Output = ProjectivePoint;
512
513
0
    fn add(self, other: AffinePoint) -> ProjectivePoint {
514
0
        ProjectivePoint::add_mixed(&self, &other)
515
0
    }
516
}
517
518
impl Add<&AffinePoint> for &ProjectivePoint {
519
    type Output = ProjectivePoint;
520
521
0
    fn add(self, other: &AffinePoint) -> ProjectivePoint {
522
0
        ProjectivePoint::add_mixed(self, other)
523
0
    }
524
}
525
526
impl Add<&AffinePoint> for ProjectivePoint {
527
    type Output = ProjectivePoint;
528
529
0
    fn add(self, other: &AffinePoint) -> ProjectivePoint {
530
0
        ProjectivePoint::add_mixed(&self, other)
531
0
    }
532
}
533
534
impl AddAssign<AffinePoint> for ProjectivePoint {
535
0
    fn add_assign(&mut self, rhs: AffinePoint) {
536
0
        *self = ProjectivePoint::add_mixed(self, &rhs);
537
0
    }
538
}
539
540
impl AddAssign<&AffinePoint> for ProjectivePoint {
541
0
    fn add_assign(&mut self, rhs: &AffinePoint) {
542
0
        *self = ProjectivePoint::add_mixed(self, rhs);
543
0
    }
544
}
545
546
impl Sum for ProjectivePoint {
547
0
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
548
0
        iter.fold(ProjectivePoint::IDENTITY, |a, b| a + b)
549
0
    }
550
}
551
552
impl<'a> Sum<&'a ProjectivePoint> for ProjectivePoint {
553
0
    fn sum<I: Iterator<Item = &'a ProjectivePoint>>(iter: I) -> Self {
554
0
        iter.cloned().sum()
555
0
    }
556
}
557
558
impl Sub<ProjectivePoint> for ProjectivePoint {
559
    type Output = ProjectivePoint;
560
561
0
    fn sub(self, other: ProjectivePoint) -> ProjectivePoint {
562
0
        ProjectivePoint::sub(&self, &other)
563
0
    }
564
}
565
566
impl Sub<&ProjectivePoint> for &ProjectivePoint {
567
    type Output = ProjectivePoint;
568
569
0
    fn sub(self, other: &ProjectivePoint) -> ProjectivePoint {
570
0
        ProjectivePoint::sub(self, other)
571
0
    }
572
}
573
574
impl Sub<&ProjectivePoint> for ProjectivePoint {
575
    type Output = ProjectivePoint;
576
577
0
    fn sub(self, other: &ProjectivePoint) -> ProjectivePoint {
578
0
        ProjectivePoint::sub(&self, other)
579
0
    }
580
}
581
582
impl SubAssign<ProjectivePoint> for ProjectivePoint {
583
0
    fn sub_assign(&mut self, rhs: ProjectivePoint) {
584
0
        *self = ProjectivePoint::sub(self, &rhs);
585
0
    }
586
}
587
588
impl SubAssign<&ProjectivePoint> for ProjectivePoint {
589
0
    fn sub_assign(&mut self, rhs: &ProjectivePoint) {
590
0
        *self = ProjectivePoint::sub(self, rhs);
591
0
    }
592
}
593
594
impl Sub<AffinePoint> for ProjectivePoint {
595
    type Output = ProjectivePoint;
596
597
0
    fn sub(self, other: AffinePoint) -> ProjectivePoint {
598
0
        ProjectivePoint::sub_mixed(&self, &other)
599
0
    }
600
}
601
602
impl Sub<&AffinePoint> for &ProjectivePoint {
603
    type Output = ProjectivePoint;
604
605
0
    fn sub(self, other: &AffinePoint) -> ProjectivePoint {
606
0
        ProjectivePoint::sub_mixed(self, other)
607
0
    }
608
}
609
610
impl Sub<&AffinePoint> for ProjectivePoint {
611
    type Output = ProjectivePoint;
612
613
0
    fn sub(self, other: &AffinePoint) -> ProjectivePoint {
614
0
        ProjectivePoint::sub_mixed(&self, other)
615
0
    }
616
}
617
618
impl SubAssign<AffinePoint> for ProjectivePoint {
619
0
    fn sub_assign(&mut self, rhs: AffinePoint) {
620
0
        *self = ProjectivePoint::sub_mixed(self, &rhs);
621
0
    }
622
}
623
624
impl SubAssign<&AffinePoint> for ProjectivePoint {
625
0
    fn sub_assign(&mut self, rhs: &AffinePoint) {
626
0
        *self = ProjectivePoint::sub_mixed(self, rhs);
627
0
    }
628
}
629
630
impl Neg for ProjectivePoint {
631
    type Output = ProjectivePoint;
632
633
71.1k
    fn neg(self) -> ProjectivePoint {
634
71.1k
        ProjectivePoint::neg(&self)
635
71.1k
    }
636
}
637
638
impl<'a> Neg for &'a ProjectivePoint {
639
    type Output = ProjectivePoint;
640
641
0
    fn neg(self) -> ProjectivePoint {
642
0
        ProjectivePoint::neg(self)
643
0
    }
644
}
645
646
impl From<PublicKey> for ProjectivePoint {
647
0
    fn from(public_key: PublicKey) -> ProjectivePoint {
648
0
        AffinePoint::from(public_key).into()
649
0
    }
650
}
651
652
impl From<&PublicKey> for ProjectivePoint {
653
0
    fn from(public_key: &PublicKey) -> ProjectivePoint {
654
0
        AffinePoint::from(public_key).into()
655
0
    }
656
}
657
658
impl TryFrom<ProjectivePoint> for PublicKey {
659
    type Error = Error;
660
661
0
    fn try_from(point: ProjectivePoint) -> Result<PublicKey> {
662
0
        AffinePoint::from(point).try_into()
663
0
    }
664
}
665
666
impl TryFrom<&ProjectivePoint> for PublicKey {
667
    type Error = Error;
668
669
0
    fn try_from(point: &ProjectivePoint) -> Result<PublicKey> {
670
0
        AffinePoint::from(point).try_into()
671
0
    }
672
}
673
674
#[cfg(test)]
675
mod tests {
676
    use super::{AffinePoint, ProjectivePoint};
677
    use crate::{
678
        test_vectors::group::{ADD_TEST_VECTORS, MUL_TEST_VECTORS},
679
        Scalar,
680
    };
681
    use elliptic_curve::group::{ff::PrimeField, prime::PrimeCurveAffine};
682
    use elliptic_curve::ops::MulByGenerator;
683
    use elliptic_curve::Field;
684
    use elliptic_curve::{group, BatchNormalize};
685
    use rand_core::OsRng;
686
687
    #[cfg(feature = "alloc")]
688
    use alloc::vec::Vec;
689
690
    #[test]
691
    fn affine_to_projective() {
692
        let basepoint_affine = AffinePoint::GENERATOR;
693
        let basepoint_projective = ProjectivePoint::GENERATOR;
694
695
        assert_eq!(
696
            ProjectivePoint::from(basepoint_affine),
697
            basepoint_projective,
698
        );
699
        assert_eq!(basepoint_projective.to_affine(), basepoint_affine);
700
        assert!(!bool::from(basepoint_projective.to_affine().is_identity()));
701
702
        assert!(bool::from(
703
            ProjectivePoint::IDENTITY.to_affine().is_identity()
704
        ));
705
    }
706
707
    #[test]
708
    fn batch_normalize_array() {
709
        let k: Scalar = Scalar::random(&mut OsRng);
710
        let l: Scalar = Scalar::random(&mut OsRng);
711
        let g = ProjectivePoint::mul_by_generator(&k);
712
        let h = ProjectivePoint::mul_by_generator(&l);
713
714
        let mut res = [AffinePoint::IDENTITY; 2];
715
        let expected = [g.to_affine(), h.to_affine()];
716
        assert_eq!(
717
            <ProjectivePoint as BatchNormalize<_>>::batch_normalize(&[g, h]),
718
            expected
719
        );
720
721
        <ProjectivePoint as group::Curve>::batch_normalize(&[g, h], &mut res);
722
        assert_eq!(res, expected);
723
724
        let expected = [g.to_affine(), AffinePoint::IDENTITY];
725
        assert_eq!(
726
            <ProjectivePoint as BatchNormalize<_>>::batch_normalize(&[
727
                g,
728
                ProjectivePoint::IDENTITY
729
            ]),
730
            expected
731
        );
732
733
        <ProjectivePoint as group::Curve>::batch_normalize(
734
            &[g, ProjectivePoint::IDENTITY],
735
            &mut res,
736
        );
737
        assert_eq!(res, expected);
738
    }
739
740
    #[test]
741
    #[cfg(feature = "alloc")]
742
    fn batch_normalize_slice() {
743
        let k: Scalar = Scalar::random(&mut OsRng);
744
        let l: Scalar = Scalar::random(&mut OsRng);
745
        let g = ProjectivePoint::mul_by_generator(&k);
746
        let h = ProjectivePoint::mul_by_generator(&l);
747
748
        let expected = vec![g.to_affine(), h.to_affine()];
749
        let scalars = vec![g, h];
750
        let mut res: Vec<_> =
751
            <ProjectivePoint as BatchNormalize<_>>::batch_normalize(scalars.as_slice());
752
        assert_eq!(res, expected);
753
754
        <ProjectivePoint as group::Curve>::batch_normalize(&[g, h], res.as_mut());
755
        assert_eq!(res.to_vec(), expected);
756
757
        let expected = vec![g.to_affine(), AffinePoint::IDENTITY];
758
        let scalars = vec![g, ProjectivePoint::IDENTITY];
759
        res = <ProjectivePoint as BatchNormalize<_>>::batch_normalize(scalars.as_slice());
760
761
        assert_eq!(res, expected);
762
763
        <ProjectivePoint as group::Curve>::batch_normalize(
764
            &[g, ProjectivePoint::IDENTITY],
765
            res.as_mut(),
766
        );
767
        assert_eq!(res.to_vec(), expected);
768
    }
769
770
    #[test]
771
    fn projective_identity_addition() {
772
        let identity = ProjectivePoint::IDENTITY;
773
        let generator = ProjectivePoint::GENERATOR;
774
775
        assert_eq!(identity + &generator, generator);
776
        assert_eq!(generator + &identity, generator);
777
    }
778
779
    #[test]
780
    fn projective_mixed_addition() {
781
        let identity = ProjectivePoint::IDENTITY;
782
        let basepoint_affine = AffinePoint::GENERATOR;
783
        let basepoint_projective = ProjectivePoint::GENERATOR;
784
785
        assert_eq!(identity + &basepoint_affine, basepoint_projective);
786
        assert_eq!(
787
            basepoint_projective + &basepoint_affine,
788
            basepoint_projective + &basepoint_projective
789
        );
790
    }
791
792
    #[test]
793
    fn test_vector_repeated_add() {
794
        let generator = ProjectivePoint::GENERATOR;
795
        let mut p = generator;
796
797
        for i in 0..ADD_TEST_VECTORS.len() {
798
            let affine = p.to_affine();
799
800
            let (expected_x, expected_y) = ADD_TEST_VECTORS[i];
801
            assert_eq!(affine.x.to_bytes(), expected_x.into());
802
            assert_eq!(affine.y.to_bytes(), expected_y.into());
803
804
            p += &generator;
805
        }
806
    }
807
808
    #[test]
809
    fn test_vector_repeated_add_mixed() {
810
        let generator = AffinePoint::GENERATOR;
811
        let mut p = ProjectivePoint::GENERATOR;
812
813
        for i in 0..ADD_TEST_VECTORS.len() {
814
            let affine = p.to_affine();
815
816
            let (expected_x, expected_y) = ADD_TEST_VECTORS[i];
817
            assert_eq!(affine.x.to_bytes(), expected_x.into());
818
            assert_eq!(affine.y.to_bytes(), expected_y.into());
819
820
            p += &generator;
821
        }
822
    }
823
824
    #[test]
825
    fn test_vector_add_mixed_identity() {
826
        let generator = ProjectivePoint::GENERATOR;
827
        let p0 = generator + ProjectivePoint::IDENTITY;
828
        let p1 = generator + AffinePoint::IDENTITY;
829
        assert_eq!(p0, p1);
830
    }
831
832
    #[test]
833
    fn test_vector_double_generator() {
834
        let generator = ProjectivePoint::GENERATOR;
835
        let mut p = generator;
836
837
        for i in 0..2 {
838
            let affine = p.to_affine();
839
840
            let (expected_x, expected_y) = ADD_TEST_VECTORS[i];
841
            assert_eq!(affine.x.to_bytes(), expected_x.into());
842
            assert_eq!(affine.y.to_bytes(), expected_y.into());
843
844
            p = p.double();
845
        }
846
    }
847
848
    #[test]
849
    fn projective_add_vs_double() {
850
        let generator = ProjectivePoint::GENERATOR;
851
852
        let r1 = generator + &generator;
853
        let r2 = generator.double();
854
        assert_eq!(r1, r2);
855
856
        let r1 = (generator + &generator) + &(generator + &generator);
857
        let r2 = generator.double().double();
858
        assert_eq!(r1, r2);
859
    }
860
861
    #[test]
862
    fn projective_add_and_sub() {
863
        let basepoint_affine = AffinePoint::GENERATOR;
864
        let basepoint_projective = ProjectivePoint::GENERATOR;
865
866
        assert_eq!(
867
            (basepoint_projective + &basepoint_projective) - &basepoint_projective,
868
            basepoint_projective
869
        );
870
        assert_eq!(
871
            (basepoint_projective + &basepoint_affine) - &basepoint_affine,
872
            basepoint_projective
873
        );
874
    }
875
876
    #[test]
877
    fn projective_double_and_sub() {
878
        let generator = ProjectivePoint::GENERATOR;
879
        assert_eq!(generator.double() - &generator, generator);
880
    }
881
882
    #[test]
883
    fn test_vector_scalar_mult() {
884
        let generator = ProjectivePoint::GENERATOR;
885
886
        for (k, coords) in ADD_TEST_VECTORS
887
            .iter()
888
            .enumerate()
889
            .map(|(k, coords)| (Scalar::from(k as u32 + 1), *coords))
890
            .chain(
891
                MUL_TEST_VECTORS
892
                    .iter()
893
                    .cloned()
894
                    .map(|(k, x, y)| (Scalar::from_repr(k.into()).unwrap(), (x, y))),
895
            )
896
        {
897
            let res = (generator * &k).to_affine();
898
            assert_eq!(res.x.to_bytes(), coords.0.into());
899
            assert_eq!(res.y.to_bytes(), coords.1.into());
900
        }
901
    }
902
903
    #[test]
904
    fn projective_equality() {
905
        use core::ops::Neg;
906
        assert_ne!(ProjectivePoint::GENERATOR, ProjectivePoint::IDENTITY);
907
        assert_ne!(ProjectivePoint::IDENTITY, ProjectivePoint::GENERATOR);
908
        assert_eq!(ProjectivePoint::IDENTITY, ProjectivePoint::IDENTITY);
909
        assert_eq!(ProjectivePoint::IDENTITY.neg(), ProjectivePoint::IDENTITY);
910
        assert_eq!(ProjectivePoint::GENERATOR, ProjectivePoint::GENERATOR);
911
        assert_ne!(ProjectivePoint::GENERATOR, ProjectivePoint::GENERATOR.neg());
912
913
        assert_ne!(ProjectivePoint::GENERATOR, AffinePoint::IDENTITY);
914
        assert_ne!(ProjectivePoint::IDENTITY, AffinePoint::GENERATOR);
915
        assert_eq!(ProjectivePoint::IDENTITY, AffinePoint::IDENTITY);
916
        assert_eq!(ProjectivePoint::IDENTITY.neg(), AffinePoint::IDENTITY);
917
        assert_eq!(ProjectivePoint::GENERATOR, AffinePoint::GENERATOR);
918
        assert_ne!(ProjectivePoint::GENERATOR.neg(), AffinePoint::GENERATOR);
919
        assert_eq!(
920
            ProjectivePoint::GENERATOR.neg(),
921
            AffinePoint::GENERATOR.neg()
922
        );
923
    }
924
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/arithmetic/scalar.rs
Line
Count
Source
1
//! Scalar field arithmetic.
2
3
#[cfg_attr(not(target_pointer_width = "64"), path = "scalar/wide32.rs")]
4
#[cfg_attr(target_pointer_width = "64", path = "scalar/wide64.rs")]
5
mod wide;
6
7
pub(crate) use self::wide::WideScalar;
8
9
use crate::{FieldBytes, Secp256k1, WideBytes, ORDER, ORDER_HEX};
10
use core::{
11
    iter::{Product, Sum},
12
    ops::{Add, AddAssign, Mul, MulAssign, Neg, Shr, ShrAssign, Sub, SubAssign},
13
};
14
use elliptic_curve::{
15
    bigint::{prelude::*, Limb, Word, U256, U512},
16
    ff::{self, Field, PrimeField},
17
    ops::{Invert, Reduce, ReduceNonZero},
18
    rand_core::{CryptoRngCore, RngCore},
19
    scalar::{FromUintUnchecked, IsHigh},
20
    subtle::{
21
        Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
22
        CtOption,
23
    },
24
    zeroize::DefaultIsZeroes,
25
    Curve, ScalarPrimitive,
26
};
27
28
#[cfg(feature = "bits")]
29
use {crate::ScalarBits, elliptic_curve::group::ff::PrimeFieldBits};
30
31
#[cfg(feature = "serde")]
32
use serdect::serde::{de, ser, Deserialize, Serialize};
33
34
#[cfg(test)]
35
use num_bigint::{BigUint, ToBigUint};
36
37
/// Constant representing the modulus
38
/// n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
39
const MODULUS: [Word; U256::LIMBS] = ORDER.to_words();
40
41
/// Constant representing the modulus / 2
42
const FRAC_MODULUS_2: U256 = ORDER.shr_vartime(1);
43
44
/// Scalars are elements in the finite field modulo n.
45
///
46
/// # Trait impls
47
///
48
/// Much of the important functionality of scalars is provided by traits from
49
/// the [`ff`](https://docs.rs/ff/) crate, which is re-exported as
50
/// `k256::elliptic_curve::ff`:
51
///
52
/// - [`Field`](https://docs.rs/ff/latest/ff/trait.Field.html) -
53
///   represents elements of finite fields and provides:
54
///   - [`Field::random`](https://docs.rs/ff/latest/ff/trait.Field.html#tymethod.random) -
55
///     generate a random scalar
56
///   - `double`, `square`, and `invert` operations
57
///   - Bounds for [`Add`], [`Sub`], [`Mul`], and [`Neg`] (as well as `*Assign` equivalents)
58
///   - Bounds for [`ConditionallySelectable`] from the `subtle` crate
59
/// - [`PrimeField`](https://docs.rs/ff/latest/ff/trait.PrimeField.html) -
60
///   represents elements of prime fields and provides:
61
///   - `from_repr`/`to_repr` for converting field elements from/to big integers.
62
///   - `multiplicative_generator` and `root_of_unity` constants.
63
/// - [`PrimeFieldBits`](https://docs.rs/ff/latest/ff/trait.PrimeFieldBits.html) -
64
///   operations over field elements represented as bits (requires `bits` feature)
65
///
66
/// Please see the documentation for the relevant traits for more information.
67
///
68
/// # `serde` support
69
///
70
/// When the `serde` feature of this crate is enabled, the `Serialize` and
71
/// `Deserialize` traits are impl'd for this type.
72
///
73
/// The serialization is a fixed-width big endian encoding. When used with
74
/// textual formats, the binary data is encoded as hexadecimal.
75
#[derive(Clone, Copy, Debug, Default, PartialOrd, Ord)]
76
pub struct Scalar(pub(crate) U256);
77
78
impl Scalar {
79
    /// Zero scalar.
80
    pub const ZERO: Self = Self(U256::ZERO);
81
82
    /// Multiplicative identity.
83
    pub const ONE: Self = Self(U256::ONE);
84
85
    /// Checks if the scalar is zero.
86
96.7k
    pub fn is_zero(&self) -> Choice {
87
96.7k
        self.0.is_zero()
88
96.7k
    }
89
90
    /// Returns the SEC1 encoding of this scalar.
91
2.09k
    pub fn to_bytes(&self) -> FieldBytes {
92
2.09k
        self.0.to_be_byte_array()
93
2.09k
    }
94
95
    /// Negates the scalar.
96
2.09k
    pub const fn negate(&self) -> Self {
97
2.09k
        Self(self.0.neg_mod(&ORDER))
98
2.09k
    }
99
100
    /// Returns self + rhs mod n.
101
199k
    pub const fn add(&self, rhs: &Self) -> Self {
102
199k
        Self(self.0.add_mod(&rhs.0, &ORDER))
103
199k
    }
104
105
    /// Returns self - rhs mod n.
106
187k
    pub const fn sub(&self, rhs: &Self) -> Self {
107
187k
        Self(self.0.sub_mod(&rhs.0, &ORDER))
108
187k
    }
109
110
    /// Modulo multiplies two scalars.
111
4.18k
    pub fn mul(&self, rhs: &Scalar) -> Scalar {
112
4.18k
        WideScalar::mul_wide(self, rhs).reduce()
113
4.18k
    }
114
115
    /// Modulo squares the scalar.
116
0
    pub fn square(&self) -> Self {
117
0
        self.mul(self)
118
0
    }
119
120
    /// Right shifts the scalar.
121
    ///
122
    /// Note: not constant-time with respect to the `shift` parameter.
123
375k
    pub fn shr_vartime(&self, shift: usize) -> Scalar {
124
375k
        Self(self.0.shr_vartime(shift))
125
375k
    }
126
127
    /// Inverts the scalar.
128
0
    pub fn invert(&self) -> CtOption<Self> {
129
0
        // Using an addition chain from
130
0
        // https://briansmith.org/ecc-inversion-addition-chains-01#secp256k1_scalar_inversion
131
0
        let x_1 = *self;
132
0
        let x_10 = self.pow2k(1);
133
0
        let x_11 = x_10.mul(&x_1);
134
0
        let x_101 = x_10.mul(&x_11);
135
0
        let x_111 = x_10.mul(&x_101);
136
0
        let x_1001 = x_10.mul(&x_111);
137
0
        let x_1011 = x_10.mul(&x_1001);
138
0
        let x_1101 = x_10.mul(&x_1011);
139
0
140
0
        let x6 = x_1101.pow2k(2).mul(&x_1011);
141
0
        let x8 = x6.pow2k(2).mul(&x_11);
142
0
        let x14 = x8.pow2k(6).mul(&x6);
143
0
        let x28 = x14.pow2k(14).mul(&x14);
144
0
        let x56 = x28.pow2k(28).mul(&x28);
145
0
146
0
        #[rustfmt::skip]
147
0
            let res = x56
148
0
            .pow2k(56).mul(&x56)
149
0
            .pow2k(14).mul(&x14)
150
0
            .pow2k(3).mul(&x_101)
151
0
            .pow2k(4).mul(&x_111)
152
0
            .pow2k(4).mul(&x_101)
153
0
            .pow2k(5).mul(&x_1011)
154
0
            .pow2k(4).mul(&x_1011)
155
0
            .pow2k(4).mul(&x_111)
156
0
            .pow2k(5).mul(&x_111)
157
0
            .pow2k(6).mul(&x_1101)
158
0
            .pow2k(4).mul(&x_101)
159
0
            .pow2k(3).mul(&x_111)
160
0
            .pow2k(5).mul(&x_1001)
161
0
            .pow2k(6).mul(&x_101)
162
0
            .pow2k(10).mul(&x_111)
163
0
            .pow2k(4).mul(&x_111)
164
0
            .pow2k(9).mul(&x8)
165
0
            .pow2k(5).mul(&x_1001)
166
0
            .pow2k(6).mul(&x_1011)
167
0
            .pow2k(4).mul(&x_1101)
168
0
            .pow2k(5).mul(&x_11)
169
0
            .pow2k(6).mul(&x_1101)
170
0
            .pow2k(10).mul(&x_1101)
171
0
            .pow2k(4).mul(&x_1001)
172
0
            .pow2k(6).mul(&x_1)
173
0
            .pow2k(8).mul(&x6);
174
0
175
0
        CtOption::new(res, !self.is_zero())
176
0
    }
177
178
    /// Returns the scalar modulus as a `BigUint` object.
179
    #[cfg(test)]
180
    pub fn modulus_as_biguint() -> BigUint {
181
        Self::ONE.negate().to_biguint().unwrap() + 1.to_biguint().unwrap()
182
    }
183
184
    /// Returns a (nearly) uniformly-random scalar, generated in constant time.
185
0
    pub fn generate_biased(rng: &mut impl CryptoRngCore) -> Self {
186
0
        // We reduce a random 512-bit value into a 256-bit field, which results in a
187
0
        // negligible bias from the uniform distribution, but the process is constant-time.
188
0
        let mut buf = [0u8; 64];
189
0
        rng.fill_bytes(&mut buf);
190
0
        WideScalar::from_bytes(&buf).reduce()
191
0
    }
192
193
    /// Returns a uniformly-random scalar, generated using rejection sampling.
194
    // TODO(tarcieri): make this a `CryptoRng` when `ff` allows it
195
0
    pub fn generate_vartime(rng: &mut impl RngCore) -> Self {
196
0
        let mut bytes = FieldBytes::default();
197
198
        // TODO: pre-generate several scalars to bring the probability of non-constant-timeness down?
199
        loop {
200
0
            rng.fill_bytes(&mut bytes);
201
0
            if let Some(scalar) = Scalar::from_repr(bytes).into() {
202
0
                return scalar;
203
0
            }
204
        }
205
0
    }
206
207
    /// Attempts to parse the given byte array as a scalar.
208
    /// Does not check the result for being in the correct range.
209
0
    pub(crate) const fn from_bytes_unchecked(bytes: &[u8; 32]) -> Self {
210
0
        Self(U256::from_be_slice(bytes))
211
0
    }
212
213
    /// Raises the scalar to the power `2^k`.
214
0
    fn pow2k(&self, k: usize) -> Self {
215
0
        let mut x = *self;
216
0
        for _j in 0..k {
217
0
            x = x.square();
218
0
        }
219
0
        x
220
0
    }
221
}
222
223
impl Field for Scalar {
224
    const ZERO: Self = Self::ZERO;
225
    const ONE: Self = Self::ONE;
226
227
0
    fn random(mut rng: impl RngCore) -> Self {
228
0
        // Uses rejection sampling as the default random generation method,
229
0
        // which produces a uniformly random distribution of scalars.
230
0
        //
231
0
        // This method is not constant time, but should be secure so long as
232
0
        // rejected RNG outputs are unrelated to future ones (which is a
233
0
        // necessary property of a `CryptoRng`).
234
0
        //
235
0
        // With an unbiased RNG, the probability of failing to complete after 4
236
0
        // iterations is vanishingly small.
237
0
        Self::generate_vartime(&mut rng)
238
0
    }
239
240
    #[must_use]
241
0
    fn square(&self) -> Self {
242
0
        Scalar::square(self)
243
0
    }
244
245
    #[must_use]
246
0
    fn double(&self) -> Self {
247
0
        self.add(self)
248
0
    }
249
250
0
    fn invert(&self) -> CtOption<Self> {
251
0
        Scalar::invert(self)
252
0
    }
253
254
    /// Tonelli-Shank's algorithm for q mod 16 = 1
255
    /// <https://eprint.iacr.org/2012/685.pdf> (page 12, algorithm 5)
256
    #[allow(clippy::many_single_char_names)]
257
0
    fn sqrt(&self) -> CtOption<Self> {
258
0
        // Note: `pow_vartime` is constant-time with respect to `self`
259
0
        let w = self.pow_vartime([
260
0
            0x777fa4bd19a06c82,
261
0
            0xfd755db9cd5e9140,
262
0
            0xffffffffffffffff,
263
0
            0x1ffffffffffffff,
264
0
        ]);
265
0
266
0
        let mut v = Self::S;
267
0
        let mut x = *self * w;
268
0
        let mut b = x * w;
269
0
        let mut z = Self::ROOT_OF_UNITY;
270
271
0
        for max_v in (1..=Self::S).rev() {
272
0
            let mut k = 1;
273
0
            let mut tmp = b.square();
274
0
            let mut j_less_than_v = Choice::from(1);
275
276
0
            for j in 2..max_v {
277
0
                let tmp_is_one = tmp.ct_eq(&Self::ONE);
278
0
                let squared = Self::conditional_select(&tmp, &z, tmp_is_one).square();
279
0
                tmp = Self::conditional_select(&squared, &tmp, tmp_is_one);
280
0
                let new_z = Self::conditional_select(&z, &squared, tmp_is_one);
281
0
                j_less_than_v &= !j.ct_eq(&v);
282
0
                k = u32::conditional_select(&j, &k, tmp_is_one);
283
0
                z = Self::conditional_select(&z, &new_z, j_less_than_v);
284
0
            }
285
286
0
            let result = x * z;
287
0
            x = Self::conditional_select(&result, &x, b.ct_eq(&Self::ONE));
288
0
            z = z.square();
289
0
            b *= z;
290
0
            v = k;
291
        }
292
293
0
        CtOption::new(x, x.square().ct_eq(self))
294
0
    }
295
296
0
    fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
297
0
        ff::helpers::sqrt_ratio_generic(num, div)
298
0
    }
299
}
300
301
impl AsRef<Scalar> for Scalar {
302
0
    fn as_ref(&self) -> &Scalar {
303
0
        self
304
0
    }
305
}
306
307
impl PrimeField for Scalar {
308
    type Repr = FieldBytes;
309
310
    const MODULUS: &'static str = ORDER_HEX;
311
    const NUM_BITS: u32 = 256;
312
    const CAPACITY: u32 = 255;
313
    const TWO_INV: Self = Self(U256::from_be_hex(
314
        "7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1",
315
    ));
316
    const MULTIPLICATIVE_GENERATOR: Self = Self(U256::from_u8(7));
317
    const S: u32 = 6;
318
    const ROOT_OF_UNITY: Self = Self(U256::from_be_hex(
319
        "0c1dc060e7a91986df9879a3fbc483a898bdeab680756045992f4b5402b052f2",
320
    ));
321
    const ROOT_OF_UNITY_INV: Self = Self(U256::from_be_hex(
322
        "fd3ae181f12d7096efc7b0c75b8cbb7277a275910aa413c3b6fb30a0884f0d1c",
323
    ));
324
    const DELTA: Self = Self(U256::from_be_hex(
325
        "0000000000000000000cbc21fe4561c8d63b78e780e1341e199417c8c0bb7601",
326
    ));
327
328
    /// Attempts to parse the given byte array as an SEC1-encoded scalar.
329
    ///
330
    /// Returns None if the byte array does not contain a big-endian integer in the range
331
    /// [0, p).
332
0
    fn from_repr(bytes: FieldBytes) -> CtOption<Self> {
333
0
        let inner = U256::from_be_byte_array(bytes);
334
0
        CtOption::new(Self(inner), inner.ct_lt(&Secp256k1::ORDER))
335
0
    }
336
337
0
    fn to_repr(&self) -> FieldBytes {
338
0
        self.to_bytes()
339
0
    }
340
341
560k
    fn is_odd(&self) -> Choice {
342
560k
        self.0.is_odd()
343
560k
    }
344
}
345
346
#[cfg(feature = "bits")]
347
impl PrimeFieldBits for Scalar {
348
    #[cfg(target_pointer_width = "32")]
349
    type ReprBits = [u32; 8];
350
351
    #[cfg(target_pointer_width = "64")]
352
    type ReprBits = [u64; 4];
353
354
    fn to_le_bits(&self) -> ScalarBits {
355
        self.into()
356
    }
357
358
    fn char_le_bits() -> ScalarBits {
359
        ORDER.to_words().into()
360
    }
361
}
362
363
impl DefaultIsZeroes for Scalar {}
364
365
impl From<u32> for Scalar {
366
0
    fn from(k: u32) -> Self {
367
0
        Self(k.into())
368
0
    }
369
}
370
371
impl From<u64> for Scalar {
372
0
    fn from(k: u64) -> Self {
373
0
        Self(k.into())
374
0
    }
375
}
376
377
impl From<u128> for Scalar {
378
0
    fn from(k: u128) -> Self {
379
0
        Self(k.into())
380
0
    }
381
}
382
383
impl From<ScalarPrimitive<Secp256k1>> for Scalar {
384
1.58k
    fn from(scalar: ScalarPrimitive<Secp256k1>) -> Scalar {
385
1.58k
        Scalar(*scalar.as_uint())
386
1.58k
    }
387
}
388
389
impl From<&ScalarPrimitive<Secp256k1>> for Scalar {
390
0
    fn from(scalar: &ScalarPrimitive<Secp256k1>) -> Scalar {
391
0
        Scalar(*scalar.as_uint())
392
0
    }
393
}
394
395
impl From<Scalar> for ScalarPrimitive<Secp256k1> {
396
0
    fn from(scalar: Scalar) -> ScalarPrimitive<Secp256k1> {
397
0
        ScalarPrimitive::from(&scalar)
398
0
    }
399
}
400
401
impl From<&Scalar> for ScalarPrimitive<Secp256k1> {
402
0
    fn from(scalar: &Scalar) -> ScalarPrimitive<Secp256k1> {
403
0
        ScalarPrimitive::new(scalar.0).unwrap()
404
0
    }
405
}
406
407
impl FromUintUnchecked for Scalar {
408
    type Uint = U256;
409
410
98.2k
    fn from_uint_unchecked(uint: Self::Uint) -> Self {
411
98.2k
        Self(uint)
412
98.2k
    }
413
}
414
415
impl Invert for Scalar {
416
    type Output = CtOption<Self>;
417
418
0
    fn invert(&self) -> CtOption<Self> {
419
0
        self.invert()
420
0
    }
421
422
    /// Fast variable-time inversion using Stein's algorithm.
423
    ///
424
    /// Returns none if the scalar is zero.
425
    ///
426
    /// <https://link.springer.com/article/10.1007/s13389-016-0135-4>
427
    ///
428
    /// ⚠️ WARNING!
429
    ///
430
    /// This method should not be used with (unblinded) secret scalars, as its
431
    /// variable-time operation can potentially leak secrets through
432
    /// sidechannels.
433
    #[allow(non_snake_case)]
434
523
    fn invert_vartime(&self) -> CtOption<Self> {
435
523
        let mut u = *self;
436
523
        let mut v = Self::from_uint_unchecked(Secp256k1::ORDER);
437
523
        let mut A = Self::ONE;
438
523
        let mut C = Self::ZERO;
439
440
94.1k
        while !bool::from(u.is_zero()) {
441
            // u-loop
442
186k
            while bool::from(u.is_even()) {
443
92.7k
                u >>= 1;
444
92.7k
445
92.7k
                let was_odd: bool = A.is_odd().into();
446
92.7k
                A >>= 1;
447
92.7k
448
92.7k
                if was_odd {
449
47.6k
                    A += Self::from_uint_unchecked(FRAC_MODULUS_2);
450
47.6k
                    A += Self::ONE;
451
47.6k
                }
452
            }
453
454
            // v-loop
455
187k
            while bool::from(v.is_even()) {
456
94.0k
                v >>= 1;
457
94.0k
458
94.0k
                let was_odd: bool = C.is_odd().into();
459
94.0k
                C >>= 1;
460
94.0k
461
94.0k
                if was_odd {
462
50.0k
                    C += Self::from_uint_unchecked(FRAC_MODULUS_2);
463
50.0k
                    C += Self::ONE;
464
50.0k
                }
465
            }
466
467
            // sub-step
468
93.5k
            if u >= v {
469
49.5k
                u -= &v;
470
49.5k
                A -= &C;
471
49.5k
            } else {
472
44.0k
                v -= &u;
473
44.0k
                C -= &A;
474
44.0k
            }
475
        }
476
477
523
        CtOption::new(C, !self.is_zero())
478
523
    }
479
}
480
481
impl IsHigh for Scalar {
482
2.62k
    fn is_high(&self) -> Choice {
483
2.62k
        self.0.ct_gt(&FRAC_MODULUS_2)
484
2.62k
    }
485
}
486
487
impl Shr<usize> for Scalar {
488
    type Output = Self;
489
490
373k
    fn shr(self, rhs: usize) -> Self::Output {
491
373k
        self.shr_vartime(rhs)
492
373k
    }
493
}
494
495
impl Shr<usize> for &Scalar {
496
    type Output = Scalar;
497
498
2.09k
    fn shr(self, rhs: usize) -> Self::Output {
499
2.09k
        self.shr_vartime(rhs)
500
2.09k
    }
501
}
502
503
impl ShrAssign<usize> for Scalar {
504
373k
    fn shr_assign(&mut self, rhs: usize) {
505
373k
        *self = *self >> rhs;
506
373k
    }
507
}
508
509
impl ConditionallySelectable for Scalar {
510
4.18k
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
511
4.18k
        Self(U256::conditional_select(&a.0, &b.0, choice))
512
4.18k
    }
513
}
514
515
impl ConstantTimeEq for Scalar {
516
2.10k
    fn ct_eq(&self, other: &Self) -> Choice {
517
2.10k
        self.0.ct_eq(&(other.0))
518
2.10k
    }
519
}
520
521
impl PartialEq for Scalar {
522
523
    fn eq(&self, other: &Self) -> bool {
523
523
        self.ct_eq(other).into()
524
523
    }
525
}
526
527
impl Eq for Scalar {}
528
529
impl Neg for Scalar {
530
    type Output = Scalar;
531
532
2.09k
    fn neg(self) -> Scalar {
533
2.09k
        self.negate()
534
2.09k
    }
535
}
536
537
impl Neg for &Scalar {
538
    type Output = Scalar;
539
540
0
    fn neg(self) -> Scalar {
541
0
        self.negate()
542
0
    }
543
}
544
545
impl Add<Scalar> for Scalar {
546
    type Output = Scalar;
547
548
1.04k
    fn add(self, other: Scalar) -> Scalar {
549
1.04k
        Scalar::add(&self, &other)
550
1.04k
    }
551
}
552
553
impl Add<&Scalar> for &Scalar {
554
    type Output = Scalar;
555
556
0
    fn add(self, other: &Scalar) -> Scalar {
557
0
        Scalar::add(self, other)
558
0
    }
559
}
560
561
impl Add<Scalar> for &Scalar {
562
    type Output = Scalar;
563
564
1.04k
    fn add(self, other: Scalar) -> Scalar {
565
1.04k
        Scalar::add(self, &other)
566
1.04k
    }
567
}
568
569
impl Add<&Scalar> for Scalar {
570
    type Output = Scalar;
571
572
0
    fn add(self, other: &Scalar) -> Scalar {
573
0
        Scalar::add(&self, other)
574
0
    }
575
}
576
577
impl AddAssign<Scalar> for Scalar {
578
    #[inline]
579
195k
    fn add_assign(&mut self, rhs: Scalar) {
580
195k
        *self = Scalar::add(self, &rhs);
581
195k
    }
582
}
583
584
impl AddAssign<&Scalar> for Scalar {
585
0
    fn add_assign(&mut self, rhs: &Scalar) {
586
0
        *self = Scalar::add(self, rhs);
587
0
    }
588
}
589
590
impl Sub<Scalar> for Scalar {
591
    type Output = Scalar;
592
593
0
    fn sub(self, other: Scalar) -> Scalar {
594
0
        Scalar::sub(&self, &other)
595
0
    }
596
}
597
598
impl Sub<&Scalar> for &Scalar {
599
    type Output = Scalar;
600
601
0
    fn sub(self, other: &Scalar) -> Scalar {
602
0
        Scalar::sub(self, other)
603
0
    }
604
}
605
606
impl Sub<&Scalar> for Scalar {
607
    type Output = Scalar;
608
609
0
    fn sub(self, other: &Scalar) -> Scalar {
610
0
        Scalar::sub(&self, other)
611
0
    }
612
}
613
614
impl SubAssign<Scalar> for Scalar {
615
0
    fn sub_assign(&mut self, rhs: Scalar) {
616
0
        *self = Scalar::sub(self, &rhs);
617
0
    }
618
}
619
620
impl SubAssign<&Scalar> for Scalar {
621
187k
    fn sub_assign(&mut self, rhs: &Scalar) {
622
187k
        *self = Scalar::sub(self, rhs);
623
187k
    }
624
}
625
626
impl Mul<Scalar> for Scalar {
627
    type Output = Scalar;
628
629
4.18k
    fn mul(self, other: Scalar) -> Scalar {
630
4.18k
        Scalar::mul(&self, &other)
631
4.18k
    }
632
}
633
634
impl Mul<&Scalar> for &Scalar {
635
    type Output = Scalar;
636
637
0
    fn mul(self, other: &Scalar) -> Scalar {
638
0
        Scalar::mul(self, other)
639
0
    }
640
}
641
642
impl Mul<&Scalar> for Scalar {
643
    type Output = Scalar;
644
645
0
    fn mul(self, other: &Scalar) -> Scalar {
646
0
        Scalar::mul(&self, other)
647
0
    }
648
}
649
650
impl MulAssign<Scalar> for Scalar {
651
0
    fn mul_assign(&mut self, rhs: Scalar) {
652
0
        *self = Scalar::mul(self, &rhs);
653
0
    }
654
}
655
656
impl MulAssign<&Scalar> for Scalar {
657
0
    fn mul_assign(&mut self, rhs: &Scalar) {
658
0
        *self = Scalar::mul(self, rhs);
659
0
    }
660
}
661
662
impl Reduce<U256> for Scalar {
663
    type Bytes = FieldBytes;
664
665
1.04k
    fn reduce(w: U256) -> Self {
666
1.04k
        let (r, underflow) = w.sbb(&ORDER, Limb::ZERO);
667
1.04k
        let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8);
668
1.04k
        Self(U256::conditional_select(&w, &r, !underflow))
669
1.04k
    }
670
671
    #[inline]
672
1.04k
    fn reduce_bytes(bytes: &FieldBytes) -> Self {
673
1.04k
        Self::reduce(U256::from_be_byte_array(*bytes))
674
1.04k
    }
675
}
676
677
impl Reduce<U512> for Scalar {
678
    type Bytes = WideBytes;
679
680
0
    fn reduce(w: U512) -> Self {
681
0
        WideScalar(w).reduce()
682
0
    }
683
684
0
    fn reduce_bytes(bytes: &WideBytes) -> Self {
685
0
        Self::reduce(U512::from_be_byte_array(*bytes))
686
0
    }
687
}
688
689
impl ReduceNonZero<U256> for Scalar {
690
0
    fn reduce_nonzero(w: U256) -> Self {
691
        const ORDER_MINUS_ONE: U256 = ORDER.wrapping_sub(&U256::ONE);
692
0
        let (r, underflow) = w.sbb(&ORDER_MINUS_ONE, Limb::ZERO);
693
0
        let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8);
694
0
        Self(U256::conditional_select(&w, &r, !underflow).wrapping_add(&U256::ONE))
695
0
    }
696
697
    #[inline]
698
0
    fn reduce_nonzero_bytes(bytes: &FieldBytes) -> Self {
699
0
        Self::reduce_nonzero(U256::from_be_byte_array(*bytes))
700
0
    }
701
}
702
703
impl ReduceNonZero<U512> for Scalar {
704
0
    fn reduce_nonzero(w: U512) -> Self {
705
0
        WideScalar(w).reduce_nonzero()
706
0
    }
707
708
    #[inline]
709
0
    fn reduce_nonzero_bytes(bytes: &WideBytes) -> Self {
710
0
        Self::reduce_nonzero(U512::from_be_byte_array(*bytes))
711
0
    }
712
}
713
714
impl Sum for Scalar {
715
0
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
716
0
        iter.reduce(core::ops::Add::add).unwrap_or(Self::ZERO)
717
0
    }
718
}
719
720
impl<'a> Sum<&'a Scalar> for Scalar {
721
0
    fn sum<I: Iterator<Item = &'a Scalar>>(iter: I) -> Self {
722
0
        iter.copied().sum()
723
0
    }
724
}
725
726
impl Product for Scalar {
727
0
    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
728
0
        iter.reduce(core::ops::Mul::mul).unwrap_or(Self::ONE)
729
0
    }
730
}
731
732
impl<'a> Product<&'a Scalar> for Scalar {
733
0
    fn product<I: Iterator<Item = &'a Scalar>>(iter: I) -> Self {
734
0
        iter.copied().product()
735
0
    }
736
}
737
738
#[cfg(feature = "bits")]
739
impl From<&Scalar> for ScalarBits {
740
    fn from(scalar: &Scalar) -> ScalarBits {
741
        scalar.0.to_words().into()
742
    }
743
}
744
745
impl From<Scalar> for FieldBytes {
746
0
    fn from(scalar: Scalar) -> Self {
747
0
        scalar.to_bytes()
748
0
    }
749
}
750
751
impl From<&Scalar> for FieldBytes {
752
0
    fn from(scalar: &Scalar) -> Self {
753
0
        scalar.to_bytes()
754
0
    }
755
}
756
757
impl From<Scalar> for U256 {
758
0
    fn from(scalar: Scalar) -> Self {
759
0
        scalar.0
760
0
    }
761
}
762
763
impl From<&Scalar> for U256 {
764
0
    fn from(scalar: &Scalar) -> Self {
765
0
        scalar.0
766
0
    }
767
}
768
769
#[cfg(feature = "serde")]
770
impl Serialize for Scalar {
771
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
772
    where
773
        S: ser::Serializer,
774
    {
775
        ScalarPrimitive::from(self).serialize(serializer)
776
    }
777
}
778
779
#[cfg(feature = "serde")]
780
impl<'de> Deserialize<'de> for Scalar {
781
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
782
    where
783
        D: de::Deserializer<'de>,
784
    {
785
        Ok(ScalarPrimitive::deserialize(deserializer)?.into())
786
    }
787
}
788
789
#[cfg(test)]
790
mod tests {
791
    use super::Scalar;
792
    use crate::{
793
        arithmetic::dev::{biguint_to_bytes, bytes_to_biguint},
794
        FieldBytes, NonZeroScalar, WideBytes, ORDER,
795
    };
796
    use elliptic_curve::{
797
        bigint::{ArrayEncoding, U256, U512},
798
        ff::{Field, PrimeField},
799
        generic_array::GenericArray,
800
        ops::{Invert, Reduce},
801
        scalar::IsHigh,
802
    };
803
    use num_bigint::{BigUint, ToBigUint};
804
    use num_traits::Zero;
805
    use proptest::prelude::*;
806
    use rand_core::OsRng;
807
808
    #[cfg(feature = "alloc")]
809
    use alloc::vec::Vec;
810
    use elliptic_curve::ops::BatchInvert;
811
812
    impl From<&BigUint> for Scalar {
813
        fn from(x: &BigUint) -> Self {
814
            debug_assert!(x < &Scalar::modulus_as_biguint());
815
            let bytes = biguint_to_bytes(x);
816
            Self::from_repr(bytes.into()).unwrap()
817
        }
818
    }
819
820
    impl From<BigUint> for Scalar {
821
        fn from(x: BigUint) -> Self {
822
            Self::from(&x)
823
        }
824
    }
825
826
    impl ToBigUint for Scalar {
827
        fn to_biguint(&self) -> Option<BigUint> {
828
            Some(bytes_to_biguint(self.to_bytes().as_ref()))
829
        }
830
    }
831
832
    /// t = (modulus - 1) >> S
833
    const T: [u64; 4] = [
834
        0xeeff497a3340d905,
835
        0xfaeabb739abd2280,
836
        0xffffffffffffffff,
837
        0x03ffffffffffffff,
838
    ];
839
840
    #[test]
841
    fn two_inv_constant() {
842
        assert_eq!(Scalar::from(2u32) * Scalar::TWO_INV, Scalar::ONE);
843
    }
844
845
    #[test]
846
    fn root_of_unity_constant() {
847
        // ROOT_OF_UNITY^{2^s} mod m == 1
848
        assert_eq!(
849
            Scalar::ROOT_OF_UNITY.pow_vartime(&[1u64 << Scalar::S, 0, 0, 0]),
850
            Scalar::ONE
851
        );
852
853
        // MULTIPLICATIVE_GENERATOR^{t} mod m == ROOT_OF_UNITY
854
        assert_eq!(
855
            Scalar::MULTIPLICATIVE_GENERATOR.pow_vartime(&T),
856
            Scalar::ROOT_OF_UNITY
857
        )
858
    }
859
860
    #[test]
861
    fn root_of_unity_inv_constant() {
862
        assert_eq!(
863
            Scalar::ROOT_OF_UNITY * Scalar::ROOT_OF_UNITY_INV,
864
            Scalar::ONE
865
        );
866
    }
867
868
    #[test]
869
    fn delta_constant() {
870
        // DELTA^{t} mod m == 1
871
        assert_eq!(Scalar::DELTA.pow_vartime(&T), Scalar::ONE);
872
    }
873
874
    #[test]
875
    fn is_high() {
876
        // 0 is not high
877
        let high: bool = Scalar::ZERO.is_high().into();
878
        assert!(!high);
879
880
        // 1 is not high
881
        let one = 1.to_biguint().unwrap();
882
        let high: bool = Scalar::from(&one).is_high().into();
883
        assert!(!high);
884
885
        let m = Scalar::modulus_as_biguint();
886
        let m_by_2 = &m >> 1;
887
888
        // M / 2 is not high
889
        let high: bool = Scalar::from(&m_by_2).is_high().into();
890
        assert!(!high);
891
892
        // M / 2 + 1 is high
893
        let high: bool = Scalar::from(&m_by_2 + &one).is_high().into();
894
        assert!(high);
895
896
        // MODULUS - 1 is high
897
        let high: bool = Scalar::from(&m - &one).is_high().into();
898
        assert!(high);
899
    }
900
901
    /// Basic tests that sqrt works.
902
    #[test]
903
    fn sqrt() {
904
        for &n in &[1u64, 4, 9, 16, 25, 36, 49, 64] {
905
            let scalar = Scalar::from(n);
906
            let sqrt = scalar.sqrt().unwrap();
907
            assert_eq!(sqrt.square(), scalar);
908
        }
909
    }
910
911
    /// Basic tests that `invert` works.
912
    #[test]
913
    fn invert() {
914
        assert_eq!(Scalar::ONE, Scalar::ONE.invert().unwrap());
915
916
        let three = Scalar::from(3u64);
917
        let inv_three = three.invert().unwrap();
918
        assert_eq!(three * inv_three, Scalar::ONE);
919
920
        let minus_three = -three;
921
        let inv_minus_three = minus_three.invert().unwrap();
922
        assert_eq!(inv_minus_three, -inv_three);
923
        assert_eq!(three * inv_minus_three, -Scalar::ONE);
924
925
        assert!(bool::from(Scalar::ZERO.invert().is_none()));
926
        assert_eq!(Scalar::from(2u64).invert().unwrap(), Scalar::TWO_INV);
927
        assert_eq!(
928
            Scalar::ROOT_OF_UNITY.invert_vartime().unwrap(),
929
            Scalar::ROOT_OF_UNITY_INV
930
        );
931
    }
932
933
    /// Basic tests that `invert_vartime` works.
934
    #[test]
935
    fn invert_vartime() {
936
        assert_eq!(Scalar::ONE, Scalar::ONE.invert_vartime().unwrap());
937
938
        let three = Scalar::from(3u64);
939
        let inv_three = three.invert_vartime().unwrap();
940
        assert_eq!(three * inv_three, Scalar::ONE);
941
942
        let minus_three = -three;
943
        let inv_minus_three = minus_three.invert_vartime().unwrap();
944
        assert_eq!(inv_minus_three, -inv_three);
945
        assert_eq!(three * inv_minus_three, -Scalar::ONE);
946
947
        assert!(bool::from(Scalar::ZERO.invert_vartime().is_none()));
948
        assert_eq!(
949
            Scalar::from(2u64).invert_vartime().unwrap(),
950
            Scalar::TWO_INV
951
        );
952
        assert_eq!(
953
            Scalar::ROOT_OF_UNITY.invert_vartime().unwrap(),
954
            Scalar::ROOT_OF_UNITY_INV
955
        );
956
    }
957
958
    #[test]
959
    fn batch_invert_array() {
960
        let k: Scalar = Scalar::random(&mut OsRng);
961
        let l: Scalar = Scalar::random(&mut OsRng);
962
963
        let expected = [k.invert().unwrap(), l.invert().unwrap()];
964
        assert_eq!(
965
            <Scalar as BatchInvert<_>>::batch_invert(&[k, l]).unwrap(),
966
            expected
967
        );
968
    }
969
970
    #[test]
971
    #[cfg(feature = "alloc")]
972
    fn batch_invert() {
973
        let k: Scalar = Scalar::random(&mut OsRng);
974
        let l: Scalar = Scalar::random(&mut OsRng);
975
976
        let expected = vec![k.invert().unwrap(), l.invert().unwrap()];
977
        let scalars = vec![k, l];
978
        let res: Vec<_> = <Scalar as BatchInvert<_>>::batch_invert(scalars.as_slice()).unwrap();
979
        assert_eq!(res, expected);
980
    }
981
982
    #[test]
983
    fn negate() {
984
        let zero_neg = -Scalar::ZERO;
985
        assert_eq!(zero_neg, Scalar::ZERO);
986
987
        let m = Scalar::modulus_as_biguint();
988
        let one = 1.to_biguint().unwrap();
989
        let m_minus_one = &m - &one;
990
        let m_by_2 = &m >> 1;
991
992
        let one_neg = -Scalar::ONE;
993
        assert_eq!(one_neg, Scalar::from(&m_minus_one));
994
995
        let frac_modulus_2_neg = -Scalar::from(&m_by_2);
996
        let frac_modulus_2_plus_one = Scalar::from(&m_by_2 + &one);
997
        assert_eq!(frac_modulus_2_neg, frac_modulus_2_plus_one);
998
999
        let modulus_minus_one_neg = -Scalar::from(&m - &one);
1000
        assert_eq!(modulus_minus_one_neg, Scalar::ONE);
1001
    }
1002
1003
    #[test]
1004
    fn add_result_within_256_bits() {
1005
        // A regression for a bug where reduction was not applied
1006
        // when the unreduced result of addition was in the range `[modulus, 2^256)`.
1007
        let t = 1.to_biguint().unwrap() << 255;
1008
        let one = 1.to_biguint().unwrap();
1009
1010
        let a = Scalar::from(&t - &one);
1011
        let b = Scalar::from(&t);
1012
        let res = &a + &b;
1013
1014
        let m = Scalar::modulus_as_biguint();
1015
        let res_ref = Scalar::from((&t + &t - &one) % &m);
1016
1017
        assert_eq!(res, res_ref);
1018
    }
1019
1020
    #[test]
1021
    fn generate_biased() {
1022
        use elliptic_curve::rand_core::OsRng;
1023
        let a = Scalar::generate_biased(&mut OsRng);
1024
        // just to make sure `a` is not optimized out by the compiler
1025
        assert_eq!((a - &a).is_zero().unwrap_u8(), 1);
1026
    }
1027
1028
    #[test]
1029
    fn generate_vartime() {
1030
        use elliptic_curve::rand_core::OsRng;
1031
        let a = Scalar::generate_vartime(&mut OsRng);
1032
        // just to make sure `a` is not optimized out by the compiler
1033
        assert_eq!((a - &a).is_zero().unwrap_u8(), 1);
1034
    }
1035
1036
    #[test]
1037
    fn from_bytes_reduced() {
1038
        let m = Scalar::modulus_as_biguint();
1039
1040
        fn reduce<T: Reduce<U256, Bytes = FieldBytes>>(arr: &[u8]) -> T {
1041
            T::reduce_bytes(GenericArray::from_slice(arr))
1042
        }
1043
1044
        // Regular reduction
1045
1046
        let s = reduce::<Scalar>(&[0xffu8; 32]).to_biguint().unwrap();
1047
        assert!(s < m);
1048
1049
        let s = reduce::<Scalar>(&[0u8; 32]).to_biguint().unwrap();
1050
        assert!(s.is_zero());
1051
1052
        let s = reduce::<Scalar>(&ORDER.to_be_byte_array())
1053
            .to_biguint()
1054
            .unwrap();
1055
        assert!(s.is_zero());
1056
1057
        // Reduction to a non-zero scalar
1058
1059
        let s = reduce::<NonZeroScalar>(&[0xffu8; 32]).to_biguint().unwrap();
1060
        assert!(s < m);
1061
1062
        let s = reduce::<NonZeroScalar>(&[0u8; 32]).to_biguint().unwrap();
1063
        assert!(s < m);
1064
        assert!(!s.is_zero());
1065
1066
        let s = reduce::<NonZeroScalar>(&ORDER.to_be_byte_array())
1067
            .to_biguint()
1068
            .unwrap();
1069
        assert!(s < m);
1070
        assert!(!s.is_zero());
1071
1072
        let s = reduce::<NonZeroScalar>(&(ORDER.wrapping_sub(&U256::ONE)).to_be_byte_array())
1073
            .to_biguint()
1074
            .unwrap();
1075
        assert!(s < m);
1076
        assert!(!s.is_zero());
1077
    }
1078
1079
    #[test]
1080
    fn from_wide_bytes_reduced() {
1081
        let m = Scalar::modulus_as_biguint();
1082
1083
        fn reduce<T: Reduce<U512, Bytes = WideBytes>>(slice: &[u8]) -> T {
1084
            let mut bytes = WideBytes::default();
1085
            bytes[(64 - slice.len())..].copy_from_slice(slice);
1086
            T::reduce_bytes(&bytes)
1087
        }
1088
1089
        // Regular reduction
1090
1091
        let s = reduce::<Scalar>(&[0xffu8; 64]).to_biguint().unwrap();
1092
        assert!(s < m);
1093
1094
        let s = reduce::<Scalar>(&[0u8; 64]).to_biguint().unwrap();
1095
        assert!(s.is_zero());
1096
1097
        let s = reduce::<Scalar>(&ORDER.to_be_byte_array())
1098
            .to_biguint()
1099
            .unwrap();
1100
        assert!(s.is_zero());
1101
1102
        // Reduction to a non-zero scalar
1103
1104
        let s = reduce::<NonZeroScalar>(&[0xffu8; 64]).to_biguint().unwrap();
1105
        assert!(s < m);
1106
1107
        let s = reduce::<NonZeroScalar>(&[0u8; 64]).to_biguint().unwrap();
1108
        assert!(s < m);
1109
        assert!(!s.is_zero());
1110
1111
        let s = reduce::<NonZeroScalar>(&ORDER.to_be_byte_array())
1112
            .to_biguint()
1113
            .unwrap();
1114
        assert!(s < m);
1115
        assert!(!s.is_zero());
1116
1117
        let s = reduce::<NonZeroScalar>(&(ORDER.wrapping_sub(&U256::ONE)).to_be_byte_array())
1118
            .to_biguint()
1119
            .unwrap();
1120
        assert!(s < m);
1121
        assert!(!s.is_zero());
1122
    }
1123
1124
    prop_compose! {
1125
        fn scalar()(bytes in any::<[u8; 32]>()) -> Scalar {
1126
            <Scalar as Reduce<U256>>::reduce_bytes(&bytes.into())
1127
        }
1128
    }
1129
1130
    proptest! {
1131
        #[test]
1132
        fn fuzzy_roundtrip_to_bytes(a in scalar()) {
1133
            let a_back = Scalar::from_repr(a.to_bytes()).unwrap();
1134
            assert_eq!(a, a_back);
1135
        }
1136
1137
        #[test]
1138
        fn fuzzy_roundtrip_to_bytes_unchecked(a in scalar()) {
1139
            let bytes = a.to_bytes();
1140
            let a_back = Scalar::from_bytes_unchecked(bytes.as_ref());
1141
            assert_eq!(a, a_back);
1142
        }
1143
1144
        #[test]
1145
        fn fuzzy_add(a in scalar(), b in scalar()) {
1146
            let a_bi = a.to_biguint().unwrap();
1147
            let b_bi = b.to_biguint().unwrap();
1148
1149
            let res_bi = (&a_bi + &b_bi) % &Scalar::modulus_as_biguint();
1150
            let res_ref = Scalar::from(&res_bi);
1151
            let res_test = a.add(&b);
1152
1153
            assert_eq!(res_ref, res_test);
1154
        }
1155
1156
        #[test]
1157
        fn fuzzy_sub(a in scalar(), b in scalar()) {
1158
            let a_bi = a.to_biguint().unwrap();
1159
            let b_bi = b.to_biguint().unwrap();
1160
1161
            let m = Scalar::modulus_as_biguint();
1162
            let res_bi = (&m + &a_bi - &b_bi) % &m;
1163
            let res_ref = Scalar::from(&res_bi);
1164
            let res_test = a.sub(&b);
1165
1166
            assert_eq!(res_ref, res_test);
1167
        }
1168
1169
        #[test]
1170
        fn fuzzy_neg(a in scalar()) {
1171
            let a_bi = a.to_biguint().unwrap();
1172
1173
            let m = Scalar::modulus_as_biguint();
1174
            let res_bi = (&m - &a_bi) % &m;
1175
            let res_ref = Scalar::from(&res_bi);
1176
            let res_test = -a;
1177
1178
            assert_eq!(res_ref, res_test);
1179
        }
1180
1181
        #[test]
1182
        fn fuzzy_mul(a in scalar(), b in scalar()) {
1183
            let a_bi = a.to_biguint().unwrap();
1184
            let b_bi = b.to_biguint().unwrap();
1185
1186
            let res_bi = (&a_bi * &b_bi) % &Scalar::modulus_as_biguint();
1187
            let res_ref = Scalar::from(&res_bi);
1188
            let res_test = a.mul(&b);
1189
1190
            assert_eq!(res_ref, res_test);
1191
        }
1192
1193
        #[test]
1194
        fn fuzzy_rshift(a in scalar(), b in 0usize..512) {
1195
            let a_bi = a.to_biguint().unwrap();
1196
1197
            let res_bi = &a_bi >> b;
1198
            let res_ref = Scalar::from(&res_bi);
1199
            let res_test = a >> b;
1200
1201
            assert_eq!(res_ref, res_test);
1202
        }
1203
1204
        #[test]
1205
        fn fuzzy_invert(
1206
            a in scalar()
1207
        ) {
1208
            let a = if bool::from(a.is_zero()) { Scalar::ONE } else { a };
1209
            let a_bi = a.to_biguint().unwrap();
1210
            let inv = a.invert().unwrap();
1211
            let inv_bi = inv.to_biguint().unwrap();
1212
            let m = Scalar::modulus_as_biguint();
1213
            assert_eq!((&inv_bi * &a_bi) % &m, 1.to_biguint().unwrap());
1214
        }
1215
1216
        #[test]
1217
        fn fuzzy_invert_vartime(w in scalar()) {
1218
            let inv: Option<Scalar> = w.invert().into();
1219
            let inv_vartime: Option<Scalar> = w.invert_vartime().into();
1220
            assert_eq!(inv, inv_vartime);
1221
        }
1222
1223
        #[test]
1224
        fn fuzzy_from_wide_bytes_reduced(bytes_hi in any::<[u8; 32]>(), bytes_lo in any::<[u8; 32]>()) {
1225
            let m = Scalar::modulus_as_biguint();
1226
            let mut bytes = [0u8; 64];
1227
            bytes[0..32].clone_from_slice(&bytes_hi);
1228
            bytes[32..64].clone_from_slice(&bytes_lo);
1229
            let s = <Scalar as Reduce<U512>>::reduce(U512::from_be_slice(&bytes));
1230
            let s_bu = s.to_biguint().unwrap();
1231
            assert!(s_bu < m);
1232
        }
1233
    }
1234
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/arithmetic/scalar/wide64.rs
Line
Count
Source
1
//! Wide scalar (64-bit limbs)
2
3
use super::{Scalar, MODULUS};
4
use crate::ORDER;
5
use elliptic_curve::{
6
    bigint::{Limb, U256, U512},
7
    subtle::{Choice, ConditionallySelectable},
8
};
9
10
/// Limbs of 2^256 minus the secp256k1 order.
11
const NEG_MODULUS: [u64; 4] = [!MODULUS[0] + 1, !MODULUS[1], !MODULUS[2], !MODULUS[3]];
12
13
#[derive(Clone, Copy, Debug, Default)]
14
pub(crate) struct WideScalar(pub(super) U512);
15
16
impl WideScalar {
17
0
    pub const fn from_bytes(bytes: &[u8; 64]) -> Self {
18
0
        Self(U512::from_be_slice(bytes))
19
0
    }
20
21
    /// Multiplies two scalars without modulo reduction, producing up to a 512-bit scalar.
22
    #[inline(always)] // only used in Scalar::mul(), so won't cause binary bloat
23
6.27k
    pub fn mul_wide(a: &Scalar, b: &Scalar) -> Self {
24
6.27k
        let a = a.0.to_words();
25
6.27k
        let b = b.0.to_words();
26
6.27k
27
6.27k
        // 160 bit accumulator.
28
6.27k
        let c0 = 0;
29
6.27k
        let c1 = 0;
30
6.27k
        let c2 = 0;
31
6.27k
32
6.27k
        // l[0..7] = a[0..3] * b[0..3].
33
6.27k
        let (c0, c1) = muladd_fast(a[0], b[0], c0, c1);
34
6.27k
        let (l0, c0, c1) = (c0, c1, 0);
35
6.27k
        let (c0, c1, c2) = muladd(a[0], b[1], c0, c1, c2);
36
6.27k
        let (c0, c1, c2) = muladd(a[1], b[0], c0, c1, c2);
37
6.27k
        let (l1, c0, c1, c2) = (c0, c1, c2, 0);
38
6.27k
        let (c0, c1, c2) = muladd(a[0], b[2], c0, c1, c2);
39
6.27k
        let (c0, c1, c2) = muladd(a[1], b[1], c0, c1, c2);
40
6.27k
        let (c0, c1, c2) = muladd(a[2], b[0], c0, c1, c2);
41
6.27k
        let (l2, c0, c1, c2) = (c0, c1, c2, 0);
42
6.27k
        let (c0, c1, c2) = muladd(a[0], b[3], c0, c1, c2);
43
6.27k
        let (c0, c1, c2) = muladd(a[1], b[2], c0, c1, c2);
44
6.27k
        let (c0, c1, c2) = muladd(a[2], b[1], c0, c1, c2);
45
6.27k
        let (c0, c1, c2) = muladd(a[3], b[0], c0, c1, c2);
46
6.27k
        let (l3, c0, c1, c2) = (c0, c1, c2, 0);
47
6.27k
        let (c0, c1, c2) = muladd(a[1], b[3], c0, c1, c2);
48
6.27k
        let (c0, c1, c2) = muladd(a[2], b[2], c0, c1, c2);
49
6.27k
        let (c0, c1, c2) = muladd(a[3], b[1], c0, c1, c2);
50
6.27k
        let (l4, c0, c1, c2) = (c0, c1, c2, 0);
51
6.27k
        let (c0, c1, c2) = muladd(a[2], b[3], c0, c1, c2);
52
6.27k
        let (c0, c1, c2) = muladd(a[3], b[2], c0, c1, c2);
53
6.27k
        let (l5, c0, c1, _c2) = (c0, c1, c2, 0);
54
6.27k
        let (c0, c1) = muladd_fast(a[3], b[3], c0, c1);
55
6.27k
        let (l6, c0, _c1) = (c0, c1, 0);
56
6.27k
        let l7 = c0;
57
6.27k
58
6.27k
        Self(U512::from_words([l0, l1, l2, l3, l4, l5, l6, l7]))
59
6.27k
    }
60
61
    /// Multiplies `a` by `b` (without modulo reduction) divide the result by `2^shift`
62
    /// (rounding to the nearest integer).
63
    /// Variable time in `shift`.
64
2.09k
    pub(crate) fn mul_shift_vartime(a: &Scalar, b: &Scalar, shift: usize) -> Scalar {
65
2.09k
        debug_assert!(shift >= 256);
66
67
2.09k
        let l = Self::mul_wide(a, b).0.to_words();
68
2.09k
        let shiftlimbs = shift >> 6;
69
2.09k
        let shiftlow = shift & 0x3F;
70
2.09k
        let shifthigh = 64 - shiftlow;
71
72
2.09k
        let r0 = if shift < 512 {
73
2.09k
            let lo = l[shiftlimbs] >> shiftlow;
74
2.09k
            let hi = if shift < 448 && shiftlow != 0 {
75
0
                l[1 + shiftlimbs] << shifthigh
76
            } else {
77
2.09k
                0
78
            };
79
2.09k
            hi | lo
80
        } else {
81
0
            0
82
        };
83
84
2.09k
        let r1 = if shift < 448 {
85
2.09k
            let lo = l[1 + shiftlimbs] >> shiftlow;
86
2.09k
            let hi = if shift < 384 && shiftlow != 0 {
87
0
                l[2 + shiftlimbs] << shifthigh
88
            } else {
89
2.09k
                0
90
            };
91
2.09k
            hi | lo
92
        } else {
93
0
            0
94
        };
95
96
2.09k
        let r2 = if shift < 384 {
97
0
            let lo = l[2 + shiftlimbs] >> shiftlow;
98
0
            let hi = if shift < 320 && shiftlow != 0 {
99
0
                l[3 + shiftlimbs] << shifthigh
100
            } else {
101
0
                0
102
            };
103
0
            hi | lo
104
        } else {
105
2.09k
            0
106
        };
107
108
2.09k
        let r3 = if shift < 320 {
109
0
            l[3 + shiftlimbs] >> shiftlow
110
        } else {
111
2.09k
            0
112
        };
113
114
2.09k
        let res = Scalar(U256::from_words([r0, r1, r2, r3]));
115
2.09k
116
2.09k
        // Check the highmost discarded bit and round up if it is set.
117
2.09k
        let c = (l[(shift - 1) >> 6] >> ((shift - 1) & 0x3f)) & 1;
118
2.09k
        Scalar::conditional_select(&res, &res.add(&Scalar::ONE), Choice::from(c as u8))
119
2.09k
    }
120
121
4.18k
    fn reduce_impl(&self, modulus_minus_one: bool) -> Scalar {
122
4.18k
        let neg_modulus0 = if modulus_minus_one {
123
0
            NEG_MODULUS[0] + 1
124
        } else {
125
4.18k
            NEG_MODULUS[0]
126
        };
127
4.18k
        let modulus = if modulus_minus_one {
128
0
            ORDER.wrapping_sub(&U256::ONE)
129
        } else {
130
4.18k
            ORDER
131
        };
132
133
4.18k
        let w = self.0.to_words();
134
4.18k
        let n0 = w[4];
135
4.18k
        let n1 = w[5];
136
4.18k
        let n2 = w[6];
137
4.18k
        let n3 = w[7];
138
4.18k
139
4.18k
        // Reduce 512 bits into 385.
140
4.18k
        // m[0..6] = self[0..3] + n[0..3] * neg_modulus.
141
4.18k
        let c0 = w[0];
142
4.18k
        let c1 = 0;
143
4.18k
        let c2 = 0;
144
4.18k
        let (c0, c1) = muladd_fast(n0, neg_modulus0, c0, c1);
145
4.18k
        let (m0, c0, c1) = (c0, c1, 0);
146
4.18k
        let (c0, c1) = sumadd_fast(w[1], c0, c1);
147
4.18k
        let (c0, c1, c2) = muladd(n1, neg_modulus0, c0, c1, c2);
148
4.18k
        let (c0, c1, c2) = muladd(n0, NEG_MODULUS[1], c0, c1, c2);
149
4.18k
        let (m1, c0, c1, c2) = (c0, c1, c2, 0);
150
4.18k
        let (c0, c1, c2) = sumadd(w[2], c0, c1, c2);
151
4.18k
        let (c0, c1, c2) = muladd(n2, neg_modulus0, c0, c1, c2);
152
4.18k
        let (c0, c1, c2) = muladd(n1, NEG_MODULUS[1], c0, c1, c2);
153
4.18k
        let (c0, c1, c2) = sumadd(n0, c0, c1, c2);
154
4.18k
        let (m2, c0, c1, c2) = (c0, c1, c2, 0);
155
4.18k
        let (c0, c1, c2) = sumadd(w[3], c0, c1, c2);
156
4.18k
        let (c0, c1, c2) = muladd(n3, neg_modulus0, c0, c1, c2);
157
4.18k
        let (c0, c1, c2) = muladd(n2, NEG_MODULUS[1], c0, c1, c2);
158
4.18k
        let (c0, c1, c2) = sumadd(n1, c0, c1, c2);
159
4.18k
        let (m3, c0, c1, c2) = (c0, c1, c2, 0);
160
4.18k
        let (c0, c1, c2) = muladd(n3, NEG_MODULUS[1], c0, c1, c2);
161
4.18k
        let (c0, c1, c2) = sumadd(n2, c0, c1, c2);
162
4.18k
        let (m4, c0, c1, _c2) = (c0, c1, c2, 0);
163
4.18k
        let (c0, c1) = sumadd_fast(n3, c0, c1);
164
4.18k
        let (m5, c0, _c1) = (c0, c1, 0);
165
4.18k
        debug_assert!(c0 <= 1);
166
4.18k
        let m6 = c0;
167
4.18k
168
4.18k
        // Reduce 385 bits into 258.
169
4.18k
        // p[0..4] = m[0..3] + m[4..6] * neg_modulus.
170
4.18k
        let c0 = m0;
171
4.18k
        let c1 = 0;
172
4.18k
        let c2 = 0;
173
4.18k
        let (c0, c1) = muladd_fast(m4, neg_modulus0, c0, c1);
174
4.18k
        let (p0, c0, c1) = (c0, c1, 0);
175
4.18k
        let (c0, c1) = sumadd_fast(m1, c0, c1);
176
4.18k
        let (c0, c1, c2) = muladd(m5, neg_modulus0, c0, c1, c2);
177
4.18k
        let (c0, c1, c2) = muladd(m4, NEG_MODULUS[1], c0, c1, c2);
178
4.18k
        let (p1, c0, c1) = (c0, c1, 0);
179
4.18k
        let (c0, c1, c2) = sumadd(m2, c0, c1, c2);
180
4.18k
        let (c0, c1, c2) = muladd(m6, neg_modulus0, c0, c1, c2);
181
4.18k
        let (c0, c1, c2) = muladd(m5, NEG_MODULUS[1], c0, c1, c2);
182
4.18k
        let (c0, c1, c2) = sumadd(m4, c0, c1, c2);
183
4.18k
        let (p2, c0, c1, _c2) = (c0, c1, c2, 0);
184
4.18k
        let (c0, c1) = sumadd_fast(m3, c0, c1);
185
4.18k
        let (c0, c1) = muladd_fast(m6, NEG_MODULUS[1], c0, c1);
186
4.18k
        let (c0, c1) = sumadd_fast(m5, c0, c1);
187
4.18k
        let (p3, c0, _c1) = (c0, c1, 0);
188
4.18k
        let p4 = c0 + m6;
189
4.18k
        debug_assert!(p4 <= 2);
190
191
        // Reduce 258 bits into 256.
192
        // r[0..3] = p[0..3] + p[4] * neg_modulus.
193
4.18k
        let mut c = (p0 as u128) + (neg_modulus0 as u128) * (p4 as u128);
194
4.18k
        let r0 = (c & 0xFFFFFFFFFFFFFFFFu128) as u64;
195
4.18k
        c >>= 64;
196
4.18k
        c += (p1 as u128) + (NEG_MODULUS[1] as u128) * (p4 as u128);
197
4.18k
        let r1 = (c & 0xFFFFFFFFFFFFFFFFu128) as u64;
198
4.18k
        c >>= 64;
199
4.18k
        c += (p2 as u128) + (p4 as u128);
200
4.18k
        let r2 = (c & 0xFFFFFFFFFFFFFFFFu128) as u64;
201
4.18k
        c >>= 64;
202
4.18k
        c += p3 as u128;
203
4.18k
        let r3 = (c & 0xFFFFFFFFFFFFFFFFu128) as u64;
204
4.18k
        c >>= 64;
205
4.18k
206
4.18k
        // Final reduction of r.
207
4.18k
        let r = U256::from([r0, r1, r2, r3]);
208
4.18k
        let (r2, underflow) = r.sbb(&modulus, Limb::ZERO);
209
4.18k
        let high_bit = Choice::from(c as u8);
210
4.18k
        let underflow = Choice::from((underflow.0 >> 63) as u8);
211
4.18k
        Scalar(U256::conditional_select(&r, &r2, !underflow | high_bit))
212
4.18k
    }
213
214
    #[inline(always)] // only used in Scalar::mul(), so won't cause binary bloat
215
4.18k
    pub(super) fn reduce(&self) -> Scalar {
216
4.18k
        self.reduce_impl(false)
217
4.18k
    }
218
219
0
    pub(super) fn reduce_nonzero(&self) -> Scalar {
220
0
        self.reduce_impl(true) + Scalar::ONE
221
0
    }
222
}
223
224
/// Add a to the number defined by (c0,c1,c2). c2 must never overflow.
225
29.2k
fn sumadd(a: u64, c0: u64, c1: u64, c2: u64) -> (u64, u64, u64) {
226
29.2k
    let (new_c0, carry0) = c0.overflowing_add(a);
227
29.2k
    let (new_c1, carry1) = c1.overflowing_add(carry0 as u64);
228
29.2k
    let new_c2 = c2 + (carry1 as u64);
229
29.2k
    (new_c0, new_c1, new_c2)
230
29.2k
}
231
232
/// Add a to the number defined by (c0,c1). c1 must never overflow.
233
20.9k
fn sumadd_fast(a: u64, c0: u64, c1: u64) -> (u64, u64) {
234
20.9k
    let (new_c0, carry0) = c0.overflowing_add(a);
235
20.9k
    let new_c1 = c1 + (carry0 as u64);
236
20.9k
    (new_c0, new_c1)
237
20.9k
}
238
239
/// Add a*b to the number defined by (c0,c1,c2). c2 must never overflow.
240
133k
fn muladd(a: u64, b: u64, c0: u64, c1: u64, c2: u64) -> (u64, u64, u64) {
241
133k
    let t = (a as u128) * (b as u128);
242
133k
    let th = (t >> 64) as u64; // at most 0xFFFFFFFFFFFFFFFE
243
133k
    let tl = t as u64;
244
133k
245
133k
    let (new_c0, carry0) = c0.overflowing_add(tl);
246
133k
    let new_th = th.wrapping_add(carry0 as u64); // at most 0xFFFFFFFFFFFFFFFF
247
133k
    let (new_c1, carry1) = c1.overflowing_add(new_th);
248
133k
    let new_c2 = c2 + (carry1 as u64);
249
133k
250
133k
    (new_c0, new_c1, new_c2)
251
133k
}
252
253
/// Add a*b to the number defined by (c0,c1). c1 must never overflow.
254
25.1k
fn muladd_fast(a: u64, b: u64, c0: u64, c1: u64) -> (u64, u64) {
255
25.1k
    let t = (a as u128) * (b as u128);
256
25.1k
    let th = (t >> 64) as u64; // at most 0xFFFFFFFFFFFFFFFE
257
25.1k
    let tl = t as u64;
258
25.1k
259
25.1k
    let (new_c0, carry0) = c0.overflowing_add(tl);
260
25.1k
    let new_th = th.wrapping_add(carry0 as u64); // at most 0xFFFFFFFFFFFFFFFF
261
25.1k
    let new_c1 = c1 + new_th;
262
25.1k
263
25.1k
    (new_c0, new_c1)
264
25.1k
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/ecdsa.rs
Line
Count
Source
1
//! Elliptic Curve Digital Signature Algorithm (ECDSA).
2
//!
3
//! This module contains support for computing and verifying ECDSA signatures.
4
//! To use it, you will need to enable one of the two following Cargo features:
5
//!
6
//! - `ecdsa-core`: provides only the [`Signature`] type (which represents an
7
//!   ECDSA/secp256k1 signature). Does not require the `arithmetic` feature.
8
//!   This is useful for 3rd-party crates which wish to use the `Signature`
9
//!   type for interoperability purposes (particularly in conjunction with the
10
//!   [`signature::Signer`] trait). Example use cases for this include other
11
//!   software implementations of ECDSA/secp256k1 and wrappers for cloud KMS
12
//!   services or hardware devices (HSM or crypto hardware wallet).
13
//! - `ecdsa`: provides `ecdsa-core` features plus the [`SigningKey`] and
14
//!   [`VerifyingKey`] types which natively implement ECDSA/secp256k1 signing and
15
//!   verification.
16
//!
17
//! Most users of this library who want to sign/verify signatures will want to
18
//! enable the `ecdsa` and `sha256` Cargo features.
19
//!
20
//! ## Signing and Verifying Signatures
21
//!
22
//! This example requires the `ecdsa` and `sha256` Cargo features are enabled:
23
//!
24
//! ```
25
//! # #[cfg(all(feature = "ecdsa", feature = "sha256"))]
26
//! # {
27
//! use k256::{
28
//!     ecdsa::{SigningKey, Signature, signature::Signer},
29
//!     SecretKey,
30
//! };
31
//! use rand_core::OsRng; // requires 'getrandom' feature
32
//!
33
//! // Signing
34
//! let signing_key = SigningKey::random(&mut OsRng); // Serialize with `::to_bytes()`
35
//! let message = b"ECDSA proves knowledge of a secret number in the context of a single message";
36
//!
37
//! // Note: The signature type must be annotated or otherwise inferable as
38
//! // `Signer` has many impls of the `Signer` trait (for both regular and
39
//! // recoverable signature types).
40
//! let signature: Signature = signing_key.sign(message);
41
//!
42
//! // Verification
43
//! use k256::{EncodedPoint, ecdsa::{VerifyingKey, signature::Verifier}};
44
//!
45
//! let verifying_key = VerifyingKey::from(&signing_key); // Serialize with `::to_encoded_point()`
46
//! assert!(verifying_key.verify(message, &signature).is_ok());
47
//! # }
48
//! ```
49
//!
50
//! ## Recovering [`VerifyingKey`] from [`Signature`]
51
//!
52
//! ECDSA makes it possible to recover the public key used to verify a
53
//! signature with the assistance of 2-bits of additional information.
54
//!
55
//! This is helpful when there is already a trust relationship for a particular
56
//! key, and it's desirable to omit the full public key used to sign a
57
//! particular message.
58
//!
59
//! One common application of signature recovery with secp256k1 is Ethereum.
60
//!
61
//! ### Upgrading recoverable signature code from earlier versions of `k256`
62
//!
63
//! The v0.12 release of `k256` contains a brand new recoverable signature API
64
//! from previous releases. Functionality has been upstreamed from `k256` to a
65
//! generic implementation in the [`ecdsa`](`ecdsa_core`) crate.
66
//!
67
//! If you previously used `k256::ecdsa::recoverable::Signature`, the old
68
//! functionality now uses a "detached" [`Signature`] and [`RecoveryId`].
69
//! Here is where the various functionality went:
70
//!
71
//! - Signing now requires the use of the [`hazmat::SignPrimitive`] trait
72
//!   (see examples immediately below).
73
//! - Signature recovery is now implemented as methods of the [`VerifyingKey`]
74
//!   type (i.e. `::recover_from_*`).
75
//! - Trial recovery is now defined on the [`RecoveryId`] type
76
//!   (i.e. `::trial_recovery_from_*`).
77
//!
78
//! ### Computing a signature with a [`RecoveryId`].
79
//!
80
//! This example shows how to compute a signature and its associated
81
//! [`RecoveryId`] in a manner which is byte-for-byte compatible with
82
//! Ethereum libraries, leveraging the [`SigningKey::sign_digest_recoverable`]
83
//! API:
84
//!
85
#![cfg_attr(feature = "std", doc = "```")]
86
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
87
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
88
//! use hex_literal::hex;
89
//! use k256::ecdsa::{hazmat::SignPrimitive, RecoveryId, Signature, SigningKey};
90
//! use sha2::Sha256;
91
//! use sha3::{Keccak256, Digest};
92
//!
93
//! let signing_key = SigningKey::from_bytes(&hex!(
94
//!     "4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318"
95
//! ).into())?;
96
//!
97
//! let msg = hex!("e9808504e3b29200831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080018080");
98
//! let digest = Keccak256::new_with_prefix(msg);
99
//! let (signature, recid) = signing_key.sign_digest_recoverable(digest)?;
100
//!
101
//! assert_eq!(
102
//!     signature.to_bytes().as_slice(),
103
//!     &hex!("c9cf86333bcb065d140032ecaab5d9281bde80f21b9687b3e94161de42d51895727a108a0b8d101465414033c3f705a9c7b826e596766046ee1183dbc8aeaa68")
104
//! );
105
//!
106
//! assert_eq!(recid, RecoveryId::try_from(0u8).unwrap());
107
//! # Ok(())
108
//! # }
109
//! ```
110
//!
111
//! ### Recovering a [`VerifyingKey`] from a signature
112
//!
113
#![cfg_attr(feature = "std", doc = "```")]
114
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
115
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
116
//! use hex_literal::hex;
117
//! use k256::ecdsa::{RecoveryId, Signature, VerifyingKey};
118
//! use sha3::{Keccak256, Digest};
119
//! use elliptic_curve::sec1::ToEncodedPoint;
120
//!
121
//! let msg = b"example message";
122
//!
123
//! let signature = Signature::try_from(hex!(
124
//!     "46c05b6368a44b8810d79859441d819b8e7cdc8bfd371e35c53196f4bcacdb51
125
//!      35c7facce2a97b95eacba8a586d87b7958aaf8368ab29cee481f76e871dbd9cb"
126
//! ).as_slice())?;
127
//!
128
//! let recid = RecoveryId::try_from(1u8)?;
129
//!
130
//! let recovered_key = VerifyingKey::recover_from_digest(
131
//!     Keccak256::new_with_prefix(msg),
132
//!     &signature,
133
//!     recid
134
//! )?;
135
//!
136
//! let expected_key = VerifyingKey::from_sec1_bytes(
137
//!     &hex!("0200866db99873b09fc2fb1e3ba549b156e96d1a567e3284f5f0e859a83320cb8b")
138
//! )?;
139
//!
140
//! assert_eq!(recovered_key, expected_key);
141
//! # Ok(())
142
//! # }
143
//! ```
144
145
pub use ecdsa_core::{
146
    signature::{self, Error},
147
    RecoveryId,
148
};
149
150
#[cfg(any(feature = "ecdsa", feature = "sha256"))]
151
pub use ecdsa_core::hazmat;
152
153
use crate::Secp256k1;
154
155
#[cfg(feature = "ecdsa")]
156
use {
157
    crate::{AffinePoint, FieldBytes, Scalar},
158
    ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive},
159
    elliptic_curve::{ops::Invert, scalar::IsHigh, subtle::CtOption},
160
};
161
162
/// ECDSA/secp256k1 signature (fixed-size)
163
pub type Signature = ecdsa_core::Signature<Secp256k1>;
164
165
/// ECDSA/secp256k1 signature (ASN.1 DER encoded)
166
pub type DerSignature = ecdsa_core::der::Signature<Secp256k1>;
167
168
/// ECDSA/secp256k1 signing key
169
#[cfg(feature = "ecdsa")]
170
pub type SigningKey = ecdsa_core::SigningKey<Secp256k1>;
171
172
/// ECDSA/secp256k1 verification key (i.e. public key)
173
#[cfg(feature = "ecdsa")]
174
pub type VerifyingKey = ecdsa_core::VerifyingKey<Secp256k1>;
175
176
#[cfg(feature = "sha256")]
177
impl hazmat::DigestPrimitive for Secp256k1 {
178
    type Digest = sha2::Sha256;
179
}
180
181
#[cfg(feature = "ecdsa")]
182
impl SignPrimitive<Secp256k1> for Scalar {
183
    #[allow(non_snake_case, clippy::many_single_char_names)]
184
0
    fn try_sign_prehashed<K>(
185
0
        &self,
186
0
        k: K,
187
0
        z: &FieldBytes,
188
0
    ) -> Result<(Signature, Option<RecoveryId>), Error>
189
0
    where
190
0
        K: AsRef<Self> + Invert<Output = CtOption<Self>>,
191
0
    {
192
0
        let (sig, recid) = hazmat::sign_prehashed::<Secp256k1, K>(self, k, z)?;
193
0
        let is_y_odd = recid.is_y_odd() ^ bool::from(sig.s().is_high());
194
0
        let sig_low = sig.normalize_s().unwrap_or(sig);
195
0
        let recid = RecoveryId::new(is_y_odd, recid.is_x_reduced());
196
0
        Ok((sig_low, Some(recid)))
197
0
    }
198
}
199
200
#[cfg(feature = "ecdsa")]
201
impl VerifyPrimitive<Secp256k1> for AffinePoint {
202
534
    fn verify_prehashed(&self, z: &FieldBytes, sig: &Signature) -> Result<(), Error> {
203
534
        if sig.s().is_high().into() {
204
11
            return Err(Error::new());
205
523
        }
206
523
207
523
        hazmat::verify_prehashed(&self.into(), z, sig)
208
534
    }
209
}
210
211
#[cfg(all(test, feature = "ecdsa", feature = "arithmetic"))]
212
mod tests {
213
    mod normalize {
214
        use crate::ecdsa::Signature;
215
216
        // Test vectors generated using rust-secp256k1
217
        #[test]
218
        #[rustfmt::skip]
219
        fn s_high() {
220
            let sig_hi = Signature::try_from([
221
                0x20, 0xc0, 0x1a, 0x91, 0x0e, 0xbb, 0x26, 0x10,
222
                0xaf, 0x2d, 0x76, 0x3f, 0xa0, 0x9b, 0x3b, 0x30,
223
                0x92, 0x3c, 0x8e, 0x40, 0x8b, 0x11, 0xdf, 0x2c,
224
                0x61, 0xad, 0x76, 0xd9, 0x70, 0xa2, 0xf1, 0xbc,
225
                0xee, 0x2f, 0x11, 0xef, 0x8c, 0xb0, 0x0a, 0x49,
226
                0x61, 0x7d, 0x13, 0x57, 0xf4, 0xd5, 0x56, 0x41,
227
                0x09, 0x0a, 0x48, 0xf2, 0x01, 0xe9, 0xb9, 0x59,
228
                0xc4, 0x8f, 0x6f, 0x6b, 0xec, 0x6f, 0x93, 0x8f,
229
            ].as_slice()).unwrap();
230
231
            let sig_lo = Signature::try_from([
232
                0x20, 0xc0, 0x1a, 0x91, 0x0e, 0xbb, 0x26, 0x10,
233
                0xaf, 0x2d, 0x76, 0x3f, 0xa0, 0x9b, 0x3b, 0x30,
234
                0x92, 0x3c, 0x8e, 0x40, 0x8b, 0x11, 0xdf, 0x2c,
235
                0x61, 0xad, 0x76, 0xd9, 0x70, 0xa2, 0xf1, 0xbc,
236
                0x11, 0xd0, 0xee, 0x10, 0x73, 0x4f, 0xf5, 0xb6,
237
                0x9e, 0x82, 0xec, 0xa8, 0x0b, 0x2a, 0xa9, 0xbd,
238
                0xb1, 0xa4, 0x93, 0xf4, 0xad, 0x5e, 0xe6, 0xe1,
239
                0xfb, 0x42, 0xef, 0x20, 0xe3, 0xc6, 0xad, 0xb2,
240
            ].as_slice()).unwrap();
241
242
            let sig_normalized = sig_hi.normalize_s().unwrap();
243
            assert_eq!(sig_lo, sig_normalized);
244
        }
245
246
        #[test]
247
        fn s_low() {
248
            #[rustfmt::skip]
249
            let sig = Signature::try_from([
250
                1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
251
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
252
                1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
253
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
254
            ].as_slice()).unwrap();
255
256
            assert_eq!(sig.normalize_s(), None);
257
        }
258
    }
259
260
    #[cfg(feature = "sha256")]
261
    mod recovery {
262
        use crate::{
263
            ecdsa::{signature::DigestVerifier, RecoveryId, Signature, SigningKey, VerifyingKey},
264
            EncodedPoint,
265
        };
266
        use hex_literal::hex;
267
        use sha2::{Digest, Sha256};
268
        use sha3::Keccak256;
269
270
        /// Signature recovery test vectors
271
        struct RecoveryTestVector {
272
            pk: [u8; 33],
273
            msg: &'static [u8],
274
            sig: [u8; 64],
275
            recid: RecoveryId,
276
        }
277
278
        const RECOVERY_TEST_VECTORS: &[RecoveryTestVector] = &[
279
            // Recovery ID 0
280
            RecoveryTestVector {
281
                pk: hex!("021a7a569e91dbf60581509c7fc946d1003b60c7dee85299538db6353538d59574"),
282
                msg: b"example message",
283
                sig: hex!(
284
                    "ce53abb3721bafc561408ce8ff99c909f7f0b18a2f788649d6470162ab1aa032
285
                     3971edc523a6d6453f3fb6128d318d9db1a5ff3386feb1047d9816e780039d52"
286
                ),
287
                recid: RecoveryId::new(false, false),
288
            },
289
            // Recovery ID 1
290
            RecoveryTestVector {
291
                pk: hex!("036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2"),
292
                msg: b"example message",
293
                sig: hex!(
294
                    "46c05b6368a44b8810d79859441d819b8e7cdc8bfd371e35c53196f4bcacdb51
295
                     35c7facce2a97b95eacba8a586d87b7958aaf8368ab29cee481f76e871dbd9cb"
296
                ),
297
                recid: RecoveryId::new(true, false),
298
            },
299
        ];
300
301
        #[test]
302
        fn public_key_recovery() {
303
            for vector in RECOVERY_TEST_VECTORS {
304
                let digest = Sha256::new_with_prefix(vector.msg);
305
                let sig = Signature::try_from(vector.sig.as_slice()).unwrap();
306
                let recid = vector.recid;
307
                let pk = VerifyingKey::recover_from_digest(digest, &sig, recid).unwrap();
308
                assert_eq!(&vector.pk[..], EncodedPoint::from(&pk).as_bytes());
309
            }
310
        }
311
312
        /// End-to-end example which ensures RFC6979 is implemented in the same
313
        /// way as other Ethereum libraries, using HMAC-DRBG-SHA-256 for RFC6979,
314
        /// and Keccak256 for hashing the message.
315
        ///
316
        /// Test vectors adapted from:
317
        /// <https://github.com/gakonst/ethers-rs/blob/ba00f549/ethers-signers/src/wallet/private_key.rs#L197>
318
        #[test]
319
        fn ethereum_end_to_end_example() {
320
            let signing_key = SigningKey::from_bytes(
321
                &hex!("4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318").into(),
322
            )
323
            .unwrap();
324
325
            let msg = hex!(
326
                "e9808504e3b29200831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080018080"
327
            );
328
            let digest = Keccak256::new_with_prefix(msg);
329
330
            let (sig, recid) = signing_key.sign_digest_recoverable(digest.clone()).unwrap();
331
            assert_eq!(
332
                sig.to_bytes().as_slice(),
333
                &hex!("c9cf86333bcb065d140032ecaab5d9281bde80f21b9687b3e94161de42d51895727a108a0b8d101465414033c3f705a9c7b826e596766046ee1183dbc8aeaa68")
334
            );
335
            assert_eq!(recid, RecoveryId::from_byte(0).unwrap());
336
337
            let verifying_key =
338
                VerifyingKey::recover_from_digest(digest.clone(), &sig, recid).unwrap();
339
340
            assert_eq!(signing_key.verifying_key(), &verifying_key);
341
            assert!(verifying_key.verify_digest(digest, &sig).is_ok());
342
        }
343
    }
344
345
    mod wycheproof {
346
        use crate::{EncodedPoint, Secp256k1};
347
        use ecdsa_core::{signature::Verifier, Signature};
348
        use elliptic_curve::generic_array::typenum::Unsigned;
349
350
        #[test]
351
        fn wycheproof() {
352
            use blobby::Blob5Iterator;
353
354
            // Build a field element but allow for too-short input (left pad with zeros)
355
            // or too-long input (check excess leftmost bytes are zeros).
356
            fn element_from_padded_slice<C: elliptic_curve::Curve>(
357
                data: &[u8],
358
            ) -> elliptic_curve::FieldBytes<C> {
359
                let point_len = C::FieldBytesSize::USIZE;
360
                if data.len() >= point_len {
361
                    let offset = data.len() - point_len;
362
                    for v in data.iter().take(offset) {
363
                        assert_eq!(*v, 0, "EcdsaVerifier: point too large");
364
                    }
365
                    elliptic_curve::FieldBytes::<C>::clone_from_slice(&data[offset..])
366
                } else {
367
                    let iter = core::iter::repeat(0)
368
                        .take(point_len - data.len())
369
                        .chain(data.iter().cloned());
370
                    elliptic_curve::FieldBytes::<C>::from_exact_iter(iter).unwrap()
371
                }
372
            }
373
374
            fn run_test(
375
                wx: &[u8],
376
                wy: &[u8],
377
                msg: &[u8],
378
                sig: &[u8],
379
                pass: bool,
380
            ) -> Option<&'static str> {
381
                let x = element_from_padded_slice::<Secp256k1>(wx);
382
                let y = element_from_padded_slice::<Secp256k1>(wy);
383
                let q_encoded =
384
                    EncodedPoint::from_affine_coordinates(&x, &y, /* compress= */ false);
385
                let verifying_key =
386
                    ecdsa_core::VerifyingKey::from_encoded_point(&q_encoded).unwrap();
387
388
                let sig = match Signature::<Secp256k1>::from_der(sig) {
389
                    Ok(s) => s.normalize_s().unwrap_or(s),
390
                    Err(_) if !pass => return None,
391
                    Err(_) => return Some("failed to parse signature ASN.1"),
392
                };
393
394
                match verifying_key.verify(msg, &sig) {
395
                    Ok(_) if pass => None,
396
                    Ok(_) => Some("signature verify unexpectedly succeeded"),
397
                    Err(_) if !pass => None,
398
                    Err(_) => Some("signature verify failed"),
399
                }
400
            }
401
402
            let data = include_bytes!(concat!("test_vectors/data/", "wycheproof", ".blb"));
403
404
            for (i, row) in Blob5Iterator::new(data).unwrap().enumerate() {
405
                let [wx, wy, msg, sig, status] = row.unwrap();
406
                let pass = match status[0] {
407
                    0 => false,
408
                    1 => true,
409
                    _ => panic!("invalid value for pass flag"),
410
                };
411
                if let Some(desc) = run_test(wx, wy, msg, sig, pass) {
412
                    panic!(
413
                        "\n\
414
                                 Failed test №{}: {}\n\
415
                                 wx:\t{:?}\n\
416
                                 wy:\t{:?}\n\
417
                                 msg:\t{:?}\n\
418
                                 sig:\t{:?}\n\
419
                                 pass:\t{}\n",
420
                        i, desc, wx, wy, msg, sig, pass,
421
                    );
422
                }
423
            }
424
        }
425
    }
426
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/lib.rs
Line
Count
Source
1
#![no_std]
2
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3
#![doc = include_str!("../README.md")]
4
#![doc(
5
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
6
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
7
)]
8
#![allow(clippy::needless_range_loop)]
9
#![forbid(unsafe_code)]
10
#![warn(
11
    clippy::mod_module_files,
12
    clippy::unwrap_used,
13
    missing_docs,
14
    rust_2018_idioms,
15
    unused_lifetimes,
16
    unused_qualifications
17
)]
18
19
//! ## `serde` support
20
//!
21
//! When the `serde` feature of this crate is enabled, `Serialize` and
22
//! `Deserialize` are impl'd for the following types:
23
//!
24
//! - [`AffinePoint`]
25
//! - [`Scalar`]
26
//! - [`ecdsa::VerifyingKey`]
27
//!
28
//! Please see type-specific documentation for more information.
29
30
#[cfg(feature = "alloc")]
31
#[allow(unused_imports)]
32
#[macro_use]
33
extern crate alloc;
34
35
#[cfg(feature = "arithmetic")]
36
mod arithmetic;
37
38
#[cfg(feature = "ecdh")]
39
pub mod ecdh;
40
41
#[cfg(feature = "ecdsa-core")]
42
pub mod ecdsa;
43
44
#[cfg(feature = "schnorr")]
45
pub mod schnorr;
46
47
#[cfg(any(feature = "test-vectors", test))]
48
pub mod test_vectors;
49
50
pub use elliptic_curve::{self, bigint::U256};
51
52
#[cfg(feature = "arithmetic")]
53
pub use arithmetic::{affine::AffinePoint, projective::ProjectivePoint, scalar::Scalar};
54
55
#[cfg(feature = "expose-field")]
56
pub use arithmetic::FieldElement;
57
58
#[cfg(feature = "pkcs8")]
59
pub use elliptic_curve::pkcs8;
60
61
#[cfg(feature = "sha2")]
62
pub use sha2;
63
64
use elliptic_curve::{
65
    bigint::ArrayEncoding,
66
    consts::{U32, U33, U64},
67
    generic_array::GenericArray,
68
    FieldBytesEncoding,
69
};
70
71
/// Order of the secp256k1 elliptic curve in hexadecimal.
72
const ORDER_HEX: &str = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141";
73
74
/// Order of the secp256k1 elliptic curve.
75
const ORDER: U256 = U256::from_be_hex(ORDER_HEX);
76
77
/// secp256k1 (K-256) elliptic curve.
78
///
79
/// Specified in Certicom's SECG in "SEC 2: Recommended Elliptic Curve Domain Parameters":
80
///
81
/// <https://www.secg.org/sec2-v2.pdf>
82
///
83
/// The curve's equation is `y² = x³ + 7` over a ~256-bit prime field.
84
///
85
/// It's primarily notable for usage in Bitcoin and other cryptocurrencies,
86
/// particularly in conjunction with the Elliptic Curve Digital Signature
87
/// Algorithm (ECDSA).
88
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
89
pub struct Secp256k1;
90
91
impl elliptic_curve::Curve for Secp256k1 {
92
    /// 32-byte serialized field elements.
93
    type FieldBytesSize = U32;
94
95
    /// 256-bit field modulus.
96
    type Uint = U256;
97
98
    /// Curve order.
99
    const ORDER: U256 = ORDER;
100
}
101
102
impl elliptic_curve::PrimeCurve for Secp256k1 {}
103
104
impl elliptic_curve::point::PointCompression for Secp256k1 {
105
    /// secp256k1 points are typically compressed.
106
    const COMPRESS_POINTS: bool = true;
107
}
108
109
#[cfg(feature = "jwk")]
110
impl elliptic_curve::JwkParameters for Secp256k1 {
111
    const CRV: &'static str = "secp256k1";
112
}
113
114
#[cfg(feature = "pkcs8")]
115
impl pkcs8::AssociatedOid for Secp256k1 {
116
    const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new_unwrap("1.3.132.0.10");
117
}
118
119
/// Compressed SEC1-encoded secp256k1 (K-256) curve point.
120
pub type CompressedPoint = GenericArray<u8, U33>;
121
122
/// SEC1-encoded secp256k1 (K-256) curve point.
123
pub type EncodedPoint = elliptic_curve::sec1::EncodedPoint<Secp256k1>;
124
125
/// secp256k1 (K-256) field element serialized as bytes.
126
///
127
/// Byte array containing a serialized field element value (base field or scalar).
128
pub type FieldBytes = elliptic_curve::FieldBytes<Secp256k1>;
129
130
impl FieldBytesEncoding<Secp256k1> for U256 {
131
1.11k
    fn decode_field_bytes(field_bytes: &FieldBytes) -> Self {
132
1.11k
        U256::from_be_byte_array(*field_bytes)
133
1.11k
    }
134
135
0
    fn encode_field_bytes(&self) -> FieldBytes {
136
0
        self.to_be_byte_array()
137
0
    }
138
}
139
140
/// Bytes used by a wide reduction: twice the width of [`FieldBytes`].
141
pub type WideBytes = GenericArray<u8, U64>;
142
143
/// Non-zero secp256k1 (K-256) scalar field element.
144
#[cfg(feature = "arithmetic")]
145
pub type NonZeroScalar = elliptic_curve::NonZeroScalar<Secp256k1>;
146
147
/// secp256k1 (K-256) public key.
148
#[cfg(feature = "arithmetic")]
149
pub type PublicKey = elliptic_curve::PublicKey<Secp256k1>;
150
151
/// secp256k1 (K-256) secret key.
152
pub type SecretKey = elliptic_curve::SecretKey<Secp256k1>;
153
154
#[cfg(not(feature = "arithmetic"))]
155
impl elliptic_curve::sec1::ValidatePublicKey for Secp256k1 {}
156
157
/// Bit representation of a secp256k1 (K-256) scalar field element.
158
#[cfg(feature = "bits")]
159
pub type ScalarBits = elliptic_curve::scalar::ScalarBits<Secp256k1>;
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/schnorr.rs
Line
Count
Source
1
//! Taproot Schnorr signatures as defined in [BIP340].
2
//!
3
//! # About
4
//!
5
//! [Schnorr signatures] are a simple group-based digital signature scheme with
6
//! a number of desirable properties relating to security and composability:
7
//!
8
//! - Provably secure: strongly unforgable under chosen message attack (SUF-CMA).
9
//! - Non-malleable: signatures cannot be altered by an attacker and still verify.
10
//! - Linear: multiple parties can collaborate to produce a valid signature
11
//!   a.k.a. multisignatures.
12
//!
13
//! Originally described in the late 1980s by their eponymous creator Claus
14
//! Schnorr, they were patent-encumbered and thus lingered in obscurity until
15
//! the [relevant patents] expired in 2010.
16
//!
17
//! Since then, Schnorr signatures have seen something of a resurgence, with
18
//! [EdDSA] and its concrete instantiation Ed25519 over the Curve25519 elliptic
19
//! curve becoming the first Schnorr variant to see mainstream standardization.
20
//!
21
//! The Taproot upgrade to Bitcoin includes a variant of Schnorr which operates
22
//! over the secp256k1 elliptic curve, and is specified in [BIP340].
23
//! That is the variant which is implemented by this crate.
24
//!
25
//! Because Taproot Schnorr is intended for use in consensus-critical
26
//! applications (e.g. Bitcoin), it is fully specified such that no two
27
//! implementations should disagree on the validity of a signature.
28
//!
29
//! # Usage
30
//!
31
#![cfg_attr(feature = "std", doc = "```")]
32
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
33
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
34
//! use k256::schnorr::{
35
//!     signature::{Signer, Verifier},
36
//!     SigningKey, VerifyingKey
37
//! };
38
//! use rand_core::OsRng; // requires 'getrandom' feature
39
//!
40
//! //
41
//! // Signing
42
//! //
43
//! let signing_key = SigningKey::random(&mut OsRng); // serialize with `.to_bytes()`
44
//! let verifying_key_bytes = signing_key.verifying_key().to_bytes(); // 32-bytes
45
//!
46
//! let message = b"Schnorr signatures prove knowledge of a secret in the random oracle model";
47
//! let signature = signing_key.sign(message); // returns `k256::schnorr::Signature`
48
//!
49
//! //
50
//! // Verification
51
//! //
52
//! let verifying_key = VerifyingKey::from_bytes(&verifying_key_bytes)?;
53
//! verifying_key.verify(message, &signature)?;
54
//! # Ok(())
55
//! # }
56
//! ```
57
//!
58
//! [Schnorr signatures]: https://en.wikipedia.org/wiki/Schnorr_signature
59
//! [BIP340]: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
60
//! [relevant patents]: https://patents.google.com/patent/US4995082
61
//! [EdDSA]: https://en.wikipedia.org/wiki/EdDSA
62
63
#![allow(non_snake_case, clippy::many_single_char_names)]
64
65
mod signing;
66
mod verifying;
67
68
pub use self::{signing::SigningKey, verifying::VerifyingKey};
69
pub use signature::{self, rand_core::CryptoRngCore, Error};
70
71
use crate::{arithmetic::FieldElement, NonZeroScalar};
72
use core::fmt;
73
use elliptic_curve::subtle::ConstantTimeEq;
74
use sha2::{Digest, Sha256};
75
use signature::Result;
76
77
const AUX_TAG: &[u8] = b"BIP0340/aux";
78
const NONCE_TAG: &[u8] = b"BIP0340/nonce";
79
const CHALLENGE_TAG: &[u8] = b"BIP0340/challenge";
80
81
/// Taproot Schnorr signature serialized as bytes.
82
pub type SignatureBytes = [u8; Signature::BYTE_SIZE];
83
84
/// Taproot Schnorr signature as defined in [BIP340].
85
///
86
/// [BIP340]: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
87
#[derive(Copy, Clone)]
88
pub struct Signature {
89
    r: FieldElement,
90
    s: NonZeroScalar,
91
}
92
93
impl Signature {
94
    /// Size of a Taproot Schnorr signature in bytes.
95
    pub const BYTE_SIZE: usize = 64;
96
97
    /// Serialize this signature as bytes.
98
0
    pub fn to_bytes(&self) -> SignatureBytes {
99
0
        let mut ret = [0; Self::BYTE_SIZE];
100
0
        let (r_bytes, s_bytes) = ret.split_at_mut(Self::BYTE_SIZE / 2);
101
0
        r_bytes.copy_from_slice(&self.r.to_bytes());
102
0
        s_bytes.copy_from_slice(&self.s.to_bytes());
103
0
        ret
104
0
    }
105
106
    /// Get the `r` component of this signature.
107
0
    fn r(&self) -> &FieldElement {
108
0
        &self.r
109
0
    }
110
111
    /// Get the `s` component of this signature.
112
0
    fn s(&self) -> &NonZeroScalar {
113
0
        &self.s
114
0
    }
115
116
    /// Split this signature into its `r` and `s` components.
117
0
    fn split(&self) -> (&FieldElement, &NonZeroScalar) {
118
0
        (self.r(), self.s())
119
0
    }
120
}
121
122
impl Eq for Signature {}
123
124
impl From<Signature> for SignatureBytes {
125
0
    fn from(signature: Signature) -> SignatureBytes {
126
0
        signature.to_bytes()
127
0
    }
128
}
129
130
impl From<&Signature> for SignatureBytes {
131
0
    fn from(signature: &Signature) -> SignatureBytes {
132
0
        signature.to_bytes()
133
0
    }
134
}
135
136
impl PartialEq for Signature {
137
0
    fn eq(&self, other: &Self) -> bool {
138
0
        (self.r == other.r) && (self.s.ct_eq(&other.s).into())
139
0
    }
140
}
141
142
impl TryFrom<&[u8]> for Signature {
143
    type Error = Error;
144
145
0
    fn try_from(bytes: &[u8]) -> Result<Signature> {
146
0
        let (r_bytes, s_bytes) = bytes.split_at(Self::BYTE_SIZE / 2);
147
148
0
        let r: FieldElement =
149
0
            Option::from(FieldElement::from_bytes(r_bytes.into())).ok_or_else(Error::new)?;
150
151
        // one of the rules for valid signatures: !is_infinite(R);
152
0
        if r.is_zero().into() {
153
0
            return Err(Error::new());
154
0
        }
155
156
0
        let s = NonZeroScalar::try_from(s_bytes).map_err(|_| Error::new())?;
157
158
0
        Ok(Self { r, s })
159
0
    }
160
}
161
162
impl fmt::Debug for Signature {
163
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164
0
        write!(f, "{:?}", self.to_bytes())
165
0
    }
166
}
167
168
impl signature::SignatureEncoding for Signature {
169
    type Repr = SignatureBytes;
170
171
0
    fn to_bytes(&self) -> Self::Repr {
172
0
        self.into()
173
0
    }
174
}
175
176
impl signature::PrehashSignature for Signature {
177
    type Digest = Sha256;
178
}
179
180
0
fn tagged_hash(tag: &[u8]) -> Sha256 {
181
0
    let tag_hash = Sha256::digest(tag);
182
0
    let mut digest = Sha256::new();
183
0
    digest.update(tag_hash);
184
0
    digest.update(tag_hash);
185
0
    digest
186
0
}
187
188
// Test vectors from:
189
// https://github.com/bitcoin/bips/blob/master/bip-0340/test-vectors.csv
190
#[cfg(test)]
191
mod tests {
192
    use super::{Signature, SigningKey, VerifyingKey};
193
    use hex_literal::hex;
194
    use signature::hazmat::PrehashVerifier;
195
196
    /// Signing test vector
197
    struct SignVector {
198
        /// Index of test case
199
        index: u8,
200
201
        /// Signing key
202
        secret_key: [u8; 32],
203
204
        /// Verifying key
205
        public_key: [u8; 32],
206
207
        /// Auxiliary randomness value
208
        aux_rand: [u8; 32],
209
210
        /// Message digest
211
        message: [u8; 32],
212
213
        /// Expected signature
214
        signature: [u8; 64],
215
    }
216
217
    /// BIP340 signing test vectors: index 0-3
218
    const BIP340_SIGN_VECTORS: &[SignVector] = &[
219
        SignVector {
220
            index: 0,
221
            secret_key: hex!("0000000000000000000000000000000000000000000000000000000000000003"),
222
            public_key: hex!("F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9"),
223
            aux_rand: hex!("0000000000000000000000000000000000000000000000000000000000000000"),
224
            message: hex!("0000000000000000000000000000000000000000000000000000000000000000"),
225
            signature: hex!(
226
                "E907831F80848D1069A5371B402410364BDF1C5F8307B0084C55F1CE2DCA8215
227
                 25F66A4A85EA8B71E482A74F382D2CE5EBEEE8FDB2172F477DF4900D310536C0"
228
            ),
229
        },
230
        SignVector {
231
            index: 1,
232
            secret_key: hex!("B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF"),
233
            public_key: hex!("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
234
            aux_rand: hex!("0000000000000000000000000000000000000000000000000000000000000001"),
235
            message: hex!("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
236
            signature: hex!(
237
                "6896BD60EEAE296DB48A229FF71DFE071BDE413E6D43F917DC8DCF8C78DE3341
238
                 8906D11AC976ABCCB20B091292BFF4EA897EFCB639EA871CFA95F6DE339E4B0A"
239
            ),
240
        },
241
        SignVector {
242
            index: 2,
243
            secret_key: hex!("C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C9"),
244
            public_key: hex!("DD308AFEC5777E13121FA72B9CC1B7CC0139715309B086C960E18FD969774EB8"),
245
            aux_rand: hex!("C87AA53824B4D7AE2EB035A2B5BBBCCC080E76CDC6D1692C4B0B62D798E6D906"),
246
            message: hex!("7E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C"),
247
            signature: hex!(
248
                "5831AAEED7B44BB74E5EAB94BA9D4294C49BCF2A60728D8B4C200F50DD313C1B
249
                 AB745879A5AD954A72C45A91C3A51D3C7ADEA98D82F8481E0E1E03674A6F3FB7"
250
            ),
251
        },
252
        // test fails if msg is reduced modulo p or n
253
        SignVector {
254
            index: 3,
255
            secret_key: hex!("0B432B2677937381AEF05BB02A66ECD012773062CF3FA2549E44F58ED2401710"),
256
            public_key: hex!("25D1DFF95105F5253C4022F628A996AD3A0D95FBF21D468A1B33F8C160D8F517"),
257
            aux_rand: hex!("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
258
            message: hex!("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
259
            signature: hex!(
260
                "7EB0509757E246F19449885651611CB965ECC1A187DD51B64FDA1EDC9637D5EC
261
                 97582B9CB13DB3933705B32BA982AF5AF25FD78881EBB32771FC5922EFC66EA3"
262
            ),
263
        },
264
    ];
265
266
    #[test]
267
    fn bip340_sign_vectors() {
268
        for vector in BIP340_SIGN_VECTORS {
269
            let sk = SigningKey::from_bytes(&vector.secret_key).unwrap();
270
            assert_eq!(sk.verifying_key().to_bytes().as_slice(), &vector.public_key);
271
272
            let sig = sk
273
                .sign_prehash_with_aux_rand(&vector.message, &vector.aux_rand)
274
                .unwrap_or_else(|_| {
275
                    panic!(
276
                        "low-level Schnorr signing failure for index {}",
277
                        vector.index
278
                    )
279
                });
280
281
            assert_eq!(
282
                vector.signature,
283
                sig.to_bytes(),
284
                "wrong signature for index {}",
285
                vector.index
286
            );
287
        }
288
    }
289
290
    /// Verification test vector
291
    struct VerifyVector {
292
        /// Index of test case
293
        index: u8,
294
295
        /// Verifying key
296
        public_key: [u8; 32],
297
298
        /// Message digest
299
        message: [u8; 32],
300
301
        /// Claimed signature
302
        signature: [u8; 64],
303
304
        /// Is signature valid
305
        valid: bool,
306
    }
307
308
    /// BIP340 verification test vectors: index 4-14
309
    const BIP340_VERIFY_VECTORS: &[VerifyVector] = &[
310
        VerifyVector {
311
            index: 4,
312
            public_key: hex!("D69C3509BB99E412E68B0FE8544E72837DFA30746D8BE2AA65975F29D22DC7B9"),
313
            message: hex!("4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703"),
314
            signature: hex!(
315
                "00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C63
316
                 76AFB1548AF603B3EB45C9F8207DEE1060CB71C04E80F593060B07D28308D7F4"
317
            ),
318
            valid: true,
319
        },
320
        // public key not on curve
321
        VerifyVector {
322
            index: 5,
323
            public_key: hex!("EEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34"),
324
            message: hex!("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
325
            signature: hex!(
326
                "6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E177769
327
                 69E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B"
328
            ),
329
            valid: false,
330
        },
331
        // has_even_y(R) is false
332
        VerifyVector {
333
            index: 6,
334
            public_key: hex!("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
335
            message: hex!("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
336
            signature: hex!(
337
                "FFF97BD5755EEEA420453A14355235D382F6472F8568A18B2F057A1460297556
338
                 3CC27944640AC607CD107AE10923D9EF7A73C643E166BE5EBEAFA34B1AC553E2"
339
            ),
340
            valid: false,
341
        },
342
        // negated message
343
        VerifyVector {
344
            index: 7,
345
            public_key: hex!("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
346
            message: hex!("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
347
            signature: hex!(
348
                "1FA62E331EDBC21C394792D2AB1100A7B432B013DF3F6FF4F99FCB33E0E1515F
349
                 28890B3EDB6E7189B630448B515CE4F8622A954CFE545735AAEA5134FCCDB2BD"
350
            ),
351
            valid: false,
352
        },
353
        // negated s value
354
        VerifyVector {
355
            index: 8,
356
            public_key: hex!("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
357
            message: hex!("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
358
            signature: hex!(
359
                "6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E177769
360
                 961764B3AA9B2FFCB6EF947B6887A226E8D7C93E00C5ED0C1834FF0D0C2E6DA6"
361
            ),
362
            valid: false,
363
        },
364
        // sG - eP is infinite. Test fails in single verification if has_even_y(inf) is defined as true and x(inf) as 0
365
        VerifyVector {
366
            index: 9,
367
            public_key: hex!("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
368
            message: hex!("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
369
            signature: hex!(
370
                "0000000000000000000000000000000000000000000000000000000000000000
371
                 123DDA8328AF9C23A94C1FEECFD123BA4FB73476F0D594DCB65C6425BD186051"
372
            ),
373
            valid: false,
374
        },
375
        // sG - eP is infinite. Test fails in single verification if has_even_y(inf) is defined as true and x(inf) as 1
376
        VerifyVector {
377
            index: 10,
378
            public_key: hex!("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
379
            message: hex!("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
380
            signature: hex!(
381
                "0000000000000000000000000000000000000000000000000000000000000001
382
                 7615FBAF5AE28864013C099742DEADB4DBA87F11AC6754F93780D5A1837CF197"
383
            ),
384
            valid: false,
385
        },
386
        // sig[0:32] is not an X coordinate on the curve
387
        VerifyVector {
388
            index: 11,
389
            public_key: hex!("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
390
            message: hex!("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
391
            signature: hex!(
392
                "4A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D
393
                 69E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B"
394
            ),
395
            valid: false,
396
        },
397
        // sig[0:32] is equal to field size
398
        VerifyVector {
399
            index: 12,
400
            public_key: hex!("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
401
            message: hex!("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
402
            signature: hex!(
403
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
404
                 69E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B"
405
            ),
406
            valid: false,
407
        },
408
        // sig[32:64] is equal to curve order
409
        VerifyVector {
410
            index: 13,
411
            public_key: hex!("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
412
            message: hex!("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
413
            signature: hex!(
414
                "6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E177769
415
                 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"
416
            ),
417
            valid: false,
418
        },
419
        // public key is not a valid X coordinate because it exceeds the field size
420
        VerifyVector {
421
            index: 14,
422
            public_key: hex!("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC30"),
423
            message: hex!("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
424
            signature: hex!(
425
                "6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E177769
426
                 69E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B"
427
            ),
428
            valid: false,
429
        },
430
    ];
431
432
    #[test]
433
    fn bip340_verify_vectors() {
434
        for vector in BIP340_VERIFY_VECTORS {
435
            let valid = match (
436
                VerifyingKey::from_bytes(&vector.public_key),
437
                Signature::try_from(vector.signature.as_slice()),
438
            ) {
439
                (Ok(pk), Ok(sig)) => pk.verify_prehash(&vector.message, &sig).is_ok(),
440
                _ => false,
441
            };
442
443
            assert_eq!(
444
                vector.valid, valid,
445
                "incorrect validation for index {}",
446
                vector.index
447
            );
448
        }
449
    }
450
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/schnorr/signing.rs
Line
Count
Source
1
//! Taproot Schnorr signing key.
2
3
use super::{tagged_hash, Signature, VerifyingKey, AUX_TAG, CHALLENGE_TAG, NONCE_TAG};
4
use crate::{
5
    AffinePoint, FieldBytes, NonZeroScalar, ProjectivePoint, PublicKey, Scalar, SecretKey,
6
};
7
use elliptic_curve::{
8
    bigint::U256,
9
    ops::Reduce,
10
    rand_core::CryptoRngCore,
11
    subtle::ConditionallySelectable,
12
    zeroize::{Zeroize, ZeroizeOnDrop},
13
};
14
use sha2::{Digest, Sha256};
15
use signature::{
16
    digest::{consts::U32, FixedOutput},
17
    hazmat::{PrehashSigner, RandomizedPrehashSigner},
18
    DigestSigner, Error, KeypairRef, RandomizedDigestSigner, RandomizedSigner, Result, Signer,
19
};
20
21
#[cfg(feature = "serde")]
22
use serdect::serde::{de, ser, Deserialize, Serialize};
23
24
#[cfg(debug_assertions)]
25
use signature::hazmat::PrehashVerifier;
26
27
/// Taproot Schnorr signing key.
28
#[derive(Clone)]
29
pub struct SigningKey {
30
    /// Secret key material
31
    secret_key: NonZeroScalar,
32
33
    /// Verifying key
34
    verifying_key: VerifyingKey,
35
}
36
37
impl SigningKey {
38
    /// Generate a cryptographically random [`SigningKey`].
39
0
    pub fn random(rng: &mut impl CryptoRngCore) -> Self {
40
0
        NonZeroScalar::random(rng).into()
41
0
    }
42
43
    /// Parse signing key from big endian-encoded bytes.
44
0
    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
45
0
        NonZeroScalar::try_from(bytes)
46
0
            .map(Into::into)
47
0
            .map_err(|_| Error::new())
48
0
    }
49
50
    /// Serialize as bytes.
51
0
    pub fn to_bytes(&self) -> FieldBytes {
52
0
        self.secret_key.to_bytes()
53
0
    }
54
55
    /// Get the [`VerifyingKey`] that corresponds to this signing key.
56
0
    pub fn verifying_key(&self) -> &VerifyingKey {
57
0
        &self.verifying_key
58
0
    }
59
60
    /// Borrow the secret [`NonZeroScalar`] value for this key.
61
    ///
62
    /// # ⚠️ Warning
63
    ///
64
    /// This value is key material.
65
    ///
66
    /// Please treat it with the care it deserves!
67
0
    pub fn as_nonzero_scalar(&self) -> &NonZeroScalar {
68
0
        &self.secret_key
69
0
    }
70
71
    /// Compute Schnorr signature.
72
    ///
73
    /// # ⚠️ Warning
74
    ///
75
    /// This is a low-level interface intended only for unusual use cases
76
    /// involving signing pre-hashed messages.
77
    ///
78
    /// The preferred interfaces are the [`Signer`] or [`RandomizedSigner`] traits.
79
0
    pub fn sign_prehash_with_aux_rand(
80
0
        &self,
81
0
        msg_digest: &[u8; 32],
82
0
        aux_rand: &[u8; 32],
83
0
    ) -> Result<Signature> {
84
0
        let mut t = tagged_hash(AUX_TAG).chain_update(aux_rand).finalize();
85
86
0
        for (a, b) in t.iter_mut().zip(self.secret_key.to_bytes().iter()) {
87
0
            *a ^= b
88
        }
89
90
0
        let rand = tagged_hash(NONCE_TAG)
91
0
            .chain_update(t)
92
0
            .chain_update(self.verifying_key.as_affine().x.to_bytes())
93
0
            .chain_update(msg_digest)
94
0
            .finalize();
95
96
0
        let k = NonZeroScalar::try_from(&*rand)
97
0
            .map(Self::from)
98
0
            .map_err(|_| Error::new())?;
99
100
0
        let secret_key = k.secret_key;
101
0
        let verifying_point = AffinePoint::from(k.verifying_key);
102
0
        let r = verifying_point.x.normalize();
103
0
104
0
        let e = <Scalar as Reduce<U256>>::reduce_bytes(
105
0
            &tagged_hash(CHALLENGE_TAG)
106
0
                .chain_update(r.to_bytes())
107
0
                .chain_update(self.verifying_key.to_bytes())
108
0
                .chain_update(msg_digest)
109
0
                .finalize(),
110
0
        );
111
0
112
0
        let s = *secret_key + e * *self.secret_key;
113
0
        let s = Option::from(NonZeroScalar::new(s)).ok_or_else(Error::new)?;
114
0
        let sig = Signature { r, s };
115
0
116
0
        #[cfg(debug_assertions)]
117
0
        self.verifying_key.verify_prehash(msg_digest, &sig)?;
118
119
0
        Ok(sig)
120
0
    }
121
}
122
123
impl From<NonZeroScalar> for SigningKey {
124
    #[inline]
125
0
    fn from(mut secret_key: NonZeroScalar) -> SigningKey {
126
0
        let odd = (ProjectivePoint::GENERATOR * *secret_key)
127
0
            .to_affine()
128
0
            .y
129
0
            .normalize()
130
0
            .is_odd();
131
0
132
0
        secret_key.conditional_assign(&-secret_key, odd);
133
0
134
0
        let verifying_key = VerifyingKey {
135
0
            inner: PublicKey::from_secret_scalar(&secret_key),
136
0
        };
137
0
138
0
        SigningKey {
139
0
            secret_key,
140
0
            verifying_key,
141
0
        }
142
0
    }
143
}
144
145
impl From<SecretKey> for SigningKey {
146
    #[inline]
147
0
    fn from(secret_key: SecretKey) -> SigningKey {
148
0
        SigningKey::from(&secret_key)
149
0
    }
150
}
151
152
impl From<&SecretKey> for SigningKey {
153
0
    fn from(secret_key: &SecretKey) -> SigningKey {
154
0
        secret_key.to_nonzero_scalar().into()
155
0
    }
156
}
157
158
//
159
// `*Signer` trait impls
160
//
161
162
impl<D> DigestSigner<D, Signature> for SigningKey
163
where
164
    D: Digest + FixedOutput<OutputSize = U32>,
165
{
166
0
    fn try_sign_digest(&self, digest: D) -> Result<Signature> {
167
0
        self.sign_prehash_with_aux_rand(&digest.finalize_fixed().into(), &Default::default())
168
0
    }
169
}
170
171
impl PrehashSigner<Signature> for SigningKey {
172
0
    fn sign_prehash(&self, prehash: &[u8]) -> Result<Signature> {
173
0
        let prehash = prehash.try_into().map_err(|_| Error::new())?;
174
0
        self.sign_prehash_with_aux_rand(&prehash, &Default::default())
175
0
    }
176
}
177
178
impl<D> RandomizedDigestSigner<D, Signature> for SigningKey
179
where
180
    D: Digest + FixedOutput<OutputSize = U32>,
181
{
182
0
    fn try_sign_digest_with_rng(
183
0
        &self,
184
0
        rng: &mut impl CryptoRngCore,
185
0
        digest: D,
186
0
    ) -> Result<Signature> {
187
0
        let mut aux_rand = [0u8; 32];
188
0
        rng.fill_bytes(&mut aux_rand);
189
0
        self.sign_prehash_with_aux_rand(&digest.finalize_fixed().into(), &aux_rand)
190
0
    }
191
}
192
193
impl RandomizedSigner<Signature> for SigningKey {
194
0
    fn try_sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result<Signature> {
195
0
        self.try_sign_digest_with_rng(rng, Sha256::new_with_prefix(msg))
196
0
    }
197
}
198
199
impl RandomizedPrehashSigner<Signature> for SigningKey {
200
0
    fn sign_prehash_with_rng(
201
0
        &self,
202
0
        rng: &mut impl CryptoRngCore,
203
0
        prehash: &[u8],
204
0
    ) -> Result<Signature> {
205
0
        let prehash = prehash.try_into().map_err(|_| Error::new())?;
206
207
0
        let mut aux_rand = [0u8; 32];
208
0
        rng.fill_bytes(&mut aux_rand);
209
0
210
0
        self.sign_prehash_with_aux_rand(&prehash, &aux_rand)
211
0
    }
212
}
213
214
impl Signer<Signature> for SigningKey {
215
0
    fn try_sign(&self, msg: &[u8]) -> Result<Signature> {
216
0
        self.try_sign_digest(Sha256::new_with_prefix(msg))
217
0
    }
218
}
219
220
//
221
// Other trait impls
222
//
223
224
impl AsRef<VerifyingKey> for SigningKey {
225
0
    fn as_ref(&self) -> &VerifyingKey {
226
0
        &self.verifying_key
227
0
    }
228
}
229
230
impl Drop for SigningKey {
231
0
    fn drop(&mut self) {
232
0
        self.secret_key.zeroize();
233
0
    }
234
}
235
236
impl KeypairRef for SigningKey {
237
    type VerifyingKey = VerifyingKey;
238
}
239
240
impl ZeroizeOnDrop for SigningKey {}
241
242
#[cfg(feature = "serde")]
243
impl Serialize for SigningKey {
244
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
245
    where
246
        S: ser::Serializer,
247
    {
248
        self.secret_key.serialize(serializer)
249
    }
250
}
251
252
#[cfg(feature = "serde")]
253
impl<'de> Deserialize<'de> for SigningKey {
254
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
255
    where
256
        D: de::Deserializer<'de>,
257
    {
258
        Ok(SigningKey::from(NonZeroScalar::deserialize(deserializer)?))
259
    }
260
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/k256-0.13.3/src/schnorr/verifying.rs
Line
Count
Source
1
//! Taproot Schnorr verifying key.
2
3
use super::{tagged_hash, Signature, CHALLENGE_TAG};
4
use crate::{AffinePoint, FieldBytes, ProjectivePoint, PublicKey, Scalar};
5
use elliptic_curve::{
6
    bigint::U256,
7
    group::prime::PrimeCurveAffine,
8
    ops::{LinearCombination, Reduce},
9
    point::DecompactPoint,
10
};
11
use sha2::{
12
    digest::{consts::U32, FixedOutput},
13
    Digest, Sha256,
14
};
15
use signature::{hazmat::PrehashVerifier, DigestVerifier, Error, Result, Verifier};
16
17
#[cfg(feature = "serde")]
18
use serdect::serde::{de, ser, Deserialize, Serialize};
19
20
/// Taproot Schnorr verifying key.
21
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
22
pub struct VerifyingKey {
23
    /// Inner public key
24
    pub(super) inner: PublicKey,
25
}
26
27
impl VerifyingKey {
28
    /// Borrow the inner [`AffinePoint`] this type wraps.
29
0
    pub fn as_affine(&self) -> &AffinePoint {
30
0
        self.inner.as_affine()
31
0
    }
32
33
    /// Serialize as bytes.
34
0
    pub fn to_bytes(&self) -> FieldBytes {
35
0
        self.as_affine().x.to_bytes()
36
0
    }
37
38
    /// Parse verifying key from big endian-encoded x-coordinate.
39
0
    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
40
0
        let maybe_affine_point = AffinePoint::decompact(FieldBytes::from_slice(bytes));
41
0
        let affine_point = Option::from(maybe_affine_point).ok_or_else(Error::new)?;
42
0
        PublicKey::from_affine(affine_point)
43
0
            .map_err(|_| Error::new())?
44
0
            .try_into()
45
0
    }
46
}
47
48
//
49
// `*Verifier` trait impls
50
//
51
52
impl<D> DigestVerifier<D, Signature> for VerifyingKey
53
where
54
    D: Digest + FixedOutput<OutputSize = U32>,
55
{
56
0
    fn verify_digest(&self, digest: D, signature: &Signature) -> Result<()> {
57
0
        self.verify_prehash(digest.finalize_fixed().as_slice(), signature)
58
0
    }
59
}
60
61
impl PrehashVerifier<Signature> for VerifyingKey {
62
0
    fn verify_prehash(
63
0
        &self,
64
0
        prehash: &[u8],
65
0
        signature: &Signature,
66
0
    ) -> core::result::Result<(), Error> {
67
0
        let prehash: [u8; 32] = prehash.try_into().map_err(|_| Error::new())?;
68
0
        let (r, s) = signature.split();
69
0
70
0
        let e = <Scalar as Reduce<U256>>::reduce_bytes(
71
0
            &tagged_hash(CHALLENGE_TAG)
72
0
                .chain_update(signature.r.to_bytes())
73
0
                .chain_update(self.to_bytes())
74
0
                .chain_update(prehash)
75
0
                .finalize(),
76
0
        );
77
0
78
0
        let R = ProjectivePoint::lincomb(
79
0
            &ProjectivePoint::GENERATOR,
80
0
            s,
81
0
            &self.inner.to_projective(),
82
0
            &-e,
83
0
        )
84
0
        .to_affine();
85
0
86
0
        if R.is_identity().into() || R.y.normalize().is_odd().into() || R.x.normalize() != *r {
87
0
            return Err(Error::new());
88
0
        }
89
0
90
0
        Ok(())
91
0
    }
92
}
93
94
impl Verifier<Signature> for VerifyingKey {
95
0
    fn verify(&self, msg: &[u8], signature: &Signature) -> Result<()> {
96
0
        self.verify_digest(Sha256::new_with_prefix(msg), signature)
97
0
    }
98
}
99
100
//
101
// Other trait impls
102
//
103
104
impl From<VerifyingKey> for AffinePoint {
105
0
    fn from(vk: VerifyingKey) -> AffinePoint {
106
0
        *vk.as_affine()
107
0
    }
108
}
109
110
impl From<&VerifyingKey> for AffinePoint {
111
0
    fn from(vk: &VerifyingKey) -> AffinePoint {
112
0
        *vk.as_affine()
113
0
    }
114
}
115
116
impl From<VerifyingKey> for PublicKey {
117
0
    fn from(vk: VerifyingKey) -> PublicKey {
118
0
        vk.inner
119
0
    }
120
}
121
122
impl From<&VerifyingKey> for PublicKey {
123
0
    fn from(vk: &VerifyingKey) -> PublicKey {
124
0
        vk.inner
125
0
    }
126
}
127
128
impl TryFrom<PublicKey> for VerifyingKey {
129
    type Error = Error;
130
131
0
    fn try_from(public_key: PublicKey) -> Result<VerifyingKey> {
132
0
        if public_key.as_affine().y.normalize().is_even().into() {
133
0
            Ok(Self { inner: public_key })
134
        } else {
135
0
            Err(Error::new())
136
        }
137
0
    }
138
}
139
140
impl TryFrom<&PublicKey> for VerifyingKey {
141
    type Error = Error;
142
143
0
    fn try_from(public_key: &PublicKey) -> Result<VerifyingKey> {
144
0
        Self::try_from(*public_key)
145
0
    }
146
}
147
148
#[cfg(feature = "serde")]
149
impl Serialize for VerifyingKey {
150
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
151
    where
152
        S: ser::Serializer,
153
    {
154
        self.inner.serialize(serializer)
155
    }
156
}
157
158
#[cfg(feature = "serde")]
159
impl<'de> Deserialize<'de> for VerifyingKey {
160
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
161
    where
162
        D: de::Deserializer<'de>,
163
    {
164
        VerifyingKey::try_from(PublicKey::deserialize(deserializer)?).map_err(de::Error::custom)
165
    }
166
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/lazy_static-1.5.0/src/inline_lazy.rs
Line
Count
Source
1
// Copyright 2016 lazy-static.rs Developers
2
//
3
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4
// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5
// https://opensource.org/licenses/MIT>, at your option. This file may not be
6
// copied, modified, or distributed except according to those terms.
7
8
extern crate core;
9
extern crate std;
10
11
use self::std::cell::Cell;
12
use self::std::mem::MaybeUninit;
13
use self::std::prelude::v1::*;
14
use self::std::sync::Once;
15
#[allow(deprecated)]
16
pub use self::std::sync::ONCE_INIT;
17
18
#[allow(dead_code)] // Used in macros
19
pub struct Lazy<T: Sync>(Cell<MaybeUninit<T>>, Once);
20
21
impl<T: Sync> Lazy<T> {
22
    #[allow(deprecated)]
23
    pub const INIT: Self = Lazy(Cell::new(MaybeUninit::uninit()), ONCE_INIT);
24
25
    #[inline(always)]
26
14.0k
    pub fn get<F>(&'static self, f: F) -> &T
27
14.0k
    where
28
14.0k
        F: FnOnce() -> T,
29
14.0k
    {
30
14.0k
        self.1.call_once(|| {
31
1
            self.0.set(MaybeUninit::new(f()));
32
14.0k
        });
_RNCINvMNtCsku9Fx0rvNbC_11lazy_static4lazyINtB5_4LazyNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntE3getNvNvXNtCs4RkbDk9WRL5_5clvmr8op_utilsNtB1G_11GROUP_ORDERNtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5deref23___static_ref_initializeE0B1I_
Line
Count
Source
30
1
        self.1.call_once(|| {
31
1
            self.0.set(MaybeUninit::new(f()));
32
1
        });
Unexecuted instantiation: _RNCINvMNtCsku9Fx0rvNbC_11lazy_static4lazyINtB5_4LazypE3getpE0B7_
33
14.0k
34
14.0k
        // `self.0` is guaranteed to be initialized by this point
35
14.0k
        // The `Once` will catch and propagate panics
36
14.0k
        unsafe { &*(*self.0.as_ptr()).as_ptr() }
37
14.0k
    }
_RINvMNtCsku9Fx0rvNbC_11lazy_static4lazyINtB3_4LazyNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntE3getNvNvXNtCs4RkbDk9WRL5_5clvmr8op_utilsNtB1E_11GROUP_ORDERNtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5deref23___static_ref_initializeEB1G_
Line
Count
Source
26
14.0k
    pub fn get<F>(&'static self, f: F) -> &T
27
14.0k
    where
28
14.0k
        F: FnOnce() -> T,
29
14.0k
    {
30
14.0k
        self.1.call_once(|| {
31
            self.0.set(MaybeUninit::new(f()));
32
14.0k
        });
33
14.0k
34
14.0k
        // `self.0` is guaranteed to be initialized by this point
35
14.0k
        // The `Once` will catch and propagate panics
36
14.0k
        unsafe { &*(*self.0.as_ptr()).as_ptr() }
37
14.0k
    }
Unexecuted instantiation: _RINvMNtCsku9Fx0rvNbC_11lazy_static4lazyINtB3_4LazypE3getpEB5_
38
}
39
40
unsafe impl<T: Sync> Sync for Lazy<T> {}
41
42
#[macro_export]
43
#[doc(hidden)]
44
macro_rules! __lazy_static_create {
45
    ($NAME:ident, $T:ty) => {
46
        static $NAME: $crate::lazy::Lazy<$T> = $crate::lazy::Lazy::INIT;
47
    };
48
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/lazy_static-1.5.0/src/lib.rs
Line
Count
Source
1
// Copyright 2016 lazy-static.rs Developers
2
//
3
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4
// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5
// https://opensource.org/licenses/MIT>, at your option. This file may not be
6
// copied, modified, or distributed except according to those terms.
7
8
/*!
9
A macro for declaring lazily evaluated statics.
10
11
Using this macro, it is possible to have `static`s that require code to be
12
executed at runtime in order to be initialized.
13
This includes anything requiring heap allocations, like vectors or hash maps,
14
as well as anything that requires function calls to be computed.
15
16
# Syntax
17
18
```ignore
19
lazy_static! {
20
    [pub] static ref NAME_1: TYPE_1 = EXPR_1;
21
    [pub] static ref NAME_2: TYPE_2 = EXPR_2;
22
    ...
23
    [pub] static ref NAME_N: TYPE_N = EXPR_N;
24
}
25
```
26
27
Attributes (including doc comments) are supported as well:
28
29
```rust
30
use lazy_static::lazy_static;
31
32
# fn main() {
33
lazy_static! {
34
    /// This is an example for using doc comment attributes
35
    static ref EXAMPLE: u8 = 42;
36
}
37
# }
38
```
39
40
# Semantics
41
42
For a given `static ref NAME: TYPE = EXPR;`, the macro generates a unique type that
43
implements `Deref<TYPE>` and stores it in a static with name `NAME`. (Attributes end up
44
attaching to this type.)
45
46
On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
47
can return a reference to the same object. Note that this can lead to deadlocks
48
if you have multiple lazy statics that depend on each other in their initialization.
49
50
Apart from the lazy initialization, the resulting "static ref" variables
51
have generally the same properties as regular "static" variables:
52
53
- Any type in them needs to fulfill the `Sync` trait.
54
- If the type has a destructor, then it will not run when the process exits.
55
56
# Example
57
58
Using the macro:
59
60
```rust
61
use lazy_static::lazy_static;
62
use std::collections::HashMap;
63
64
lazy_static! {
65
    static ref HASHMAP: HashMap<u32, &'static str> = {
66
        let mut m = HashMap::new();
67
        m.insert(0, "foo");
68
        m.insert(1, "bar");
69
        m.insert(2, "baz");
70
        m
71
    };
72
    static ref COUNT: usize = HASHMAP.len();
73
    static ref NUMBER: u32 = times_two(21);
74
}
75
76
fn times_two(n: u32) -> u32 { n * 2 }
77
78
fn main() {
79
    println!("The map has {} entries.", *COUNT);
80
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
81
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
82
}
83
```
84
85
# Implementation details
86
87
The `Deref` implementation uses a hidden static variable that is guarded by an atomic check on each access.
88
89
# Cargo features
90
91
This crate provides one cargo feature:
92
93
- `spin_no_std`: This allows using this crate in a no-std environment, by depending on the standalone `spin` crate.
94
95
*/
96
97
#![doc(html_root_url = "https://docs.rs/lazy_static/1.5.0")]
98
#![no_std]
99
100
#[cfg(doctest)]
101
#[macro_use]
102
extern crate doc_comment;
103
104
#[cfg(doctest)]
105
doctest!("../README.md");
106
107
#[cfg_attr(feature = "spin_no_std", path = "core_lazy.rs")]
108
#[cfg_attr(not(feature = "spin_no_std"), path = "inline_lazy.rs")]
109
#[doc(hidden)]
110
pub mod lazy;
111
112
#[doc(hidden)]
113
pub use core::ops::Deref as __Deref;
114
115
#[macro_export(local_inner_macros)]
116
#[doc(hidden)]
117
macro_rules! __lazy_static_internal {
118
    // optional visibility restrictions are wrapped in `()` to allow for
119
    // explicitly passing otherwise implicit information about private items
120
    ($(#[$attr:meta])* ($($vis:tt)*) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
121
        __lazy_static_internal!(@MAKE TY, $(#[$attr])*, ($($vis)*), $N);
122
        __lazy_static_internal!(@TAIL, $N : $T = $e);
123
        lazy_static!($($t)*);
124
    };
125
    (@TAIL, $N:ident : $T:ty = $e:expr) => {
126
        impl $crate::__Deref for $N {
127
            type Target = $T;
128
14.0k
            fn deref(&self) -> &$T {
129
                #[inline(always)]
130
1
                fn __static_ref_initialize() -> $T { $e }
131
132
                #[inline(always)]
133
14.0k
                fn __stability() -> &'static $T {
134
14.0k
                    __lazy_static_create!(LAZY, $T);
135
14.0k
                    LAZY.get(__static_ref_initialize)
136
14.0k
                }
137
14.0k
                __stability()
138
14.0k
            }
139
        }
140
        impl $crate::LazyStatic for $N {
141
0
            fn initialize(lazy: &Self) {
142
0
                let _ = &**lazy;
143
0
            }
144
        }
145
    };
146
    // `vis` is wrapped in `()` to prevent parsing ambiguity
147
    (@MAKE TY, $(#[$attr:meta])*, ($($vis:tt)*), $N:ident) => {
148
        #[allow(missing_copy_implementations)]
149
        #[allow(non_camel_case_types)]
150
        #[allow(dead_code)]
151
        $(#[$attr])*
152
        $($vis)* struct $N {__private_field: ()}
153
        #[doc(hidden)]
154
        #[allow(non_upper_case_globals)]
155
        $($vis)* static $N: $N = $N {__private_field: ()};
156
    };
157
    () => ()
158
}
159
160
#[macro_export(local_inner_macros)]
161
macro_rules! lazy_static {
162
    ($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
163
        // use `()` to explicitly forward the information about private items
164
        __lazy_static_internal!($(#[$attr])* () static ref $N : $T = $e; $($t)*);
165
    };
166
    ($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
167
        __lazy_static_internal!($(#[$attr])* (pub) static ref $N : $T = $e; $($t)*);
168
    };
169
    ($(#[$attr:meta])* pub ($($vis:tt)+) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
170
        __lazy_static_internal!($(#[$attr])* (pub ($($vis)+)) static ref $N : $T = $e; $($t)*);
171
    };
172
    () => ()
173
}
174
175
/// Support trait for enabling a few common operation on lazy static values.
176
///
177
/// This is implemented by each defined lazy static, and
178
/// used by the free functions in this crate.
179
pub trait LazyStatic {
180
    #[doc(hidden)]
181
    fn initialize(lazy: &Self);
182
}
183
184
/// Takes a shared reference to a lazy static and initializes
185
/// it if it has not been already.
186
///
187
/// This can be used to control the initialization point of a lazy static.
188
///
189
/// Example:
190
///
191
/// ```rust
192
/// use lazy_static::lazy_static;
193
///
194
/// lazy_static! {
195
///     static ref BUFFER: Vec<u8> = (0..255).collect();
196
/// }
197
///
198
/// fn main() {
199
///     lazy_static::initialize(&BUFFER);
200
///
201
///     // ...
202
///     work_with_initialized_data(&BUFFER);
203
/// }
204
/// # fn work_with_initialized_data(_: &[u8]) {}
205
/// ```
206
0
pub fn initialize<T: LazyStatic>(lazy: &T) {
207
0
    LazyStatic::initialize(lazy);
208
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.155/src/macros.rs
Line
Count
Source
1
/// A macro for defining #[cfg] if-else statements.
2
///
3
/// This is similar to the `if/elif` C preprocessor macro by allowing definition
4
/// of a cascade of `#[cfg]` cases, emitting the implementation which matches
5
/// first.
6
///
7
/// This allows you to conveniently provide a long list #[cfg]'d blocks of code
8
/// without having to rewrite each clause multiple times.
9
macro_rules! cfg_if {
10
    // match if/else chains with a final `else`
11
    ($(
12
        if #[cfg($($meta:meta),*)] { $($it:item)* }
13
    ) else * else {
14
        $($it2:item)*
15
    }) => {
16
        cfg_if! {
17
            @__items
18
            () ;
19
            $( ( ($($meta),*) ($($it)*) ), )*
20
            ( () ($($it2)*) ),
21
        }
22
    };
23
24
    // match if/else chains lacking a final `else`
25
    (
26
        if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
27
        $(
28
            else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
29
        )*
30
    ) => {
31
        cfg_if! {
32
            @__items
33
            () ;
34
            ( ($($i_met),*) ($($i_it)*) ),
35
            $( ( ($($e_met),*) ($($e_it)*) ), )*
36
            ( () () ),
37
        }
38
    };
39
40
    // Internal and recursive macro to emit all the items
41
    //
42
    // Collects all the negated `cfg`s in a list at the beginning and after the
43
    // semicolon is all the remaining items
44
    (@__items ($($not:meta,)*) ; ) => {};
45
    (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ),
46
     $($rest:tt)*) => {
47
        // Emit all items within one block, applying an appropriate #[cfg]. The
48
        // #[cfg] will require all `$m` matchers specified and must also negate
49
        // all previous matchers.
50
        cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
51
52
        // Recurse to emit all other items in `$rest`, and when we do so add all
53
        // our `$m` matchers to the list of `$not` matchers as future emissions
54
        // will have to negate everything we just matched as well.
55
        cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
56
    };
57
58
    // Internal macro to Apply a cfg attribute to a list of items
59
    (@__apply $m:meta, $($it:item)*) => {
60
        $(#[$m] $it)*
61
    };
62
}
63
64
macro_rules! s {
65
    ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($(
66
        s!(it: $(#[$attr])* pub $t $i { $($field)* });
67
    )*);
68
    (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => (
69
        compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead");
70
    );
71
    (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => (
72
        __item! {
73
            #[repr(C)]
74
            #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))]
75
            #[allow(deprecated)]
76
            $(#[$attr])*
77
            pub struct $i { $($field)* }
78
        }
79
        #[allow(deprecated)]
80
        impl ::Copy for $i {}
81
        #[allow(deprecated)]
82
        impl ::Clone for $i {
83
0
            fn clone(&self) -> $i { *self }
Unexecuted instantiation: _RNvXs_NtCs2ZRhui0i743_4libc4unixNtB4_5groupNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB6_
Unexecuted instantiation: _RNvXs1_NtCs2ZRhui0i743_4libc4unixNtB5_7utimbufNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXs3_NtCs2ZRhui0i743_4libc4unixNtB5_7timevalNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXs5_NtCs2ZRhui0i743_4libc4unixNtB5_8timespecNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXs7_NtCs2ZRhui0i743_4libc4unixNtB5_6rlimitNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXs9_NtCs2ZRhui0i743_4libc4unixNtB5_6rusageNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXsb_NtCs2ZRhui0i743_4libc4unixNtB5_9ipv6_mreqNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXsd_NtCs2ZRhui0i743_4libc4unixNtB5_7hostentNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXsf_NtCs2ZRhui0i743_4libc4unixNtB5_5iovecNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXsh_NtCs2ZRhui0i743_4libc4unixNtB5_6pollfdNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXsj_NtCs2ZRhui0i743_4libc4unixNtB5_7winsizeNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXsl_NtCs2ZRhui0i743_4libc4unixNtB5_6lingerNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXsn_NtCs2ZRhui0i743_4libc4unixNtB5_6sigvalNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXsp_NtCs2ZRhui0i743_4libc4unixNtB5_9itimervalNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXsr_NtCs2ZRhui0i743_4libc4unixNtB5_3tmsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXst_NtCs2ZRhui0i743_4libc4unixNtB5_7serventNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXsv_NtCs2ZRhui0i743_4libc4unixNtB5_8protoentNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB7_
Unexecuted instantiation: _RNvXs_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB4_7in_addrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB8_
Unexecuted instantiation: _RNvXs1_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_7ip_mreqNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXs3_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_8ip_mreqnNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXs5_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_14ip_mreq_sourceNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXs7_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_8sockaddrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXs9_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_11sockaddr_inNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsb_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_12sockaddr_in6NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsd_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_8addrinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsf_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_11sockaddr_llNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsh_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_6fd_setNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsj_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_2tmNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsl_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_11sched_paramNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsn_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_7Dl_infoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsp_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_5lconvNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsr_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_10in_pktinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXst_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_7ifaddrsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsv_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_9in6_rtmsgNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsx_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_6arpreqNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsz_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_10arpreq_oldNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsB_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_6arphdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsD_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_7mmsghdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXs_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB4_6glob_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBa_
Unexecuted instantiation: _RNvXs1_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_6passwdNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXs3_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_4spwdNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXs5_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_5dqblkNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXs7_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_16signalfd_siginfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXs9_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_10itimerspecNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsb_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_6fsid_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsd_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_11packet_mreqNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsf_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_9cpu_set_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsh_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_12if_nameindexNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsj_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_7msginfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsl_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_6sembufNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsn_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_11input_eventNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsp_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_8input_idNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsr_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_13input_absinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXst_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_18input_keymap_entryNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsv_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_10input_maskNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsx_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_9ff_replayNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsz_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_10ff_triggerNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsB_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_11ff_envelopeNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsD_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_18ff_constant_effectNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsF_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_14ff_ramp_effectNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsH_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_19ff_condition_effectNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsJ_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_18ff_periodic_effectNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsL_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_16ff_rumble_effectNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsN_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_9ff_effectNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsP_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_16uinput_ff_uploadNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsR_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_15uinput_ff_eraseNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsT_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_16uinput_abs_setupNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsV_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_12dl_phdr_infoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsX_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_10Elf32_EhdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXsZ_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB5_10Elf64_EhdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBb_
Unexecuted instantiation: _RNvXs11_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_9Elf32_SymNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs13_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_9Elf64_SymNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs15_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_10Elf32_PhdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs17_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_10Elf64_PhdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs19_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_10Elf32_ShdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1b_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_10Elf64_ShdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1d_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_5ucredNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1f_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_6mntentNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1h_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_26posix_spawn_file_actions_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1j_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_17posix_spawnattr_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1l_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_10genlmsghdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1n_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_11in6_pktinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1p_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_12arpd_requestNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1r_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_13inotify_eventNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1t_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_17fanotify_responseNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1v_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_11sockaddr_vmNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1x_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_10regmatch_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1z_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_17sock_extended_errNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1B_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_29___c_anonymous_sockaddr_can_tpNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1D_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_32___c_anonymous_sockaddr_can_j1939NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1F_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_10can_filterNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1H_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_12j1939_filterNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1J_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_11sock_filterNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1L_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_10sock_fprogNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1N_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_12seccomp_dataNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1P_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_19seccomp_notif_sizesNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1R_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_13seccomp_notifNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1T_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_18seccomp_notif_respNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1V_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_19seccomp_notif_addfdNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1X_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_8nlmsghdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1Z_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_8nlmsgerrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs21_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_6nlattrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs23_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_16file_clone_rangeNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs25_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_22___c_anonymous_ifru_mapNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs27_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_9in6_ifreqNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs29_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_6optionNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2b_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_12sctp_initmsgNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2d_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_15sctp_sndrcvinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2f_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_12sctp_sndinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2h_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_12sctp_rcvinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2j_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_12sctp_nxtinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2l_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_11sctp_prinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2n_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_13sctp_authinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2p_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_8rlimit64NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2r_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_15tls_crypto_infoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2t_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_29tls12_crypto_info_aes_gcm_128NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2v_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_29tls12_crypto_info_aes_gcm_256NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2x_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_35tls12_crypto_info_chacha20_poly1305NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs0_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_5statxNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXs2_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_15statx_timestampNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXs4_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_5aiocbNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXs6_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_13___exit_statusNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXs8_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_9___timevalNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsa_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_8glob64_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsc_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_6msghdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXse_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_7cmsghdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsg_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_7termiosNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsi_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_8mallinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsk_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_9mallinfo2NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsm_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_10nl_pktinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXso_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_11nl_mmap_reqNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsq_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_11nl_mmap_hdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXss_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_7rtentryNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsu_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_5timexNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsw_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_10ntptimevalNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsy_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_7regex_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsA_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_10Elf64_ChdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsC_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_10Elf32_ChdrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsE_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_7seminfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsG_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_23ptrace_peeksiginfo_argsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsI_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_39___c_anonymous_ptrace_syscall_info_entryNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsK_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_38___c_anonymous_ptrace_syscall_info_exitNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsM_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_41___c_anonymous_ptrace_syscall_info_seccompNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsO_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_19ptrace_syscall_infoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsQ_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_12sockaddr_xdpNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsS_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_15xdp_ring_offsetNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsU_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_16xdp_mmap_offsetsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsW_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_18xdp_ring_offset_v1NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXsY_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB5_19xdp_mmap_offsets_v1NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBd_
Unexecuted instantiation: _RNvXs10_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB6_12xdp_umem_regNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBe_
Unexecuted instantiation: _RNvXs12_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB6_15xdp_umem_reg_v1NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBe_
Unexecuted instantiation: _RNvXs14_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB6_14xdp_statisticsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBe_
Unexecuted instantiation: _RNvXs16_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB6_17xdp_statistics_v1NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBe_
Unexecuted instantiation: _RNvXs18_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB6_11xdp_optionsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBe_
Unexecuted instantiation: _RNvXs1a_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB6_8xdp_descNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBe_
Unexecuted instantiation: _RNvXs1c_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB6_4iocbNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBe_
Unexecuted instantiation: _RNvXs_NtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b64NtB4_8sigset_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBe_
Unexecuted instantiation: _RNvXs1_NtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b64NtB5_7sysinfoNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBf_
Unexecuted instantiation: _RNvXs3_NtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b64NtB5_8msqid_dsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBf_
Unexecuted instantiation: _RNvXs5_NtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b64NtB5_8semid_dsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBf_
Unexecuted instantiation: _RNvXs_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB4_9sigactionNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBg_
Unexecuted instantiation: _RNvXs1_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_6statfsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXs3_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_5flockNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXs5_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_7flock64NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXs7_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_9siginfo_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXs9_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_7stack_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsb_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_4statNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsd_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_6stat64NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsf_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_8statfs64NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsh_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_9statvfs64NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsj_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_14pthread_attr_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsl_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_12__libc_fpxregNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsn_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_12__libc_xmmregNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsp_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_13__libc_fpstateNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsr_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_16user_regs_structNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXst_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_4userNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsv_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_10mcontext_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsx_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_8ipc_permNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsz_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_8shmid_dsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsB_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_25ptrace_rseq_configurationNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXs_NtNtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_647not_x32NtB4_7statvfsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBi_
Unexecuted instantiation: _RNvXs1_NtNtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_645alignNtB5_10clone_argsNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBj_
Unexecuted instantiation: _RNvXs_NtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu5alignNtB4_5sem_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBe_
Unexecuted instantiation: _RNvXs_NtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux4arch7genericNtB4_8termios2NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBe_
Unexecuted instantiation: _RNvXs37_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_19pthread_mutexattr_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs39_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_20pthread_rwlockattr_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs3b_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_18pthread_condattr_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs3d_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_21pthread_barrierattr_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs3f_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_23fanotify_event_metadataNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux14non_exhaustiveNtB4_8open_howNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs_NtNtCs2ZRhui0i743_4libc4unix5alignNtB4_8in6_addrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB8_
84
        }
85
    );
86
}
87
88
macro_rules! s_no_extra_traits {
89
    ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($(
90
        s_no_extra_traits!(it: $(#[$attr])* pub $t $i { $($field)* });
91
    )*);
92
    (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => (
93
        cfg_if! {
94
            if #[cfg(libc_union)] {
95
                __item! {
96
                    #[repr(C)]
97
                    $(#[$attr])*
98
                    pub union $i { $($field)* }
99
                }
100
101
                impl ::Copy for $i {}
102
                impl ::Clone for $i {
103
0
                    fn clone(&self) -> $i { *self }
Unexecuted instantiation: _RNvXs2N_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_22___c_anonymous_ifr_ifruNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2R_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_22___c_anonymous_ifc_ifcuNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs33_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_35___c_anonymous_sockaddr_can_can_addrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
104
                }
105
            }
106
        }
107
    );
108
    (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => (
109
        __item! {
110
            #[repr(C)]
111
            $(#[$attr])*
112
            pub struct $i { $($field)* }
113
        }
114
        #[allow(deprecated)]
115
        impl ::Copy for $i {}
116
        #[allow(deprecated)]
117
        impl ::Clone for $i {
118
0
            fn clone(&self) -> $i { *self }
Unexecuted instantiation: _RNvXsF_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_11epoll_eventNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsH_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_11sockaddr_unNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_16sockaddr_storageNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsL_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_7utsnameNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXsN_NtNtCs2ZRhui0i743_4libc4unix10linux_likeNtB5_8sigeventNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB9_
Unexecuted instantiation: _RNvXs2z_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_11sockaddr_nlNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2B_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_6direntNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2D_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_12sockaddr_algNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2F_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_12uinput_setupNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2H_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_15uinput_user_devNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2J_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_9af_alg_ivNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2L_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_7mq_attrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2P_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_5ifreqNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2T_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_6ifconfNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2V_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_15hwtstamp_configNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2X_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_8dirent64NtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs2Z_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_10sched_attrNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs31_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_11sock_txtimeNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs35_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_12sockaddr_canNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs1j_NtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnuNtB6_5utmpxNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBe_
Unexecuted instantiation: _RNvXsD_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_18user_fpregs_structNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXsF_NtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_64NtB5_10ucontext_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBh_
Unexecuted instantiation: _RNvXs_NtNtNtNtNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux3gnu3b646x86_645alignNtB4_11max_align_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBi_
Unexecuted instantiation: _RNvXs3h_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_14pthread_cond_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs3j_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_15pthread_mutex_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs3l_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_16pthread_rwlock_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs3n_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_17pthread_barrier_tNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs3p_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_9can_frameNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs3r_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_11canfd_frameNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
Unexecuted instantiation: _RNvXs3t_NtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linuxNtB6_11canxl_frameNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBc_
119
        }
120
    );
121
}
122
123
macro_rules! missing {
124
    ($($(#[$attr:meta])* pub enum $i:ident {})*) => ($(
125
        $(#[$attr])* #[allow(missing_copy_implementations)] pub enum $i { }
126
    )*);
127
}
128
129
macro_rules! e {
130
    ($($(#[$attr:meta])* pub enum $i:ident { $($field:tt)* })*) => ($(
131
        __item! {
132
            #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))]
133
            $(#[$attr])*
134
            pub enum $i { $($field)* }
135
        }
136
        impl ::Copy for $i {}
137
        impl ::Clone for $i {
138
            fn clone(&self) -> $i { *self }
139
        }
140
    )*);
141
}
142
143
macro_rules! s_paren {
144
    ($($(#[$attr:meta])* pub struct $i:ident ( $($field:tt)* ); )* ) => ($(
145
        __item! {
146
            #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))]
147
            $(#[$attr])*
148
            pub struct $i ( $($field)* );
149
        }
150
        impl ::Copy for $i {}
151
        impl ::Clone for $i {
152
            fn clone(&self) -> $i { *self }
153
        }
154
    )*);
155
}
156
157
// This is a pretty horrible hack to allow us to conditionally mark
158
// some functions as 'const', without requiring users of this macro
159
// to care about the "const-extern-fn" feature.
160
//
161
// When 'const-extern-fn' is enabled, we emit the captured 'const' keyword
162
// in the expanded function.
163
//
164
// When 'const-extern-fn' is disabled, we always emit a plain 'pub unsafe extern fn'.
165
// Note that the expression matched by the macro is exactly the same - this allows
166
// users of this macro to work whether or not 'const-extern-fn' is enabled
167
//
168
// Unfortunately, we need to duplicate most of this macro between the 'cfg_if' blocks.
169
// This is because 'const unsafe extern fn' won't even parse on older compilers,
170
// so we need to avoid emitting it at all of 'const-extern-fn'.
171
//
172
// Specifically, moving the 'cfg_if' into the macro body will *not* work.
173
// Doing so would cause the '#[cfg(feature = "const-extern-fn")]' to be emitted
174
// into user code. The 'cfg' gate will not stop Rust from trying to parse the
175
// 'pub const unsafe extern fn', so users would get a compiler error even when
176
// the 'const-extern-fn' feature is disabled
177
//
178
// Note that users of this macro need to place 'const' in a weird position
179
// (after the closing ')' for the arguments, but before the return type).
180
// This was the only way I could satisfy the following two requirements:
181
// 1. Avoid ambiguity errors from 'macro_rules!' (which happen when writing '$foo:ident fn'
182
// 2. Allow users of this macro to mix 'pub fn foo' and 'pub const fn bar' within the same
183
// 'f!' block
184
cfg_if! {
185
    if #[cfg(libc_const_extern_fn)] {
186
        macro_rules! f {
187
            ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident(
188
                        $($arg:ident: $argty:ty),*
189
            ) -> $ret:ty {
190
                $($body:stmt);*
191
            })*) => ($(
192
                #[inline]
193
                $(#[$attr])*
194
0
                pub $($constness)* unsafe extern fn $i($($arg: $argty),*
195
0
                ) -> $ret {
196
0
                    $($body);*
197
0
                }
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like13CMSG_FIRSTHDRB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like9CMSG_DATAB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like10CMSG_SPACEB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like8CMSG_LENB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like6FD_CLRB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like8FD_ISSETB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like6FD_SETB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like7FD_ZEROB5_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux9NLA_ALIGNB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux11CMSG_NXTHDRB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux14CPU_ALLOC_SIZEB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux8CPU_ZEROB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux7CPU_SETB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux7CPU_CLRB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux9CPU_ISSETB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux11CPU_COUNT_SB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux9CPU_COUNTB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux9CPU_EQUALB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux13SCTP_PR_INDEXB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux14SCTP_PR_POLICYB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux18SCTP_PR_SET_POLICYB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux5majorB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux5minorB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux9IPTOS_TOSB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux10IPTOS_PRECB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux6RT_TOSB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux12RT_ADDRCLASSB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux12RT_LOCALADDRB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux14SO_EE_OFFENDERB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux8BPF_RVALB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux10BPF_MISCOPB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux8BPF_STMTB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux8BPF_JUMPB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux9CPU_ISSETCsh9AfkWWthE7_8num_cpus
198
            )*)
199
        }
200
201
        macro_rules! safe_f {
202
            ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident(
203
                        $($arg:ident: $argty:ty),*
204
            ) -> $ret:ty {
205
                $($body:stmt);*
206
            })*) => ($(
207
                #[inline]
208
                $(#[$attr])*
209
0
                pub $($constness)* extern fn $i($($arg: $argty),*
210
0
                ) -> $ret {
211
0
                    $($body);*
212
0
                }
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like8SIGRTMAXB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like8SIGRTMINB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like10WIFSTOPPEDB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like8WSTOPSIGB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like12WIFCONTINUEDB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like11WIFSIGNALEDB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like8WTERMSIGB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like9WIFEXITEDB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like11WEXITSTATUSB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like9WCOREDUMPB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like10W_EXITCODEB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like10W_STOPCODEB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like4QCMDB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like12IPOPT_COPIEDB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like11IPOPT_CLASSB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like12IPOPT_NUMBERB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like9IPTOS_ECNB5_
Unexecuted instantiation: _RNvNtNtCs2ZRhui0i743_4libc4unix10linux_like14KERNEL_VERSIONB5_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux7makedevB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux19SCTP_PR_TTL_ENABLEDB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux19SCTP_PR_RTX_ENABLEDB7_
Unexecuted instantiation: _RNvNtNtNtCs2ZRhui0i743_4libc4unix10linux_like5linux20SCTP_PR_PRIO_ENABLEDB7_
213
            )*)
214
        }
215
216
        macro_rules! const_fn {
217
            ($($(#[$attr:meta])* $({$constness:ident})* fn $i:ident(
218
                        $($arg:ident: $argty:ty),*
219
            ) -> $ret:ty {
220
                $($body:stmt);*
221
            })*) => ($(
222
                #[inline]
223
                $(#[$attr])*
224
0
                $($constness)* fn $i($($arg: $argty),*
225
0
                ) -> $ret {
226
0
                    $($body);*
227
0
                }
228
            )*)
229
        }
230
231
    } else {
232
        macro_rules! f {
233
            ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident(
234
                        $($arg:ident: $argty:ty),*
235
            ) -> $ret:ty {
236
                $($body:stmt);*
237
            })*) => ($(
238
                #[inline]
239
                $(#[$attr])*
240
                pub unsafe extern fn $i($($arg: $argty),*
241
                ) -> $ret {
242
                    $($body);*
243
                }
244
            )*)
245
        }
246
247
        macro_rules! safe_f {
248
            ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident(
249
                        $($arg:ident: $argty:ty),*
250
            ) -> $ret:ty {
251
                $($body:stmt);*
252
            })*) => ($(
253
                #[inline]
254
                $(#[$attr])*
255
                pub extern fn $i($($arg: $argty),*
256
                ) -> $ret {
257
                    $($body);*
258
                }
259
            )*)
260
        }
261
262
        macro_rules! const_fn {
263
            ($($(#[$attr:meta])* $({$constness:ident})* fn $i:ident(
264
                        $($arg:ident: $argty:ty),*
265
            ) -> $ret:ty {
266
                $($body:stmt);*
267
            })*) => ($(
268
                #[inline]
269
                $(#[$attr])*
270
                fn $i($($arg: $argty),*
271
                ) -> $ret {
272
                    $($body);*
273
                }
274
            )*)
275
        }
276
    }
277
}
278
279
macro_rules! __item {
280
    ($i:item) => {
281
        $i
282
    };
283
}
284
285
macro_rules! align_const {
286
    ($($(#[$attr:meta])*
287
       pub const $name:ident : $t1:ty
288
       = $t2:ident { $($field:tt)* };)*) => ($(
289
        #[cfg(libc_align)]
290
        $(#[$attr])*
291
        pub const $name : $t1 = $t2 {
292
            $($field)*
293
        };
294
        #[cfg(not(libc_align))]
295
        $(#[$attr])*
296
        pub const $name : $t1 = $t2 {
297
            $($field)*
298
            __align: [],
299
        };
300
    )*)
301
}
302
303
// This macro is used to deprecate items that should be accessed via the mach2 crate
304
macro_rules! deprecated_mach {
305
    (pub const $id:ident: $ty:ty = $expr:expr;) => {
306
        #[deprecated(
307
            since = "0.2.55",
308
            note = "Use the `mach2` crate instead",
309
        )]
310
        #[allow(deprecated)]
311
        pub const $id: $ty = $expr;
312
    };
313
    ($(pub const $id:ident: $ty:ty = $expr:expr;)*) => {
314
        $(
315
            deprecated_mach!(
316
                pub const $id: $ty = $expr;
317
            );
318
        )*
319
    };
320
    (pub type $id:ident = $ty:ty;) => {
321
        #[deprecated(
322
            since = "0.2.55",
323
            note = "Use the `mach2` crate instead",
324
        )]
325
        #[allow(deprecated)]
326
        pub type $id = $ty;
327
    };
328
    ($(pub type $id:ident = $ty:ty;)*) => {
329
        $(
330
            deprecated_mach!(
331
                pub type $id = $ty;
332
            );
333
        )*
334
    }
335
}
336
337
#[cfg(not(libc_ptr_addr_of))]
338
macro_rules! ptr_addr_of {
339
    ($place:expr) => {
340
        &$place
341
    };
342
}
343
344
#[cfg(libc_ptr_addr_of)]
345
macro_rules! ptr_addr_of {
346
    ($place:expr) => {
347
        ::core::ptr::addr_of!($place)
348
    };
349
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.155/src/unix/linux_like/linux/gnu/mod.rs
Line
Count
Source
1
pub type pthread_t = c_ulong;
2
pub type __priority_which_t = ::c_uint;
3
pub type __rlimit_resource_t = ::c_uint;
4
pub type Lmid_t = ::c_long;
5
pub type regoff_t = ::c_int;
6
pub type __kernel_rwf_t = ::c_int;
7
8
cfg_if! {
9
    if #[cfg(doc)] {
10
        // Used in `linux::arch` to define ioctl constants.
11
        pub(crate) type Ioctl = ::c_ulong;
12
    } else {
13
        #[doc(hidden)]
14
        pub type Ioctl = ::c_ulong;
15
    }
16
}
17
18
s! {
19
    pub struct statx {
20
        pub stx_mask: u32,
21
        pub stx_blksize: u32,
22
        pub stx_attributes: u64,
23
        pub stx_nlink: u32,
24
        pub stx_uid: u32,
25
        pub stx_gid: u32,
26
        pub stx_mode: u16,
27
        __statx_pad1: [u16; 1],
28
        pub stx_ino: u64,
29
        pub stx_size: u64,
30
        pub stx_blocks: u64,
31
        pub stx_attributes_mask: u64,
32
        pub stx_atime: ::statx_timestamp,
33
        pub stx_btime: ::statx_timestamp,
34
        pub stx_ctime: ::statx_timestamp,
35
        pub stx_mtime: ::statx_timestamp,
36
        pub stx_rdev_major: u32,
37
        pub stx_rdev_minor: u32,
38
        pub stx_dev_major: u32,
39
        pub stx_dev_minor: u32,
40
        pub stx_mnt_id: u64,
41
        pub stx_dio_mem_align: u32,
42
        pub stx_dio_offset_align: u32,
43
        __statx_pad3: [u64; 12],
44
    }
45
46
    pub struct statx_timestamp {
47
        pub tv_sec: i64,
48
        pub tv_nsec: u32,
49
        pub __statx_timestamp_pad1: [i32; 1],
50
    }
51
52
    pub struct aiocb {
53
        pub aio_fildes: ::c_int,
54
        pub aio_lio_opcode: ::c_int,
55
        pub aio_reqprio: ::c_int,
56
        pub aio_buf: *mut ::c_void,
57
        pub aio_nbytes: ::size_t,
58
        pub aio_sigevent: ::sigevent,
59
        __next_prio: *mut aiocb,
60
        __abs_prio: ::c_int,
61
        __policy: ::c_int,
62
        __error_code: ::c_int,
63
        __return_value: ::ssize_t,
64
        pub aio_offset: off_t,
65
        #[cfg(all(not(target_arch = "x86_64"), target_pointer_width = "32"))]
66
        __unused1: [::c_char; 4],
67
        __glibc_reserved: [::c_char; 32]
68
    }
69
70
    pub struct __exit_status {
71
        pub e_termination: ::c_short,
72
        pub e_exit: ::c_short,
73
    }
74
75
    pub struct __timeval {
76
        pub tv_sec: i32,
77
        pub tv_usec: i32,
78
    }
79
80
    pub struct glob64_t {
81
        pub gl_pathc: ::size_t,
82
        pub gl_pathv: *mut *mut ::c_char,
83
        pub gl_offs: ::size_t,
84
        pub gl_flags: ::c_int,
85
86
        __unused1: *mut ::c_void,
87
        __unused2: *mut ::c_void,
88
        __unused3: *mut ::c_void,
89
        __unused4: *mut ::c_void,
90
        __unused5: *mut ::c_void,
91
    }
92
93
    pub struct msghdr {
94
        pub msg_name: *mut ::c_void,
95
        pub msg_namelen: ::socklen_t,
96
        pub msg_iov: *mut ::iovec,
97
        pub msg_iovlen: ::size_t,
98
        pub msg_control: *mut ::c_void,
99
        pub msg_controllen: ::size_t,
100
        pub msg_flags: ::c_int,
101
    }
102
103
    pub struct cmsghdr {
104
        pub cmsg_len: ::size_t,
105
        pub cmsg_level: ::c_int,
106
        pub cmsg_type: ::c_int,
107
    }
108
109
    pub struct termios {
110
        pub c_iflag: ::tcflag_t,
111
        pub c_oflag: ::tcflag_t,
112
        pub c_cflag: ::tcflag_t,
113
        pub c_lflag: ::tcflag_t,
114
        pub c_line: ::cc_t,
115
        pub c_cc: [::cc_t; ::NCCS],
116
        #[cfg(not(any(
117
            target_arch = "sparc",
118
            target_arch = "sparc64",
119
            target_arch = "mips",
120
            target_arch = "mips32r6",
121
            target_arch = "mips64",
122
            target_arch = "mips64r6")))]
123
        pub c_ispeed: ::speed_t,
124
        #[cfg(not(any(
125
            target_arch = "sparc",
126
            target_arch = "sparc64",
127
            target_arch = "mips",
128
            target_arch = "mips32r6",
129
            target_arch = "mips64",
130
            target_arch = "mips64r6")))]
131
        pub c_ospeed: ::speed_t,
132
    }
133
134
    pub struct mallinfo {
135
        pub arena: ::c_int,
136
        pub ordblks: ::c_int,
137
        pub smblks: ::c_int,
138
        pub hblks: ::c_int,
139
        pub hblkhd: ::c_int,
140
        pub usmblks: ::c_int,
141
        pub fsmblks: ::c_int,
142
        pub uordblks: ::c_int,
143
        pub fordblks: ::c_int,
144
        pub keepcost: ::c_int,
145
    }
146
147
    pub struct mallinfo2 {
148
        pub arena: ::size_t,
149
        pub ordblks: ::size_t,
150
        pub smblks: ::size_t,
151
        pub hblks: ::size_t,
152
        pub hblkhd: ::size_t,
153
        pub usmblks: ::size_t,
154
        pub fsmblks: ::size_t,
155
        pub uordblks: ::size_t,
156
        pub fordblks: ::size_t,
157
        pub keepcost: ::size_t,
158
    }
159
160
    pub struct nl_pktinfo {
161
        pub group: u32,
162
    }
163
164
    pub struct nl_mmap_req {
165
        pub nm_block_size: ::c_uint,
166
        pub nm_block_nr: ::c_uint,
167
        pub nm_frame_size: ::c_uint,
168
        pub nm_frame_nr: ::c_uint,
169
    }
170
171
    pub struct nl_mmap_hdr {
172
        pub nm_status: ::c_uint,
173
        pub nm_len: ::c_uint,
174
        pub nm_group: u32,
175
        pub nm_pid: u32,
176
        pub nm_uid: u32,
177
        pub nm_gid: u32,
178
    }
179
180
    pub struct rtentry {
181
        pub rt_pad1: ::c_ulong,
182
        pub rt_dst: ::sockaddr,
183
        pub rt_gateway: ::sockaddr,
184
        pub rt_genmask: ::sockaddr,
185
        pub rt_flags: ::c_ushort,
186
        pub rt_pad2: ::c_short,
187
        pub rt_pad3: ::c_ulong,
188
        pub rt_tos: ::c_uchar,
189
        pub rt_class: ::c_uchar,
190
        #[cfg(target_pointer_width = "64")]
191
        pub rt_pad4: [::c_short; 3usize],
192
        #[cfg(not(target_pointer_width = "64"))]
193
        pub rt_pad4: ::c_short,
194
        pub rt_metric: ::c_short,
195
        pub rt_dev: *mut ::c_char,
196
        pub rt_mtu: ::c_ulong,
197
        pub rt_window: ::c_ulong,
198
        pub rt_irtt: ::c_ushort,
199
    }
200
201
    pub struct timex {
202
        pub modes: ::c_uint,
203
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
204
        pub offset: i64,
205
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
206
        pub offset: ::c_long,
207
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
208
        pub freq: i64,
209
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
210
        pub freq: ::c_long,
211
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
212
        pub maxerror: i64,
213
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
214
        pub maxerror: ::c_long,
215
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
216
        pub esterror: i64,
217
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
218
        pub esterror: ::c_long,
219
        pub status: ::c_int,
220
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
221
        pub constant: i64,
222
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
223
        pub constant: ::c_long,
224
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
225
        pub precision: i64,
226
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
227
        pub precision: ::c_long,
228
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
229
        pub tolerance: i64,
230
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
231
        pub tolerance: ::c_long,
232
        pub time: ::timeval,
233
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
234
        pub tick: i64,
235
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
236
        pub tick: ::c_long,
237
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
238
        pub ppsfreq: i64,
239
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
240
        pub ppsfreq: ::c_long,
241
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
242
        pub jitter: i64,
243
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
244
        pub jitter: ::c_long,
245
        pub shift: ::c_int,
246
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
247
        pub stabil: i64,
248
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
249
        pub stabil: ::c_long,
250
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
251
        pub jitcnt: i64,
252
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
253
        pub jitcnt: ::c_long,
254
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
255
        pub calcnt: i64,
256
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
257
        pub calcnt: ::c_long,
258
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
259
        pub errcnt: i64,
260
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
261
        pub errcnt: ::c_long,
262
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
263
        pub stbcnt: i64,
264
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
265
        pub stbcnt: ::c_long,
266
        pub tai: ::c_int,
267
        pub __unused1: i32,
268
        pub __unused2: i32,
269
        pub __unused3: i32,
270
        pub __unused4: i32,
271
        pub __unused5: i32,
272
        pub __unused6: i32,
273
        pub __unused7: i32,
274
        pub __unused8: i32,
275
        pub __unused9: i32,
276
        pub __unused10: i32,
277
        pub __unused11: i32,
278
    }
279
280
    pub struct ntptimeval {
281
        pub time: ::timeval,
282
        pub maxerror: ::c_long,
283
        pub esterror: ::c_long,
284
        pub tai: ::c_long,
285
        pub __glibc_reserved1: ::c_long,
286
        pub __glibc_reserved2: ::c_long,
287
        pub __glibc_reserved3: ::c_long,
288
        pub __glibc_reserved4: ::c_long,
289
    }
290
291
    pub struct regex_t {
292
        __buffer: *mut ::c_void,
293
        __allocated: ::size_t,
294
        __used: ::size_t,
295
        __syntax: ::c_ulong,
296
        __fastmap: *mut ::c_char,
297
        __translate: *mut ::c_char,
298
        __re_nsub: ::size_t,
299
        __bitfield: u8,
300
    }
301
302
    pub struct Elf64_Chdr {
303
        pub ch_type: ::Elf64_Word,
304
        pub ch_reserved: ::Elf64_Word,
305
        pub ch_size: ::Elf64_Xword,
306
        pub ch_addralign: ::Elf64_Xword,
307
    }
308
309
    pub struct Elf32_Chdr {
310
        pub ch_type: ::Elf32_Word,
311
        pub ch_size: ::Elf32_Word,
312
        pub ch_addralign: ::Elf32_Word,
313
    }
314
315
    pub struct seminfo {
316
        pub semmap: ::c_int,
317
        pub semmni: ::c_int,
318
        pub semmns: ::c_int,
319
        pub semmnu: ::c_int,
320
        pub semmsl: ::c_int,
321
        pub semopm: ::c_int,
322
        pub semume: ::c_int,
323
        pub semusz: ::c_int,
324
        pub semvmx: ::c_int,
325
        pub semaem: ::c_int,
326
    }
327
328
    pub struct ptrace_peeksiginfo_args {
329
        pub off: ::__u64,
330
        pub flags: ::__u32,
331
        pub nr: ::__s32,
332
    }
333
334
    pub struct __c_anonymous_ptrace_syscall_info_entry {
335
        pub nr: ::__u64,
336
        pub args: [::__u64; 6],
337
    }
338
339
    pub struct __c_anonymous_ptrace_syscall_info_exit {
340
        pub sval: ::__s64,
341
        pub is_error: ::__u8,
342
    }
343
344
    pub struct __c_anonymous_ptrace_syscall_info_seccomp {
345
        pub nr: ::__u64,
346
        pub args: [::__u64; 6],
347
        pub ret_data: ::__u32,
348
    }
349
350
    pub struct ptrace_syscall_info {
351
        pub op: ::__u8,
352
        pub pad: [::__u8; 3],
353
        pub arch: ::__u32,
354
        pub instruction_pointer: ::__u64,
355
        pub stack_pointer: ::__u64,
356
        #[cfg(libc_union)]
357
        pub u: __c_anonymous_ptrace_syscall_info_data,
358
    }
359
360
    // linux/if_xdp.h
361
362
    pub struct sockaddr_xdp {
363
        pub sxdp_family: ::__u16,
364
        pub sxdp_flags: ::__u16,
365
        pub sxdp_ifindex: ::__u32,
366
        pub sxdp_queue_id: ::__u32,
367
        pub sxdp_shared_umem_fd: ::__u32,
368
    }
369
370
    pub struct xdp_ring_offset {
371
        pub producer: ::__u64,
372
        pub consumer: ::__u64,
373
        pub desc: ::__u64,
374
        pub flags: ::__u64,
375
    }
376
377
    pub struct xdp_mmap_offsets {
378
        pub rx: xdp_ring_offset,
379
        pub tx: xdp_ring_offset,
380
        pub fr: xdp_ring_offset,
381
        pub cr: xdp_ring_offset,
382
    }
383
384
    pub struct xdp_ring_offset_v1 {
385
        pub producer: ::__u64,
386
        pub consumer: ::__u64,
387
        pub desc: ::__u64,
388
    }
389
390
    pub struct xdp_mmap_offsets_v1 {
391
        pub rx: xdp_ring_offset_v1,
392
        pub tx: xdp_ring_offset_v1,
393
        pub fr: xdp_ring_offset_v1,
394
        pub cr: xdp_ring_offset_v1,
395
    }
396
397
    pub struct xdp_umem_reg {
398
        pub addr: ::__u64,
399
        pub len: ::__u64,
400
        pub chunk_size: ::__u32,
401
        pub headroom: ::__u32,
402
        pub flags: ::__u32,
403
    }
404
405
    pub struct xdp_umem_reg_v1 {
406
        pub addr: ::__u64,
407
        pub len: ::__u64,
408
        pub chunk_size: ::__u32,
409
        pub headroom: ::__u32,
410
    }
411
412
    pub struct xdp_statistics {
413
        pub rx_dropped: ::__u64,
414
        pub rx_invalid_descs: ::__u64,
415
        pub tx_invalid_descs: ::__u64,
416
        pub rx_ring_full: ::__u64,
417
        pub rx_fill_ring_empty_descs: ::__u64,
418
        pub tx_ring_empty_descs: ::__u64,
419
    }
420
421
    pub struct xdp_statistics_v1 {
422
        pub rx_dropped: ::__u64,
423
        pub rx_invalid_descs: ::__u64,
424
        pub tx_invalid_descs: ::__u64,
425
    }
426
427
    pub struct xdp_options {
428
        pub flags: ::__u32,
429
    }
430
431
    pub struct xdp_desc {
432
        pub addr: ::__u64,
433
        pub len: ::__u32,
434
        pub options: ::__u32,
435
    }
436
437
    pub struct iocb {
438
        pub aio_data: ::__u64,
439
        #[cfg(target_endian = "little")]
440
        pub aio_key: ::__u32,
441
        #[cfg(target_endian = "little")]
442
        pub aio_rw_flags: ::__kernel_rwf_t,
443
        #[cfg(target_endian = "big")]
444
        pub aio_rw_flags: ::__kernel_rwf_t,
445
        #[cfg(target_endian = "big")]
446
        pub aio_key: ::__u32,
447
        pub aio_lio_opcode: ::__u16,
448
        pub aio_reqprio: ::__s16,
449
        pub aio_fildes: ::__u32,
450
        pub aio_buf: ::__u64,
451
        pub aio_nbytes: ::__u64,
452
        pub aio_offset: ::__s64,
453
        aio_reserved2: ::__u64,
454
        pub aio_flags: ::__u32,
455
        pub aio_resfd: ::__u32,
456
    }
457
}
458
459
impl siginfo_t {
460
0
    pub unsafe fn si_addr(&self) -> *mut ::c_void {
461
        #[repr(C)]
462
        struct siginfo_sigfault {
463
            _si_signo: ::c_int,
464
            _si_errno: ::c_int,
465
            _si_code: ::c_int,
466
            si_addr: *mut ::c_void,
467
        }
468
0
        (*(self as *const siginfo_t as *const siginfo_sigfault)).si_addr
469
0
    }
470
471
0
    pub unsafe fn si_value(&self) -> ::sigval {
472
        #[repr(C)]
473
        struct siginfo_timer {
474
            _si_signo: ::c_int,
475
            _si_errno: ::c_int,
476
            _si_code: ::c_int,
477
            _si_tid: ::c_int,
478
            _si_overrun: ::c_int,
479
            si_sigval: ::sigval,
480
        }
481
0
        (*(self as *const siginfo_t as *const siginfo_timer)).si_sigval
482
0
    }
483
}
484
485
cfg_if! {
486
    if #[cfg(libc_union)] {
487
        // Internal, for casts to access union fields
488
        #[repr(C)]
489
        struct sifields_sigchld {
490
            si_pid: ::pid_t,
491
            si_uid: ::uid_t,
492
            si_status: ::c_int,
493
            si_utime: ::c_long,
494
            si_stime: ::c_long,
495
        }
496
        impl ::Copy for sifields_sigchld {}
497
        impl ::Clone for sifields_sigchld {
498
0
            fn clone(&self) -> sifields_sigchld {
499
0
                *self
500
0
            }
501
        }
502
503
        // Internal, for casts to access union fields
504
        #[repr(C)]
505
        union sifields {
506
            _align_pointer: *mut ::c_void,
507
            sigchld: sifields_sigchld,
508
        }
509
510
        // Internal, for casts to access union fields. Note that some variants
511
        // of sifields start with a pointer, which makes the alignment of
512
        // sifields vary on 32-bit and 64-bit architectures.
513
        #[repr(C)]
514
        struct siginfo_f {
515
            _siginfo_base: [::c_int; 3],
516
            sifields: sifields,
517
        }
518
519
        impl siginfo_t {
520
0
            unsafe fn sifields(&self) -> &sifields {
521
0
                &(*(self as *const siginfo_t as *const siginfo_f)).sifields
522
0
            }
523
524
0
            pub unsafe fn si_pid(&self) -> ::pid_t {
525
0
                self.sifields().sigchld.si_pid
526
0
            }
527
528
0
            pub unsafe fn si_uid(&self) -> ::uid_t {
529
0
                self.sifields().sigchld.si_uid
530
0
            }
531
532
0
            pub unsafe fn si_status(&self) -> ::c_int {
533
0
                self.sifields().sigchld.si_status
534
0
            }
535
536
0
            pub unsafe fn si_utime(&self) -> ::c_long {
537
0
                self.sifields().sigchld.si_utime
538
0
            }
539
540
0
            pub unsafe fn si_stime(&self) -> ::c_long {
541
0
                self.sifields().sigchld.si_stime
542
0
            }
543
        }
544
545
        pub union __c_anonymous_ptrace_syscall_info_data {
546
            pub entry: __c_anonymous_ptrace_syscall_info_entry,
547
            pub exit: __c_anonymous_ptrace_syscall_info_exit,
548
            pub seccomp: __c_anonymous_ptrace_syscall_info_seccomp,
549
        }
550
        impl ::Copy for __c_anonymous_ptrace_syscall_info_data {}
551
        impl ::Clone for __c_anonymous_ptrace_syscall_info_data {
552
0
            fn clone(&self) -> __c_anonymous_ptrace_syscall_info_data {
553
0
                *self
554
0
            }
555
        }
556
    }
557
}
558
559
s_no_extra_traits! {
560
    pub struct utmpx {
561
        pub ut_type: ::c_short,
562
        pub ut_pid: ::pid_t,
563
        pub ut_line: [::c_char; __UT_LINESIZE],
564
        pub ut_id: [::c_char; 4],
565
566
        pub ut_user: [::c_char; __UT_NAMESIZE],
567
        pub ut_host: [::c_char; __UT_HOSTSIZE],
568
        pub ut_exit: __exit_status,
569
570
        #[cfg(any(target_arch = "aarch64",
571
                  target_arch = "s390x",
572
                  target_arch = "loongarch64",
573
                  all(target_pointer_width = "32",
574
                      not(target_arch = "x86_64"))))]
575
        pub ut_session: ::c_long,
576
        #[cfg(any(target_arch = "aarch64",
577
                  target_arch = "s390x",
578
                  target_arch = "loongarch64",
579
                  all(target_pointer_width = "32",
580
                      not(target_arch = "x86_64"))))]
581
        pub ut_tv: ::timeval,
582
583
        #[cfg(not(any(target_arch = "aarch64",
584
                      target_arch = "s390x",
585
                      target_arch = "loongarch64",
586
                      all(target_pointer_width = "32",
587
                          not(target_arch = "x86_64")))))]
588
        pub ut_session: i32,
589
        #[cfg(not(any(target_arch = "aarch64",
590
                      target_arch = "s390x",
591
                      target_arch = "loongarch64",
592
                      all(target_pointer_width = "32",
593
                          not(target_arch = "x86_64")))))]
594
        pub ut_tv: __timeval,
595
596
        pub ut_addr_v6: [i32; 4],
597
        __glibc_reserved: [::c_char; 20],
598
    }
599
}
600
601
cfg_if! {
602
    if #[cfg(feature = "extra_traits")] {
603
        impl PartialEq for utmpx {
604
            fn eq(&self, other: &utmpx) -> bool {
605
                self.ut_type == other.ut_type
606
                    && self.ut_pid == other.ut_pid
607
                    && self.ut_line == other.ut_line
608
                    && self.ut_id == other.ut_id
609
                    && self.ut_user == other.ut_user
610
                    && self
611
                    .ut_host
612
                    .iter()
613
                    .zip(other.ut_host.iter())
614
                    .all(|(a,b)| a == b)
615
                    && self.ut_exit == other.ut_exit
616
                    && self.ut_session == other.ut_session
617
                    && self.ut_tv == other.ut_tv
618
                    && self.ut_addr_v6 == other.ut_addr_v6
619
                    && self.__glibc_reserved == other.__glibc_reserved
620
            }
621
        }
622
623
        impl Eq for utmpx {}
624
625
        impl ::fmt::Debug for utmpx {
626
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
627
                f.debug_struct("utmpx")
628
                    .field("ut_type", &self.ut_type)
629
                    .field("ut_pid", &self.ut_pid)
630
                    .field("ut_line", &self.ut_line)
631
                    .field("ut_id", &self.ut_id)
632
                    .field("ut_user", &self.ut_user)
633
                // FIXME: .field("ut_host", &self.ut_host)
634
                    .field("ut_exit", &self.ut_exit)
635
                    .field("ut_session", &self.ut_session)
636
                    .field("ut_tv", &self.ut_tv)
637
                    .field("ut_addr_v6", &self.ut_addr_v6)
638
                    .field("__glibc_reserved", &self.__glibc_reserved)
639
                    .finish()
640
            }
641
        }
642
643
        impl ::hash::Hash for utmpx {
644
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
645
                self.ut_type.hash(state);
646
                self.ut_pid.hash(state);
647
                self.ut_line.hash(state);
648
                self.ut_id.hash(state);
649
                self.ut_user.hash(state);
650
                self.ut_host.hash(state);
651
                self.ut_exit.hash(state);
652
                self.ut_session.hash(state);
653
                self.ut_tv.hash(state);
654
                self.ut_addr_v6.hash(state);
655
                self.__glibc_reserved.hash(state);
656
            }
657
        }
658
659
        #[cfg(libc_union)]
660
        impl PartialEq for __c_anonymous_ptrace_syscall_info_data {
661
            fn eq(&self, other: &__c_anonymous_ptrace_syscall_info_data) -> bool {
662
                unsafe {
663
                self.entry == other.entry ||
664
                    self.exit == other.exit ||
665
                    self.seccomp == other.seccomp
666
                }
667
            }
668
        }
669
670
        #[cfg(libc_union)]
671
        impl Eq for __c_anonymous_ptrace_syscall_info_data {}
672
673
        #[cfg(libc_union)]
674
        impl ::fmt::Debug for __c_anonymous_ptrace_syscall_info_data {
675
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
676
                unsafe {
677
                f.debug_struct("__c_anonymous_ptrace_syscall_info_data")
678
                    .field("entry", &self.entry)
679
                    .field("exit", &self.exit)
680
                    .field("seccomp", &self.seccomp)
681
                    .finish()
682
                }
683
            }
684
        }
685
686
        #[cfg(libc_union)]
687
        impl ::hash::Hash for __c_anonymous_ptrace_syscall_info_data {
688
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
689
                unsafe {
690
                self.entry.hash(state);
691
                self.exit.hash(state);
692
                self.seccomp.hash(state);
693
                }
694
            }
695
        }
696
    }
697
}
698
699
// include/uapi/asm-generic/hugetlb_encode.h
700
pub const HUGETLB_FLAG_ENCODE_SHIFT: ::c_int = 26;
701
pub const HUGETLB_FLAG_ENCODE_MASK: ::c_int = 0x3f;
702
703
pub const HUGETLB_FLAG_ENCODE_64KB: ::c_int = 16 << HUGETLB_FLAG_ENCODE_SHIFT;
704
pub const HUGETLB_FLAG_ENCODE_512KB: ::c_int = 19 << HUGETLB_FLAG_ENCODE_SHIFT;
705
pub const HUGETLB_FLAG_ENCODE_1MB: ::c_int = 20 << HUGETLB_FLAG_ENCODE_SHIFT;
706
pub const HUGETLB_FLAG_ENCODE_2MB: ::c_int = 21 << HUGETLB_FLAG_ENCODE_SHIFT;
707
pub const HUGETLB_FLAG_ENCODE_8MB: ::c_int = 23 << HUGETLB_FLAG_ENCODE_SHIFT;
708
pub const HUGETLB_FLAG_ENCODE_16MB: ::c_int = 24 << HUGETLB_FLAG_ENCODE_SHIFT;
709
pub const HUGETLB_FLAG_ENCODE_32MB: ::c_int = 25 << HUGETLB_FLAG_ENCODE_SHIFT;
710
pub const HUGETLB_FLAG_ENCODE_256MB: ::c_int = 28 << HUGETLB_FLAG_ENCODE_SHIFT;
711
pub const HUGETLB_FLAG_ENCODE_512MB: ::c_int = 29 << HUGETLB_FLAG_ENCODE_SHIFT;
712
pub const HUGETLB_FLAG_ENCODE_1GB: ::c_int = 30 << HUGETLB_FLAG_ENCODE_SHIFT;
713
pub const HUGETLB_FLAG_ENCODE_2GB: ::c_int = 31 << HUGETLB_FLAG_ENCODE_SHIFT;
714
pub const HUGETLB_FLAG_ENCODE_16GB: ::c_int = 34 << HUGETLB_FLAG_ENCODE_SHIFT;
715
716
// include/uapi/linux/mman.h
717
/*
718
 * Huge page size encoding when MAP_HUGETLB is specified, and a huge page
719
 * size other than the default is desired.  See hugetlb_encode.h.
720
 * All known huge page size encodings are provided here.  It is the
721
 * responsibility of the application to know which sizes are supported on
722
 * the running system.  See mmap(2) man page for details.
723
 */
724
pub const MAP_HUGE_SHIFT: ::c_int = HUGETLB_FLAG_ENCODE_SHIFT;
725
pub const MAP_HUGE_MASK: ::c_int = HUGETLB_FLAG_ENCODE_MASK;
726
727
pub const MAP_HUGE_64KB: ::c_int = HUGETLB_FLAG_ENCODE_64KB;
728
pub const MAP_HUGE_512KB: ::c_int = HUGETLB_FLAG_ENCODE_512KB;
729
pub const MAP_HUGE_1MB: ::c_int = HUGETLB_FLAG_ENCODE_1MB;
730
pub const MAP_HUGE_2MB: ::c_int = HUGETLB_FLAG_ENCODE_2MB;
731
pub const MAP_HUGE_8MB: ::c_int = HUGETLB_FLAG_ENCODE_8MB;
732
pub const MAP_HUGE_16MB: ::c_int = HUGETLB_FLAG_ENCODE_16MB;
733
pub const MAP_HUGE_32MB: ::c_int = HUGETLB_FLAG_ENCODE_32MB;
734
pub const MAP_HUGE_256MB: ::c_int = HUGETLB_FLAG_ENCODE_256MB;
735
pub const MAP_HUGE_512MB: ::c_int = HUGETLB_FLAG_ENCODE_512MB;
736
pub const MAP_HUGE_1GB: ::c_int = HUGETLB_FLAG_ENCODE_1GB;
737
pub const MAP_HUGE_2GB: ::c_int = HUGETLB_FLAG_ENCODE_2GB;
738
pub const MAP_HUGE_16GB: ::c_int = HUGETLB_FLAG_ENCODE_16GB;
739
740
pub const PRIO_PROCESS: ::__priority_which_t = 0;
741
pub const PRIO_PGRP: ::__priority_which_t = 1;
742
pub const PRIO_USER: ::__priority_which_t = 2;
743
744
pub const MS_RMT_MASK: ::c_ulong = 0x02800051;
745
746
pub const __UT_LINESIZE: usize = 32;
747
pub const __UT_NAMESIZE: usize = 32;
748
pub const __UT_HOSTSIZE: usize = 256;
749
pub const EMPTY: ::c_short = 0;
750
pub const RUN_LVL: ::c_short = 1;
751
pub const BOOT_TIME: ::c_short = 2;
752
pub const NEW_TIME: ::c_short = 3;
753
pub const OLD_TIME: ::c_short = 4;
754
pub const INIT_PROCESS: ::c_short = 5;
755
pub const LOGIN_PROCESS: ::c_short = 6;
756
pub const USER_PROCESS: ::c_short = 7;
757
pub const DEAD_PROCESS: ::c_short = 8;
758
pub const ACCOUNTING: ::c_short = 9;
759
760
// dlfcn.h
761
pub const LM_ID_BASE: ::c_long = 0;
762
pub const LM_ID_NEWLM: ::c_long = -1;
763
764
pub const RTLD_DI_LMID: ::c_int = 1;
765
pub const RTLD_DI_LINKMAP: ::c_int = 2;
766
pub const RTLD_DI_CONFIGADDR: ::c_int = 3;
767
pub const RTLD_DI_SERINFO: ::c_int = 4;
768
pub const RTLD_DI_SERINFOSIZE: ::c_int = 5;
769
pub const RTLD_DI_ORIGIN: ::c_int = 6;
770
pub const RTLD_DI_PROFILENAME: ::c_int = 7;
771
pub const RTLD_DI_PROFILEOUT: ::c_int = 8;
772
pub const RTLD_DI_TLS_MODID: ::c_int = 9;
773
pub const RTLD_DI_TLS_DATA: ::c_int = 10;
774
775
pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK;
776
pub const PIDFD_NONBLOCK: ::c_uint = O_NONBLOCK as ::c_uint;
777
778
pub const SOL_RXRPC: ::c_int = 272;
779
pub const SOL_PPPOL2TP: ::c_int = 273;
780
pub const SOL_PNPIPE: ::c_int = 275;
781
pub const SOL_RDS: ::c_int = 276;
782
pub const SOL_IUCV: ::c_int = 277;
783
pub const SOL_CAIF: ::c_int = 278;
784
pub const SOL_NFC: ::c_int = 280;
785
pub const SOL_XDP: ::c_int = 283;
786
787
pub const MSG_TRYHARD: ::c_int = 4;
788
789
pub const LC_PAPER: ::c_int = 7;
790
pub const LC_NAME: ::c_int = 8;
791
pub const LC_ADDRESS: ::c_int = 9;
792
pub const LC_TELEPHONE: ::c_int = 10;
793
pub const LC_MEASUREMENT: ::c_int = 11;
794
pub const LC_IDENTIFICATION: ::c_int = 12;
795
pub const LC_PAPER_MASK: ::c_int = 1 << LC_PAPER;
796
pub const LC_NAME_MASK: ::c_int = 1 << LC_NAME;
797
pub const LC_ADDRESS_MASK: ::c_int = 1 << LC_ADDRESS;
798
pub const LC_TELEPHONE_MASK: ::c_int = 1 << LC_TELEPHONE;
799
pub const LC_MEASUREMENT_MASK: ::c_int = 1 << LC_MEASUREMENT;
800
pub const LC_IDENTIFICATION_MASK: ::c_int = 1 << LC_IDENTIFICATION;
801
pub const LC_ALL_MASK: ::c_int = ::LC_CTYPE_MASK
802
    | ::LC_NUMERIC_MASK
803
    | ::LC_TIME_MASK
804
    | ::LC_COLLATE_MASK
805
    | ::LC_MONETARY_MASK
806
    | ::LC_MESSAGES_MASK
807
    | LC_PAPER_MASK
808
    | LC_NAME_MASK
809
    | LC_ADDRESS_MASK
810
    | LC_TELEPHONE_MASK
811
    | LC_MEASUREMENT_MASK
812
    | LC_IDENTIFICATION_MASK;
813
814
pub const ENOTSUP: ::c_int = EOPNOTSUPP;
815
816
pub const SOCK_SEQPACKET: ::c_int = 5;
817
pub const SOCK_DCCP: ::c_int = 6;
818
pub const SOCK_PACKET: ::c_int = 10;
819
820
pub const AF_IB: ::c_int = 27;
821
pub const AF_MPLS: ::c_int = 28;
822
pub const AF_NFC: ::c_int = 39;
823
pub const AF_VSOCK: ::c_int = 40;
824
pub const AF_XDP: ::c_int = 44;
825
pub const PF_IB: ::c_int = AF_IB;
826
pub const PF_MPLS: ::c_int = AF_MPLS;
827
pub const PF_NFC: ::c_int = AF_NFC;
828
pub const PF_VSOCK: ::c_int = AF_VSOCK;
829
pub const PF_XDP: ::c_int = AF_XDP;
830
831
pub const SIGEV_THREAD_ID: ::c_int = 4;
832
833
pub const BUFSIZ: ::c_uint = 8192;
834
pub const TMP_MAX: ::c_uint = 238328;
835
pub const FOPEN_MAX: ::c_uint = 16;
836
pub const FILENAME_MAX: ::c_uint = 4096;
837
pub const POSIX_MADV_DONTNEED: ::c_int = 4;
838
pub const _SC_EQUIV_CLASS_MAX: ::c_int = 41;
839
pub const _SC_CHARCLASS_NAME_MAX: ::c_int = 45;
840
pub const _SC_PII: ::c_int = 53;
841
pub const _SC_PII_XTI: ::c_int = 54;
842
pub const _SC_PII_SOCKET: ::c_int = 55;
843
pub const _SC_PII_INTERNET: ::c_int = 56;
844
pub const _SC_PII_OSI: ::c_int = 57;
845
pub const _SC_POLL: ::c_int = 58;
846
pub const _SC_SELECT: ::c_int = 59;
847
pub const _SC_PII_INTERNET_STREAM: ::c_int = 61;
848
pub const _SC_PII_INTERNET_DGRAM: ::c_int = 62;
849
pub const _SC_PII_OSI_COTS: ::c_int = 63;
850
pub const _SC_PII_OSI_CLTS: ::c_int = 64;
851
pub const _SC_PII_OSI_M: ::c_int = 65;
852
pub const _SC_T_IOV_MAX: ::c_int = 66;
853
pub const _SC_2_C_VERSION: ::c_int = 96;
854
pub const _SC_CHAR_BIT: ::c_int = 101;
855
pub const _SC_CHAR_MAX: ::c_int = 102;
856
pub const _SC_CHAR_MIN: ::c_int = 103;
857
pub const _SC_INT_MAX: ::c_int = 104;
858
pub const _SC_INT_MIN: ::c_int = 105;
859
pub const _SC_LONG_BIT: ::c_int = 106;
860
pub const _SC_WORD_BIT: ::c_int = 107;
861
pub const _SC_MB_LEN_MAX: ::c_int = 108;
862
pub const _SC_SSIZE_MAX: ::c_int = 110;
863
pub const _SC_SCHAR_MAX: ::c_int = 111;
864
pub const _SC_SCHAR_MIN: ::c_int = 112;
865
pub const _SC_SHRT_MAX: ::c_int = 113;
866
pub const _SC_SHRT_MIN: ::c_int = 114;
867
pub const _SC_UCHAR_MAX: ::c_int = 115;
868
pub const _SC_UINT_MAX: ::c_int = 116;
869
pub const _SC_ULONG_MAX: ::c_int = 117;
870
pub const _SC_USHRT_MAX: ::c_int = 118;
871
pub const _SC_NL_ARGMAX: ::c_int = 119;
872
pub const _SC_NL_LANGMAX: ::c_int = 120;
873
pub const _SC_NL_MSGMAX: ::c_int = 121;
874
pub const _SC_NL_NMAX: ::c_int = 122;
875
pub const _SC_NL_SETMAX: ::c_int = 123;
876
pub const _SC_NL_TEXTMAX: ::c_int = 124;
877
pub const _SC_BASE: ::c_int = 134;
878
pub const _SC_C_LANG_SUPPORT: ::c_int = 135;
879
pub const _SC_C_LANG_SUPPORT_R: ::c_int = 136;
880
pub const _SC_DEVICE_IO: ::c_int = 140;
881
pub const _SC_DEVICE_SPECIFIC: ::c_int = 141;
882
pub const _SC_DEVICE_SPECIFIC_R: ::c_int = 142;
883
pub const _SC_FD_MGMT: ::c_int = 143;
884
pub const _SC_FIFO: ::c_int = 144;
885
pub const _SC_PIPE: ::c_int = 145;
886
pub const _SC_FILE_ATTRIBUTES: ::c_int = 146;
887
pub const _SC_FILE_LOCKING: ::c_int = 147;
888
pub const _SC_FILE_SYSTEM: ::c_int = 148;
889
pub const _SC_MULTI_PROCESS: ::c_int = 150;
890
pub const _SC_SINGLE_PROCESS: ::c_int = 151;
891
pub const _SC_NETWORKING: ::c_int = 152;
892
pub const _SC_REGEX_VERSION: ::c_int = 156;
893
pub const _SC_SIGNALS: ::c_int = 158;
894
pub const _SC_SYSTEM_DATABASE: ::c_int = 162;
895
pub const _SC_SYSTEM_DATABASE_R: ::c_int = 163;
896
pub const _SC_USER_GROUPS: ::c_int = 166;
897
pub const _SC_USER_GROUPS_R: ::c_int = 167;
898
pub const _SC_LEVEL1_ICACHE_SIZE: ::c_int = 185;
899
pub const _SC_LEVEL1_ICACHE_ASSOC: ::c_int = 186;
900
pub const _SC_LEVEL1_ICACHE_LINESIZE: ::c_int = 187;
901
pub const _SC_LEVEL1_DCACHE_SIZE: ::c_int = 188;
902
pub const _SC_LEVEL1_DCACHE_ASSOC: ::c_int = 189;
903
pub const _SC_LEVEL1_DCACHE_LINESIZE: ::c_int = 190;
904
pub const _SC_LEVEL2_CACHE_SIZE: ::c_int = 191;
905
pub const _SC_LEVEL2_CACHE_ASSOC: ::c_int = 192;
906
pub const _SC_LEVEL2_CACHE_LINESIZE: ::c_int = 193;
907
pub const _SC_LEVEL3_CACHE_SIZE: ::c_int = 194;
908
pub const _SC_LEVEL3_CACHE_ASSOC: ::c_int = 195;
909
pub const _SC_LEVEL3_CACHE_LINESIZE: ::c_int = 196;
910
pub const _SC_LEVEL4_CACHE_SIZE: ::c_int = 197;
911
pub const _SC_LEVEL4_CACHE_ASSOC: ::c_int = 198;
912
pub const _SC_LEVEL4_CACHE_LINESIZE: ::c_int = 199;
913
pub const O_ACCMODE: ::c_int = 3;
914
pub const ST_RELATIME: ::c_ulong = 4096;
915
pub const NI_MAXHOST: ::socklen_t = 1025;
916
917
// Most `*_SUPER_MAGIC` constants are defined at the `linux_like` level; the
918
// following are only available on newer Linux versions than the versions
919
// currently used in CI in some configurations, so we define them here.
920
cfg_if! {
921
    if #[cfg(not(target_arch = "s390x"))] {
922
        pub const BINDERFS_SUPER_MAGIC: ::c_long = 0x6c6f6f70;
923
        pub const XFS_SUPER_MAGIC: ::c_long = 0x58465342;
924
    } else if #[cfg(target_arch = "s390x")] {
925
        pub const BINDERFS_SUPER_MAGIC: ::c_uint = 0x6c6f6f70;
926
        pub const XFS_SUPER_MAGIC: ::c_uint = 0x58465342;
927
    }
928
}
929
930
pub const CPU_SETSIZE: ::c_int = 0x400;
931
932
pub const PTRACE_TRACEME: ::c_uint = 0;
933
pub const PTRACE_PEEKTEXT: ::c_uint = 1;
934
pub const PTRACE_PEEKDATA: ::c_uint = 2;
935
pub const PTRACE_PEEKUSER: ::c_uint = 3;
936
pub const PTRACE_POKETEXT: ::c_uint = 4;
937
pub const PTRACE_POKEDATA: ::c_uint = 5;
938
pub const PTRACE_POKEUSER: ::c_uint = 6;
939
pub const PTRACE_CONT: ::c_uint = 7;
940
pub const PTRACE_KILL: ::c_uint = 8;
941
pub const PTRACE_SINGLESTEP: ::c_uint = 9;
942
pub const PTRACE_ATTACH: ::c_uint = 16;
943
pub const PTRACE_SYSCALL: ::c_uint = 24;
944
pub const PTRACE_SETOPTIONS: ::c_uint = 0x4200;
945
pub const PTRACE_GETEVENTMSG: ::c_uint = 0x4201;
946
pub const PTRACE_GETSIGINFO: ::c_uint = 0x4202;
947
pub const PTRACE_SETSIGINFO: ::c_uint = 0x4203;
948
pub const PTRACE_GETREGSET: ::c_uint = 0x4204;
949
pub const PTRACE_SETREGSET: ::c_uint = 0x4205;
950
pub const PTRACE_SEIZE: ::c_uint = 0x4206;
951
pub const PTRACE_INTERRUPT: ::c_uint = 0x4207;
952
pub const PTRACE_LISTEN: ::c_uint = 0x4208;
953
pub const PTRACE_PEEKSIGINFO: ::c_uint = 0x4209;
954
pub const PTRACE_GETSIGMASK: ::c_uint = 0x420a;
955
pub const PTRACE_SETSIGMASK: ::c_uint = 0x420b;
956
pub const PTRACE_GET_SYSCALL_INFO: ::c_uint = 0x420e;
957
pub const PTRACE_SYSCALL_INFO_NONE: ::__u8 = 0;
958
pub const PTRACE_SYSCALL_INFO_ENTRY: ::__u8 = 1;
959
pub const PTRACE_SYSCALL_INFO_EXIT: ::__u8 = 2;
960
pub const PTRACE_SYSCALL_INFO_SECCOMP: ::__u8 = 3;
961
962
// linux/fs.h
963
964
// Flags for preadv2/pwritev2
965
pub const RWF_HIPRI: ::c_int = 0x00000001;
966
pub const RWF_DSYNC: ::c_int = 0x00000002;
967
pub const RWF_SYNC: ::c_int = 0x00000004;
968
pub const RWF_NOWAIT: ::c_int = 0x00000008;
969
pub const RWF_APPEND: ::c_int = 0x00000010;
970
971
// linux/rtnetlink.h
972
pub const TCA_PAD: ::c_ushort = 9;
973
pub const TCA_DUMP_INVISIBLE: ::c_ushort = 10;
974
pub const TCA_CHAIN: ::c_ushort = 11;
975
pub const TCA_HW_OFFLOAD: ::c_ushort = 12;
976
977
pub const RTM_DELNETCONF: u16 = 81;
978
pub const RTM_NEWSTATS: u16 = 92;
979
pub const RTM_GETSTATS: u16 = 94;
980
pub const RTM_NEWCACHEREPORT: u16 = 96;
981
982
pub const RTM_F_LOOKUP_TABLE: ::c_uint = 0x1000;
983
pub const RTM_F_FIB_MATCH: ::c_uint = 0x2000;
984
985
pub const RTA_VIA: ::c_ushort = 18;
986
pub const RTA_NEWDST: ::c_ushort = 19;
987
pub const RTA_PREF: ::c_ushort = 20;
988
pub const RTA_ENCAP_TYPE: ::c_ushort = 21;
989
pub const RTA_ENCAP: ::c_ushort = 22;
990
pub const RTA_EXPIRES: ::c_ushort = 23;
991
pub const RTA_PAD: ::c_ushort = 24;
992
pub const RTA_UID: ::c_ushort = 25;
993
pub const RTA_TTL_PROPAGATE: ::c_ushort = 26;
994
995
// linux/neighbor.h
996
pub const NTF_EXT_LEARNED: u8 = 0x10;
997
pub const NTF_OFFLOADED: u8 = 0x20;
998
999
pub const NDA_MASTER: ::c_ushort = 9;
1000
pub const NDA_LINK_NETNSID: ::c_ushort = 10;
1001
pub const NDA_SRC_VNI: ::c_ushort = 11;
1002
1003
// linux/personality.h
1004
pub const UNAME26: ::c_int = 0x0020000;
1005
pub const FDPIC_FUNCPTRS: ::c_int = 0x0080000;
1006
1007
// linux/if_addr.h
1008
pub const IFA_FLAGS: ::c_ushort = 8;
1009
1010
pub const IFA_F_MANAGETEMPADDR: u32 = 0x100;
1011
pub const IFA_F_NOPREFIXROUTE: u32 = 0x200;
1012
pub const IFA_F_MCAUTOJOIN: u32 = 0x400;
1013
pub const IFA_F_STABLE_PRIVACY: u32 = 0x800;
1014
1015
pub const MAX_LINKS: ::c_int = 32;
1016
1017
pub const GENL_UNS_ADMIN_PERM: ::c_int = 0x10;
1018
1019
pub const GENL_ID_VFS_DQUOT: ::c_int = ::NLMSG_MIN_TYPE + 1;
1020
pub const GENL_ID_PMCRAID: ::c_int = ::NLMSG_MIN_TYPE + 2;
1021
1022
// linux/if_xdp.h
1023
pub const XDP_SHARED_UMEM: ::__u16 = 1 << 0;
1024
pub const XDP_COPY: ::__u16 = 1 << 1;
1025
pub const XDP_ZEROCOPY: ::__u16 = 1 << 2;
1026
pub const XDP_USE_NEED_WAKEUP: ::__u16 = 1 << 3;
1027
pub const XDP_USE_SG: ::__u16 = 1 << 4;
1028
1029
pub const XDP_UMEM_UNALIGNED_CHUNK_FLAG: ::__u32 = 1 << 0;
1030
1031
pub const XDP_RING_NEED_WAKEUP: ::__u32 = 1 << 0;
1032
1033
pub const XDP_MMAP_OFFSETS: ::c_int = 1;
1034
pub const XDP_RX_RING: ::c_int = 2;
1035
pub const XDP_TX_RING: ::c_int = 3;
1036
pub const XDP_UMEM_REG: ::c_int = 4;
1037
pub const XDP_UMEM_FILL_RING: ::c_int = 5;
1038
pub const XDP_UMEM_COMPLETION_RING: ::c_int = 6;
1039
pub const XDP_STATISTICS: ::c_int = 7;
1040
pub const XDP_OPTIONS: ::c_int = 8;
1041
1042
pub const XDP_OPTIONS_ZEROCOPY: ::__u32 = 1 << 0;
1043
1044
pub const XDP_PGOFF_RX_RING: ::off_t = 0;
1045
pub const XDP_PGOFF_TX_RING: ::off_t = 0x80000000;
1046
pub const XDP_UMEM_PGOFF_FILL_RING: ::c_ulonglong = 0x100000000;
1047
pub const XDP_UMEM_PGOFF_COMPLETION_RING: ::c_ulonglong = 0x180000000;
1048
1049
pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT: ::c_int = 48;
1050
pub const XSK_UNALIGNED_BUF_ADDR_MASK: ::c_ulonglong = (1 << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1;
1051
1052
pub const XDP_PKT_CONTD: ::__u32 = 1 << 0;
1053
1054
// elf.h
1055
pub const NT_PRSTATUS: ::c_int = 1;
1056
pub const NT_PRFPREG: ::c_int = 2;
1057
pub const NT_FPREGSET: ::c_int = 2;
1058
pub const NT_PRPSINFO: ::c_int = 3;
1059
pub const NT_PRXREG: ::c_int = 4;
1060
pub const NT_TASKSTRUCT: ::c_int = 4;
1061
pub const NT_PLATFORM: ::c_int = 5;
1062
pub const NT_AUXV: ::c_int = 6;
1063
pub const NT_GWINDOWS: ::c_int = 7;
1064
pub const NT_ASRS: ::c_int = 8;
1065
pub const NT_PSTATUS: ::c_int = 10;
1066
pub const NT_PSINFO: ::c_int = 13;
1067
pub const NT_PRCRED: ::c_int = 14;
1068
pub const NT_UTSNAME: ::c_int = 15;
1069
pub const NT_LWPSTATUS: ::c_int = 16;
1070
pub const NT_LWPSINFO: ::c_int = 17;
1071
pub const NT_PRFPXREG: ::c_int = 20;
1072
1073
pub const ELFOSABI_ARM_AEABI: u8 = 64;
1074
1075
// linux/sched.h
1076
pub const CLONE_NEWTIME: ::c_int = 0x80;
1077
pub const CLONE_CLEAR_SIGHAND: ::c_int = 0x100000000;
1078
pub const CLONE_INTO_CGROUP: ::c_int = 0x200000000;
1079
1080
// linux/keyctl.h
1081
pub const KEYCTL_DH_COMPUTE: u32 = 23;
1082
pub const KEYCTL_PKEY_QUERY: u32 = 24;
1083
pub const KEYCTL_PKEY_ENCRYPT: u32 = 25;
1084
pub const KEYCTL_PKEY_DECRYPT: u32 = 26;
1085
pub const KEYCTL_PKEY_SIGN: u32 = 27;
1086
pub const KEYCTL_PKEY_VERIFY: u32 = 28;
1087
pub const KEYCTL_RESTRICT_KEYRING: u32 = 29;
1088
1089
pub const KEYCTL_SUPPORTS_ENCRYPT: u32 = 0x01;
1090
pub const KEYCTL_SUPPORTS_DECRYPT: u32 = 0x02;
1091
pub const KEYCTL_SUPPORTS_SIGN: u32 = 0x04;
1092
pub const KEYCTL_SUPPORTS_VERIFY: u32 = 0x08;
1093
cfg_if! {
1094
    if #[cfg(not(any(target_arch = "mips",
1095
                     target_arch = "mips32r6",
1096
                     target_arch = "mips64",
1097
                     target_arch = "mips64r6")))] {
1098
        pub const KEYCTL_MOVE: u32 = 30;
1099
        pub const KEYCTL_CAPABILITIES: u32 = 31;
1100
1101
        pub const KEYCTL_CAPS0_CAPABILITIES: u32 = 0x01;
1102
        pub const KEYCTL_CAPS0_PERSISTENT_KEYRINGS: u32 = 0x02;
1103
        pub const KEYCTL_CAPS0_DIFFIE_HELLMAN: u32 = 0x04;
1104
        pub const KEYCTL_CAPS0_PUBLIC_KEY: u32 = 0x08;
1105
        pub const KEYCTL_CAPS0_BIG_KEY: u32 = 0x10;
1106
        pub const KEYCTL_CAPS0_INVALIDATE: u32 = 0x20;
1107
        pub const KEYCTL_CAPS0_RESTRICT_KEYRING: u32 = 0x40;
1108
        pub const KEYCTL_CAPS0_MOVE: u32 = 0x80;
1109
        pub const KEYCTL_CAPS1_NS_KEYRING_NAME: u32 = 0x01;
1110
        pub const KEYCTL_CAPS1_NS_KEY_TAG: u32 = 0x02;
1111
    }
1112
}
1113
1114
pub const M_MXFAST: ::c_int = 1;
1115
pub const M_NLBLKS: ::c_int = 2;
1116
pub const M_GRAIN: ::c_int = 3;
1117
pub const M_KEEP: ::c_int = 4;
1118
pub const M_TRIM_THRESHOLD: ::c_int = -1;
1119
pub const M_TOP_PAD: ::c_int = -2;
1120
pub const M_MMAP_THRESHOLD: ::c_int = -3;
1121
pub const M_MMAP_MAX: ::c_int = -4;
1122
pub const M_CHECK_ACTION: ::c_int = -5;
1123
pub const M_PERTURB: ::c_int = -6;
1124
pub const M_ARENA_TEST: ::c_int = -7;
1125
pub const M_ARENA_MAX: ::c_int = -8;
1126
1127
pub const AT_STATX_SYNC_TYPE: ::c_int = 0x6000;
1128
pub const AT_STATX_SYNC_AS_STAT: ::c_int = 0x0000;
1129
pub const AT_STATX_FORCE_SYNC: ::c_int = 0x2000;
1130
pub const AT_STATX_DONT_SYNC: ::c_int = 0x4000;
1131
pub const STATX_TYPE: ::c_uint = 0x0001;
1132
pub const STATX_MODE: ::c_uint = 0x0002;
1133
pub const STATX_NLINK: ::c_uint = 0x0004;
1134
pub const STATX_UID: ::c_uint = 0x0008;
1135
pub const STATX_GID: ::c_uint = 0x0010;
1136
pub const STATX_ATIME: ::c_uint = 0x0020;
1137
pub const STATX_MTIME: ::c_uint = 0x0040;
1138
pub const STATX_CTIME: ::c_uint = 0x0080;
1139
pub const STATX_INO: ::c_uint = 0x0100;
1140
pub const STATX_SIZE: ::c_uint = 0x0200;
1141
pub const STATX_BLOCKS: ::c_uint = 0x0400;
1142
pub const STATX_BASIC_STATS: ::c_uint = 0x07ff;
1143
pub const STATX_BTIME: ::c_uint = 0x0800;
1144
pub const STATX_MNT_ID: ::c_uint = 0x1000;
1145
pub const STATX_DIOALIGN: ::c_uint = 0x2000;
1146
pub const STATX_ALL: ::c_uint = 0x0fff;
1147
pub const STATX__RESERVED: ::c_int = 0x80000000;
1148
pub const STATX_ATTR_COMPRESSED: ::c_int = 0x0004;
1149
pub const STATX_ATTR_IMMUTABLE: ::c_int = 0x0010;
1150
pub const STATX_ATTR_APPEND: ::c_int = 0x0020;
1151
pub const STATX_ATTR_NODUMP: ::c_int = 0x0040;
1152
pub const STATX_ATTR_ENCRYPTED: ::c_int = 0x0800;
1153
pub const STATX_ATTR_AUTOMOUNT: ::c_int = 0x1000;
1154
pub const STATX_ATTR_MOUNT_ROOT: ::c_int = 0x2000;
1155
pub const STATX_ATTR_VERITY: ::c_int = 0x00100000;
1156
pub const STATX_ATTR_DAX: ::c_int = 0x00200000;
1157
1158
pub const SOMAXCONN: ::c_int = 4096;
1159
1160
// linux/mount.h
1161
pub const MOVE_MOUNT_F_SYMLINKS: ::c_uint = 0x00000001;
1162
pub const MOVE_MOUNT_F_AUTOMOUNTS: ::c_uint = 0x00000002;
1163
pub const MOVE_MOUNT_F_EMPTY_PATH: ::c_uint = 0x00000004;
1164
pub const MOVE_MOUNT_T_SYMLINKS: ::c_uint = 0x00000010;
1165
pub const MOVE_MOUNT_T_AUTOMOUNTS: ::c_uint = 0x00000020;
1166
pub const MOVE_MOUNT_T_EMPTY_PATH: ::c_uint = 0x00000040;
1167
pub const MOVE_MOUNT_SET_GROUP: ::c_uint = 0x00000100;
1168
pub const MOVE_MOUNT_BENEATH: ::c_uint = 0x00000200;
1169
1170
// sys/timex.h
1171
pub const ADJ_OFFSET: ::c_uint = 0x0001;
1172
pub const ADJ_FREQUENCY: ::c_uint = 0x0002;
1173
pub const ADJ_MAXERROR: ::c_uint = 0x0004;
1174
pub const ADJ_ESTERROR: ::c_uint = 0x0008;
1175
pub const ADJ_STATUS: ::c_uint = 0x0010;
1176
pub const ADJ_TIMECONST: ::c_uint = 0x0020;
1177
pub const ADJ_TAI: ::c_uint = 0x0080;
1178
pub const ADJ_SETOFFSET: ::c_uint = 0x0100;
1179
pub const ADJ_MICRO: ::c_uint = 0x1000;
1180
pub const ADJ_NANO: ::c_uint = 0x2000;
1181
pub const ADJ_TICK: ::c_uint = 0x4000;
1182
pub const ADJ_OFFSET_SINGLESHOT: ::c_uint = 0x8001;
1183
pub const ADJ_OFFSET_SS_READ: ::c_uint = 0xa001;
1184
pub const MOD_OFFSET: ::c_uint = ADJ_OFFSET;
1185
pub const MOD_FREQUENCY: ::c_uint = ADJ_FREQUENCY;
1186
pub const MOD_MAXERROR: ::c_uint = ADJ_MAXERROR;
1187
pub const MOD_ESTERROR: ::c_uint = ADJ_ESTERROR;
1188
pub const MOD_STATUS: ::c_uint = ADJ_STATUS;
1189
pub const MOD_TIMECONST: ::c_uint = ADJ_TIMECONST;
1190
pub const MOD_CLKB: ::c_uint = ADJ_TICK;
1191
pub const MOD_CLKA: ::c_uint = ADJ_OFFSET_SINGLESHOT;
1192
pub const MOD_TAI: ::c_uint = ADJ_TAI;
1193
pub const MOD_MICRO: ::c_uint = ADJ_MICRO;
1194
pub const MOD_NANO: ::c_uint = ADJ_NANO;
1195
pub const STA_PLL: ::c_int = 0x0001;
1196
pub const STA_PPSFREQ: ::c_int = 0x0002;
1197
pub const STA_PPSTIME: ::c_int = 0x0004;
1198
pub const STA_FLL: ::c_int = 0x0008;
1199
pub const STA_INS: ::c_int = 0x0010;
1200
pub const STA_DEL: ::c_int = 0x0020;
1201
pub const STA_UNSYNC: ::c_int = 0x0040;
1202
pub const STA_FREQHOLD: ::c_int = 0x0080;
1203
pub const STA_PPSSIGNAL: ::c_int = 0x0100;
1204
pub const STA_PPSJITTER: ::c_int = 0x0200;
1205
pub const STA_PPSWANDER: ::c_int = 0x0400;
1206
pub const STA_PPSERROR: ::c_int = 0x0800;
1207
pub const STA_CLOCKERR: ::c_int = 0x1000;
1208
pub const STA_NANO: ::c_int = 0x2000;
1209
pub const STA_MODE: ::c_int = 0x4000;
1210
pub const STA_CLK: ::c_int = 0x8000;
1211
pub const STA_RONLY: ::c_int = STA_PPSSIGNAL
1212
    | STA_PPSJITTER
1213
    | STA_PPSWANDER
1214
    | STA_PPSERROR
1215
    | STA_CLOCKERR
1216
    | STA_NANO
1217
    | STA_MODE
1218
    | STA_CLK;
1219
pub const NTP_API: ::c_int = 4;
1220
pub const TIME_OK: ::c_int = 0;
1221
pub const TIME_INS: ::c_int = 1;
1222
pub const TIME_DEL: ::c_int = 2;
1223
pub const TIME_OOP: ::c_int = 3;
1224
pub const TIME_WAIT: ::c_int = 4;
1225
pub const TIME_ERROR: ::c_int = 5;
1226
pub const TIME_BAD: ::c_int = TIME_ERROR;
1227
pub const MAXTC: ::c_long = 6;
1228
1229
// Portable GLOB_* flags are defined at the `linux_like` level.
1230
// The following are GNU extensions.
1231
pub const GLOB_PERIOD: ::c_int = 1 << 7;
1232
pub const GLOB_ALTDIRFUNC: ::c_int = 1 << 9;
1233
pub const GLOB_BRACE: ::c_int = 1 << 10;
1234
pub const GLOB_NOMAGIC: ::c_int = 1 << 11;
1235
pub const GLOB_TILDE: ::c_int = 1 << 12;
1236
pub const GLOB_ONLYDIR: ::c_int = 1 << 13;
1237
pub const GLOB_TILDE_CHECK: ::c_int = 1 << 14;
1238
1239
pub const MADV_COLLAPSE: ::c_int = 25;
1240
1241
cfg_if! {
1242
    if #[cfg(any(
1243
        target_arch = "arm",
1244
        target_arch = "x86",
1245
        target_arch = "x86_64",
1246
        target_arch = "s390x",
1247
        target_arch = "riscv64",
1248
        target_arch = "riscv32"
1249
    ))] {
1250
        pub const PTHREAD_STACK_MIN: ::size_t = 16384;
1251
    } else if #[cfg(any(
1252
               target_arch = "sparc",
1253
               target_arch = "sparc64"
1254
           ))] {
1255
        pub const PTHREAD_STACK_MIN: ::size_t = 0x6000;
1256
    } else {
1257
        pub const PTHREAD_STACK_MIN: ::size_t = 131072;
1258
    }
1259
}
1260
pub const PTHREAD_MUTEX_ADAPTIVE_NP: ::c_int = 3;
1261
1262
pub const REG_STARTEND: ::c_int = 4;
1263
1264
pub const REG_EEND: ::c_int = 14;
1265
pub const REG_ESIZE: ::c_int = 15;
1266
pub const REG_ERPAREN: ::c_int = 16;
1267
1268
extern "C" {
1269
    pub fn fgetspent_r(
1270
        fp: *mut ::FILE,
1271
        spbuf: *mut ::spwd,
1272
        buf: *mut ::c_char,
1273
        buflen: ::size_t,
1274
        spbufp: *mut *mut ::spwd,
1275
    ) -> ::c_int;
1276
    pub fn sgetspent_r(
1277
        s: *const ::c_char,
1278
        spbuf: *mut ::spwd,
1279
        buf: *mut ::c_char,
1280
        buflen: ::size_t,
1281
        spbufp: *mut *mut ::spwd,
1282
    ) -> ::c_int;
1283
    pub fn getspent_r(
1284
        spbuf: *mut ::spwd,
1285
        buf: *mut ::c_char,
1286
        buflen: ::size_t,
1287
        spbufp: *mut *mut ::spwd,
1288
    ) -> ::c_int;
1289
    pub fn qsort_r(
1290
        base: *mut ::c_void,
1291
        num: ::size_t,
1292
        size: ::size_t,
1293
        compar: ::Option<
1294
            unsafe extern "C" fn(*const ::c_void, *const ::c_void, *mut ::c_void) -> ::c_int,
1295
        >,
1296
        arg: *mut ::c_void,
1297
    );
1298
    pub fn sendmmsg(
1299
        sockfd: ::c_int,
1300
        msgvec: *mut ::mmsghdr,
1301
        vlen: ::c_uint,
1302
        flags: ::c_int,
1303
    ) -> ::c_int;
1304
    pub fn recvmmsg(
1305
        sockfd: ::c_int,
1306
        msgvec: *mut ::mmsghdr,
1307
        vlen: ::c_uint,
1308
        flags: ::c_int,
1309
        timeout: *mut ::timespec,
1310
    ) -> ::c_int;
1311
1312
    pub fn getrlimit64(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit64) -> ::c_int;
1313
    pub fn setrlimit64(resource: ::__rlimit_resource_t, rlim: *const ::rlimit64) -> ::c_int;
1314
    pub fn getrlimit(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit) -> ::c_int;
1315
    pub fn setrlimit(resource: ::__rlimit_resource_t, rlim: *const ::rlimit) -> ::c_int;
1316
    pub fn prlimit(
1317
        pid: ::pid_t,
1318
        resource: ::__rlimit_resource_t,
1319
        new_limit: *const ::rlimit,
1320
        old_limit: *mut ::rlimit,
1321
    ) -> ::c_int;
1322
    pub fn prlimit64(
1323
        pid: ::pid_t,
1324
        resource: ::__rlimit_resource_t,
1325
        new_limit: *const ::rlimit64,
1326
        old_limit: *mut ::rlimit64,
1327
    ) -> ::c_int;
1328
    pub fn utmpname(file: *const ::c_char) -> ::c_int;
1329
    pub fn utmpxname(file: *const ::c_char) -> ::c_int;
1330
    pub fn getutxent() -> *mut utmpx;
1331
    pub fn getutxid(ut: *const utmpx) -> *mut utmpx;
1332
    pub fn getutxline(ut: *const utmpx) -> *mut utmpx;
1333
    pub fn pututxline(ut: *const utmpx) -> *mut utmpx;
1334
    pub fn setutxent();
1335
    pub fn endutxent();
1336
    pub fn getpt() -> ::c_int;
1337
    pub fn mallopt(param: ::c_int, value: ::c_int) -> ::c_int;
1338
    pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int;
1339
    pub fn statx(
1340
        dirfd: ::c_int,
1341
        pathname: *const c_char,
1342
        flags: ::c_int,
1343
        mask: ::c_uint,
1344
        statxbuf: *mut statx,
1345
    ) -> ::c_int;
1346
    pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int;
1347
    pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t;
1348
    pub fn getauxval(type_: ::c_ulong) -> ::c_ulong;
1349
1350
    pub fn adjtimex(buf: *mut timex) -> ::c_int;
1351
    pub fn ntp_adjtime(buf: *mut timex) -> ::c_int;
1352
    #[link_name = "ntp_gettimex"]
1353
    pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int;
1354
    pub fn clock_adjtime(clk_id: ::clockid_t, buf: *mut ::timex) -> ::c_int;
1355
1356
    pub fn fanotify_mark(
1357
        fd: ::c_int,
1358
        flags: ::c_uint,
1359
        mask: u64,
1360
        dirfd: ::c_int,
1361
        path: *const ::c_char,
1362
    ) -> ::c_int;
1363
    pub fn preadv2(
1364
        fd: ::c_int,
1365
        iov: *const ::iovec,
1366
        iovcnt: ::c_int,
1367
        offset: ::off_t,
1368
        flags: ::c_int,
1369
    ) -> ::ssize_t;
1370
    pub fn pwritev2(
1371
        fd: ::c_int,
1372
        iov: *const ::iovec,
1373
        iovcnt: ::c_int,
1374
        offset: ::off_t,
1375
        flags: ::c_int,
1376
    ) -> ::ssize_t;
1377
    pub fn preadv64v2(
1378
        fd: ::c_int,
1379
        iov: *const ::iovec,
1380
        iovcnt: ::c_int,
1381
        offset: ::off64_t,
1382
        flags: ::c_int,
1383
    ) -> ::ssize_t;
1384
    pub fn pwritev64v2(
1385
        fd: ::c_int,
1386
        iov: *const ::iovec,
1387
        iovcnt: ::c_int,
1388
        offset: ::off64_t,
1389
        flags: ::c_int,
1390
    ) -> ::ssize_t;
1391
    pub fn renameat2(
1392
        olddirfd: ::c_int,
1393
        oldpath: *const ::c_char,
1394
        newdirfd: ::c_int,
1395
        newpath: *const ::c_char,
1396
        flags: ::c_uint,
1397
    ) -> ::c_int;
1398
1399
    // Added in `glibc` 2.25
1400
    pub fn explicit_bzero(s: *mut ::c_void, len: ::size_t);
1401
    // Added in `glibc` 2.29
1402
    pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void;
1403
1404
    pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char;
1405
    pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int;
1406
    pub fn backtrace(buf: *mut *mut ::c_void, sz: ::c_int) -> ::c_int;
1407
    pub fn glob64(
1408
        pattern: *const ::c_char,
1409
        flags: ::c_int,
1410
        errfunc: ::Option<extern "C" fn(epath: *const ::c_char, errno: ::c_int) -> ::c_int>,
1411
        pglob: *mut glob64_t,
1412
    ) -> ::c_int;
1413
    pub fn globfree64(pglob: *mut glob64_t);
1414
    pub fn ptrace(request: ::c_uint, ...) -> ::c_long;
1415
    pub fn pthread_attr_getaffinity_np(
1416
        attr: *const ::pthread_attr_t,
1417
        cpusetsize: ::size_t,
1418
        cpuset: *mut ::cpu_set_t,
1419
    ) -> ::c_int;
1420
    pub fn pthread_attr_setaffinity_np(
1421
        attr: *mut ::pthread_attr_t,
1422
        cpusetsize: ::size_t,
1423
        cpuset: *const ::cpu_set_t,
1424
    ) -> ::c_int;
1425
    pub fn getpriority(which: ::__priority_which_t, who: ::id_t) -> ::c_int;
1426
    pub fn setpriority(which: ::__priority_which_t, who: ::id_t, prio: ::c_int) -> ::c_int;
1427
    pub fn pthread_rwlockattr_getkind_np(
1428
        attr: *const ::pthread_rwlockattr_t,
1429
        val: *mut ::c_int,
1430
    ) -> ::c_int;
1431
    pub fn pthread_rwlockattr_setkind_np(
1432
        attr: *mut ::pthread_rwlockattr_t,
1433
        val: ::c_int,
1434
    ) -> ::c_int;
1435
    pub fn pthread_sigqueue(thread: ::pthread_t, sig: ::c_int, value: ::sigval) -> ::c_int;
1436
    pub fn mallinfo() -> ::mallinfo;
1437
    pub fn mallinfo2() -> ::mallinfo2;
1438
    pub fn malloc_info(options: ::c_int, stream: *mut ::FILE) -> ::c_int;
1439
    pub fn malloc_usable_size(ptr: *mut ::c_void) -> ::size_t;
1440
    pub fn getpwent_r(
1441
        pwd: *mut ::passwd,
1442
        buf: *mut ::c_char,
1443
        buflen: ::size_t,
1444
        result: *mut *mut ::passwd,
1445
    ) -> ::c_int;
1446
    pub fn getgrent_r(
1447
        grp: *mut ::group,
1448
        buf: *mut ::c_char,
1449
        buflen: ::size_t,
1450
        result: *mut *mut ::group,
1451
    ) -> ::c_int;
1452
    pub fn fgetpwent_r(
1453
        stream: *mut ::FILE,
1454
        pwd: *mut ::passwd,
1455
        buf: *mut ::c_char,
1456
        buflen: ::size_t,
1457
        result: *mut *mut ::passwd,
1458
    ) -> ::c_int;
1459
    pub fn fgetgrent_r(
1460
        stream: *mut ::FILE,
1461
        grp: *mut ::group,
1462
        buf: *mut ::c_char,
1463
        buflen: ::size_t,
1464
        result: *mut *mut ::group,
1465
    ) -> ::c_int;
1466
1467
    pub fn putpwent(p: *const ::passwd, stream: *mut ::FILE) -> ::c_int;
1468
    pub fn putgrent(grp: *const ::group, stream: *mut ::FILE) -> ::c_int;
1469
1470
    pub fn sethostid(hostid: ::c_long) -> ::c_int;
1471
1472
    pub fn memfd_create(name: *const ::c_char, flags: ::c_uint) -> ::c_int;
1473
    pub fn mlock2(addr: *const ::c_void, len: ::size_t, flags: ::c_uint) -> ::c_int;
1474
1475
    pub fn euidaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int;
1476
    pub fn eaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int;
1477
1478
    pub fn asctime_r(tm: *const ::tm, buf: *mut ::c_char) -> *mut ::c_char;
1479
    pub fn ctime_r(timep: *const time_t, buf: *mut ::c_char) -> *mut ::c_char;
1480
1481
    pub fn dirname(path: *mut ::c_char) -> *mut ::c_char;
1482
    /// POSIX version of `basename(3)`, defined in `libgen.h`.
1483
    #[link_name = "__xpg_basename"]
1484
    pub fn posix_basename(path: *mut ::c_char) -> *mut ::c_char;
1485
    /// GNU version of `basename(3)`, defined in `string.h`.
1486
    #[link_name = "basename"]
1487
    pub fn gnu_basename(path: *const ::c_char) -> *mut ::c_char;
1488
    pub fn dlmopen(lmid: Lmid_t, filename: *const ::c_char, flag: ::c_int) -> *mut ::c_void;
1489
    pub fn dlinfo(handle: *mut ::c_void, request: ::c_int, info: *mut ::c_void) -> ::c_int;
1490
    pub fn dladdr1(
1491
        addr: *const ::c_void,
1492
        info: *mut ::Dl_info,
1493
        extra_info: *mut *mut ::c_void,
1494
        flags: ::c_int,
1495
    ) -> ::c_int;
1496
    pub fn malloc_trim(__pad: ::size_t) -> ::c_int;
1497
    pub fn gnu_get_libc_release() -> *const ::c_char;
1498
    pub fn gnu_get_libc_version() -> *const ::c_char;
1499
1500
    // posix/spawn.h
1501
    // Added in `glibc` 2.29
1502
    pub fn posix_spawn_file_actions_addchdir_np(
1503
        actions: *mut ::posix_spawn_file_actions_t,
1504
        path: *const ::c_char,
1505
    ) -> ::c_int;
1506
    // Added in `glibc` 2.29
1507
    pub fn posix_spawn_file_actions_addfchdir_np(
1508
        actions: *mut ::posix_spawn_file_actions_t,
1509
        fd: ::c_int,
1510
    ) -> ::c_int;
1511
    // Added in `glibc` 2.34
1512
    pub fn posix_spawn_file_actions_addclosefrom_np(
1513
        actions: *mut ::posix_spawn_file_actions_t,
1514
        from: ::c_int,
1515
    ) -> ::c_int;
1516
    // Added in `glibc` 2.35
1517
    pub fn posix_spawn_file_actions_addtcsetpgrp_np(
1518
        actions: *mut ::posix_spawn_file_actions_t,
1519
        tcfd: ::c_int,
1520
    ) -> ::c_int;
1521
1522
    // mntent.h
1523
    pub fn getmntent_r(
1524
        stream: *mut ::FILE,
1525
        mntbuf: *mut ::mntent,
1526
        buf: *mut ::c_char,
1527
        buflen: ::c_int,
1528
    ) -> *mut ::mntent;
1529
1530
    pub fn execveat(
1531
        dirfd: ::c_int,
1532
        pathname: *const ::c_char,
1533
        argv: *const *mut c_char,
1534
        envp: *const *mut c_char,
1535
        flags: ::c_int,
1536
    ) -> ::c_int;
1537
1538
    // Added in `glibc` 2.34
1539
    pub fn close_range(first: ::c_uint, last: ::c_uint, flags: ::c_int) -> ::c_int;
1540
}
1541
1542
cfg_if! {
1543
    if #[cfg(any(target_arch = "x86",
1544
                 target_arch = "arm",
1545
                 target_arch = "m68k",
1546
                 target_arch = "csky",
1547
                 target_arch = "mips",
1548
                 target_arch = "mips32r6",
1549
                 target_arch = "powerpc",
1550
                 target_arch = "sparc",
1551
                 target_arch = "riscv32"))] {
1552
        mod b32;
1553
        pub use self::b32::*;
1554
    } else if #[cfg(any(target_arch = "x86_64",
1555
                        target_arch = "aarch64",
1556
                        target_arch = "powerpc64",
1557
                        target_arch = "mips64",
1558
                        target_arch = "mips64r6",
1559
                        target_arch = "s390x",
1560
                        target_arch = "sparc64",
1561
                        target_arch = "riscv64",
1562
                        target_arch = "loongarch64"))] {
1563
        mod b64;
1564
        pub use self::b64::*;
1565
    } else {
1566
        // Unknown target_arch
1567
    }
1568
}
1569
1570
cfg_if! {
1571
    if #[cfg(libc_align)] {
1572
        mod align;
1573
        pub use self::align::*;
1574
    } else {
1575
        mod no_align;
1576
        pub use self::no_align::*;
1577
    }
1578
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.155/src/unix/linux_like/linux/mod.rs
Line
Count
Source
1
//! Linux-specific definitions for linux-like values
2
3
pub type useconds_t = u32;
4
pub type dev_t = u64;
5
pub type socklen_t = u32;
6
pub type mode_t = u32;
7
pub type ino64_t = u64;
8
pub type off64_t = i64;
9
pub type blkcnt64_t = i64;
10
pub type rlim64_t = u64;
11
pub type mqd_t = ::c_int;
12
pub type nfds_t = ::c_ulong;
13
pub type nl_item = ::c_int;
14
pub type idtype_t = ::c_uint;
15
pub type loff_t = ::c_longlong;
16
pub type pthread_key_t = ::c_uint;
17
pub type pthread_once_t = ::c_int;
18
pub type pthread_spinlock_t = ::c_int;
19
20
pub type __u8 = ::c_uchar;
21
pub type __u16 = ::c_ushort;
22
pub type __s16 = ::c_short;
23
pub type __u32 = ::c_uint;
24
pub type __s32 = ::c_int;
25
26
pub type Elf32_Half = u16;
27
pub type Elf32_Word = u32;
28
pub type Elf32_Off = u32;
29
pub type Elf32_Addr = u32;
30
31
pub type Elf64_Half = u16;
32
pub type Elf64_Word = u32;
33
pub type Elf64_Off = u64;
34
pub type Elf64_Addr = u64;
35
pub type Elf64_Xword = u64;
36
pub type Elf64_Sxword = i64;
37
38
pub type Elf32_Section = u16;
39
pub type Elf64_Section = u16;
40
41
// linux/can.h
42
pub type canid_t = u32;
43
44
// linux/can/j1939.h
45
pub type can_err_mask_t = u32;
46
pub type pgn_t = u32;
47
pub type priority_t = u8;
48
pub type name_t = u64;
49
50
pub type iconv_t = *mut ::c_void;
51
52
// linux/sctp.h
53
pub type sctp_assoc_t = ::__s32;
54
55
pub type eventfd_t = u64;
56
missing! {
57
    #[cfg_attr(feature = "extra_traits", derive(Debug))]
58
    pub enum fpos64_t {} // FIXME: fill this out with a struct
59
}
60
61
s! {
62
    pub struct glob_t {
63
        pub gl_pathc: ::size_t,
64
        pub gl_pathv: *mut *mut c_char,
65
        pub gl_offs: ::size_t,
66
        pub gl_flags: ::c_int,
67
68
        __unused1: *mut ::c_void,
69
        __unused2: *mut ::c_void,
70
        __unused3: *mut ::c_void,
71
        __unused4: *mut ::c_void,
72
        __unused5: *mut ::c_void,
73
    }
74
75
    pub struct passwd {
76
        pub pw_name: *mut ::c_char,
77
        pub pw_passwd: *mut ::c_char,
78
        pub pw_uid: ::uid_t,
79
        pub pw_gid: ::gid_t,
80
        pub pw_gecos: *mut ::c_char,
81
        pub pw_dir: *mut ::c_char,
82
        pub pw_shell: *mut ::c_char,
83
    }
84
85
    pub struct spwd {
86
        pub sp_namp: *mut ::c_char,
87
        pub sp_pwdp: *mut ::c_char,
88
        pub sp_lstchg: ::c_long,
89
        pub sp_min: ::c_long,
90
        pub sp_max: ::c_long,
91
        pub sp_warn: ::c_long,
92
        pub sp_inact: ::c_long,
93
        pub sp_expire: ::c_long,
94
        pub sp_flag: ::c_ulong,
95
    }
96
97
    pub struct dqblk {
98
        pub dqb_bhardlimit: u64,
99
        pub dqb_bsoftlimit: u64,
100
        pub dqb_curspace: u64,
101
        pub dqb_ihardlimit: u64,
102
        pub dqb_isoftlimit: u64,
103
        pub dqb_curinodes: u64,
104
        pub dqb_btime: u64,
105
        pub dqb_itime: u64,
106
        pub dqb_valid: u32,
107
    }
108
109
    pub struct signalfd_siginfo {
110
        pub ssi_signo: u32,
111
        pub ssi_errno: i32,
112
        pub ssi_code: i32,
113
        pub ssi_pid: u32,
114
        pub ssi_uid: u32,
115
        pub ssi_fd: i32,
116
        pub ssi_tid: u32,
117
        pub ssi_band: u32,
118
        pub ssi_overrun: u32,
119
        pub ssi_trapno: u32,
120
        pub ssi_status: i32,
121
        pub ssi_int: i32,
122
        pub ssi_ptr: u64,
123
        pub ssi_utime: u64,
124
        pub ssi_stime: u64,
125
        pub ssi_addr: u64,
126
        pub ssi_addr_lsb: u16,
127
        _pad2: u16,
128
        pub ssi_syscall: i32,
129
        pub ssi_call_addr: u64,
130
        pub ssi_arch: u32,
131
        _pad: [u8; 28],
132
    }
133
134
    pub struct itimerspec {
135
        pub it_interval: ::timespec,
136
        pub it_value: ::timespec,
137
    }
138
139
    pub struct fsid_t {
140
        __val: [::c_int; 2],
141
    }
142
143
    pub struct packet_mreq {
144
        pub mr_ifindex: ::c_int,
145
        pub mr_type: ::c_ushort,
146
        pub mr_alen: ::c_ushort,
147
        pub mr_address: [::c_uchar; 8],
148
    }
149
150
    pub struct cpu_set_t {
151
        #[cfg(all(target_pointer_width = "32",
152
                  not(target_arch = "x86_64")))]
153
        bits: [u32; 32],
154
        #[cfg(not(all(target_pointer_width = "32",
155
                      not(target_arch = "x86_64"))))]
156
        bits: [u64; 16],
157
    }
158
159
    pub struct if_nameindex {
160
        pub if_index: ::c_uint,
161
        pub if_name: *mut ::c_char,
162
    }
163
164
    // System V IPC
165
    pub struct msginfo {
166
        pub msgpool: ::c_int,
167
        pub msgmap: ::c_int,
168
        pub msgmax: ::c_int,
169
        pub msgmnb: ::c_int,
170
        pub msgmni: ::c_int,
171
        pub msgssz: ::c_int,
172
        pub msgtql: ::c_int,
173
        pub msgseg: ::c_ushort,
174
    }
175
176
    pub struct sembuf {
177
        pub sem_num: ::c_ushort,
178
        pub sem_op: ::c_short,
179
        pub sem_flg: ::c_short,
180
    }
181
182
    pub struct input_event {
183
        pub time: ::timeval,
184
        pub type_: ::__u16,
185
        pub code: ::__u16,
186
        pub value: ::__s32,
187
    }
188
189
    pub struct input_id {
190
        pub bustype: ::__u16,
191
        pub vendor: ::__u16,
192
        pub product: ::__u16,
193
        pub version: ::__u16,
194
    }
195
196
    pub struct input_absinfo {
197
        pub value: ::__s32,
198
        pub minimum: ::__s32,
199
        pub maximum: ::__s32,
200
        pub fuzz: ::__s32,
201
        pub flat: ::__s32,
202
        pub resolution: ::__s32,
203
    }
204
205
    pub struct input_keymap_entry {
206
        pub flags: ::__u8,
207
        pub len: ::__u8,
208
        pub index: ::__u16,
209
        pub keycode: ::__u32,
210
        pub scancode: [::__u8; 32],
211
    }
212
213
    pub struct input_mask {
214
        pub type_: ::__u32,
215
        pub codes_size: ::__u32,
216
        pub codes_ptr: ::__u64,
217
    }
218
219
    pub struct ff_replay {
220
        pub length: ::__u16,
221
        pub delay: ::__u16,
222
    }
223
224
    pub struct ff_trigger {
225
        pub button: ::__u16,
226
        pub interval: ::__u16,
227
    }
228
229
    pub struct ff_envelope {
230
        pub attack_length: ::__u16,
231
        pub attack_level: ::__u16,
232
        pub fade_length: ::__u16,
233
        pub fade_level: ::__u16,
234
    }
235
236
    pub struct ff_constant_effect {
237
        pub level: ::__s16,
238
        pub envelope: ff_envelope,
239
    }
240
241
    pub struct ff_ramp_effect {
242
        pub start_level: ::__s16,
243
        pub end_level: ::__s16,
244
        pub envelope: ff_envelope,
245
    }
246
247
    pub struct ff_condition_effect {
248
        pub right_saturation: ::__u16,
249
        pub left_saturation: ::__u16,
250
251
        pub right_coeff: ::__s16,
252
        pub left_coeff: ::__s16,
253
254
        pub deadband: ::__u16,
255
        pub center: ::__s16,
256
    }
257
258
    pub struct ff_periodic_effect {
259
        pub waveform: ::__u16,
260
        pub period: ::__u16,
261
        pub magnitude: ::__s16,
262
        pub offset: ::__s16,
263
        pub phase: ::__u16,
264
265
        pub envelope: ff_envelope,
266
267
        pub custom_len: ::__u32,
268
        pub custom_data: *mut ::__s16,
269
    }
270
271
    pub struct ff_rumble_effect {
272
        pub strong_magnitude: ::__u16,
273
        pub weak_magnitude: ::__u16,
274
    }
275
276
    pub struct ff_effect {
277
        pub type_: ::__u16,
278
        pub id: ::__s16,
279
        pub direction: ::__u16,
280
        pub trigger: ff_trigger,
281
        pub replay: ff_replay,
282
        // FIXME this is actually a union
283
        #[cfg(target_pointer_width = "64")]
284
        pub u: [u64; 4],
285
        #[cfg(target_pointer_width = "32")]
286
        pub u: [u32; 7],
287
    }
288
289
    pub struct uinput_ff_upload {
290
        pub request_id: ::__u32,
291
        pub retval: ::__s32,
292
        pub effect: ff_effect,
293
        pub old: ff_effect,
294
    }
295
296
    pub struct uinput_ff_erase {
297
        pub request_id: ::__u32,
298
        pub retval: ::__s32,
299
        pub effect_id: ::__u32,
300
    }
301
302
    pub struct uinput_abs_setup {
303
        pub code: ::__u16,
304
        pub absinfo: input_absinfo,
305
    }
306
307
    pub struct dl_phdr_info {
308
        #[cfg(target_pointer_width = "64")]
309
        pub dlpi_addr: Elf64_Addr,
310
        #[cfg(target_pointer_width = "32")]
311
        pub dlpi_addr: Elf32_Addr,
312
313
        pub dlpi_name: *const ::c_char,
314
315
        #[cfg(target_pointer_width = "64")]
316
        pub dlpi_phdr: *const Elf64_Phdr,
317
        #[cfg(target_pointer_width = "32")]
318
        pub dlpi_phdr: *const Elf32_Phdr,
319
320
        #[cfg(target_pointer_width = "64")]
321
        pub dlpi_phnum: Elf64_Half,
322
        #[cfg(target_pointer_width = "32")]
323
        pub dlpi_phnum: Elf32_Half,
324
325
        // As of uClibc 1.0.36, the following fields are
326
        // gated behind a "#if 0" block which always evaluates
327
        // to false. So I'm just removing these, and if uClibc changes
328
        // the #if block in the future to include the following fields, these
329
        // will probably need including here. tsidea, skrap
330
        #[cfg(not(target_env = "uclibc"))]
331
        pub dlpi_adds: ::c_ulonglong,
332
        #[cfg(not(target_env = "uclibc"))]
333
        pub dlpi_subs: ::c_ulonglong,
334
        #[cfg(not(target_env = "uclibc"))]
335
        pub dlpi_tls_modid: ::size_t,
336
        #[cfg(not(target_env = "uclibc"))]
337
        pub dlpi_tls_data: *mut ::c_void,
338
    }
339
340
    pub struct Elf32_Ehdr {
341
        pub e_ident: [::c_uchar; 16],
342
        pub e_type: Elf32_Half,
343
        pub e_machine: Elf32_Half,
344
        pub e_version: Elf32_Word,
345
        pub e_entry: Elf32_Addr,
346
        pub e_phoff: Elf32_Off,
347
        pub e_shoff: Elf32_Off,
348
        pub e_flags: Elf32_Word,
349
        pub e_ehsize: Elf32_Half,
350
        pub e_phentsize: Elf32_Half,
351
        pub e_phnum: Elf32_Half,
352
        pub e_shentsize: Elf32_Half,
353
        pub e_shnum: Elf32_Half,
354
        pub e_shstrndx: Elf32_Half,
355
    }
356
357
    pub struct Elf64_Ehdr {
358
        pub e_ident: [::c_uchar; 16],
359
        pub e_type: Elf64_Half,
360
        pub e_machine: Elf64_Half,
361
        pub e_version: Elf64_Word,
362
        pub e_entry: Elf64_Addr,
363
        pub e_phoff: Elf64_Off,
364
        pub e_shoff: Elf64_Off,
365
        pub e_flags: Elf64_Word,
366
        pub e_ehsize: Elf64_Half,
367
        pub e_phentsize: Elf64_Half,
368
        pub e_phnum: Elf64_Half,
369
        pub e_shentsize: Elf64_Half,
370
        pub e_shnum: Elf64_Half,
371
        pub e_shstrndx: Elf64_Half,
372
    }
373
374
    pub struct Elf32_Sym {
375
        pub st_name: Elf32_Word,
376
        pub st_value: Elf32_Addr,
377
        pub st_size: Elf32_Word,
378
        pub st_info: ::c_uchar,
379
        pub st_other: ::c_uchar,
380
        pub st_shndx: Elf32_Section,
381
    }
382
383
    pub struct Elf64_Sym {
384
        pub st_name: Elf64_Word,
385
        pub st_info: ::c_uchar,
386
        pub st_other: ::c_uchar,
387
        pub st_shndx: Elf64_Section,
388
        pub st_value: Elf64_Addr,
389
        pub st_size: Elf64_Xword,
390
    }
391
392
    pub struct Elf32_Phdr {
393
        pub p_type: Elf32_Word,
394
        pub p_offset: Elf32_Off,
395
        pub p_vaddr: Elf32_Addr,
396
        pub p_paddr: Elf32_Addr,
397
        pub p_filesz: Elf32_Word,
398
        pub p_memsz: Elf32_Word,
399
        pub p_flags: Elf32_Word,
400
        pub p_align: Elf32_Word,
401
    }
402
403
    pub struct Elf64_Phdr {
404
        pub p_type: Elf64_Word,
405
        pub p_flags: Elf64_Word,
406
        pub p_offset: Elf64_Off,
407
        pub p_vaddr: Elf64_Addr,
408
        pub p_paddr: Elf64_Addr,
409
        pub p_filesz: Elf64_Xword,
410
        pub p_memsz: Elf64_Xword,
411
        pub p_align: Elf64_Xword,
412
    }
413
414
    pub struct Elf32_Shdr {
415
        pub sh_name: Elf32_Word,
416
        pub sh_type: Elf32_Word,
417
        pub sh_flags: Elf32_Word,
418
        pub sh_addr: Elf32_Addr,
419
        pub sh_offset: Elf32_Off,
420
        pub sh_size: Elf32_Word,
421
        pub sh_link: Elf32_Word,
422
        pub sh_info: Elf32_Word,
423
        pub sh_addralign: Elf32_Word,
424
        pub sh_entsize: Elf32_Word,
425
    }
426
427
    pub struct Elf64_Shdr {
428
        pub sh_name: Elf64_Word,
429
        pub sh_type: Elf64_Word,
430
        pub sh_flags: Elf64_Xword,
431
        pub sh_addr: Elf64_Addr,
432
        pub sh_offset: Elf64_Off,
433
        pub sh_size: Elf64_Xword,
434
        pub sh_link: Elf64_Word,
435
        pub sh_info: Elf64_Word,
436
        pub sh_addralign: Elf64_Xword,
437
        pub sh_entsize: Elf64_Xword,
438
    }
439
440
    pub struct ucred {
441
        pub pid: ::pid_t,
442
        pub uid: ::uid_t,
443
        pub gid: ::gid_t,
444
    }
445
446
    pub struct mntent {
447
        pub mnt_fsname: *mut ::c_char,
448
        pub mnt_dir: *mut ::c_char,
449
        pub mnt_type: *mut ::c_char,
450
        pub mnt_opts: *mut ::c_char,
451
        pub mnt_freq: ::c_int,
452
        pub mnt_passno: ::c_int,
453
    }
454
455
    pub struct posix_spawn_file_actions_t {
456
        __allocated: ::c_int,
457
        __used: ::c_int,
458
        __actions: *mut ::c_int,
459
        __pad: [::c_int; 16],
460
    }
461
462
    pub struct posix_spawnattr_t {
463
        __flags: ::c_short,
464
        __pgrp: ::pid_t,
465
        __sd: ::sigset_t,
466
        __ss: ::sigset_t,
467
        #[cfg(any(target_env = "musl", target_env = "ohos"))]
468
        __prio: ::c_int,
469
        #[cfg(not(any(target_env = "musl", target_env = "ohos")))]
470
        __sp: ::sched_param,
471
        __policy: ::c_int,
472
        __pad: [::c_int; 16],
473
    }
474
475
    pub struct genlmsghdr {
476
        pub cmd: u8,
477
        pub version: u8,
478
        pub reserved: u16,
479
    }
480
481
    pub struct in6_pktinfo {
482
        pub ipi6_addr: ::in6_addr,
483
        pub ipi6_ifindex: ::c_uint,
484
    }
485
486
    pub struct arpd_request {
487
        pub req: ::c_ushort,
488
        pub ip: u32,
489
        pub dev: ::c_ulong,
490
        pub stamp: ::c_ulong,
491
        pub updated: ::c_ulong,
492
        pub ha: [::c_uchar; ::MAX_ADDR_LEN],
493
    }
494
495
    pub struct inotify_event {
496
        pub wd: ::c_int,
497
        pub mask: u32,
498
        pub cookie: u32,
499
        pub len: u32
500
    }
501
502
    pub struct fanotify_response {
503
        pub fd: ::c_int,
504
        pub response: __u32,
505
    }
506
507
    pub struct sockaddr_vm {
508
        pub svm_family: ::sa_family_t,
509
        pub svm_reserved1: ::c_ushort,
510
        pub svm_port: ::c_uint,
511
        pub svm_cid: ::c_uint,
512
        pub svm_zero: [u8; 4]
513
    }
514
515
    pub struct regmatch_t {
516
        pub rm_so: regoff_t,
517
        pub rm_eo: regoff_t,
518
    }
519
520
    pub struct sock_extended_err {
521
        pub ee_errno: u32,
522
        pub ee_origin: u8,
523
        pub ee_type: u8,
524
        pub ee_code: u8,
525
        pub ee_pad: u8,
526
        pub ee_info: u32,
527
        pub ee_data: u32,
528
    }
529
530
    // linux/can.h
531
    pub struct __c_anonymous_sockaddr_can_tp {
532
        pub rx_id: canid_t,
533
        pub tx_id: canid_t,
534
    }
535
536
    pub struct __c_anonymous_sockaddr_can_j1939 {
537
        pub name: u64,
538
        pub pgn: u32,
539
        pub addr: u8,
540
    }
541
542
    pub struct can_filter {
543
        pub can_id: canid_t,
544
        pub can_mask: canid_t,
545
    }
546
547
    // linux/can/j1939.h
548
    pub struct j1939_filter {
549
        pub name: name_t,
550
        pub name_mask: name_t,
551
        pub pgn: pgn_t,
552
        pub pgn_mask: pgn_t,
553
        pub addr: u8,
554
        pub addr_mask: u8,
555
    }
556
557
    // linux/filter.h
558
    pub struct sock_filter {
559
        pub code: ::__u16,
560
        pub jt: ::__u8,
561
        pub jf: ::__u8,
562
        pub k: ::__u32,
563
    }
564
565
    pub struct sock_fprog {
566
        pub len: ::c_ushort,
567
        pub filter: *mut sock_filter,
568
    }
569
570
    // linux/seccomp.h
571
    pub struct seccomp_data {
572
        pub nr: ::c_int,
573
        pub arch: ::__u32,
574
        pub instruction_pointer: ::__u64,
575
        pub args: [::__u64; 6],
576
    }
577
578
    pub struct seccomp_notif_sizes {
579
        pub seccomp_notif: ::__u16,
580
        pub seccomp_notif_resp: ::__u16,
581
        pub seccomp_data: ::__u16,
582
    }
583
584
    pub struct seccomp_notif {
585
        pub id: ::__u64,
586
        pub pid: ::__u32,
587
        pub flags: ::__u32,
588
        pub data: seccomp_data,
589
    }
590
591
    pub struct seccomp_notif_resp {
592
        pub id: ::__u64,
593
        pub val: ::__s64,
594
        pub error: ::__s32,
595
        pub flags: ::__u32,
596
    }
597
598
    pub struct seccomp_notif_addfd {
599
        pub id: ::__u64,
600
        pub flags: ::__u32,
601
        pub srcfd: ::__u32,
602
        pub newfd: ::__u32,
603
        pub newfd_flags: ::__u32,
604
    }
605
606
    pub struct nlmsghdr {
607
        pub nlmsg_len: u32,
608
        pub nlmsg_type: u16,
609
        pub nlmsg_flags: u16,
610
        pub nlmsg_seq: u32,
611
        pub nlmsg_pid: u32,
612
    }
613
614
    pub struct nlmsgerr {
615
        pub error: ::c_int,
616
        pub msg: nlmsghdr,
617
    }
618
619
    pub struct nlattr {
620
        pub nla_len: u16,
621
        pub nla_type: u16,
622
    }
623
624
    pub struct file_clone_range {
625
        pub src_fd: ::__s64,
626
        pub src_offset: ::__u64,
627
        pub src_length: ::__u64,
628
        pub dest_offset: ::__u64,
629
    }
630
631
    pub struct __c_anonymous_ifru_map {
632
        pub mem_start: ::c_ulong,
633
        pub mem_end: ::c_ulong,
634
        pub base_addr: ::c_ushort,
635
        pub irq: ::c_uchar,
636
        pub dma: ::c_uchar,
637
        pub port: ::c_uchar,
638
    }
639
640
   pub struct in6_ifreq {
641
       pub ifr6_addr: ::in6_addr,
642
       pub ifr6_prefixlen: u32,
643
       pub ifr6_ifindex: ::c_int,
644
   }
645
646
    pub struct option {
647
        pub name: *const ::c_char,
648
        pub has_arg: ::c_int,
649
        pub flag: *mut ::c_int,
650
        pub val: ::c_int,
651
    }
652
653
    // linux/sctp.h
654
655
    pub struct sctp_initmsg {
656
        pub sinit_num_ostreams: ::__u16,
657
        pub sinit_max_instreams: ::__u16,
658
        pub sinit_max_attempts: ::__u16,
659
        pub sinit_max_init_timeo: ::__u16,
660
    }
661
662
    pub struct sctp_sndrcvinfo {
663
        pub sinfo_stream: ::__u16,
664
        pub sinfo_ssn: ::__u16,
665
        pub sinfo_flags: ::__u16,
666
        pub sinfo_ppid: ::__u32,
667
        pub sinfo_context: ::__u32,
668
        pub sinfo_timetolive: ::__u32,
669
        pub sinfo_tsn: ::__u32,
670
        pub sinfo_cumtsn: ::__u32,
671
        pub sinfo_assoc_id: ::sctp_assoc_t,
672
    }
673
674
    pub struct sctp_sndinfo {
675
        pub snd_sid: ::__u16,
676
        pub snd_flags: ::__u16,
677
        pub snd_ppid: ::__u32,
678
        pub snd_context: ::__u32,
679
        pub snd_assoc_id: ::sctp_assoc_t,
680
    }
681
682
    pub struct sctp_rcvinfo {
683
        pub rcv_sid: ::__u16,
684
        pub rcv_ssn: ::__u16,
685
        pub rcv_flags: ::__u16,
686
        pub rcv_ppid: ::__u32,
687
        pub rcv_tsn: ::__u32,
688
        pub rcv_cumtsn: ::__u32,
689
        pub rcv_context: ::__u32,
690
        pub rcv_assoc_id: ::sctp_assoc_t,
691
    }
692
693
    pub struct sctp_nxtinfo {
694
        pub nxt_sid: ::__u16,
695
        pub nxt_flags: ::__u16,
696
        pub nxt_ppid: ::__u32,
697
        pub nxt_length: ::__u32,
698
        pub nxt_assoc_id: ::sctp_assoc_t,
699
    }
700
701
    pub struct sctp_prinfo {
702
        pub pr_policy: ::__u16,
703
        pub pr_value: ::__u32,
704
    }
705
706
    pub struct sctp_authinfo {
707
        pub auth_keynumber: ::__u16,
708
    }
709
710
    pub struct rlimit64 {
711
        pub rlim_cur: rlim64_t,
712
        pub rlim_max: rlim64_t,
713
    }
714
715
    // linux/tls.h
716
717
    pub struct tls_crypto_info {
718
        pub version: ::__u16,
719
        pub cipher_type: ::__u16,
720
    }
721
722
    pub struct tls12_crypto_info_aes_gcm_128 {
723
        pub info: tls_crypto_info,
724
        pub iv: [::c_uchar; TLS_CIPHER_AES_GCM_128_IV_SIZE],
725
        pub key: [::c_uchar; TLS_CIPHER_AES_GCM_128_KEY_SIZE],
726
        pub salt: [::c_uchar; TLS_CIPHER_AES_GCM_128_SALT_SIZE],
727
        pub rec_seq: [::c_uchar; TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE],
728
    }
729
730
    pub struct tls12_crypto_info_aes_gcm_256 {
731
        pub info: tls_crypto_info,
732
        pub iv: [::c_uchar; TLS_CIPHER_AES_GCM_256_IV_SIZE],
733
        pub key: [::c_uchar; TLS_CIPHER_AES_GCM_256_KEY_SIZE],
734
        pub salt: [::c_uchar; TLS_CIPHER_AES_GCM_256_SALT_SIZE],
735
        pub rec_seq: [::c_uchar; TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE],
736
    }
737
738
    pub struct tls12_crypto_info_chacha20_poly1305 {
739
        pub info: tls_crypto_info,
740
        pub iv: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE],
741
        pub key: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE],
742
        pub salt: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE],
743
        pub rec_seq: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE],
744
    }
745
}
746
747
s_no_extra_traits! {
748
    pub struct sockaddr_nl {
749
        pub nl_family: ::sa_family_t,
750
        nl_pad: ::c_ushort,
751
        pub nl_pid: u32,
752
        pub nl_groups: u32
753
    }
754
755
    pub struct dirent {
756
        pub d_ino: ::ino_t,
757
        pub d_off: ::off_t,
758
        pub d_reclen: ::c_ushort,
759
        pub d_type: ::c_uchar,
760
        pub d_name: [::c_char; 256],
761
    }
762
763
    pub struct sockaddr_alg {
764
        pub salg_family: ::sa_family_t,
765
        pub salg_type: [::c_uchar; 14],
766
        pub salg_feat: u32,
767
        pub salg_mask: u32,
768
        pub salg_name: [::c_uchar; 64],
769
    }
770
771
    pub struct uinput_setup {
772
        pub id: input_id,
773
        pub name: [::c_char; UINPUT_MAX_NAME_SIZE],
774
        pub ff_effects_max: ::__u32,
775
    }
776
777
    pub struct uinput_user_dev {
778
        pub name: [::c_char; UINPUT_MAX_NAME_SIZE],
779
        pub id: input_id,
780
        pub ff_effects_max: ::__u32,
781
        pub absmax: [::__s32; ABS_CNT],
782
        pub absmin: [::__s32; ABS_CNT],
783
        pub absfuzz: [::__s32; ABS_CNT],
784
        pub absflat: [::__s32; ABS_CNT],
785
    }
786
787
    /// WARNING: The `PartialEq`, `Eq` and `Hash` implementations of this
788
    /// type are unsound and will be removed in the future.
789
    #[deprecated(
790
        note = "this struct has unsafe trait implementations that will be \
791
                removed in the future",
792
        since = "0.2.80"
793
    )]
794
    pub struct af_alg_iv {
795
        pub ivlen: u32,
796
        pub iv: [::c_uchar; 0],
797
    }
798
799
    // x32 compatibility
800
    // See https://sourceware.org/bugzilla/show_bug.cgi?id=21279
801
    pub struct mq_attr {
802
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
803
        pub mq_flags: i64,
804
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
805
        pub mq_maxmsg: i64,
806
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
807
        pub mq_msgsize: i64,
808
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
809
        pub mq_curmsgs: i64,
810
        #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
811
        pad: [i64; 4],
812
813
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
814
        pub mq_flags: ::c_long,
815
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
816
        pub mq_maxmsg: ::c_long,
817
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
818
        pub mq_msgsize: ::c_long,
819
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
820
        pub mq_curmsgs: ::c_long,
821
        #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
822
        pad: [::c_long; 4],
823
    }
824
825
    #[cfg(libc_union)]
826
    pub union __c_anonymous_ifr_ifru {
827
        pub ifru_addr: ::sockaddr,
828
        pub ifru_dstaddr: ::sockaddr,
829
        pub ifru_broadaddr: ::sockaddr,
830
        pub ifru_netmask: ::sockaddr,
831
        pub ifru_hwaddr: ::sockaddr,
832
        pub ifru_flags: ::c_short,
833
        pub ifru_ifindex: ::c_int,
834
        pub ifru_metric: ::c_int,
835
        pub ifru_mtu: ::c_int,
836
        pub ifru_map: __c_anonymous_ifru_map,
837
        pub ifru_slave: [::c_char; ::IFNAMSIZ],
838
        pub ifru_newname: [::c_char; ::IFNAMSIZ],
839
        pub ifru_data: *mut ::c_char,
840
    }
841
842
    pub struct ifreq {
843
        /// interface name, e.g. "en0"
844
        pub ifr_name: [::c_char; ::IFNAMSIZ],
845
        #[cfg(libc_union)]
846
        pub ifr_ifru: __c_anonymous_ifr_ifru,
847
        #[cfg(not(libc_union))]
848
        pub ifr_ifru: ::sockaddr,
849
    }
850
851
    #[cfg(libc_union)]
852
    pub union __c_anonymous_ifc_ifcu {
853
        pub ifcu_buf: *mut ::c_char,
854
        pub ifcu_req: *mut ::ifreq,
855
    }
856
857
    /*  Structure used in SIOCGIFCONF request.  Used to retrieve interface
858
    configuration for machine (useful for programs which must know all
859
    networks accessible).  */
860
    pub struct ifconf {
861
        pub ifc_len: ::c_int,       /* Size of buffer.  */
862
        #[cfg(libc_union)]
863
        pub ifc_ifcu: __c_anonymous_ifc_ifcu,
864
        #[cfg(not(libc_union))]
865
        pub ifc_ifcu: *mut ::ifreq,
866
    }
867
868
    pub struct hwtstamp_config {
869
        pub flags: ::c_int,
870
        pub tx_type: ::c_int,
871
        pub rx_filter: ::c_int,
872
    }
873
874
    pub struct dirent64 {
875
        pub d_ino: ::ino64_t,
876
        pub d_off: ::off64_t,
877
        pub d_reclen: ::c_ushort,
878
        pub d_type: ::c_uchar,
879
        pub d_name: [::c_char; 256],
880
    }
881
882
    pub struct sched_attr {
883
        pub size: ::__u32,
884
        pub sched_policy: ::__u32,
885
        pub sched_flags: ::__u64,
886
        pub sched_nice: ::__s32,
887
        pub sched_priority: ::__u32,
888
        pub sched_runtime: ::__u64,
889
        pub sched_deadline: ::__u64,
890
        pub sched_period: ::__u64,
891
    }
892
}
893
894
s_no_extra_traits! {
895
    // linux/net_tstamp.h
896
    #[allow(missing_debug_implementations)]
897
    pub struct sock_txtime {
898
        pub clockid: ::clockid_t,
899
        pub flags: ::__u32,
900
    }
901
}
902
903
cfg_if! {
904
    if #[cfg(libc_union)] {
905
        s_no_extra_traits! {
906
            // linux/can.h
907
            #[allow(missing_debug_implementations)]
908
            pub union __c_anonymous_sockaddr_can_can_addr {
909
                pub tp: __c_anonymous_sockaddr_can_tp,
910
                pub j1939: __c_anonymous_sockaddr_can_j1939,
911
            }
912
913
            #[allow(missing_debug_implementations)]
914
            pub struct sockaddr_can {
915
                pub can_family: ::sa_family_t,
916
                pub can_ifindex: ::c_int,
917
                pub can_addr: __c_anonymous_sockaddr_can_can_addr,
918
            }
919
        }
920
    }
921
}
922
923
cfg_if! {
924
    if #[cfg(feature = "extra_traits")] {
925
        impl PartialEq for sockaddr_nl {
926
            fn eq(&self, other: &sockaddr_nl) -> bool {
927
                self.nl_family == other.nl_family &&
928
                    self.nl_pid == other.nl_pid &&
929
                    self.nl_groups == other.nl_groups
930
            }
931
        }
932
        impl Eq for sockaddr_nl {}
933
        impl ::fmt::Debug for sockaddr_nl {
934
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
935
                f.debug_struct("sockaddr_nl")
936
                    .field("nl_family", &self.nl_family)
937
                    .field("nl_pid", &self.nl_pid)
938
                    .field("nl_groups", &self.nl_groups)
939
                    .finish()
940
            }
941
        }
942
        impl ::hash::Hash for sockaddr_nl {
943
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
944
                self.nl_family.hash(state);
945
                self.nl_pid.hash(state);
946
                self.nl_groups.hash(state);
947
            }
948
        }
949
950
        impl PartialEq for dirent {
951
            fn eq(&self, other: &dirent) -> bool {
952
                self.d_ino == other.d_ino
953
                    && self.d_off == other.d_off
954
                    && self.d_reclen == other.d_reclen
955
                    && self.d_type == other.d_type
956
                    && self
957
                    .d_name
958
                    .iter()
959
                    .zip(other.d_name.iter())
960
                    .all(|(a,b)| a == b)
961
            }
962
        }
963
964
        impl Eq for dirent {}
965
966
        impl ::fmt::Debug for dirent {
967
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
968
                f.debug_struct("dirent")
969
                    .field("d_ino", &self.d_ino)
970
                    .field("d_off", &self.d_off)
971
                    .field("d_reclen", &self.d_reclen)
972
                    .field("d_type", &self.d_type)
973
                // FIXME: .field("d_name", &self.d_name)
974
                    .finish()
975
            }
976
        }
977
978
        impl ::hash::Hash for dirent {
979
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
980
                self.d_ino.hash(state);
981
                self.d_off.hash(state);
982
                self.d_reclen.hash(state);
983
                self.d_type.hash(state);
984
                self.d_name.hash(state);
985
            }
986
        }
987
988
        impl PartialEq for dirent64 {
989
            fn eq(&self, other: &dirent64) -> bool {
990
                self.d_ino == other.d_ino
991
                    && self.d_off == other.d_off
992
                    && self.d_reclen == other.d_reclen
993
                    && self.d_type == other.d_type
994
                    && self
995
                    .d_name
996
                    .iter()
997
                    .zip(other.d_name.iter())
998
                    .all(|(a,b)| a == b)
999
            }
1000
        }
1001
1002
        impl Eq for dirent64 {}
1003
1004
        impl ::fmt::Debug for dirent64 {
1005
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1006
                f.debug_struct("dirent64")
1007
                    .field("d_ino", &self.d_ino)
1008
                    .field("d_off", &self.d_off)
1009
                    .field("d_reclen", &self.d_reclen)
1010
                    .field("d_type", &self.d_type)
1011
                // FIXME: .field("d_name", &self.d_name)
1012
                    .finish()
1013
            }
1014
        }
1015
1016
        impl ::hash::Hash for dirent64 {
1017
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1018
                self.d_ino.hash(state);
1019
                self.d_off.hash(state);
1020
                self.d_reclen.hash(state);
1021
                self.d_type.hash(state);
1022
                self.d_name.hash(state);
1023
            }
1024
        }
1025
1026
        impl PartialEq for pthread_cond_t {
1027
            fn eq(&self, other: &pthread_cond_t) -> bool {
1028
                self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b)
1029
            }
1030
        }
1031
1032
        impl Eq for pthread_cond_t {}
1033
1034
        impl ::fmt::Debug for pthread_cond_t {
1035
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1036
                f.debug_struct("pthread_cond_t")
1037
                // FIXME: .field("size", &self.size)
1038
                    .finish()
1039
            }
1040
        }
1041
1042
        impl ::hash::Hash for pthread_cond_t {
1043
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1044
                self.size.hash(state);
1045
            }
1046
        }
1047
1048
        impl PartialEq for pthread_mutex_t {
1049
            fn eq(&self, other: &pthread_mutex_t) -> bool {
1050
                self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b)
1051
            }
1052
        }
1053
1054
        impl Eq for pthread_mutex_t {}
1055
1056
        impl ::fmt::Debug for pthread_mutex_t {
1057
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1058
                f.debug_struct("pthread_mutex_t")
1059
                // FIXME: .field("size", &self.size)
1060
                    .finish()
1061
            }
1062
        }
1063
1064
        impl ::hash::Hash for pthread_mutex_t {
1065
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1066
                self.size.hash(state);
1067
            }
1068
        }
1069
1070
        impl PartialEq for pthread_rwlock_t {
1071
            fn eq(&self, other: &pthread_rwlock_t) -> bool {
1072
                self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b)
1073
            }
1074
        }
1075
1076
        impl Eq for pthread_rwlock_t {}
1077
1078
        impl ::fmt::Debug for pthread_rwlock_t {
1079
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1080
                f.debug_struct("pthread_rwlock_t")
1081
                // FIXME: .field("size", &self.size)
1082
                    .finish()
1083
            }
1084
        }
1085
1086
        impl ::hash::Hash for pthread_rwlock_t {
1087
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1088
                self.size.hash(state);
1089
            }
1090
        }
1091
1092
        impl PartialEq for pthread_barrier_t {
1093
            fn eq(&self, other: &pthread_barrier_t) -> bool {
1094
                self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b)
1095
            }
1096
        }
1097
1098
        impl Eq for pthread_barrier_t {}
1099
1100
        impl ::fmt::Debug for pthread_barrier_t {
1101
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1102
                f.debug_struct("pthread_barrier_t")
1103
                    .field("size", &self.size)
1104
                    .finish()
1105
            }
1106
        }
1107
1108
        impl ::hash::Hash for pthread_barrier_t {
1109
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1110
                self.size.hash(state);
1111
            }
1112
        }
1113
1114
        impl PartialEq for sockaddr_alg {
1115
            fn eq(&self, other: &sockaddr_alg) -> bool {
1116
                self.salg_family == other.salg_family
1117
                    && self
1118
                    .salg_type
1119
                    .iter()
1120
                    .zip(other.salg_type.iter())
1121
                    .all(|(a, b)| a == b)
1122
                    && self.salg_feat == other.salg_feat
1123
                    && self.salg_mask == other.salg_mask
1124
                    && self
1125
                    .salg_name
1126
                    .iter()
1127
                    .zip(other.salg_name.iter())
1128
                    .all(|(a, b)| a == b)
1129
           }
1130
        }
1131
1132
        impl Eq for sockaddr_alg {}
1133
1134
        impl ::fmt::Debug for sockaddr_alg {
1135
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1136
                f.debug_struct("sockaddr_alg")
1137
                    .field("salg_family", &self.salg_family)
1138
                    .field("salg_type", &self.salg_type)
1139
                    .field("salg_feat", &self.salg_feat)
1140
                    .field("salg_mask", &self.salg_mask)
1141
                    .field("salg_name", &&self.salg_name[..])
1142
                    .finish()
1143
            }
1144
        }
1145
1146
        impl ::hash::Hash for sockaddr_alg {
1147
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1148
                self.salg_family.hash(state);
1149
                self.salg_type.hash(state);
1150
                self.salg_feat.hash(state);
1151
                self.salg_mask.hash(state);
1152
                self.salg_name.hash(state);
1153
            }
1154
        }
1155
1156
        impl PartialEq for uinput_setup {
1157
            fn eq(&self, other: &uinput_setup) -> bool {
1158
                self.id == other.id
1159
                    && self.name[..] == other.name[..]
1160
                    && self.ff_effects_max == other.ff_effects_max
1161
           }
1162
        }
1163
        impl Eq for uinput_setup {}
1164
1165
        impl ::fmt::Debug for uinput_setup {
1166
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1167
                f.debug_struct("uinput_setup")
1168
                    .field("id", &self.id)
1169
                    .field("name", &&self.name[..])
1170
                    .field("ff_effects_max", &self.ff_effects_max)
1171
                    .finish()
1172
            }
1173
        }
1174
1175
        impl ::hash::Hash for uinput_setup {
1176
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1177
                self.id.hash(state);
1178
                self.name.hash(state);
1179
                self.ff_effects_max.hash(state);
1180
            }
1181
        }
1182
1183
        impl PartialEq for uinput_user_dev {
1184
            fn eq(&self, other: &uinput_user_dev) -> bool {
1185
                 self.name[..] == other.name[..]
1186
                    && self.id == other.id
1187
                    && self.ff_effects_max == other.ff_effects_max
1188
                    && self.absmax[..] == other.absmax[..]
1189
                    && self.absmin[..] == other.absmin[..]
1190
                    && self.absfuzz[..] == other.absfuzz[..]
1191
                    && self.absflat[..] == other.absflat[..]
1192
           }
1193
        }
1194
        impl Eq for uinput_user_dev {}
1195
1196
        impl ::fmt::Debug for uinput_user_dev {
1197
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1198
                f.debug_struct("uinput_setup")
1199
                    .field("name", &&self.name[..])
1200
                    .field("id", &self.id)
1201
                    .field("ff_effects_max", &self.ff_effects_max)
1202
                    .field("absmax", &&self.absmax[..])
1203
                    .field("absmin", &&self.absmin[..])
1204
                    .field("absfuzz", &&self.absfuzz[..])
1205
                    .field("absflat", &&self.absflat[..])
1206
                    .finish()
1207
            }
1208
        }
1209
1210
        impl ::hash::Hash for uinput_user_dev {
1211
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1212
                self.name.hash(state);
1213
                self.id.hash(state);
1214
                self.ff_effects_max.hash(state);
1215
                self.absmax.hash(state);
1216
                self.absmin.hash(state);
1217
                self.absfuzz.hash(state);
1218
                self.absflat.hash(state);
1219
            }
1220
        }
1221
1222
        #[allow(deprecated)]
1223
        impl af_alg_iv {
1224
            fn as_slice(&self) -> &[u8] {
1225
                unsafe {
1226
                    ::core::slice::from_raw_parts(
1227
                        self.iv.as_ptr(),
1228
                        self.ivlen as usize
1229
                    )
1230
                }
1231
            }
1232
        }
1233
1234
        #[allow(deprecated)]
1235
        impl PartialEq for af_alg_iv {
1236
            fn eq(&self, other: &af_alg_iv) -> bool {
1237
                *self.as_slice() == *other.as_slice()
1238
           }
1239
        }
1240
1241
        #[allow(deprecated)]
1242
        impl Eq for af_alg_iv {}
1243
1244
        #[allow(deprecated)]
1245
        impl ::fmt::Debug for af_alg_iv {
1246
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1247
                f.debug_struct("af_alg_iv")
1248
                    .field("ivlen", &self.ivlen)
1249
                    .finish()
1250
            }
1251
        }
1252
1253
        #[allow(deprecated)]
1254
        impl ::hash::Hash for af_alg_iv {
1255
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1256
                self.as_slice().hash(state);
1257
            }
1258
        }
1259
1260
        impl PartialEq for mq_attr {
1261
            fn eq(&self, other: &mq_attr) -> bool {
1262
                self.mq_flags == other.mq_flags &&
1263
                self.mq_maxmsg == other.mq_maxmsg &&
1264
                self.mq_msgsize == other.mq_msgsize &&
1265
                self.mq_curmsgs == other.mq_curmsgs
1266
            }
1267
        }
1268
        impl Eq for mq_attr {}
1269
        impl ::fmt::Debug for mq_attr {
1270
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1271
                f.debug_struct("mq_attr")
1272
                    .field("mq_flags", &self.mq_flags)
1273
                    .field("mq_maxmsg", &self.mq_maxmsg)
1274
                    .field("mq_msgsize", &self.mq_msgsize)
1275
                    .field("mq_curmsgs", &self.mq_curmsgs)
1276
                    .finish()
1277
            }
1278
        }
1279
        impl ::hash::Hash for mq_attr {
1280
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1281
                self.mq_flags.hash(state);
1282
                self.mq_maxmsg.hash(state);
1283
                self.mq_msgsize.hash(state);
1284
                self.mq_curmsgs.hash(state);
1285
            }
1286
        }
1287
        #[cfg(libc_union)]
1288
        impl ::fmt::Debug for __c_anonymous_ifr_ifru {
1289
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1290
                f.debug_struct("ifr_ifru")
1291
                    .field("ifru_addr", unsafe { &self.ifru_addr })
1292
                    .field("ifru_dstaddr", unsafe { &self.ifru_dstaddr })
1293
                    .field("ifru_broadaddr", unsafe { &self.ifru_broadaddr })
1294
                    .field("ifru_netmask", unsafe { &self.ifru_netmask })
1295
                    .field("ifru_hwaddr", unsafe { &self.ifru_hwaddr })
1296
                    .field("ifru_flags", unsafe { &self.ifru_flags })
1297
                    .field("ifru_ifindex", unsafe { &self.ifru_ifindex })
1298
                    .field("ifru_metric", unsafe { &self.ifru_metric })
1299
                    .field("ifru_mtu", unsafe { &self.ifru_mtu })
1300
                    .field("ifru_map", unsafe { &self.ifru_map })
1301
                    .field("ifru_slave", unsafe { &self.ifru_slave })
1302
                    .field("ifru_newname", unsafe { &self.ifru_newname })
1303
                    .field("ifru_data", unsafe { &self.ifru_data })
1304
                    .finish()
1305
            }
1306
        }
1307
        impl ::fmt::Debug for ifreq {
1308
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1309
                f.debug_struct("ifreq")
1310
                    .field("ifr_name", &self.ifr_name)
1311
                    .field("ifr_ifru", &self.ifr_ifru)
1312
                    .finish()
1313
            }
1314
        }
1315
1316
        #[cfg(libc_union)]
1317
        impl ::fmt::Debug for __c_anonymous_ifc_ifcu {
1318
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1319
                f.debug_struct("ifr_ifru")
1320
                    .field("ifcu_buf", unsafe { &self.ifcu_buf })
1321
                    .field("ifcu_req", unsafe { &self.ifcu_req })
1322
                    .finish()
1323
            }
1324
        }
1325
        impl ::fmt::Debug for ifconf {
1326
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1327
                f.debug_struct("ifconf")
1328
                    .field("ifc_len", &self.ifc_len)
1329
                    .field("ifc_ifcu", &self.ifc_ifcu)
1330
                    .finish()
1331
            }
1332
        }
1333
        impl ::fmt::Debug for hwtstamp_config {
1334
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1335
                f.debug_struct("hwtstamp_config")
1336
                    .field("flags", &self.flags)
1337
                    .field("tx_type", &self.tx_type)
1338
                    .field("rx_filter", &self.rx_filter)
1339
                    .finish()
1340
            }
1341
        }
1342
        impl PartialEq for hwtstamp_config {
1343
            fn eq(&self, other: &hwtstamp_config) -> bool {
1344
                self.flags == other.flags &&
1345
                self.tx_type == other.tx_type &&
1346
                self.rx_filter == other.rx_filter
1347
            }
1348
        }
1349
        impl Eq for hwtstamp_config {}
1350
        impl ::hash::Hash for hwtstamp_config {
1351
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1352
                self.flags.hash(state);
1353
                self.tx_type.hash(state);
1354
                self.rx_filter.hash(state);
1355
            }
1356
        }
1357
1358
        impl ::fmt::Debug for sched_attr {
1359
            fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
1360
                f.debug_struct("sched_attr")
1361
                    .field("size", &self.size)
1362
                    .field("sched_policy", &self.sched_policy)
1363
                    .field("sched_flags", &self.sched_flags)
1364
                    .field("sched_nice", &self.sched_nice)
1365
                    .field("sched_priority", &self.sched_priority)
1366
                    .field("sched_runtime", &self.sched_runtime)
1367
                    .field("sched_deadline", &self.sched_deadline)
1368
                    .field("sched_period", &self.sched_period)
1369
                    .finish()
1370
            }
1371
        }
1372
        impl PartialEq for sched_attr {
1373
            fn eq(&self, other: &sched_attr) -> bool {
1374
                self.size == other.size &&
1375
                self.sched_policy == other.sched_policy &&
1376
                self.sched_flags == other.sched_flags &&
1377
                self.sched_nice == other.sched_nice &&
1378
                self.sched_priority == other.sched_priority &&
1379
                self.sched_runtime == other.sched_runtime &&
1380
                self.sched_deadline == other.sched_deadline &&
1381
                self.sched_period == other.sched_period
1382
            }
1383
        }
1384
        impl Eq for sched_attr {}
1385
        impl ::hash::Hash for sched_attr {
1386
            fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
1387
                self.size.hash(state);
1388
                self.sched_policy.hash(state);
1389
                self.sched_flags.hash(state);
1390
                self.sched_nice.hash(state);
1391
                self.sched_priority.hash(state);
1392
                self.sched_runtime.hash(state);
1393
                self.sched_deadline.hash(state);
1394
                self.sched_period.hash(state);
1395
            }
1396
        }
1397
    }
1398
}
1399
1400
cfg_if! {
1401
    if #[cfg(any(target_env = "gnu", target_env = "musl", target_env = "ohos"))] {
1402
        pub const ABDAY_1: ::nl_item = 0x20000;
1403
        pub const ABDAY_2: ::nl_item = 0x20001;
1404
        pub const ABDAY_3: ::nl_item = 0x20002;
1405
        pub const ABDAY_4: ::nl_item = 0x20003;
1406
        pub const ABDAY_5: ::nl_item = 0x20004;
1407
        pub const ABDAY_6: ::nl_item = 0x20005;
1408
        pub const ABDAY_7: ::nl_item = 0x20006;
1409
1410
        pub const DAY_1: ::nl_item = 0x20007;
1411
        pub const DAY_2: ::nl_item = 0x20008;
1412
        pub const DAY_3: ::nl_item = 0x20009;
1413
        pub const DAY_4: ::nl_item = 0x2000A;
1414
        pub const DAY_5: ::nl_item = 0x2000B;
1415
        pub const DAY_6: ::nl_item = 0x2000C;
1416
        pub const DAY_7: ::nl_item = 0x2000D;
1417
1418
        pub const ABMON_1: ::nl_item = 0x2000E;
1419
        pub const ABMON_2: ::nl_item = 0x2000F;
1420
        pub const ABMON_3: ::nl_item = 0x20010;
1421
        pub const ABMON_4: ::nl_item = 0x20011;
1422
        pub const ABMON_5: ::nl_item = 0x20012;
1423
        pub const ABMON_6: ::nl_item = 0x20013;
1424
        pub const ABMON_7: ::nl_item = 0x20014;
1425
        pub const ABMON_8: ::nl_item = 0x20015;
1426
        pub const ABMON_9: ::nl_item = 0x20016;
1427
        pub const ABMON_10: ::nl_item = 0x20017;
1428
        pub const ABMON_11: ::nl_item = 0x20018;
1429
        pub const ABMON_12: ::nl_item = 0x20019;
1430
1431
        pub const MON_1: ::nl_item = 0x2001A;
1432
        pub const MON_2: ::nl_item = 0x2001B;
1433
        pub const MON_3: ::nl_item = 0x2001C;
1434
        pub const MON_4: ::nl_item = 0x2001D;
1435
        pub const MON_5: ::nl_item = 0x2001E;
1436
        pub const MON_6: ::nl_item = 0x2001F;
1437
        pub const MON_7: ::nl_item = 0x20020;
1438
        pub const MON_8: ::nl_item = 0x20021;
1439
        pub const MON_9: ::nl_item = 0x20022;
1440
        pub const MON_10: ::nl_item = 0x20023;
1441
        pub const MON_11: ::nl_item = 0x20024;
1442
        pub const MON_12: ::nl_item = 0x20025;
1443
1444
        pub const AM_STR: ::nl_item = 0x20026;
1445
        pub const PM_STR: ::nl_item = 0x20027;
1446
1447
        pub const D_T_FMT: ::nl_item = 0x20028;
1448
        pub const D_FMT: ::nl_item = 0x20029;
1449
        pub const T_FMT: ::nl_item = 0x2002A;
1450
        pub const T_FMT_AMPM: ::nl_item = 0x2002B;
1451
1452
        pub const ERA: ::nl_item = 0x2002C;
1453
        pub const ERA_D_FMT: ::nl_item = 0x2002E;
1454
        pub const ALT_DIGITS: ::nl_item = 0x2002F;
1455
        pub const ERA_D_T_FMT: ::nl_item = 0x20030;
1456
        pub const ERA_T_FMT: ::nl_item = 0x20031;
1457
1458
        pub const CODESET: ::nl_item = 14;
1459
        pub const CRNCYSTR: ::nl_item = 0x4000F;
1460
        pub const RADIXCHAR: ::nl_item = 0x10000;
1461
        pub const THOUSEP: ::nl_item = 0x10001;
1462
        pub const YESEXPR: ::nl_item = 0x50000;
1463
        pub const NOEXPR: ::nl_item = 0x50001;
1464
        pub const YESSTR: ::nl_item = 0x50002;
1465
        pub const NOSTR: ::nl_item = 0x50003;
1466
    }
1467
}
1468
1469
pub const RUSAGE_CHILDREN: ::c_int = -1;
1470
pub const L_tmpnam: ::c_uint = 20;
1471
pub const _PC_LINK_MAX: ::c_int = 0;
1472
pub const _PC_MAX_CANON: ::c_int = 1;
1473
pub const _PC_MAX_INPUT: ::c_int = 2;
1474
pub const _PC_NAME_MAX: ::c_int = 3;
1475
pub const _PC_PATH_MAX: ::c_int = 4;
1476
pub const _PC_PIPE_BUF: ::c_int = 5;
1477
pub const _PC_CHOWN_RESTRICTED: ::c_int = 6;
1478
pub const _PC_NO_TRUNC: ::c_int = 7;
1479
pub const _PC_VDISABLE: ::c_int = 8;
1480
pub const _PC_SYNC_IO: ::c_int = 9;
1481
pub const _PC_ASYNC_IO: ::c_int = 10;
1482
pub const _PC_PRIO_IO: ::c_int = 11;
1483
pub const _PC_SOCK_MAXBUF: ::c_int = 12;
1484
pub const _PC_FILESIZEBITS: ::c_int = 13;
1485
pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14;
1486
pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15;
1487
pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16;
1488
pub const _PC_REC_XFER_ALIGN: ::c_int = 17;
1489
pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18;
1490
pub const _PC_SYMLINK_MAX: ::c_int = 19;
1491
pub const _PC_2_SYMLINKS: ::c_int = 20;
1492
1493
pub const MS_NOUSER: ::c_ulong = 0xffffffff80000000;
1494
1495
pub const _SC_ARG_MAX: ::c_int = 0;
1496
pub const _SC_CHILD_MAX: ::c_int = 1;
1497
pub const _SC_CLK_TCK: ::c_int = 2;
1498
pub const _SC_NGROUPS_MAX: ::c_int = 3;
1499
pub const _SC_OPEN_MAX: ::c_int = 4;
1500
pub const _SC_STREAM_MAX: ::c_int = 5;
1501
pub const _SC_TZNAME_MAX: ::c_int = 6;
1502
pub const _SC_JOB_CONTROL: ::c_int = 7;
1503
pub const _SC_SAVED_IDS: ::c_int = 8;
1504
pub const _SC_REALTIME_SIGNALS: ::c_int = 9;
1505
pub const _SC_PRIORITY_SCHEDULING: ::c_int = 10;
1506
pub const _SC_TIMERS: ::c_int = 11;
1507
pub const _SC_ASYNCHRONOUS_IO: ::c_int = 12;
1508
pub const _SC_PRIORITIZED_IO: ::c_int = 13;
1509
pub const _SC_SYNCHRONIZED_IO: ::c_int = 14;
1510
pub const _SC_FSYNC: ::c_int = 15;
1511
pub const _SC_MAPPED_FILES: ::c_int = 16;
1512
pub const _SC_MEMLOCK: ::c_int = 17;
1513
pub const _SC_MEMLOCK_RANGE: ::c_int = 18;
1514
pub const _SC_MEMORY_PROTECTION: ::c_int = 19;
1515
pub const _SC_MESSAGE_PASSING: ::c_int = 20;
1516
pub const _SC_SEMAPHORES: ::c_int = 21;
1517
pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 22;
1518
pub const _SC_AIO_LISTIO_MAX: ::c_int = 23;
1519
pub const _SC_AIO_MAX: ::c_int = 24;
1520
pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 25;
1521
pub const _SC_DELAYTIMER_MAX: ::c_int = 26;
1522
pub const _SC_MQ_OPEN_MAX: ::c_int = 27;
1523
pub const _SC_MQ_PRIO_MAX: ::c_int = 28;
1524
pub const _SC_VERSION: ::c_int = 29;
1525
pub const _SC_PAGESIZE: ::c_int = 30;
1526
pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE;
1527
pub const _SC_RTSIG_MAX: ::c_int = 31;
1528
pub const _SC_SEM_NSEMS_MAX: ::c_int = 32;
1529
pub const _SC_SEM_VALUE_MAX: ::c_int = 33;
1530
pub const _SC_SIGQUEUE_MAX: ::c_int = 34;
1531
pub const _SC_TIMER_MAX: ::c_int = 35;
1532
pub const _SC_BC_BASE_MAX: ::c_int = 36;
1533
pub const _SC_BC_DIM_MAX: ::c_int = 37;
1534
pub const _SC_BC_SCALE_MAX: ::c_int = 38;
1535
pub const _SC_BC_STRING_MAX: ::c_int = 39;
1536
pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 40;
1537
pub const _SC_EXPR_NEST_MAX: ::c_int = 42;
1538
pub const _SC_LINE_MAX: ::c_int = 43;
1539
pub const _SC_RE_DUP_MAX: ::c_int = 44;
1540
pub const _SC_2_VERSION: ::c_int = 46;
1541
pub const _SC_2_C_BIND: ::c_int = 47;
1542
pub const _SC_2_C_DEV: ::c_int = 48;
1543
pub const _SC_2_FORT_DEV: ::c_int = 49;
1544
pub const _SC_2_FORT_RUN: ::c_int = 50;
1545
pub const _SC_2_SW_DEV: ::c_int = 51;
1546
pub const _SC_2_LOCALEDEF: ::c_int = 52;
1547
pub const _SC_UIO_MAXIOV: ::c_int = 60;
1548
pub const _SC_IOV_MAX: ::c_int = 60;
1549
pub const _SC_THREADS: ::c_int = 67;
1550
pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 68;
1551
pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 69;
1552
pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 70;
1553
pub const _SC_LOGIN_NAME_MAX: ::c_int = 71;
1554
pub const _SC_TTY_NAME_MAX: ::c_int = 72;
1555
pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 73;
1556
pub const _SC_THREAD_KEYS_MAX: ::c_int = 74;
1557
pub const _SC_THREAD_STACK_MIN: ::c_int = 75;
1558
pub const _SC_THREAD_THREADS_MAX: ::c_int = 76;
1559
pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77;
1560
pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78;
1561
pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 79;
1562
pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 80;
1563
pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 81;
1564
pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 82;
1565
pub const _SC_NPROCESSORS_CONF: ::c_int = 83;
1566
pub const _SC_NPROCESSORS_ONLN: ::c_int = 84;
1567
pub const _SC_PHYS_PAGES: ::c_int = 85;
1568
pub const _SC_AVPHYS_PAGES: ::c_int = 86;
1569
pub const _SC_ATEXIT_MAX: ::c_int = 87;
1570
pub const _SC_PASS_MAX: ::c_int = 88;
1571
pub const _SC_XOPEN_VERSION: ::c_int = 89;
1572
pub const _SC_XOPEN_XCU_VERSION: ::c_int = 90;
1573
pub const _SC_XOPEN_UNIX: ::c_int = 91;
1574
pub const _SC_XOPEN_CRYPT: ::c_int = 92;
1575
pub const _SC_XOPEN_ENH_I18N: ::c_int = 93;
1576
pub const _SC_XOPEN_SHM: ::c_int = 94;
1577
pub const _SC_2_CHAR_TERM: ::c_int = 95;
1578
pub const _SC_2_UPE: ::c_int = 97;
1579
pub const _SC_XOPEN_XPG2: ::c_int = 98;
1580
pub const _SC_XOPEN_XPG3: ::c_int = 99;
1581
pub const _SC_XOPEN_XPG4: ::c_int = 100;
1582
pub const _SC_NZERO: ::c_int = 109;
1583
pub const _SC_XBS5_ILP32_OFF32: ::c_int = 125;
1584
pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 126;
1585
pub const _SC_XBS5_LP64_OFF64: ::c_int = 127;
1586
pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 128;
1587
pub const _SC_XOPEN_LEGACY: ::c_int = 129;
1588
pub const _SC_XOPEN_REALTIME: ::c_int = 130;
1589
pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 131;
1590
pub const _SC_ADVISORY_INFO: ::c_int = 132;
1591
pub const _SC_BARRIERS: ::c_int = 133;
1592
pub const _SC_CLOCK_SELECTION: ::c_int = 137;
1593
pub const _SC_CPUTIME: ::c_int = 138;
1594
pub const _SC_THREAD_CPUTIME: ::c_int = 139;
1595
pub const _SC_MONOTONIC_CLOCK: ::c_int = 149;
1596
pub const _SC_READER_WRITER_LOCKS: ::c_int = 153;
1597
pub const _SC_SPIN_LOCKS: ::c_int = 154;
1598
pub const _SC_REGEXP: ::c_int = 155;
1599
pub const _SC_SHELL: ::c_int = 157;
1600
pub const _SC_SPAWN: ::c_int = 159;
1601
pub const _SC_SPORADIC_SERVER: ::c_int = 160;
1602
pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 161;
1603
pub const _SC_TIMEOUTS: ::c_int = 164;
1604
pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 165;
1605
pub const _SC_2_PBS: ::c_int = 168;
1606
pub const _SC_2_PBS_ACCOUNTING: ::c_int = 169;
1607
pub const _SC_2_PBS_LOCATE: ::c_int = 170;
1608
pub const _SC_2_PBS_MESSAGE: ::c_int = 171;
1609
pub const _SC_2_PBS_TRACK: ::c_int = 172;
1610
pub const _SC_SYMLOOP_MAX: ::c_int = 173;
1611
pub const _SC_STREAMS: ::c_int = 174;
1612
pub const _SC_2_PBS_CHECKPOINT: ::c_int = 175;
1613
pub const _SC_V6_ILP32_OFF32: ::c_int = 176;
1614
pub const _SC_V6_ILP32_OFFBIG: ::c_int = 177;
1615
pub const _SC_V6_LP64_OFF64: ::c_int = 178;
1616
pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 179;
1617
pub const _SC_HOST_NAME_MAX: ::c_int = 180;
1618
pub const _SC_TRACE: ::c_int = 181;
1619
pub const _SC_TRACE_EVENT_FILTER: ::c_int = 182;
1620
pub const _SC_TRACE_INHERIT: ::c_int = 183;
1621
pub const _SC_TRACE_LOG: ::c_int = 184;
1622
pub const _SC_IPV6: ::c_int = 235;
1623
pub const _SC_RAW_SOCKETS: ::c_int = 236;
1624
pub const _SC_V7_ILP32_OFF32: ::c_int = 237;
1625
pub const _SC_V7_ILP32_OFFBIG: ::c_int = 238;
1626
pub const _SC_V7_LP64_OFF64: ::c_int = 239;
1627
pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 240;
1628
pub const _SC_SS_REPL_MAX: ::c_int = 241;
1629
pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 242;
1630
pub const _SC_TRACE_NAME_MAX: ::c_int = 243;
1631
pub const _SC_TRACE_SYS_MAX: ::c_int = 244;
1632
pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 245;
1633
pub const _SC_XOPEN_STREAMS: ::c_int = 246;
1634
pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 247;
1635
pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 248;
1636
1637
pub const RLIM_SAVED_MAX: ::rlim_t = RLIM_INFINITY;
1638
pub const RLIM_SAVED_CUR: ::rlim_t = RLIM_INFINITY;
1639
1640
// elf.h - Fields in the e_ident array.
1641
pub const EI_NIDENT: usize = 16;
1642
1643
pub const EI_MAG0: usize = 0;
1644
pub const ELFMAG0: u8 = 0x7f;
1645
pub const EI_MAG1: usize = 1;
1646
pub const ELFMAG1: u8 = b'E';
1647
pub const EI_MAG2: usize = 2;
1648
pub const ELFMAG2: u8 = b'L';
1649
pub const EI_MAG3: usize = 3;
1650
pub const ELFMAG3: u8 = b'F';
1651
pub const SELFMAG: usize = 4;
1652
1653
pub const EI_CLASS: usize = 4;
1654
pub const ELFCLASSNONE: u8 = 0;
1655
pub const ELFCLASS32: u8 = 1;
1656
pub const ELFCLASS64: u8 = 2;
1657
pub const ELFCLASSNUM: usize = 3;
1658
1659
pub const EI_DATA: usize = 5;
1660
pub const ELFDATANONE: u8 = 0;
1661
pub const ELFDATA2LSB: u8 = 1;
1662
pub const ELFDATA2MSB: u8 = 2;
1663
pub const ELFDATANUM: usize = 3;
1664
1665
pub const EI_VERSION: usize = 6;
1666
1667
pub const EI_OSABI: usize = 7;
1668
pub const ELFOSABI_NONE: u8 = 0;
1669
pub const ELFOSABI_SYSV: u8 = 0;
1670
pub const ELFOSABI_HPUX: u8 = 1;
1671
pub const ELFOSABI_NETBSD: u8 = 2;
1672
pub const ELFOSABI_GNU: u8 = 3;
1673
pub const ELFOSABI_LINUX: u8 = ELFOSABI_GNU;
1674
pub const ELFOSABI_SOLARIS: u8 = 6;
1675
pub const ELFOSABI_AIX: u8 = 7;
1676
pub const ELFOSABI_IRIX: u8 = 8;
1677
pub const ELFOSABI_FREEBSD: u8 = 9;
1678
pub const ELFOSABI_TRU64: u8 = 10;
1679
pub const ELFOSABI_MODESTO: u8 = 11;
1680
pub const ELFOSABI_OPENBSD: u8 = 12;
1681
pub const ELFOSABI_ARM: u8 = 97;
1682
pub const ELFOSABI_STANDALONE: u8 = 255;
1683
1684
pub const EI_ABIVERSION: usize = 8;
1685
1686
pub const EI_PAD: usize = 9;
1687
1688
// elf.h - Legal values for e_type (object file type).
1689
pub const ET_NONE: u16 = 0;
1690
pub const ET_REL: u16 = 1;
1691
pub const ET_EXEC: u16 = 2;
1692
pub const ET_DYN: u16 = 3;
1693
pub const ET_CORE: u16 = 4;
1694
pub const ET_NUM: u16 = 5;
1695
pub const ET_LOOS: u16 = 0xfe00;
1696
pub const ET_HIOS: u16 = 0xfeff;
1697
pub const ET_LOPROC: u16 = 0xff00;
1698
pub const ET_HIPROC: u16 = 0xffff;
1699
1700
// elf.h - Legal values for e_machine (architecture).
1701
pub const EM_NONE: u16 = 0;
1702
pub const EM_M32: u16 = 1;
1703
pub const EM_SPARC: u16 = 2;
1704
pub const EM_386: u16 = 3;
1705
pub const EM_68K: u16 = 4;
1706
pub const EM_88K: u16 = 5;
1707
pub const EM_860: u16 = 7;
1708
pub const EM_MIPS: u16 = 8;
1709
pub const EM_S370: u16 = 9;
1710
pub const EM_MIPS_RS3_LE: u16 = 10;
1711
pub const EM_PARISC: u16 = 15;
1712
pub const EM_VPP500: u16 = 17;
1713
pub const EM_SPARC32PLUS: u16 = 18;
1714
pub const EM_960: u16 = 19;
1715
pub const EM_PPC: u16 = 20;
1716
pub const EM_PPC64: u16 = 21;
1717
pub const EM_S390: u16 = 22;
1718
pub const EM_V800: u16 = 36;
1719
pub const EM_FR20: u16 = 37;
1720
pub const EM_RH32: u16 = 38;
1721
pub const EM_RCE: u16 = 39;
1722
pub const EM_ARM: u16 = 40;
1723
pub const EM_FAKE_ALPHA: u16 = 41;
1724
pub const EM_SH: u16 = 42;
1725
pub const EM_SPARCV9: u16 = 43;
1726
pub const EM_TRICORE: u16 = 44;
1727
pub const EM_ARC: u16 = 45;
1728
pub const EM_H8_300: u16 = 46;
1729
pub const EM_H8_300H: u16 = 47;
1730
pub const EM_H8S: u16 = 48;
1731
pub const EM_H8_500: u16 = 49;
1732
pub const EM_IA_64: u16 = 50;
1733
pub const EM_MIPS_X: u16 = 51;
1734
pub const EM_COLDFIRE: u16 = 52;
1735
pub const EM_68HC12: u16 = 53;
1736
pub const EM_MMA: u16 = 54;
1737
pub const EM_PCP: u16 = 55;
1738
pub const EM_NCPU: u16 = 56;
1739
pub const EM_NDR1: u16 = 57;
1740
pub const EM_STARCORE: u16 = 58;
1741
pub const EM_ME16: u16 = 59;
1742
pub const EM_ST100: u16 = 60;
1743
pub const EM_TINYJ: u16 = 61;
1744
pub const EM_X86_64: u16 = 62;
1745
pub const EM_PDSP: u16 = 63;
1746
pub const EM_FX66: u16 = 66;
1747
pub const EM_ST9PLUS: u16 = 67;
1748
pub const EM_ST7: u16 = 68;
1749
pub const EM_68HC16: u16 = 69;
1750
pub const EM_68HC11: u16 = 70;
1751
pub const EM_68HC08: u16 = 71;
1752
pub const EM_68HC05: u16 = 72;
1753
pub const EM_SVX: u16 = 73;
1754
pub const EM_ST19: u16 = 74;
1755
pub const EM_VAX: u16 = 75;
1756
pub const EM_CRIS: u16 = 76;
1757
pub const EM_JAVELIN: u16 = 77;
1758
pub const EM_FIREPATH: u16 = 78;
1759
pub const EM_ZSP: u16 = 79;
1760
pub const EM_MMIX: u16 = 80;
1761
pub const EM_HUANY: u16 = 81;
1762
pub const EM_PRISM: u16 = 82;
1763
pub const EM_AVR: u16 = 83;
1764
pub const EM_FR30: u16 = 84;
1765
pub const EM_D10V: u16 = 85;
1766
pub const EM_D30V: u16 = 86;
1767
pub const EM_V850: u16 = 87;
1768
pub const EM_M32R: u16 = 88;
1769
pub const EM_MN10300: u16 = 89;
1770
pub const EM_MN10200: u16 = 90;
1771
pub const EM_PJ: u16 = 91;
1772
pub const EM_OPENRISC: u16 = 92;
1773
pub const EM_ARC_A5: u16 = 93;
1774
pub const EM_XTENSA: u16 = 94;
1775
pub const EM_AARCH64: u16 = 183;
1776
pub const EM_TILEPRO: u16 = 188;
1777
pub const EM_TILEGX: u16 = 191;
1778
pub const EM_ALPHA: u16 = 0x9026;
1779
1780
// elf.h - Legal values for e_version (version).
1781
pub const EV_NONE: u32 = 0;
1782
pub const EV_CURRENT: u32 = 1;
1783
pub const EV_NUM: u32 = 2;
1784
1785
// elf.h - Legal values for p_type (segment type).
1786
pub const PT_NULL: u32 = 0;
1787
pub const PT_LOAD: u32 = 1;
1788
pub const PT_DYNAMIC: u32 = 2;
1789
pub const PT_INTERP: u32 = 3;
1790
pub const PT_NOTE: u32 = 4;
1791
pub const PT_SHLIB: u32 = 5;
1792
pub const PT_PHDR: u32 = 6;
1793
pub const PT_TLS: u32 = 7;
1794
pub const PT_NUM: u32 = 8;
1795
pub const PT_LOOS: u32 = 0x60000000;
1796
pub const PT_GNU_EH_FRAME: u32 = 0x6474e550;
1797
pub const PT_GNU_STACK: u32 = 0x6474e551;
1798
pub const PT_GNU_RELRO: u32 = 0x6474e552;
1799
pub const PT_LOSUNW: u32 = 0x6ffffffa;
1800
pub const PT_SUNWBSS: u32 = 0x6ffffffa;
1801
pub const PT_SUNWSTACK: u32 = 0x6ffffffb;
1802
pub const PT_HISUNW: u32 = 0x6fffffff;
1803
pub const PT_HIOS: u32 = 0x6fffffff;
1804
pub const PT_LOPROC: u32 = 0x70000000;
1805
pub const PT_HIPROC: u32 = 0x7fffffff;
1806
1807
// Legal values for p_flags (segment flags).
1808
pub const PF_X: u32 = 1 << 0;
1809
pub const PF_W: u32 = 1 << 1;
1810
pub const PF_R: u32 = 1 << 2;
1811
pub const PF_MASKOS: u32 = 0x0ff00000;
1812
pub const PF_MASKPROC: u32 = 0xf0000000;
1813
1814
// elf.h - Legal values for a_type (entry type).
1815
pub const AT_NULL: ::c_ulong = 0;
1816
pub const AT_IGNORE: ::c_ulong = 1;
1817
pub const AT_EXECFD: ::c_ulong = 2;
1818
pub const AT_PHDR: ::c_ulong = 3;
1819
pub const AT_PHENT: ::c_ulong = 4;
1820
pub const AT_PHNUM: ::c_ulong = 5;
1821
pub const AT_PAGESZ: ::c_ulong = 6;
1822
pub const AT_BASE: ::c_ulong = 7;
1823
pub const AT_FLAGS: ::c_ulong = 8;
1824
pub const AT_ENTRY: ::c_ulong = 9;
1825
pub const AT_NOTELF: ::c_ulong = 10;
1826
pub const AT_UID: ::c_ulong = 11;
1827
pub const AT_EUID: ::c_ulong = 12;
1828
pub const AT_GID: ::c_ulong = 13;
1829
pub const AT_EGID: ::c_ulong = 14;
1830
pub const AT_PLATFORM: ::c_ulong = 15;
1831
pub const AT_HWCAP: ::c_ulong = 16;
1832
pub const AT_CLKTCK: ::c_ulong = 17;
1833
1834
pub const AT_SECURE: ::c_ulong = 23;
1835
pub const AT_BASE_PLATFORM: ::c_ulong = 24;
1836
pub const AT_RANDOM: ::c_ulong = 25;
1837
pub const AT_HWCAP2: ::c_ulong = 26;
1838
1839
pub const AT_EXECFN: ::c_ulong = 31;
1840
1841
// defined in arch/<arch>/include/uapi/asm/auxvec.h but has the same value
1842
// wherever it is defined.
1843
pub const AT_SYSINFO_EHDR: ::c_ulong = 33;
1844
pub const AT_MINSIGSTKSZ: ::c_ulong = 51;
1845
1846
pub const GLOB_ERR: ::c_int = 1 << 0;
1847
pub const GLOB_MARK: ::c_int = 1 << 1;
1848
pub const GLOB_NOSORT: ::c_int = 1 << 2;
1849
pub const GLOB_DOOFFS: ::c_int = 1 << 3;
1850
pub const GLOB_NOCHECK: ::c_int = 1 << 4;
1851
pub const GLOB_APPEND: ::c_int = 1 << 5;
1852
pub const GLOB_NOESCAPE: ::c_int = 1 << 6;
1853
1854
pub const GLOB_NOSPACE: ::c_int = 1;
1855
pub const GLOB_ABORTED: ::c_int = 2;
1856
pub const GLOB_NOMATCH: ::c_int = 3;
1857
1858
pub const POSIX_MADV_NORMAL: ::c_int = 0;
1859
pub const POSIX_MADV_RANDOM: ::c_int = 1;
1860
pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2;
1861
pub const POSIX_MADV_WILLNEED: ::c_int = 3;
1862
pub const POSIX_SPAWN_USEVFORK: ::c_int = 64;
1863
pub const POSIX_SPAWN_SETSID: ::c_int = 128;
1864
1865
pub const S_IEXEC: mode_t = 64;
1866
pub const S_IWRITE: mode_t = 128;
1867
pub const S_IREAD: mode_t = 256;
1868
1869
pub const F_LOCK: ::c_int = 1;
1870
pub const F_TEST: ::c_int = 3;
1871
pub const F_TLOCK: ::c_int = 2;
1872
pub const F_ULOCK: ::c_int = 0;
1873
1874
pub const F_SEAL_FUTURE_WRITE: ::c_int = 0x0010;
1875
1876
pub const IFF_LOWER_UP: ::c_int = 0x10000;
1877
pub const IFF_DORMANT: ::c_int = 0x20000;
1878
pub const IFF_ECHO: ::c_int = 0x40000;
1879
1880
// linux/if_addr.h
1881
pub const IFA_UNSPEC: ::c_ushort = 0;
1882
pub const IFA_ADDRESS: ::c_ushort = 1;
1883
pub const IFA_LOCAL: ::c_ushort = 2;
1884
pub const IFA_LABEL: ::c_ushort = 3;
1885
pub const IFA_BROADCAST: ::c_ushort = 4;
1886
pub const IFA_ANYCAST: ::c_ushort = 5;
1887
pub const IFA_CACHEINFO: ::c_ushort = 6;
1888
pub const IFA_MULTICAST: ::c_ushort = 7;
1889
1890
pub const IFA_F_SECONDARY: u32 = 0x01;
1891
pub const IFA_F_TEMPORARY: u32 = 0x01;
1892
pub const IFA_F_NODAD: u32 = 0x02;
1893
pub const IFA_F_OPTIMISTIC: u32 = 0x04;
1894
pub const IFA_F_DADFAILED: u32 = 0x08;
1895
pub const IFA_F_HOMEADDRESS: u32 = 0x10;
1896
pub const IFA_F_DEPRECATED: u32 = 0x20;
1897
pub const IFA_F_TENTATIVE: u32 = 0x40;
1898
pub const IFA_F_PERMANENT: u32 = 0x80;
1899
1900
// linux/if_link.h
1901
pub const IFLA_UNSPEC: ::c_ushort = 0;
1902
pub const IFLA_ADDRESS: ::c_ushort = 1;
1903
pub const IFLA_BROADCAST: ::c_ushort = 2;
1904
pub const IFLA_IFNAME: ::c_ushort = 3;
1905
pub const IFLA_MTU: ::c_ushort = 4;
1906
pub const IFLA_LINK: ::c_ushort = 5;
1907
pub const IFLA_QDISC: ::c_ushort = 6;
1908
pub const IFLA_STATS: ::c_ushort = 7;
1909
pub const IFLA_COST: ::c_ushort = 8;
1910
pub const IFLA_PRIORITY: ::c_ushort = 9;
1911
pub const IFLA_MASTER: ::c_ushort = 10;
1912
pub const IFLA_WIRELESS: ::c_ushort = 11;
1913
pub const IFLA_PROTINFO: ::c_ushort = 12;
1914
pub const IFLA_TXQLEN: ::c_ushort = 13;
1915
pub const IFLA_MAP: ::c_ushort = 14;
1916
pub const IFLA_WEIGHT: ::c_ushort = 15;
1917
pub const IFLA_OPERSTATE: ::c_ushort = 16;
1918
pub const IFLA_LINKMODE: ::c_ushort = 17;
1919
pub const IFLA_LINKINFO: ::c_ushort = 18;
1920
pub const IFLA_NET_NS_PID: ::c_ushort = 19;
1921
pub const IFLA_IFALIAS: ::c_ushort = 20;
1922
pub const IFLA_NUM_VF: ::c_ushort = 21;
1923
pub const IFLA_VFINFO_LIST: ::c_ushort = 22;
1924
pub const IFLA_STATS64: ::c_ushort = 23;
1925
pub const IFLA_VF_PORTS: ::c_ushort = 24;
1926
pub const IFLA_PORT_SELF: ::c_ushort = 25;
1927
pub const IFLA_AF_SPEC: ::c_ushort = 26;
1928
pub const IFLA_GROUP: ::c_ushort = 27;
1929
pub const IFLA_NET_NS_FD: ::c_ushort = 28;
1930
pub const IFLA_EXT_MASK: ::c_ushort = 29;
1931
pub const IFLA_PROMISCUITY: ::c_ushort = 30;
1932
pub const IFLA_NUM_TX_QUEUES: ::c_ushort = 31;
1933
pub const IFLA_NUM_RX_QUEUES: ::c_ushort = 32;
1934
pub const IFLA_CARRIER: ::c_ushort = 33;
1935
pub const IFLA_PHYS_PORT_ID: ::c_ushort = 34;
1936
pub const IFLA_CARRIER_CHANGES: ::c_ushort = 35;
1937
pub const IFLA_PHYS_SWITCH_ID: ::c_ushort = 36;
1938
pub const IFLA_LINK_NETNSID: ::c_ushort = 37;
1939
pub const IFLA_PHYS_PORT_NAME: ::c_ushort = 38;
1940
pub const IFLA_PROTO_DOWN: ::c_ushort = 39;
1941
pub const IFLA_GSO_MAX_SEGS: ::c_ushort = 40;
1942
pub const IFLA_GSO_MAX_SIZE: ::c_ushort = 41;
1943
pub const IFLA_PAD: ::c_ushort = 42;
1944
pub const IFLA_XDP: ::c_ushort = 43;
1945
pub const IFLA_EVENT: ::c_ushort = 44;
1946
pub const IFLA_NEW_NETNSID: ::c_ushort = 45;
1947
pub const IFLA_IF_NETNSID: ::c_ushort = 46;
1948
pub const IFLA_TARGET_NETNSID: ::c_ushort = IFLA_IF_NETNSID;
1949
pub const IFLA_CARRIER_UP_COUNT: ::c_ushort = 47;
1950
pub const IFLA_CARRIER_DOWN_COUNT: ::c_ushort = 48;
1951
pub const IFLA_NEW_IFINDEX: ::c_ushort = 49;
1952
pub const IFLA_MIN_MTU: ::c_ushort = 50;
1953
pub const IFLA_MAX_MTU: ::c_ushort = 51;
1954
pub const IFLA_PROP_LIST: ::c_ushort = 52;
1955
pub const IFLA_ALT_IFNAME: ::c_ushort = 53;
1956
pub const IFLA_PERM_ADDRESS: ::c_ushort = 54;
1957
pub const IFLA_PROTO_DOWN_REASON: ::c_ushort = 55;
1958
pub const IFLA_PARENT_DEV_NAME: ::c_ushort = 56;
1959
pub const IFLA_PARENT_DEV_BUS_NAME: ::c_ushort = 57;
1960
pub const IFLA_GRO_MAX_SIZE: ::c_ushort = 58;
1961
pub const IFLA_TSO_MAX_SIZE: ::c_ushort = 59;
1962
pub const IFLA_TSO_MAX_SEGS: ::c_ushort = 60;
1963
pub const IFLA_ALLMULTI: ::c_ushort = 61;
1964
1965
pub const IFLA_INFO_UNSPEC: ::c_ushort = 0;
1966
pub const IFLA_INFO_KIND: ::c_ushort = 1;
1967
pub const IFLA_INFO_DATA: ::c_ushort = 2;
1968
pub const IFLA_INFO_XSTATS: ::c_ushort = 3;
1969
pub const IFLA_INFO_SLAVE_KIND: ::c_ushort = 4;
1970
pub const IFLA_INFO_SLAVE_DATA: ::c_ushort = 5;
1971
1972
// linux/if_tun.h
1973
pub const IFF_TUN: ::c_int = 0x0001;
1974
pub const IFF_TAP: ::c_int = 0x0002;
1975
pub const IFF_NAPI: ::c_int = 0x0010;
1976
pub const IFF_NAPI_FRAGS: ::c_int = 0x0020;
1977
// Used in TUNSETIFF to bring up tun/tap without carrier
1978
pub const IFF_NO_CARRIER: ::c_int = 0x0040;
1979
pub const IFF_NO_PI: ::c_int = 0x1000;
1980
// Read queue size
1981
pub const TUN_READQ_SIZE: ::c_short = 500;
1982
// TUN device type flags: deprecated. Use IFF_TUN/IFF_TAP instead.
1983
pub const TUN_TUN_DEV: ::c_short = ::IFF_TUN as ::c_short;
1984
pub const TUN_TAP_DEV: ::c_short = ::IFF_TAP as ::c_short;
1985
pub const TUN_TYPE_MASK: ::c_short = 0x000f;
1986
// This flag has no real effect
1987
pub const IFF_ONE_QUEUE: ::c_int = 0x2000;
1988
pub const IFF_VNET_HDR: ::c_int = 0x4000;
1989
pub const IFF_TUN_EXCL: ::c_int = 0x8000;
1990
pub const IFF_MULTI_QUEUE: ::c_int = 0x0100;
1991
pub const IFF_ATTACH_QUEUE: ::c_int = 0x0200;
1992
pub const IFF_DETACH_QUEUE: ::c_int = 0x0400;
1993
// read-only flag
1994
pub const IFF_PERSIST: ::c_int = 0x0800;
1995
pub const IFF_NOFILTER: ::c_int = 0x1000;
1996
// Socket options
1997
pub const TUN_TX_TIMESTAMP: ::c_int = 1;
1998
// Features for GSO (TUNSETOFFLOAD)
1999
pub const TUN_F_CSUM: ::c_uint = 0x01;
2000
pub const TUN_F_TSO4: ::c_uint = 0x02;
2001
pub const TUN_F_TSO6: ::c_uint = 0x04;
2002
pub const TUN_F_TSO_ECN: ::c_uint = 0x08;
2003
pub const TUN_F_UFO: ::c_uint = 0x10;
2004
pub const TUN_F_USO4: ::c_uint = 0x20;
2005
pub const TUN_F_USO6: ::c_uint = 0x40;
2006
// Protocol info prepended to the packets (when IFF_NO_PI is not set)
2007
pub const TUN_PKT_STRIP: ::c_int = 0x0001;
2008
// Accept all multicast packets
2009
pub const TUN_FLT_ALLMULTI: ::c_int = 0x0001;
2010
2011
// Since Linux 3.1
2012
pub const SEEK_DATA: ::c_int = 3;
2013
pub const SEEK_HOLE: ::c_int = 4;
2014
2015
pub const ST_RDONLY: ::c_ulong = 1;
2016
pub const ST_NOSUID: ::c_ulong = 2;
2017
pub const ST_NODEV: ::c_ulong = 4;
2018
pub const ST_NOEXEC: ::c_ulong = 8;
2019
pub const ST_SYNCHRONOUS: ::c_ulong = 16;
2020
pub const ST_MANDLOCK: ::c_ulong = 64;
2021
pub const ST_WRITE: ::c_ulong = 128;
2022
pub const ST_APPEND: ::c_ulong = 256;
2023
pub const ST_IMMUTABLE: ::c_ulong = 512;
2024
pub const ST_NOATIME: ::c_ulong = 1024;
2025
pub const ST_NODIRATIME: ::c_ulong = 2048;
2026
2027
pub const RTLD_NEXT: *mut ::c_void = -1i64 as *mut ::c_void;
2028
pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void;
2029
pub const RTLD_NODELETE: ::c_int = 0x1000;
2030
pub const RTLD_NOW: ::c_int = 0x2;
2031
2032
pub const AT_EACCESS: ::c_int = 0x200;
2033
2034
// linux/mempolicy.h
2035
pub const MPOL_DEFAULT: ::c_int = 0;
2036
pub const MPOL_PREFERRED: ::c_int = 1;
2037
pub const MPOL_BIND: ::c_int = 2;
2038
pub const MPOL_INTERLEAVE: ::c_int = 3;
2039
pub const MPOL_LOCAL: ::c_int = 4;
2040
pub const MPOL_F_NUMA_BALANCING: ::c_int = 1 << 13;
2041
pub const MPOL_F_RELATIVE_NODES: ::c_int = 1 << 14;
2042
pub const MPOL_F_STATIC_NODES: ::c_int = 1 << 15;
2043
2044
// linux/membarrier.h
2045
pub const MEMBARRIER_CMD_QUERY: ::c_int = 0;
2046
pub const MEMBARRIER_CMD_GLOBAL: ::c_int = 1 << 0;
2047
pub const MEMBARRIER_CMD_GLOBAL_EXPEDITED: ::c_int = 1 << 1;
2048
pub const MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED: ::c_int = 1 << 2;
2049
pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED: ::c_int = 1 << 3;
2050
pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED: ::c_int = 1 << 4;
2051
pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE: ::c_int = 1 << 5;
2052
pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE: ::c_int = 1 << 6;
2053
pub const MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ: ::c_int = 1 << 7;
2054
pub const MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ: ::c_int = 1 << 8;
2055
2056
align_const! {
2057
    pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
2058
        size: [0; __SIZEOF_PTHREAD_MUTEX_T],
2059
    };
2060
    pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
2061
        size: [0; __SIZEOF_PTHREAD_COND_T],
2062
    };
2063
    pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
2064
        size: [0; __SIZEOF_PTHREAD_RWLOCK_T],
2065
    };
2066
}
2067
pub const PTHREAD_ONCE_INIT: pthread_once_t = 0;
2068
pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0;
2069
pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1;
2070
pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2;
2071
pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL;
2072
pub const PTHREAD_MUTEX_STALLED: ::c_int = 0;
2073
pub const PTHREAD_MUTEX_ROBUST: ::c_int = 1;
2074
pub const PTHREAD_PRIO_NONE: ::c_int = 0;
2075
pub const PTHREAD_PRIO_INHERIT: ::c_int = 1;
2076
pub const PTHREAD_PRIO_PROTECT: ::c_int = 2;
2077
pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0;
2078
pub const PTHREAD_PROCESS_SHARED: ::c_int = 1;
2079
pub const PTHREAD_INHERIT_SCHED: ::c_int = 0;
2080
pub const PTHREAD_EXPLICIT_SCHED: ::c_int = 1;
2081
pub const __SIZEOF_PTHREAD_COND_T: usize = 48;
2082
2083
pub const RENAME_NOREPLACE: ::c_uint = 1;
2084
pub const RENAME_EXCHANGE: ::c_uint = 2;
2085
pub const RENAME_WHITEOUT: ::c_uint = 4;
2086
2087
// netinet/in.h
2088
// NOTE: These are in addition to the constants defined in src/unix/mod.rs
2089
2090
#[deprecated(
2091
    since = "0.2.80",
2092
    note = "This value was increased in the newer kernel \
2093
            and we'll change this following upstream in the future release. \
2094
            See #1896 for more info."
2095
)]
2096
pub const IPPROTO_MAX: ::c_int = 256;
2097
2098
// System V IPC
2099
pub const IPC_PRIVATE: ::key_t = 0;
2100
2101
pub const IPC_CREAT: ::c_int = 0o1000;
2102
pub const IPC_EXCL: ::c_int = 0o2000;
2103
pub const IPC_NOWAIT: ::c_int = 0o4000;
2104
2105
pub const IPC_RMID: ::c_int = 0;
2106
pub const IPC_SET: ::c_int = 1;
2107
pub const IPC_STAT: ::c_int = 2;
2108
pub const IPC_INFO: ::c_int = 3;
2109
pub const MSG_STAT: ::c_int = 11;
2110
pub const MSG_INFO: ::c_int = 12;
2111
pub const MSG_NOTIFICATION: ::c_int = 0x8000;
2112
2113
pub const MSG_NOERROR: ::c_int = 0o10000;
2114
pub const MSG_EXCEPT: ::c_int = 0o20000;
2115
pub const MSG_ZEROCOPY: ::c_int = 0x4000000;
2116
2117
pub const SHM_R: ::c_int = 0o400;
2118
pub const SHM_W: ::c_int = 0o200;
2119
2120
pub const SHM_RDONLY: ::c_int = 0o10000;
2121
pub const SHM_RND: ::c_int = 0o20000;
2122
pub const SHM_REMAP: ::c_int = 0o40000;
2123
2124
pub const SHM_LOCK: ::c_int = 11;
2125
pub const SHM_UNLOCK: ::c_int = 12;
2126
2127
pub const SHM_HUGETLB: ::c_int = 0o4000;
2128
#[cfg(not(all(target_env = "uclibc", target_arch = "mips")))]
2129
pub const SHM_NORESERVE: ::c_int = 0o10000;
2130
2131
pub const QFMT_VFS_OLD: ::c_int = 1;
2132
pub const QFMT_VFS_V0: ::c_int = 2;
2133
pub const QFMT_VFS_V1: ::c_int = 4;
2134
2135
pub const EFD_SEMAPHORE: ::c_int = 0x1;
2136
2137
pub const LOG_NFACILITIES: ::c_int = 24;
2138
2139
pub const SEM_FAILED: *mut ::sem_t = 0 as *mut sem_t;
2140
2141
pub const RB_AUTOBOOT: ::c_int = 0x01234567u32 as i32;
2142
pub const RB_HALT_SYSTEM: ::c_int = 0xcdef0123u32 as i32;
2143
pub const RB_ENABLE_CAD: ::c_int = 0x89abcdefu32 as i32;
2144
pub const RB_DISABLE_CAD: ::c_int = 0x00000000u32 as i32;
2145
pub const RB_POWER_OFF: ::c_int = 0x4321fedcu32 as i32;
2146
pub const RB_SW_SUSPEND: ::c_int = 0xd000fce2u32 as i32;
2147
pub const RB_KEXEC: ::c_int = 0x45584543u32 as i32;
2148
2149
pub const AI_PASSIVE: ::c_int = 0x0001;
2150
pub const AI_CANONNAME: ::c_int = 0x0002;
2151
pub const AI_NUMERICHOST: ::c_int = 0x0004;
2152
pub const AI_V4MAPPED: ::c_int = 0x0008;
2153
pub const AI_ALL: ::c_int = 0x0010;
2154
pub const AI_ADDRCONFIG: ::c_int = 0x0020;
2155
2156
pub const AI_NUMERICSERV: ::c_int = 0x0400;
2157
2158
pub const EAI_BADFLAGS: ::c_int = -1;
2159
pub const EAI_NONAME: ::c_int = -2;
2160
pub const EAI_AGAIN: ::c_int = -3;
2161
pub const EAI_FAIL: ::c_int = -4;
2162
pub const EAI_NODATA: ::c_int = -5;
2163
pub const EAI_FAMILY: ::c_int = -6;
2164
pub const EAI_SOCKTYPE: ::c_int = -7;
2165
pub const EAI_SERVICE: ::c_int = -8;
2166
pub const EAI_MEMORY: ::c_int = -10;
2167
pub const EAI_SYSTEM: ::c_int = -11;
2168
pub const EAI_OVERFLOW: ::c_int = -12;
2169
2170
pub const NI_NUMERICHOST: ::c_int = 1;
2171
pub const NI_NUMERICSERV: ::c_int = 2;
2172
pub const NI_NOFQDN: ::c_int = 4;
2173
pub const NI_NAMEREQD: ::c_int = 8;
2174
pub const NI_DGRAM: ::c_int = 16;
2175
pub const NI_IDN: ::c_int = 32;
2176
2177
pub const SYNC_FILE_RANGE_WAIT_BEFORE: ::c_uint = 1;
2178
pub const SYNC_FILE_RANGE_WRITE: ::c_uint = 2;
2179
pub const SYNC_FILE_RANGE_WAIT_AFTER: ::c_uint = 4;
2180
2181
cfg_if! {
2182
    if #[cfg(not(target_env = "uclibc"))] {
2183
        pub const AIO_CANCELED: ::c_int = 0;
2184
        pub const AIO_NOTCANCELED: ::c_int = 1;
2185
        pub const AIO_ALLDONE: ::c_int = 2;
2186
        pub const LIO_READ: ::c_int = 0;
2187
        pub const LIO_WRITE: ::c_int = 1;
2188
        pub const LIO_NOP: ::c_int = 2;
2189
        pub const LIO_WAIT: ::c_int = 0;
2190
        pub const LIO_NOWAIT: ::c_int = 1;
2191
        pub const RUSAGE_THREAD: ::c_int = 1;
2192
        pub const MSG_COPY: ::c_int = 0o40000;
2193
        pub const SHM_EXEC: ::c_int = 0o100000;
2194
        pub const IPV6_MULTICAST_ALL: ::c_int = 29;
2195
        pub const IPV6_ROUTER_ALERT_ISOLATE: ::c_int = 30;
2196
        pub const PACKET_MR_UNICAST: ::c_int = 3;
2197
        pub const PTRACE_EVENT_STOP: ::c_int = 128;
2198
        pub const UDP_SEGMENT: ::c_int = 103;
2199
        pub const UDP_GRO: ::c_int = 104;
2200
    }
2201
}
2202
2203
pub const MREMAP_MAYMOVE: ::c_int = 1;
2204
pub const MREMAP_FIXED: ::c_int = 2;
2205
pub const MREMAP_DONTUNMAP: ::c_int = 4;
2206
2207
pub const PR_SET_PDEATHSIG: ::c_int = 1;
2208
pub const PR_GET_PDEATHSIG: ::c_int = 2;
2209
2210
pub const PR_GET_DUMPABLE: ::c_int = 3;
2211
pub const PR_SET_DUMPABLE: ::c_int = 4;
2212
2213
pub const PR_GET_UNALIGN: ::c_int = 5;
2214
pub const PR_SET_UNALIGN: ::c_int = 6;
2215
pub const PR_UNALIGN_NOPRINT: ::c_int = 1;
2216
pub const PR_UNALIGN_SIGBUS: ::c_int = 2;
2217
2218
pub const PR_GET_KEEPCAPS: ::c_int = 7;
2219
pub const PR_SET_KEEPCAPS: ::c_int = 8;
2220
2221
pub const PR_GET_FPEMU: ::c_int = 9;
2222
pub const PR_SET_FPEMU: ::c_int = 10;
2223
pub const PR_FPEMU_NOPRINT: ::c_int = 1;
2224
pub const PR_FPEMU_SIGFPE: ::c_int = 2;
2225
2226
pub const PR_GET_FPEXC: ::c_int = 11;
2227
pub const PR_SET_FPEXC: ::c_int = 12;
2228
pub const PR_FP_EXC_SW_ENABLE: ::c_int = 0x80;
2229
pub const PR_FP_EXC_DIV: ::c_int = 0x010000;
2230
pub const PR_FP_EXC_OVF: ::c_int = 0x020000;
2231
pub const PR_FP_EXC_UND: ::c_int = 0x040000;
2232
pub const PR_FP_EXC_RES: ::c_int = 0x080000;
2233
pub const PR_FP_EXC_INV: ::c_int = 0x100000;
2234
pub const PR_FP_EXC_DISABLED: ::c_int = 0;
2235
pub const PR_FP_EXC_NONRECOV: ::c_int = 1;
2236
pub const PR_FP_EXC_ASYNC: ::c_int = 2;
2237
pub const PR_FP_EXC_PRECISE: ::c_int = 3;
2238
2239
pub const PR_GET_TIMING: ::c_int = 13;
2240
pub const PR_SET_TIMING: ::c_int = 14;
2241
pub const PR_TIMING_STATISTICAL: ::c_int = 0;
2242
pub const PR_TIMING_TIMESTAMP: ::c_int = 1;
2243
2244
pub const PR_SET_NAME: ::c_int = 15;
2245
pub const PR_GET_NAME: ::c_int = 16;
2246
2247
pub const PR_GET_ENDIAN: ::c_int = 19;
2248
pub const PR_SET_ENDIAN: ::c_int = 20;
2249
pub const PR_ENDIAN_BIG: ::c_int = 0;
2250
pub const PR_ENDIAN_LITTLE: ::c_int = 1;
2251
pub const PR_ENDIAN_PPC_LITTLE: ::c_int = 2;
2252
2253
pub const PR_GET_SECCOMP: ::c_int = 21;
2254
pub const PR_SET_SECCOMP: ::c_int = 22;
2255
2256
pub const PR_CAPBSET_READ: ::c_int = 23;
2257
pub const PR_CAPBSET_DROP: ::c_int = 24;
2258
2259
pub const PR_GET_TSC: ::c_int = 25;
2260
pub const PR_SET_TSC: ::c_int = 26;
2261
pub const PR_TSC_ENABLE: ::c_int = 1;
2262
pub const PR_TSC_SIGSEGV: ::c_int = 2;
2263
2264
pub const PR_GET_SECUREBITS: ::c_int = 27;
2265
pub const PR_SET_SECUREBITS: ::c_int = 28;
2266
2267
pub const PR_SET_TIMERSLACK: ::c_int = 29;
2268
pub const PR_GET_TIMERSLACK: ::c_int = 30;
2269
2270
pub const PR_TASK_PERF_EVENTS_DISABLE: ::c_int = 31;
2271
pub const PR_TASK_PERF_EVENTS_ENABLE: ::c_int = 32;
2272
2273
pub const PR_MCE_KILL: ::c_int = 33;
2274
pub const PR_MCE_KILL_CLEAR: ::c_int = 0;
2275
pub const PR_MCE_KILL_SET: ::c_int = 1;
2276
2277
pub const PR_MCE_KILL_LATE: ::c_int = 0;
2278
pub const PR_MCE_KILL_EARLY: ::c_int = 1;
2279
pub const PR_MCE_KILL_DEFAULT: ::c_int = 2;
2280
2281
pub const PR_MCE_KILL_GET: ::c_int = 34;
2282
2283
pub const PR_SET_MM: ::c_int = 35;
2284
pub const PR_SET_MM_START_CODE: ::c_int = 1;
2285
pub const PR_SET_MM_END_CODE: ::c_int = 2;
2286
pub const PR_SET_MM_START_DATA: ::c_int = 3;
2287
pub const PR_SET_MM_END_DATA: ::c_int = 4;
2288
pub const PR_SET_MM_START_STACK: ::c_int = 5;
2289
pub const PR_SET_MM_START_BRK: ::c_int = 6;
2290
pub const PR_SET_MM_BRK: ::c_int = 7;
2291
pub const PR_SET_MM_ARG_START: ::c_int = 8;
2292
pub const PR_SET_MM_ARG_END: ::c_int = 9;
2293
pub const PR_SET_MM_ENV_START: ::c_int = 10;
2294
pub const PR_SET_MM_ENV_END: ::c_int = 11;
2295
pub const PR_SET_MM_AUXV: ::c_int = 12;
2296
pub const PR_SET_MM_EXE_FILE: ::c_int = 13;
2297
pub const PR_SET_MM_MAP: ::c_int = 14;
2298
pub const PR_SET_MM_MAP_SIZE: ::c_int = 15;
2299
2300
pub const PR_SET_PTRACER: ::c_int = 0x59616d61;
2301
pub const PR_SET_PTRACER_ANY: ::c_ulong = 0xffffffffffffffff;
2302
2303
pub const PR_SET_CHILD_SUBREAPER: ::c_int = 36;
2304
pub const PR_GET_CHILD_SUBREAPER: ::c_int = 37;
2305
2306
pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38;
2307
pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39;
2308
2309
pub const PR_GET_TID_ADDRESS: ::c_int = 40;
2310
2311
pub const PR_SET_THP_DISABLE: ::c_int = 41;
2312
pub const PR_GET_THP_DISABLE: ::c_int = 42;
2313
2314
pub const PR_MPX_ENABLE_MANAGEMENT: ::c_int = 43;
2315
pub const PR_MPX_DISABLE_MANAGEMENT: ::c_int = 44;
2316
2317
pub const PR_SET_FP_MODE: ::c_int = 45;
2318
pub const PR_GET_FP_MODE: ::c_int = 46;
2319
pub const PR_FP_MODE_FR: ::c_int = 1 << 0;
2320
pub const PR_FP_MODE_FRE: ::c_int = 1 << 1;
2321
2322
pub const PR_CAP_AMBIENT: ::c_int = 47;
2323
pub const PR_CAP_AMBIENT_IS_SET: ::c_int = 1;
2324
pub const PR_CAP_AMBIENT_RAISE: ::c_int = 2;
2325
pub const PR_CAP_AMBIENT_LOWER: ::c_int = 3;
2326
pub const PR_CAP_AMBIENT_CLEAR_ALL: ::c_int = 4;
2327
2328
pub const PR_SET_VMA: ::c_int = 0x53564d41;
2329
pub const PR_SET_VMA_ANON_NAME: ::c_int = 0;
2330
2331
pub const PR_SCHED_CORE: ::c_int = 62;
2332
pub const PR_SCHED_CORE_GET: ::c_int = 0;
2333
pub const PR_SCHED_CORE_CREATE: ::c_int = 1;
2334
pub const PR_SCHED_CORE_SHARE_TO: ::c_int = 2;
2335
pub const PR_SCHED_CORE_SHARE_FROM: ::c_int = 3;
2336
pub const PR_SCHED_CORE_MAX: ::c_int = 4;
2337
pub const PR_SCHED_CORE_SCOPE_THREAD: ::c_int = 0;
2338
pub const PR_SCHED_CORE_SCOPE_THREAD_GROUP: ::c_int = 1;
2339
pub const PR_SCHED_CORE_SCOPE_PROCESS_GROUP: ::c_int = 2;
2340
2341
pub const GRND_NONBLOCK: ::c_uint = 0x0001;
2342
pub const GRND_RANDOM: ::c_uint = 0x0002;
2343
pub const GRND_INSECURE: ::c_uint = 0x0004;
2344
2345
// <linux/seccomp.h>
2346
pub const SECCOMP_MODE_DISABLED: ::c_uint = 0;
2347
pub const SECCOMP_MODE_STRICT: ::c_uint = 1;
2348
pub const SECCOMP_MODE_FILTER: ::c_uint = 2;
2349
2350
pub const SECCOMP_SET_MODE_STRICT: ::c_uint = 0;
2351
pub const SECCOMP_SET_MODE_FILTER: ::c_uint = 1;
2352
pub const SECCOMP_GET_ACTION_AVAIL: ::c_uint = 2;
2353
pub const SECCOMP_GET_NOTIF_SIZES: ::c_uint = 3;
2354
2355
pub const SECCOMP_FILTER_FLAG_TSYNC: ::c_ulong = 1;
2356
pub const SECCOMP_FILTER_FLAG_LOG: ::c_ulong = 2;
2357
pub const SECCOMP_FILTER_FLAG_SPEC_ALLOW: ::c_ulong = 4;
2358
pub const SECCOMP_FILTER_FLAG_NEW_LISTENER: ::c_ulong = 8;
2359
pub const SECCOMP_FILTER_FLAG_TSYNC_ESRCH: ::c_ulong = 16;
2360
pub const SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV: ::c_ulong = 32;
2361
2362
pub const SECCOMP_RET_KILL_PROCESS: ::c_uint = 0x80000000;
2363
pub const SECCOMP_RET_KILL_THREAD: ::c_uint = 0x00000000;
2364
pub const SECCOMP_RET_KILL: ::c_uint = SECCOMP_RET_KILL_THREAD;
2365
pub const SECCOMP_RET_TRAP: ::c_uint = 0x00030000;
2366
pub const SECCOMP_RET_ERRNO: ::c_uint = 0x00050000;
2367
pub const SECCOMP_RET_TRACE: ::c_uint = 0x7ff00000;
2368
pub const SECCOMP_RET_LOG: ::c_uint = 0x7ffc0000;
2369
pub const SECCOMP_RET_ALLOW: ::c_uint = 0x7fff0000;
2370
2371
pub const SECCOMP_RET_ACTION_FULL: ::c_uint = 0xffff0000;
2372
pub const SECCOMP_RET_ACTION: ::c_uint = 0x7fff0000;
2373
pub const SECCOMP_RET_DATA: ::c_uint = 0x0000ffff;
2374
2375
pub const SECCOMP_USER_NOTIF_FLAG_CONTINUE: ::c_ulong = 1;
2376
2377
pub const SECCOMP_ADDFD_FLAG_SETFD: ::c_ulong = 1;
2378
pub const SECCOMP_ADDFD_FLAG_SEND: ::c_ulong = 2;
2379
2380
pub const ITIMER_REAL: ::c_int = 0;
2381
pub const ITIMER_VIRTUAL: ::c_int = 1;
2382
pub const ITIMER_PROF: ::c_int = 2;
2383
2384
pub const TFD_CLOEXEC: ::c_int = O_CLOEXEC;
2385
pub const TFD_NONBLOCK: ::c_int = O_NONBLOCK;
2386
pub const TFD_TIMER_ABSTIME: ::c_int = 1;
2387
pub const TFD_TIMER_CANCEL_ON_SET: ::c_int = 2;
2388
2389
pub const _POSIX_VDISABLE: ::cc_t = 0;
2390
2391
pub const FALLOC_FL_KEEP_SIZE: ::c_int = 0x01;
2392
pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02;
2393
pub const FALLOC_FL_COLLAPSE_RANGE: ::c_int = 0x08;
2394
pub const FALLOC_FL_ZERO_RANGE: ::c_int = 0x10;
2395
pub const FALLOC_FL_INSERT_RANGE: ::c_int = 0x20;
2396
pub const FALLOC_FL_UNSHARE_RANGE: ::c_int = 0x40;
2397
2398
#[deprecated(
2399
    since = "0.2.55",
2400
    note = "ENOATTR is not available on Linux; use ENODATA instead"
2401
)]
2402
pub const ENOATTR: ::c_int = ::ENODATA;
2403
2404
pub const SO_ORIGINAL_DST: ::c_int = 80;
2405
2406
pub const IP_RECVFRAGSIZE: ::c_int = 25;
2407
2408
pub const IPV6_FLOWINFO: ::c_int = 11;
2409
pub const IPV6_FLOWLABEL_MGR: ::c_int = 32;
2410
pub const IPV6_FLOWINFO_SEND: ::c_int = 33;
2411
pub const IPV6_RECVFRAGSIZE: ::c_int = 77;
2412
pub const IPV6_FREEBIND: ::c_int = 78;
2413
pub const IPV6_FLOWINFO_FLOWLABEL: ::c_int = 0x000fffff;
2414
pub const IPV6_FLOWINFO_PRIORITY: ::c_int = 0x0ff00000;
2415
2416
pub const IPV6_RTHDR_LOOSE: ::c_int = 0;
2417
pub const IPV6_RTHDR_STRICT: ::c_int = 1;
2418
2419
// SO_MEMINFO offsets
2420
pub const SK_MEMINFO_RMEM_ALLOC: ::c_int = 0;
2421
pub const SK_MEMINFO_RCVBUF: ::c_int = 1;
2422
pub const SK_MEMINFO_WMEM_ALLOC: ::c_int = 2;
2423
pub const SK_MEMINFO_SNDBUF: ::c_int = 3;
2424
pub const SK_MEMINFO_FWD_ALLOC: ::c_int = 4;
2425
pub const SK_MEMINFO_WMEM_QUEUED: ::c_int = 5;
2426
pub const SK_MEMINFO_OPTMEM: ::c_int = 6;
2427
pub const SK_MEMINFO_BACKLOG: ::c_int = 7;
2428
pub const SK_MEMINFO_DROPS: ::c_int = 8;
2429
2430
pub const IUTF8: ::tcflag_t = 0x00004000;
2431
#[cfg(not(all(target_env = "uclibc", target_arch = "mips")))]
2432
pub const CMSPAR: ::tcflag_t = 0o10000000000;
2433
2434
pub const MFD_CLOEXEC: ::c_uint = 0x0001;
2435
pub const MFD_ALLOW_SEALING: ::c_uint = 0x0002;
2436
pub const MFD_HUGETLB: ::c_uint = 0x0004;
2437
pub const MFD_NOEXEC_SEAL: ::c_uint = 0x0008;
2438
pub const MFD_EXEC: ::c_uint = 0x0010;
2439
pub const MFD_HUGE_64KB: ::c_uint = 0x40000000;
2440
pub const MFD_HUGE_512KB: ::c_uint = 0x4c000000;
2441
pub const MFD_HUGE_1MB: ::c_uint = 0x50000000;
2442
pub const MFD_HUGE_2MB: ::c_uint = 0x54000000;
2443
pub const MFD_HUGE_8MB: ::c_uint = 0x5c000000;
2444
pub const MFD_HUGE_16MB: ::c_uint = 0x60000000;
2445
pub const MFD_HUGE_32MB: ::c_uint = 0x64000000;
2446
pub const MFD_HUGE_256MB: ::c_uint = 0x70000000;
2447
pub const MFD_HUGE_512MB: ::c_uint = 0x74000000;
2448
pub const MFD_HUGE_1GB: ::c_uint = 0x78000000;
2449
pub const MFD_HUGE_2GB: ::c_uint = 0x7c000000;
2450
pub const MFD_HUGE_16GB: ::c_uint = 0x88000000;
2451
pub const MFD_HUGE_MASK: ::c_uint = 63;
2452
pub const MFD_HUGE_SHIFT: ::c_uint = 26;
2453
2454
// linux/close_range.h
2455
pub const CLOSE_RANGE_UNSHARE: ::c_uint = 1 << 1;
2456
pub const CLOSE_RANGE_CLOEXEC: ::c_uint = 1 << 2;
2457
2458
// linux/filter.h
2459
pub const SKF_AD_OFF: ::c_int = -0x1000;
2460
pub const SKF_AD_PROTOCOL: ::c_int = 0;
2461
pub const SKF_AD_PKTTYPE: ::c_int = 4;
2462
pub const SKF_AD_IFINDEX: ::c_int = 8;
2463
pub const SKF_AD_NLATTR: ::c_int = 12;
2464
pub const SKF_AD_NLATTR_NEST: ::c_int = 16;
2465
pub const SKF_AD_MARK: ::c_int = 20;
2466
pub const SKF_AD_QUEUE: ::c_int = 24;
2467
pub const SKF_AD_HATYPE: ::c_int = 28;
2468
pub const SKF_AD_RXHASH: ::c_int = 32;
2469
pub const SKF_AD_CPU: ::c_int = 36;
2470
pub const SKF_AD_ALU_XOR_X: ::c_int = 40;
2471
pub const SKF_AD_VLAN_TAG: ::c_int = 44;
2472
pub const SKF_AD_VLAN_TAG_PRESENT: ::c_int = 48;
2473
pub const SKF_AD_PAY_OFFSET: ::c_int = 52;
2474
pub const SKF_AD_RANDOM: ::c_int = 56;
2475
pub const SKF_AD_VLAN_TPID: ::c_int = 60;
2476
pub const SKF_AD_MAX: ::c_int = 64;
2477
pub const SKF_NET_OFF: ::c_int = -0x100000;
2478
pub const SKF_LL_OFF: ::c_int = -0x200000;
2479
pub const BPF_NET_OFF: ::c_int = SKF_NET_OFF;
2480
pub const BPF_LL_OFF: ::c_int = SKF_LL_OFF;
2481
pub const BPF_MEMWORDS: ::c_int = 16;
2482
pub const BPF_MAXINSNS: ::c_int = 4096;
2483
2484
// linux/bpf_common.h
2485
pub const BPF_LD: ::__u32 = 0x00;
2486
pub const BPF_LDX: ::__u32 = 0x01;
2487
pub const BPF_ST: ::__u32 = 0x02;
2488
pub const BPF_STX: ::__u32 = 0x03;
2489
pub const BPF_ALU: ::__u32 = 0x04;
2490
pub const BPF_JMP: ::__u32 = 0x05;
2491
pub const BPF_RET: ::__u32 = 0x06;
2492
pub const BPF_MISC: ::__u32 = 0x07;
2493
pub const BPF_W: ::__u32 = 0x00;
2494
pub const BPF_H: ::__u32 = 0x08;
2495
pub const BPF_B: ::__u32 = 0x10;
2496
pub const BPF_IMM: ::__u32 = 0x00;
2497
pub const BPF_ABS: ::__u32 = 0x20;
2498
pub const BPF_IND: ::__u32 = 0x40;
2499
pub const BPF_MEM: ::__u32 = 0x60;
2500
pub const BPF_LEN: ::__u32 = 0x80;
2501
pub const BPF_MSH: ::__u32 = 0xa0;
2502
pub const BPF_ADD: ::__u32 = 0x00;
2503
pub const BPF_SUB: ::__u32 = 0x10;
2504
pub const BPF_MUL: ::__u32 = 0x20;
2505
pub const BPF_DIV: ::__u32 = 0x30;
2506
pub const BPF_OR: ::__u32 = 0x40;
2507
pub const BPF_AND: ::__u32 = 0x50;
2508
pub const BPF_LSH: ::__u32 = 0x60;
2509
pub const BPF_RSH: ::__u32 = 0x70;
2510
pub const BPF_NEG: ::__u32 = 0x80;
2511
pub const BPF_MOD: ::__u32 = 0x90;
2512
pub const BPF_XOR: ::__u32 = 0xa0;
2513
pub const BPF_JA: ::__u32 = 0x00;
2514
pub const BPF_JEQ: ::__u32 = 0x10;
2515
pub const BPF_JGT: ::__u32 = 0x20;
2516
pub const BPF_JGE: ::__u32 = 0x30;
2517
pub const BPF_JSET: ::__u32 = 0x40;
2518
pub const BPF_K: ::__u32 = 0x00;
2519
pub const BPF_X: ::__u32 = 0x08;
2520
2521
// linux/openat2.h
2522
pub const RESOLVE_NO_XDEV: ::__u64 = 0x01;
2523
pub const RESOLVE_NO_MAGICLINKS: ::__u64 = 0x02;
2524
pub const RESOLVE_NO_SYMLINKS: ::__u64 = 0x04;
2525
pub const RESOLVE_BENEATH: ::__u64 = 0x08;
2526
pub const RESOLVE_IN_ROOT: ::__u64 = 0x10;
2527
pub const RESOLVE_CACHED: ::__u64 = 0x20;
2528
2529
// linux/if_ether.h
2530
pub const ETH_ALEN: ::c_int = 6;
2531
pub const ETH_HLEN: ::c_int = 14;
2532
pub const ETH_ZLEN: ::c_int = 60;
2533
pub const ETH_DATA_LEN: ::c_int = 1500;
2534
pub const ETH_FRAME_LEN: ::c_int = 1514;
2535
pub const ETH_FCS_LEN: ::c_int = 4;
2536
2537
// These are the defined Ethernet Protocol ID's.
2538
pub const ETH_P_LOOP: ::c_int = 0x0060;
2539
pub const ETH_P_PUP: ::c_int = 0x0200;
2540
pub const ETH_P_PUPAT: ::c_int = 0x0201;
2541
pub const ETH_P_IP: ::c_int = 0x0800;
2542
pub const ETH_P_X25: ::c_int = 0x0805;
2543
pub const ETH_P_ARP: ::c_int = 0x0806;
2544
pub const ETH_P_BPQ: ::c_int = 0x08FF;
2545
pub const ETH_P_IEEEPUP: ::c_int = 0x0a00;
2546
pub const ETH_P_IEEEPUPAT: ::c_int = 0x0a01;
2547
pub const ETH_P_BATMAN: ::c_int = 0x4305;
2548
pub const ETH_P_DEC: ::c_int = 0x6000;
2549
pub const ETH_P_DNA_DL: ::c_int = 0x6001;
2550
pub const ETH_P_DNA_RC: ::c_int = 0x6002;
2551
pub const ETH_P_DNA_RT: ::c_int = 0x6003;
2552
pub const ETH_P_LAT: ::c_int = 0x6004;
2553
pub const ETH_P_DIAG: ::c_int = 0x6005;
2554
pub const ETH_P_CUST: ::c_int = 0x6006;
2555
pub const ETH_P_SCA: ::c_int = 0x6007;
2556
pub const ETH_P_TEB: ::c_int = 0x6558;
2557
pub const ETH_P_RARP: ::c_int = 0x8035;
2558
pub const ETH_P_ATALK: ::c_int = 0x809B;
2559
pub const ETH_P_AARP: ::c_int = 0x80F3;
2560
pub const ETH_P_8021Q: ::c_int = 0x8100;
2561
pub const ETH_P_IPX: ::c_int = 0x8137;
2562
pub const ETH_P_IPV6: ::c_int = 0x86DD;
2563
pub const ETH_P_PAUSE: ::c_int = 0x8808;
2564
pub const ETH_P_SLOW: ::c_int = 0x8809;
2565
pub const ETH_P_WCCP: ::c_int = 0x883E;
2566
pub const ETH_P_MPLS_UC: ::c_int = 0x8847;
2567
pub const ETH_P_MPLS_MC: ::c_int = 0x8848;
2568
pub const ETH_P_ATMMPOA: ::c_int = 0x884c;
2569
pub const ETH_P_PPP_DISC: ::c_int = 0x8863;
2570
pub const ETH_P_PPP_SES: ::c_int = 0x8864;
2571
pub const ETH_P_LINK_CTL: ::c_int = 0x886c;
2572
pub const ETH_P_ATMFATE: ::c_int = 0x8884;
2573
pub const ETH_P_PAE: ::c_int = 0x888E;
2574
pub const ETH_P_AOE: ::c_int = 0x88A2;
2575
pub const ETH_P_8021AD: ::c_int = 0x88A8;
2576
pub const ETH_P_802_EX1: ::c_int = 0x88B5;
2577
pub const ETH_P_TIPC: ::c_int = 0x88CA;
2578
pub const ETH_P_MACSEC: ::c_int = 0x88E5;
2579
pub const ETH_P_8021AH: ::c_int = 0x88E7;
2580
pub const ETH_P_MVRP: ::c_int = 0x88F5;
2581
pub const ETH_P_1588: ::c_int = 0x88F7;
2582
pub const ETH_P_PRP: ::c_int = 0x88FB;
2583
pub const ETH_P_FCOE: ::c_int = 0x8906;
2584
pub const ETH_P_TDLS: ::c_int = 0x890D;
2585
pub const ETH_P_FIP: ::c_int = 0x8914;
2586
pub const ETH_P_80221: ::c_int = 0x8917;
2587
pub const ETH_P_LOOPBACK: ::c_int = 0x9000;
2588
pub const ETH_P_QINQ1: ::c_int = 0x9100;
2589
pub const ETH_P_QINQ2: ::c_int = 0x9200;
2590
pub const ETH_P_QINQ3: ::c_int = 0x9300;
2591
pub const ETH_P_EDSA: ::c_int = 0xDADA;
2592
pub const ETH_P_AF_IUCV: ::c_int = 0xFBFB;
2593
2594
pub const ETH_P_802_3_MIN: ::c_int = 0x0600;
2595
2596
// Non DIX types. Won't clash for 1500 types.
2597
pub const ETH_P_802_3: ::c_int = 0x0001;
2598
pub const ETH_P_AX25: ::c_int = 0x0002;
2599
pub const ETH_P_ALL: ::c_int = 0x0003;
2600
pub const ETH_P_802_2: ::c_int = 0x0004;
2601
pub const ETH_P_SNAP: ::c_int = 0x0005;
2602
pub const ETH_P_DDCMP: ::c_int = 0x0006;
2603
pub const ETH_P_WAN_PPP: ::c_int = 0x0007;
2604
pub const ETH_P_PPP_MP: ::c_int = 0x0008;
2605
pub const ETH_P_LOCALTALK: ::c_int = 0x0009;
2606
pub const ETH_P_CANFD: ::c_int = 0x000D;
2607
pub const ETH_P_PPPTALK: ::c_int = 0x0010;
2608
pub const ETH_P_TR_802_2: ::c_int = 0x0011;
2609
pub const ETH_P_MOBITEX: ::c_int = 0x0015;
2610
pub const ETH_P_CONTROL: ::c_int = 0x0016;
2611
pub const ETH_P_IRDA: ::c_int = 0x0017;
2612
pub const ETH_P_ECONET: ::c_int = 0x0018;
2613
pub const ETH_P_HDLC: ::c_int = 0x0019;
2614
pub const ETH_P_ARCNET: ::c_int = 0x001A;
2615
pub const ETH_P_DSA: ::c_int = 0x001B;
2616
pub const ETH_P_TRAILER: ::c_int = 0x001C;
2617
pub const ETH_P_PHONET: ::c_int = 0x00F5;
2618
pub const ETH_P_IEEE802154: ::c_int = 0x00F6;
2619
pub const ETH_P_CAIF: ::c_int = 0x00F7;
2620
2621
pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x01;
2622
pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x02;
2623
pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x04;
2624
pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x08;
2625
pub const POSIX_SPAWN_SETSCHEDPARAM: ::c_int = 0x10;
2626
pub const POSIX_SPAWN_SETSCHEDULER: ::c_int = 0x20;
2627
2628
pub const NLMSG_NOOP: ::c_int = 0x1;
2629
pub const NLMSG_ERROR: ::c_int = 0x2;
2630
pub const NLMSG_DONE: ::c_int = 0x3;
2631
pub const NLMSG_OVERRUN: ::c_int = 0x4;
2632
pub const NLMSG_MIN_TYPE: ::c_int = 0x10;
2633
2634
// linux/netfilter/nfnetlink.h
2635
pub const NFNLGRP_NONE: ::c_int = 0;
2636
pub const NFNLGRP_CONNTRACK_NEW: ::c_int = 1;
2637
pub const NFNLGRP_CONNTRACK_UPDATE: ::c_int = 2;
2638
pub const NFNLGRP_CONNTRACK_DESTROY: ::c_int = 3;
2639
pub const NFNLGRP_CONNTRACK_EXP_NEW: ::c_int = 4;
2640
pub const NFNLGRP_CONNTRACK_EXP_UPDATE: ::c_int = 5;
2641
pub const NFNLGRP_CONNTRACK_EXP_DESTROY: ::c_int = 6;
2642
pub const NFNLGRP_NFTABLES: ::c_int = 7;
2643
pub const NFNLGRP_ACCT_QUOTA: ::c_int = 8;
2644
pub const NFNLGRP_NFTRACE: ::c_int = 9;
2645
2646
pub const NFNETLINK_V0: ::c_int = 0;
2647
2648
pub const NFNL_SUBSYS_NONE: ::c_int = 0;
2649
pub const NFNL_SUBSYS_CTNETLINK: ::c_int = 1;
2650
pub const NFNL_SUBSYS_CTNETLINK_EXP: ::c_int = 2;
2651
pub const NFNL_SUBSYS_QUEUE: ::c_int = 3;
2652
pub const NFNL_SUBSYS_ULOG: ::c_int = 4;
2653
pub const NFNL_SUBSYS_OSF: ::c_int = 5;
2654
pub const NFNL_SUBSYS_IPSET: ::c_int = 6;
2655
pub const NFNL_SUBSYS_ACCT: ::c_int = 7;
2656
pub const NFNL_SUBSYS_CTNETLINK_TIMEOUT: ::c_int = 8;
2657
pub const NFNL_SUBSYS_CTHELPER: ::c_int = 9;
2658
pub const NFNL_SUBSYS_NFTABLES: ::c_int = 10;
2659
pub const NFNL_SUBSYS_NFT_COMPAT: ::c_int = 11;
2660
pub const NFNL_SUBSYS_HOOK: ::c_int = 12;
2661
pub const NFNL_SUBSYS_COUNT: ::c_int = 13;
2662
2663
pub const NFNL_MSG_BATCH_BEGIN: ::c_int = NLMSG_MIN_TYPE;
2664
pub const NFNL_MSG_BATCH_END: ::c_int = NLMSG_MIN_TYPE + 1;
2665
2666
pub const NFNL_BATCH_UNSPEC: ::c_int = 0;
2667
pub const NFNL_BATCH_GENID: ::c_int = 1;
2668
2669
// linux/netfilter/nfnetlink_log.h
2670
pub const NFULNL_MSG_PACKET: ::c_int = 0;
2671
pub const NFULNL_MSG_CONFIG: ::c_int = 1;
2672
2673
pub const NFULA_VLAN_UNSPEC: ::c_int = 0;
2674
pub const NFULA_VLAN_PROTO: ::c_int = 1;
2675
pub const NFULA_VLAN_TCI: ::c_int = 2;
2676
2677
pub const NFULA_UNSPEC: ::c_int = 0;
2678
pub const NFULA_PACKET_HDR: ::c_int = 1;
2679
pub const NFULA_MARK: ::c_int = 2;
2680
pub const NFULA_TIMESTAMP: ::c_int = 3;
2681
pub const NFULA_IFINDEX_INDEV: ::c_int = 4;
2682
pub const NFULA_IFINDEX_OUTDEV: ::c_int = 5;
2683
pub const NFULA_IFINDEX_PHYSINDEV: ::c_int = 6;
2684
pub const NFULA_IFINDEX_PHYSOUTDEV: ::c_int = 7;
2685
pub const NFULA_HWADDR: ::c_int = 8;
2686
pub const NFULA_PAYLOAD: ::c_int = 9;
2687
pub const NFULA_PREFIX: ::c_int = 10;
2688
pub const NFULA_UID: ::c_int = 11;
2689
pub const NFULA_SEQ: ::c_int = 12;
2690
pub const NFULA_SEQ_GLOBAL: ::c_int = 13;
2691
pub const NFULA_GID: ::c_int = 14;
2692
pub const NFULA_HWTYPE: ::c_int = 15;
2693
pub const NFULA_HWHEADER: ::c_int = 16;
2694
pub const NFULA_HWLEN: ::c_int = 17;
2695
pub const NFULA_CT: ::c_int = 18;
2696
pub const NFULA_CT_INFO: ::c_int = 19;
2697
pub const NFULA_VLAN: ::c_int = 20;
2698
pub const NFULA_L2HDR: ::c_int = 21;
2699
2700
pub const NFULNL_CFG_CMD_NONE: ::c_int = 0;
2701
pub const NFULNL_CFG_CMD_BIND: ::c_int = 1;
2702
pub const NFULNL_CFG_CMD_UNBIND: ::c_int = 2;
2703
pub const NFULNL_CFG_CMD_PF_BIND: ::c_int = 3;
2704
pub const NFULNL_CFG_CMD_PF_UNBIND: ::c_int = 4;
2705
2706
pub const NFULA_CFG_UNSPEC: ::c_int = 0;
2707
pub const NFULA_CFG_CMD: ::c_int = 1;
2708
pub const NFULA_CFG_MODE: ::c_int = 2;
2709
pub const NFULA_CFG_NLBUFSIZ: ::c_int = 3;
2710
pub const NFULA_CFG_TIMEOUT: ::c_int = 4;
2711
pub const NFULA_CFG_QTHRESH: ::c_int = 5;
2712
pub const NFULA_CFG_FLAGS: ::c_int = 6;
2713
2714
pub const NFULNL_COPY_NONE: ::c_int = 0x00;
2715
pub const NFULNL_COPY_META: ::c_int = 0x01;
2716
pub const NFULNL_COPY_PACKET: ::c_int = 0x02;
2717
2718
pub const NFULNL_CFG_F_SEQ: ::c_int = 0x0001;
2719
pub const NFULNL_CFG_F_SEQ_GLOBAL: ::c_int = 0x0002;
2720
pub const NFULNL_CFG_F_CONNTRACK: ::c_int = 0x0004;
2721
2722
// linux/netfilter/nfnetlink_queue.h
2723
pub const NFQNL_MSG_PACKET: ::c_int = 0;
2724
pub const NFQNL_MSG_VERDICT: ::c_int = 1;
2725
pub const NFQNL_MSG_CONFIG: ::c_int = 2;
2726
pub const NFQNL_MSG_VERDICT_BATCH: ::c_int = 3;
2727
2728
pub const NFQA_UNSPEC: ::c_int = 0;
2729
pub const NFQA_PACKET_HDR: ::c_int = 1;
2730
pub const NFQA_VERDICT_HDR: ::c_int = 2;
2731
pub const NFQA_MARK: ::c_int = 3;
2732
pub const NFQA_TIMESTAMP: ::c_int = 4;
2733
pub const NFQA_IFINDEX_INDEV: ::c_int = 5;
2734
pub const NFQA_IFINDEX_OUTDEV: ::c_int = 6;
2735
pub const NFQA_IFINDEX_PHYSINDEV: ::c_int = 7;
2736
pub const NFQA_IFINDEX_PHYSOUTDEV: ::c_int = 8;
2737
pub const NFQA_HWADDR: ::c_int = 9;
2738
pub const NFQA_PAYLOAD: ::c_int = 10;
2739
pub const NFQA_CT: ::c_int = 11;
2740
pub const NFQA_CT_INFO: ::c_int = 12;
2741
pub const NFQA_CAP_LEN: ::c_int = 13;
2742
pub const NFQA_SKB_INFO: ::c_int = 14;
2743
pub const NFQA_EXP: ::c_int = 15;
2744
pub const NFQA_UID: ::c_int = 16;
2745
pub const NFQA_GID: ::c_int = 17;
2746
pub const NFQA_SECCTX: ::c_int = 18;
2747
pub const NFQA_VLAN: ::c_int = 19;
2748
pub const NFQA_L2HDR: ::c_int = 20;
2749
pub const NFQA_PRIORITY: ::c_int = 21;
2750
2751
pub const NFQA_VLAN_UNSPEC: ::c_int = 0;
2752
pub const NFQA_VLAN_PROTO: ::c_int = 1;
2753
pub const NFQA_VLAN_TCI: ::c_int = 2;
2754
2755
pub const NFQNL_CFG_CMD_NONE: ::c_int = 0;
2756
pub const NFQNL_CFG_CMD_BIND: ::c_int = 1;
2757
pub const NFQNL_CFG_CMD_UNBIND: ::c_int = 2;
2758
pub const NFQNL_CFG_CMD_PF_BIND: ::c_int = 3;
2759
pub const NFQNL_CFG_CMD_PF_UNBIND: ::c_int = 4;
2760
2761
pub const NFQNL_COPY_NONE: ::c_int = 0;
2762
pub const NFQNL_COPY_META: ::c_int = 1;
2763
pub const NFQNL_COPY_PACKET: ::c_int = 2;
2764
2765
pub const NFQA_CFG_UNSPEC: ::c_int = 0;
2766
pub const NFQA_CFG_CMD: ::c_int = 1;
2767
pub const NFQA_CFG_PARAMS: ::c_int = 2;
2768
pub const NFQA_CFG_QUEUE_MAXLEN: ::c_int = 3;
2769
pub const NFQA_CFG_MASK: ::c_int = 4;
2770
pub const NFQA_CFG_FLAGS: ::c_int = 5;
2771
2772
pub const NFQA_CFG_F_FAIL_OPEN: ::c_int = 0x0001;
2773
pub const NFQA_CFG_F_CONNTRACK: ::c_int = 0x0002;
2774
pub const NFQA_CFG_F_GSO: ::c_int = 0x0004;
2775
pub const NFQA_CFG_F_UID_GID: ::c_int = 0x0008;
2776
pub const NFQA_CFG_F_SECCTX: ::c_int = 0x0010;
2777
pub const NFQA_CFG_F_MAX: ::c_int = 0x0020;
2778
2779
pub const NFQA_SKB_CSUMNOTREADY: ::c_int = 0x0001;
2780
pub const NFQA_SKB_GSO: ::c_int = 0x0002;
2781
pub const NFQA_SKB_CSUM_NOTVERIFIED: ::c_int = 0x0004;
2782
2783
// linux/genetlink.h
2784
2785
pub const GENL_NAMSIZ: ::c_int = 16;
2786
2787
pub const GENL_MIN_ID: ::c_int = NLMSG_MIN_TYPE;
2788
pub const GENL_MAX_ID: ::c_int = 1023;
2789
2790
pub const GENL_ADMIN_PERM: ::c_int = 0x01;
2791
pub const GENL_CMD_CAP_DO: ::c_int = 0x02;
2792
pub const GENL_CMD_CAP_DUMP: ::c_int = 0x04;
2793
pub const GENL_CMD_CAP_HASPOL: ::c_int = 0x08;
2794
2795
pub const GENL_ID_CTRL: ::c_int = NLMSG_MIN_TYPE;
2796
2797
pub const CTRL_CMD_UNSPEC: ::c_int = 0;
2798
pub const CTRL_CMD_NEWFAMILY: ::c_int = 1;
2799
pub const CTRL_CMD_DELFAMILY: ::c_int = 2;
2800
pub const CTRL_CMD_GETFAMILY: ::c_int = 3;
2801
pub const CTRL_CMD_NEWOPS: ::c_int = 4;
2802
pub const CTRL_CMD_DELOPS: ::c_int = 5;
2803
pub const CTRL_CMD_GETOPS: ::c_int = 6;
2804
pub const CTRL_CMD_NEWMCAST_GRP: ::c_int = 7;
2805
pub const CTRL_CMD_DELMCAST_GRP: ::c_int = 8;
2806
pub const CTRL_CMD_GETMCAST_GRP: ::c_int = 9;
2807
2808
pub const CTRL_ATTR_UNSPEC: ::c_int = 0;
2809
pub const CTRL_ATTR_FAMILY_ID: ::c_int = 1;
2810
pub const CTRL_ATTR_FAMILY_NAME: ::c_int = 2;
2811
pub const CTRL_ATTR_VERSION: ::c_int = 3;
2812
pub const CTRL_ATTR_HDRSIZE: ::c_int = 4;
2813
pub const CTRL_ATTR_MAXATTR: ::c_int = 5;
2814
pub const CTRL_ATTR_OPS: ::c_int = 6;
2815
pub const CTRL_ATTR_MCAST_GROUPS: ::c_int = 7;
2816
2817
pub const CTRL_ATTR_OP_UNSPEC: ::c_int = 0;
2818
pub const CTRL_ATTR_OP_ID: ::c_int = 1;
2819
pub const CTRL_ATTR_OP_FLAGS: ::c_int = 2;
2820
2821
pub const CTRL_ATTR_MCAST_GRP_UNSPEC: ::c_int = 0;
2822
pub const CTRL_ATTR_MCAST_GRP_NAME: ::c_int = 1;
2823
pub const CTRL_ATTR_MCAST_GRP_ID: ::c_int = 2;
2824
2825
// linux/if_packet.h
2826
pub const PACKET_ADD_MEMBERSHIP: ::c_int = 1;
2827
pub const PACKET_DROP_MEMBERSHIP: ::c_int = 2;
2828
2829
pub const PACKET_MR_MULTICAST: ::c_int = 0;
2830
pub const PACKET_MR_PROMISC: ::c_int = 1;
2831
pub const PACKET_MR_ALLMULTI: ::c_int = 2;
2832
2833
// linux/netfilter.h
2834
pub const NF_DROP: ::c_int = 0;
2835
pub const NF_ACCEPT: ::c_int = 1;
2836
pub const NF_STOLEN: ::c_int = 2;
2837
pub const NF_QUEUE: ::c_int = 3;
2838
pub const NF_REPEAT: ::c_int = 4;
2839
pub const NF_STOP: ::c_int = 5;
2840
pub const NF_MAX_VERDICT: ::c_int = NF_STOP;
2841
2842
pub const NF_VERDICT_MASK: ::c_int = 0x000000ff;
2843
pub const NF_VERDICT_FLAG_QUEUE_BYPASS: ::c_int = 0x00008000;
2844
2845
pub const NF_VERDICT_QMASK: ::c_int = 0xffff0000;
2846
pub const NF_VERDICT_QBITS: ::c_int = 16;
2847
2848
pub const NF_VERDICT_BITS: ::c_int = 16;
2849
2850
pub const NF_INET_PRE_ROUTING: ::c_int = 0;
2851
pub const NF_INET_LOCAL_IN: ::c_int = 1;
2852
pub const NF_INET_FORWARD: ::c_int = 2;
2853
pub const NF_INET_LOCAL_OUT: ::c_int = 3;
2854
pub const NF_INET_POST_ROUTING: ::c_int = 4;
2855
pub const NF_INET_NUMHOOKS: ::c_int = 5;
2856
2857
// Some NFPROTO are not compatible with musl and are defined in submodules.
2858
pub const NFPROTO_UNSPEC: ::c_int = 0;
2859
pub const NFPROTO_IPV4: ::c_int = 2;
2860
pub const NFPROTO_ARP: ::c_int = 3;
2861
pub const NFPROTO_BRIDGE: ::c_int = 7;
2862
pub const NFPROTO_IPV6: ::c_int = 10;
2863
pub const NFPROTO_DECNET: ::c_int = 12;
2864
pub const NFPROTO_NUMPROTO: ::c_int = 13;
2865
pub const NFPROTO_INET: ::c_int = 1;
2866
pub const NFPROTO_NETDEV: ::c_int = 5;
2867
2868
pub const NF_NETDEV_INGRESS: ::c_int = 0;
2869
pub const NF_NETDEV_NUMHOOKS: ::c_int = 1;
2870
2871
// linux/netfilter_ipv4.h
2872
pub const NF_IP_PRE_ROUTING: ::c_int = 0;
2873
pub const NF_IP_LOCAL_IN: ::c_int = 1;
2874
pub const NF_IP_FORWARD: ::c_int = 2;
2875
pub const NF_IP_LOCAL_OUT: ::c_int = 3;
2876
pub const NF_IP_POST_ROUTING: ::c_int = 4;
2877
pub const NF_IP_NUMHOOKS: ::c_int = 5;
2878
2879
pub const NF_IP_PRI_FIRST: ::c_int = ::INT_MIN;
2880
pub const NF_IP_PRI_CONNTRACK_DEFRAG: ::c_int = -400;
2881
pub const NF_IP_PRI_RAW: ::c_int = -300;
2882
pub const NF_IP_PRI_SELINUX_FIRST: ::c_int = -225;
2883
pub const NF_IP_PRI_CONNTRACK: ::c_int = -200;
2884
pub const NF_IP_PRI_MANGLE: ::c_int = -150;
2885
pub const NF_IP_PRI_NAT_DST: ::c_int = -100;
2886
pub const NF_IP_PRI_FILTER: ::c_int = 0;
2887
pub const NF_IP_PRI_SECURITY: ::c_int = 50;
2888
pub const NF_IP_PRI_NAT_SRC: ::c_int = 100;
2889
pub const NF_IP_PRI_SELINUX_LAST: ::c_int = 225;
2890
pub const NF_IP_PRI_CONNTRACK_HELPER: ::c_int = 300;
2891
pub const NF_IP_PRI_CONNTRACK_CONFIRM: ::c_int = ::INT_MAX;
2892
pub const NF_IP_PRI_LAST: ::c_int = ::INT_MAX;
2893
2894
// linux/netfilter_ipv6.h
2895
pub const NF_IP6_PRE_ROUTING: ::c_int = 0;
2896
pub const NF_IP6_LOCAL_IN: ::c_int = 1;
2897
pub const NF_IP6_FORWARD: ::c_int = 2;
2898
pub const NF_IP6_LOCAL_OUT: ::c_int = 3;
2899
pub const NF_IP6_POST_ROUTING: ::c_int = 4;
2900
pub const NF_IP6_NUMHOOKS: ::c_int = 5;
2901
2902
pub const NF_IP6_PRI_FIRST: ::c_int = ::INT_MIN;
2903
pub const NF_IP6_PRI_CONNTRACK_DEFRAG: ::c_int = -400;
2904
pub const NF_IP6_PRI_RAW: ::c_int = -300;
2905
pub const NF_IP6_PRI_SELINUX_FIRST: ::c_int = -225;
2906
pub const NF_IP6_PRI_CONNTRACK: ::c_int = -200;
2907
pub const NF_IP6_PRI_MANGLE: ::c_int = -150;
2908
pub const NF_IP6_PRI_NAT_DST: ::c_int = -100;
2909
pub const NF_IP6_PRI_FILTER: ::c_int = 0;
2910
pub const NF_IP6_PRI_SECURITY: ::c_int = 50;
2911
pub const NF_IP6_PRI_NAT_SRC: ::c_int = 100;
2912
pub const NF_IP6_PRI_SELINUX_LAST: ::c_int = 225;
2913
pub const NF_IP6_PRI_CONNTRACK_HELPER: ::c_int = 300;
2914
pub const NF_IP6_PRI_LAST: ::c_int = ::INT_MAX;
2915
2916
// linux/netfilter_ipv6/ip6_tables.h
2917
pub const IP6T_SO_ORIGINAL_DST: ::c_int = 80;
2918
2919
pub const SIOCADDRT: ::c_ulong = 0x0000890B;
2920
pub const SIOCDELRT: ::c_ulong = 0x0000890C;
2921
pub const SIOCGIFNAME: ::c_ulong = 0x00008910;
2922
pub const SIOCSIFLINK: ::c_ulong = 0x00008911;
2923
pub const SIOCGIFCONF: ::c_ulong = 0x00008912;
2924
pub const SIOCGIFFLAGS: ::c_ulong = 0x00008913;
2925
pub const SIOCSIFFLAGS: ::c_ulong = 0x00008914;
2926
pub const SIOCGIFADDR: ::c_ulong = 0x00008915;
2927
pub const SIOCSIFADDR: ::c_ulong = 0x00008916;
2928
pub const SIOCGIFDSTADDR: ::c_ulong = 0x00008917;
2929
pub const SIOCSIFDSTADDR: ::c_ulong = 0x00008918;
2930
pub const SIOCGIFBRDADDR: ::c_ulong = 0x00008919;
2931
pub const SIOCSIFBRDADDR: ::c_ulong = 0x0000891A;
2932
pub const SIOCGIFNETMASK: ::c_ulong = 0x0000891B;
2933
pub const SIOCSIFNETMASK: ::c_ulong = 0x0000891C;
2934
pub const SIOCGIFMETRIC: ::c_ulong = 0x0000891D;
2935
pub const SIOCSIFMETRIC: ::c_ulong = 0x0000891E;
2936
pub const SIOCGIFMEM: ::c_ulong = 0x0000891F;
2937
pub const SIOCSIFMEM: ::c_ulong = 0x00008920;
2938
pub const SIOCGIFMTU: ::c_ulong = 0x00008921;
2939
pub const SIOCSIFMTU: ::c_ulong = 0x00008922;
2940
pub const SIOCSIFNAME: ::c_ulong = 0x00008923;
2941
pub const SIOCSIFHWADDR: ::c_ulong = 0x00008924;
2942
pub const SIOCGIFENCAP: ::c_ulong = 0x00008925;
2943
pub const SIOCSIFENCAP: ::c_ulong = 0x00008926;
2944
pub const SIOCGIFHWADDR: ::c_ulong = 0x00008927;
2945
pub const SIOCGIFSLAVE: ::c_ulong = 0x00008929;
2946
pub const SIOCSIFSLAVE: ::c_ulong = 0x00008930;
2947
pub const SIOCADDMULTI: ::c_ulong = 0x00008931;
2948
pub const SIOCDELMULTI: ::c_ulong = 0x00008932;
2949
pub const SIOCGIFINDEX: ::c_ulong = 0x00008933;
2950
pub const SIOGIFINDEX: ::c_ulong = SIOCGIFINDEX;
2951
pub const SIOCSIFPFLAGS: ::c_ulong = 0x00008934;
2952
pub const SIOCGIFPFLAGS: ::c_ulong = 0x00008935;
2953
pub const SIOCDIFADDR: ::c_ulong = 0x00008936;
2954
pub const SIOCSIFHWBROADCAST: ::c_ulong = 0x00008937;
2955
pub const SIOCGIFCOUNT: ::c_ulong = 0x00008938;
2956
pub const SIOCGIFBR: ::c_ulong = 0x00008940;
2957
pub const SIOCSIFBR: ::c_ulong = 0x00008941;
2958
pub const SIOCGIFTXQLEN: ::c_ulong = 0x00008942;
2959
pub const SIOCSIFTXQLEN: ::c_ulong = 0x00008943;
2960
pub const SIOCETHTOOL: ::c_ulong = 0x00008946;
2961
pub const SIOCGMIIPHY: ::c_ulong = 0x00008947;
2962
pub const SIOCGMIIREG: ::c_ulong = 0x00008948;
2963
pub const SIOCSMIIREG: ::c_ulong = 0x00008949;
2964
pub const SIOCWANDEV: ::c_ulong = 0x0000894A;
2965
pub const SIOCOUTQNSD: ::c_ulong = 0x0000894B;
2966
pub const SIOCGSKNS: ::c_ulong = 0x0000894C;
2967
pub const SIOCDARP: ::c_ulong = 0x00008953;
2968
pub const SIOCGARP: ::c_ulong = 0x00008954;
2969
pub const SIOCSARP: ::c_ulong = 0x00008955;
2970
pub const SIOCDRARP: ::c_ulong = 0x00008960;
2971
pub const SIOCGRARP: ::c_ulong = 0x00008961;
2972
pub const SIOCSRARP: ::c_ulong = 0x00008962;
2973
pub const SIOCGIFMAP: ::c_ulong = 0x00008970;
2974
pub const SIOCSIFMAP: ::c_ulong = 0x00008971;
2975
pub const SIOCSHWTSTAMP: ::c_ulong = 0x000089b0;
2976
pub const SIOCGHWTSTAMP: ::c_ulong = 0x000089b1;
2977
2978
// wireless.h
2979
pub const WIRELESS_EXT: ::c_ulong = 0x16;
2980
2981
pub const SIOCSIWCOMMIT: ::c_ulong = 0x8B00;
2982
pub const SIOCGIWNAME: ::c_ulong = 0x8B01;
2983
2984
pub const SIOCSIWNWID: ::c_ulong = 0x8B02;
2985
pub const SIOCGIWNWID: ::c_ulong = 0x8B03;
2986
pub const SIOCSIWFREQ: ::c_ulong = 0x8B04;
2987
pub const SIOCGIWFREQ: ::c_ulong = 0x8B05;
2988
pub const SIOCSIWMODE: ::c_ulong = 0x8B06;
2989
pub const SIOCGIWMODE: ::c_ulong = 0x8B07;
2990
pub const SIOCSIWSENS: ::c_ulong = 0x8B08;
2991
pub const SIOCGIWSENS: ::c_ulong = 0x8B09;
2992
2993
pub const SIOCSIWRANGE: ::c_ulong = 0x8B0A;
2994
pub const SIOCGIWRANGE: ::c_ulong = 0x8B0B;
2995
pub const SIOCSIWPRIV: ::c_ulong = 0x8B0C;
2996
pub const SIOCGIWPRIV: ::c_ulong = 0x8B0D;
2997
pub const SIOCSIWSTATS: ::c_ulong = 0x8B0E;
2998
pub const SIOCGIWSTATS: ::c_ulong = 0x8B0F;
2999
3000
pub const SIOCSIWSPY: ::c_ulong = 0x8B10;
3001
pub const SIOCGIWSPY: ::c_ulong = 0x8B11;
3002
pub const SIOCSIWTHRSPY: ::c_ulong = 0x8B12;
3003
pub const SIOCGIWTHRSPY: ::c_ulong = 0x8B13;
3004
3005
pub const SIOCSIWAP: ::c_ulong = 0x8B14;
3006
pub const SIOCGIWAP: ::c_ulong = 0x8B15;
3007
pub const SIOCGIWAPLIST: ::c_ulong = 0x8B17;
3008
pub const SIOCSIWSCAN: ::c_ulong = 0x8B18;
3009
pub const SIOCGIWSCAN: ::c_ulong = 0x8B19;
3010
3011
pub const SIOCSIWESSID: ::c_ulong = 0x8B1A;
3012
pub const SIOCGIWESSID: ::c_ulong = 0x8B1B;
3013
pub const SIOCSIWNICKN: ::c_ulong = 0x8B1C;
3014
pub const SIOCGIWNICKN: ::c_ulong = 0x8B1D;
3015
3016
pub const SIOCSIWRATE: ::c_ulong = 0x8B20;
3017
pub const SIOCGIWRATE: ::c_ulong = 0x8B21;
3018
pub const SIOCSIWRTS: ::c_ulong = 0x8B22;
3019
pub const SIOCGIWRTS: ::c_ulong = 0x8B23;
3020
pub const SIOCSIWFRAG: ::c_ulong = 0x8B24;
3021
pub const SIOCGIWFRAG: ::c_ulong = 0x8B25;
3022
pub const SIOCSIWTXPOW: ::c_ulong = 0x8B26;
3023
pub const SIOCGIWTXPOW: ::c_ulong = 0x8B27;
3024
pub const SIOCSIWRETRY: ::c_ulong = 0x8B28;
3025
pub const SIOCGIWRETRY: ::c_ulong = 0x8B29;
3026
3027
pub const SIOCSIWENCODE: ::c_ulong = 0x8B2A;
3028
pub const SIOCGIWENCODE: ::c_ulong = 0x8B2B;
3029
3030
pub const SIOCSIWPOWER: ::c_ulong = 0x8B2C;
3031
pub const SIOCGIWPOWER: ::c_ulong = 0x8B2D;
3032
3033
pub const SIOCSIWGENIE: ::c_ulong = 0x8B30;
3034
pub const SIOCGIWGENIE: ::c_ulong = 0x8B31;
3035
3036
pub const SIOCSIWMLME: ::c_ulong = 0x8B16;
3037
3038
pub const SIOCSIWAUTH: ::c_ulong = 0x8B32;
3039
pub const SIOCGIWAUTH: ::c_ulong = 0x8B33;
3040
3041
pub const SIOCSIWENCODEEXT: ::c_ulong = 0x8B34;
3042
pub const SIOCGIWENCODEEXT: ::c_ulong = 0x8B35;
3043
3044
pub const SIOCSIWPMKSA: ::c_ulong = 0x8B36;
3045
3046
pub const SIOCIWFIRSTPRIV: ::c_ulong = 0x8BE0;
3047
pub const SIOCIWLASTPRIV: ::c_ulong = 0x8BFF;
3048
3049
pub const SIOCIWFIRST: ::c_ulong = 0x8B00;
3050
pub const SIOCIWLAST: ::c_ulong = SIOCIWLASTPRIV;
3051
3052
pub const IWEVTXDROP: ::c_ulong = 0x8C00;
3053
pub const IWEVQUAL: ::c_ulong = 0x8C01;
3054
pub const IWEVCUSTOM: ::c_ulong = 0x8C02;
3055
pub const IWEVREGISTERED: ::c_ulong = 0x8C03;
3056
pub const IWEVEXPIRED: ::c_ulong = 0x8C04;
3057
pub const IWEVGENIE: ::c_ulong = 0x8C05;
3058
pub const IWEVMICHAELMICFAILURE: ::c_ulong = 0x8C06;
3059
pub const IWEVASSOCREQIE: ::c_ulong = 0x8C07;
3060
pub const IWEVASSOCRESPIE: ::c_ulong = 0x8C08;
3061
pub const IWEVPMKIDCAND: ::c_ulong = 0x8C09;
3062
pub const IWEVFIRST: ::c_ulong = 0x8C00;
3063
3064
pub const IW_PRIV_TYPE_MASK: ::c_ulong = 0x7000;
3065
pub const IW_PRIV_TYPE_NONE: ::c_ulong = 0x0000;
3066
pub const IW_PRIV_TYPE_BYTE: ::c_ulong = 0x1000;
3067
pub const IW_PRIV_TYPE_CHAR: ::c_ulong = 0x2000;
3068
pub const IW_PRIV_TYPE_INT: ::c_ulong = 0x4000;
3069
pub const IW_PRIV_TYPE_FLOAT: ::c_ulong = 0x5000;
3070
pub const IW_PRIV_TYPE_ADDR: ::c_ulong = 0x6000;
3071
3072
pub const IW_PRIV_SIZE_FIXED: ::c_ulong = 0x0800;
3073
3074
pub const IW_PRIV_SIZE_MASK: ::c_ulong = 0x07FF;
3075
3076
pub const IW_MAX_FREQUENCIES: usize = 32;
3077
pub const IW_MAX_BITRATES: usize = 32;
3078
pub const IW_MAX_TXPOWER: usize = 8;
3079
pub const IW_MAX_SPY: usize = 8;
3080
pub const IW_MAX_AP: usize = 64;
3081
pub const IW_ESSID_MAX_SIZE: usize = 32;
3082
3083
pub const IW_MODE_AUTO: usize = 0;
3084
pub const IW_MODE_ADHOC: usize = 1;
3085
pub const IW_MODE_INFRA: usize = 2;
3086
pub const IW_MODE_MASTER: usize = 3;
3087
pub const IW_MODE_REPEAT: usize = 4;
3088
pub const IW_MODE_SECOND: usize = 5;
3089
pub const IW_MODE_MONITOR: usize = 6;
3090
pub const IW_MODE_MESH: usize = 7;
3091
3092
pub const IW_QUAL_QUAL_UPDATED: ::c_ulong = 0x01;
3093
pub const IW_QUAL_LEVEL_UPDATED: ::c_ulong = 0x02;
3094
pub const IW_QUAL_NOISE_UPDATED: ::c_ulong = 0x04;
3095
pub const IW_QUAL_ALL_UPDATED: ::c_ulong = 0x07;
3096
pub const IW_QUAL_DBM: ::c_ulong = 0x08;
3097
pub const IW_QUAL_QUAL_INVALID: ::c_ulong = 0x10;
3098
pub const IW_QUAL_LEVEL_INVALID: ::c_ulong = 0x20;
3099
pub const IW_QUAL_NOISE_INVALID: ::c_ulong = 0x40;
3100
pub const IW_QUAL_RCPI: ::c_ulong = 0x80;
3101
pub const IW_QUAL_ALL_INVALID: ::c_ulong = 0x70;
3102
3103
pub const IW_FREQ_AUTO: ::c_ulong = 0x00;
3104
pub const IW_FREQ_FIXED: ::c_ulong = 0x01;
3105
3106
pub const IW_MAX_ENCODING_SIZES: usize = 8;
3107
pub const IW_ENCODING_TOKEN_MAX: usize = 64;
3108
3109
pub const IW_ENCODE_INDEX: ::c_ulong = 0x00FF;
3110
pub const IW_ENCODE_FLAGS: ::c_ulong = 0xFF00;
3111
pub const IW_ENCODE_MODE: ::c_ulong = 0xF000;
3112
pub const IW_ENCODE_DISABLED: ::c_ulong = 0x8000;
3113
pub const IW_ENCODE_ENABLED: ::c_ulong = 0x0000;
3114
pub const IW_ENCODE_RESTRICTED: ::c_ulong = 0x4000;
3115
pub const IW_ENCODE_OPEN: ::c_ulong = 0x2000;
3116
pub const IW_ENCODE_NOKEY: ::c_ulong = 0x0800;
3117
pub const IW_ENCODE_TEMP: ::c_ulong = 0x0400;
3118
3119
pub const IW_POWER_ON: ::c_ulong = 0x0000;
3120
pub const IW_POWER_TYPE: ::c_ulong = 0xF000;
3121
pub const IW_POWER_PERIOD: ::c_ulong = 0x1000;
3122
pub const IW_POWER_TIMEOUT: ::c_ulong = 0x2000;
3123
pub const IW_POWER_MODE: ::c_ulong = 0x0F00;
3124
pub const IW_POWER_UNICAST_R: ::c_ulong = 0x0100;
3125
pub const IW_POWER_MULTICAST_R: ::c_ulong = 0x0200;
3126
pub const IW_POWER_ALL_R: ::c_ulong = 0x0300;
3127
pub const IW_POWER_FORCE_S: ::c_ulong = 0x0400;
3128
pub const IW_POWER_REPEATER: ::c_ulong = 0x0800;
3129
pub const IW_POWER_MODIFIER: ::c_ulong = 0x000F;
3130
pub const IW_POWER_MIN: ::c_ulong = 0x0001;
3131
pub const IW_POWER_MAX: ::c_ulong = 0x0002;
3132
pub const IW_POWER_RELATIVE: ::c_ulong = 0x0004;
3133
3134
pub const IW_TXPOW_TYPE: ::c_ulong = 0x00FF;
3135
pub const IW_TXPOW_DBM: ::c_ulong = 0x0000;
3136
pub const IW_TXPOW_MWATT: ::c_ulong = 0x0001;
3137
pub const IW_TXPOW_RELATIVE: ::c_ulong = 0x0002;
3138
pub const IW_TXPOW_RANGE: ::c_ulong = 0x1000;
3139
3140
pub const IW_RETRY_ON: ::c_ulong = 0x0000;
3141
pub const IW_RETRY_TYPE: ::c_ulong = 0xF000;
3142
pub const IW_RETRY_LIMIT: ::c_ulong = 0x1000;
3143
pub const IW_RETRY_LIFETIME: ::c_ulong = 0x2000;
3144
pub const IW_RETRY_MODIFIER: ::c_ulong = 0x00FF;
3145
pub const IW_RETRY_MIN: ::c_ulong = 0x0001;
3146
pub const IW_RETRY_MAX: ::c_ulong = 0x0002;
3147
pub const IW_RETRY_RELATIVE: ::c_ulong = 0x0004;
3148
pub const IW_RETRY_SHORT: ::c_ulong = 0x0010;
3149
pub const IW_RETRY_LONG: ::c_ulong = 0x0020;
3150
3151
pub const IW_SCAN_DEFAULT: ::c_ulong = 0x0000;
3152
pub const IW_SCAN_ALL_ESSID: ::c_ulong = 0x0001;
3153
pub const IW_SCAN_THIS_ESSID: ::c_ulong = 0x0002;
3154
pub const IW_SCAN_ALL_FREQ: ::c_ulong = 0x0004;
3155
pub const IW_SCAN_THIS_FREQ: ::c_ulong = 0x0008;
3156
pub const IW_SCAN_ALL_MODE: ::c_ulong = 0x0010;
3157
pub const IW_SCAN_THIS_MODE: ::c_ulong = 0x0020;
3158
pub const IW_SCAN_ALL_RATE: ::c_ulong = 0x0040;
3159
pub const IW_SCAN_THIS_RATE: ::c_ulong = 0x0080;
3160
3161
pub const IW_SCAN_TYPE_ACTIVE: usize = 0;
3162
pub const IW_SCAN_TYPE_PASSIVE: usize = 1;
3163
3164
pub const IW_SCAN_MAX_DATA: usize = 4096;
3165
3166
pub const IW_SCAN_CAPA_NONE: ::c_ulong = 0x00;
3167
pub const IW_SCAN_CAPA_ESSID: ::c_ulong = 0x01;
3168
pub const IW_SCAN_CAPA_BSSID: ::c_ulong = 0x02;
3169
pub const IW_SCAN_CAPA_CHANNEL: ::c_ulong = 0x04;
3170
pub const IW_SCAN_CAPA_MODE: ::c_ulong = 0x08;
3171
pub const IW_SCAN_CAPA_RATE: ::c_ulong = 0x10;
3172
pub const IW_SCAN_CAPA_TYPE: ::c_ulong = 0x20;
3173
pub const IW_SCAN_CAPA_TIME: ::c_ulong = 0x40;
3174
3175
pub const IW_CUSTOM_MAX: ::c_ulong = 256;
3176
3177
pub const IW_GENERIC_IE_MAX: ::c_ulong = 1024;
3178
3179
pub const IW_MLME_DEAUTH: ::c_ulong = 0;
3180
pub const IW_MLME_DISASSOC: ::c_ulong = 1;
3181
pub const IW_MLME_AUTH: ::c_ulong = 2;
3182
pub const IW_MLME_ASSOC: ::c_ulong = 3;
3183
3184
pub const IW_AUTH_INDEX: ::c_ulong = 0x0FFF;
3185
pub const IW_AUTH_FLAGS: ::c_ulong = 0xF000;
3186
3187
pub const IW_AUTH_WPA_VERSION: usize = 0;
3188
pub const IW_AUTH_CIPHER_PAIRWISE: usize = 1;
3189
pub const IW_AUTH_CIPHER_GROUP: usize = 2;
3190
pub const IW_AUTH_KEY_MGMT: usize = 3;
3191
pub const IW_AUTH_TKIP_COUNTERMEASURES: usize = 4;
3192
pub const IW_AUTH_DROP_UNENCRYPTED: usize = 5;
3193
pub const IW_AUTH_80211_AUTH_ALG: usize = 6;
3194
pub const IW_AUTH_WPA_ENABLED: usize = 7;
3195
pub const IW_AUTH_RX_UNENCRYPTED_EAPOL: usize = 8;
3196
pub const IW_AUTH_ROAMING_CONTROL: usize = 9;
3197
pub const IW_AUTH_PRIVACY_INVOKED: usize = 10;
3198
pub const IW_AUTH_CIPHER_GROUP_MGMT: usize = 11;
3199
pub const IW_AUTH_MFP: usize = 12;
3200
3201
pub const IW_AUTH_WPA_VERSION_DISABLED: ::c_ulong = 0x00000001;
3202
pub const IW_AUTH_WPA_VERSION_WPA: ::c_ulong = 0x00000002;
3203
pub const IW_AUTH_WPA_VERSION_WPA2: ::c_ulong = 0x00000004;
3204
3205
pub const IW_AUTH_CIPHER_NONE: ::c_ulong = 0x00000001;
3206
pub const IW_AUTH_CIPHER_WEP40: ::c_ulong = 0x00000002;
3207
pub const IW_AUTH_CIPHER_TKIP: ::c_ulong = 0x00000004;
3208
pub const IW_AUTH_CIPHER_CCMP: ::c_ulong = 0x00000008;
3209
pub const IW_AUTH_CIPHER_WEP104: ::c_ulong = 0x00000010;
3210
pub const IW_AUTH_CIPHER_AES_CMAC: ::c_ulong = 0x00000020;
3211
3212
pub const IW_AUTH_KEY_MGMT_802_1X: usize = 1;
3213
pub const IW_AUTH_KEY_MGMT_PSK: usize = 2;
3214
3215
pub const IW_AUTH_ALG_OPEN_SYSTEM: ::c_ulong = 0x00000001;
3216
pub const IW_AUTH_ALG_SHARED_KEY: ::c_ulong = 0x00000002;
3217
pub const IW_AUTH_ALG_LEAP: ::c_ulong = 0x00000004;
3218
3219
pub const IW_AUTH_ROAMING_ENABLE: usize = 0;
3220
pub const IW_AUTH_ROAMING_DISABLE: usize = 1;
3221
3222
pub const IW_AUTH_MFP_DISABLED: usize = 0;
3223
pub const IW_AUTH_MFP_OPTIONAL: usize = 1;
3224
pub const IW_AUTH_MFP_REQUIRED: usize = 2;
3225
3226
pub const IW_ENCODE_SEQ_MAX_SIZE: usize = 8;
3227
3228
pub const IW_ENCODE_ALG_NONE: usize = 0;
3229
pub const IW_ENCODE_ALG_WEP: usize = 1;
3230
pub const IW_ENCODE_ALG_TKIP: usize = 2;
3231
pub const IW_ENCODE_ALG_CCMP: usize = 3;
3232
pub const IW_ENCODE_ALG_PMK: usize = 4;
3233
pub const IW_ENCODE_ALG_AES_CMAC: usize = 5;
3234
3235
pub const IW_ENCODE_EXT_TX_SEQ_VALID: ::c_ulong = 0x00000001;
3236
pub const IW_ENCODE_EXT_RX_SEQ_VALID: ::c_ulong = 0x00000002;
3237
pub const IW_ENCODE_EXT_GROUP_KEY: ::c_ulong = 0x00000004;
3238
pub const IW_ENCODE_EXT_SET_TX_KEY: ::c_ulong = 0x00000008;
3239
3240
pub const IW_MICFAILURE_KEY_ID: ::c_ulong = 0x00000003;
3241
pub const IW_MICFAILURE_GROUP: ::c_ulong = 0x00000004;
3242
pub const IW_MICFAILURE_PAIRWISE: ::c_ulong = 0x00000008;
3243
pub const IW_MICFAILURE_STAKEY: ::c_ulong = 0x00000010;
3244
pub const IW_MICFAILURE_COUNT: ::c_ulong = 0x00000060;
3245
3246
pub const IW_ENC_CAPA_WPA: ::c_ulong = 0x00000001;
3247
pub const IW_ENC_CAPA_WPA2: ::c_ulong = 0x00000002;
3248
pub const IW_ENC_CAPA_CIPHER_TKIP: ::c_ulong = 0x00000004;
3249
pub const IW_ENC_CAPA_CIPHER_CCMP: ::c_ulong = 0x00000008;
3250
pub const IW_ENC_CAPA_4WAY_HANDSHAKE: ::c_ulong = 0x00000010;
3251
3252
pub const IW_PMKSA_ADD: usize = 1;
3253
pub const IW_PMKSA_REMOVE: usize = 2;
3254
pub const IW_PMKSA_FLUSH: usize = 3;
3255
3256
pub const IW_PMKID_LEN: usize = 16;
3257
3258
pub const IW_PMKID_CAND_PREAUTH: ::c_ulong = 0x00000001;
3259
3260
pub const IW_EV_LCP_PK_LEN: usize = 4;
3261
3262
pub const IW_EV_CHAR_PK_LEN: usize = IW_EV_LCP_PK_LEN + ::IFNAMSIZ;
3263
pub const IW_EV_POINT_PK_LEN: usize = IW_EV_LCP_PK_LEN + 4;
3264
3265
pub const IPTOS_TOS_MASK: u8 = 0x1E;
3266
pub const IPTOS_PREC_MASK: u8 = 0xE0;
3267
3268
pub const IPTOS_ECN_NOT_ECT: u8 = 0x00;
3269
3270
pub const RTF_UP: ::c_ushort = 0x0001;
3271
pub const RTF_GATEWAY: ::c_ushort = 0x0002;
3272
3273
pub const RTF_HOST: ::c_ushort = 0x0004;
3274
pub const RTF_REINSTATE: ::c_ushort = 0x0008;
3275
pub const RTF_DYNAMIC: ::c_ushort = 0x0010;
3276
pub const RTF_MODIFIED: ::c_ushort = 0x0020;
3277
pub const RTF_MTU: ::c_ushort = 0x0040;
3278
pub const RTF_MSS: ::c_ushort = RTF_MTU;
3279
pub const RTF_WINDOW: ::c_ushort = 0x0080;
3280
pub const RTF_IRTT: ::c_ushort = 0x0100;
3281
pub const RTF_REJECT: ::c_ushort = 0x0200;
3282
pub const RTF_STATIC: ::c_ushort = 0x0400;
3283
pub const RTF_XRESOLVE: ::c_ushort = 0x0800;
3284
pub const RTF_NOFORWARD: ::c_ushort = 0x1000;
3285
pub const RTF_THROW: ::c_ushort = 0x2000;
3286
pub const RTF_NOPMTUDISC: ::c_ushort = 0x4000;
3287
3288
pub const RTF_DEFAULT: u32 = 0x00010000;
3289
pub const RTF_ALLONLINK: u32 = 0x00020000;
3290
pub const RTF_ADDRCONF: u32 = 0x00040000;
3291
pub const RTF_LINKRT: u32 = 0x00100000;
3292
pub const RTF_NONEXTHOP: u32 = 0x00200000;
3293
pub const RTF_CACHE: u32 = 0x01000000;
3294
pub const RTF_FLOW: u32 = 0x02000000;
3295
pub const RTF_POLICY: u32 = 0x04000000;
3296
3297
pub const RTCF_VALVE: u32 = 0x00200000;
3298
pub const RTCF_MASQ: u32 = 0x00400000;
3299
pub const RTCF_NAT: u32 = 0x00800000;
3300
pub const RTCF_DOREDIRECT: u32 = 0x01000000;
3301
pub const RTCF_LOG: u32 = 0x02000000;
3302
pub const RTCF_DIRECTSRC: u32 = 0x04000000;
3303
3304
pub const RTF_LOCAL: u32 = 0x80000000;
3305
pub const RTF_INTERFACE: u32 = 0x40000000;
3306
pub const RTF_MULTICAST: u32 = 0x20000000;
3307
pub const RTF_BROADCAST: u32 = 0x10000000;
3308
pub const RTF_NAT: u32 = 0x08000000;
3309
pub const RTF_ADDRCLASSMASK: u32 = 0xF8000000;
3310
3311
pub const RT_CLASS_UNSPEC: u8 = 0;
3312
pub const RT_CLASS_DEFAULT: u8 = 253;
3313
pub const RT_CLASS_MAIN: u8 = 254;
3314
pub const RT_CLASS_LOCAL: u8 = 255;
3315
pub const RT_CLASS_MAX: u8 = 255;
3316
3317
// linux/neighbor.h
3318
pub const NUD_NONE: u16 = 0x00;
3319
pub const NUD_INCOMPLETE: u16 = 0x01;
3320
pub const NUD_REACHABLE: u16 = 0x02;
3321
pub const NUD_STALE: u16 = 0x04;
3322
pub const NUD_DELAY: u16 = 0x08;
3323
pub const NUD_PROBE: u16 = 0x10;
3324
pub const NUD_FAILED: u16 = 0x20;
3325
pub const NUD_NOARP: u16 = 0x40;
3326
pub const NUD_PERMANENT: u16 = 0x80;
3327
3328
pub const NTF_USE: u8 = 0x01;
3329
pub const NTF_SELF: u8 = 0x02;
3330
pub const NTF_MASTER: u8 = 0x04;
3331
pub const NTF_PROXY: u8 = 0x08;
3332
pub const NTF_ROUTER: u8 = 0x80;
3333
3334
pub const NDA_UNSPEC: ::c_ushort = 0;
3335
pub const NDA_DST: ::c_ushort = 1;
3336
pub const NDA_LLADDR: ::c_ushort = 2;
3337
pub const NDA_CACHEINFO: ::c_ushort = 3;
3338
pub const NDA_PROBES: ::c_ushort = 4;
3339
pub const NDA_VLAN: ::c_ushort = 5;
3340
pub const NDA_PORT: ::c_ushort = 6;
3341
pub const NDA_VNI: ::c_ushort = 7;
3342
pub const NDA_IFINDEX: ::c_ushort = 8;
3343
3344
// linux/netlink.h
3345
pub const NLA_ALIGNTO: ::c_int = 4;
3346
3347
pub const NETLINK_ROUTE: ::c_int = 0;
3348
pub const NETLINK_UNUSED: ::c_int = 1;
3349
pub const NETLINK_USERSOCK: ::c_int = 2;
3350
pub const NETLINK_FIREWALL: ::c_int = 3;
3351
pub const NETLINK_SOCK_DIAG: ::c_int = 4;
3352
pub const NETLINK_NFLOG: ::c_int = 5;
3353
pub const NETLINK_XFRM: ::c_int = 6;
3354
pub const NETLINK_SELINUX: ::c_int = 7;
3355
pub const NETLINK_ISCSI: ::c_int = 8;
3356
pub const NETLINK_AUDIT: ::c_int = 9;
3357
pub const NETLINK_FIB_LOOKUP: ::c_int = 10;
3358
pub const NETLINK_CONNECTOR: ::c_int = 11;
3359
pub const NETLINK_NETFILTER: ::c_int = 12;
3360
pub const NETLINK_IP6_FW: ::c_int = 13;
3361
pub const NETLINK_DNRTMSG: ::c_int = 14;
3362
pub const NETLINK_KOBJECT_UEVENT: ::c_int = 15;
3363
pub const NETLINK_GENERIC: ::c_int = 16;
3364
pub const NETLINK_SCSITRANSPORT: ::c_int = 18;
3365
pub const NETLINK_ECRYPTFS: ::c_int = 19;
3366
pub const NETLINK_RDMA: ::c_int = 20;
3367
pub const NETLINK_CRYPTO: ::c_int = 21;
3368
pub const NETLINK_INET_DIAG: ::c_int = NETLINK_SOCK_DIAG;
3369
3370
pub const NLM_F_REQUEST: ::c_int = 1;
3371
pub const NLM_F_MULTI: ::c_int = 2;
3372
pub const NLM_F_ACK: ::c_int = 4;
3373
pub const NLM_F_ECHO: ::c_int = 8;
3374
pub const NLM_F_DUMP_INTR: ::c_int = 16;
3375
pub const NLM_F_DUMP_FILTERED: ::c_int = 32;
3376
3377
pub const NLM_F_ROOT: ::c_int = 0x100;
3378
pub const NLM_F_MATCH: ::c_int = 0x200;
3379
pub const NLM_F_ATOMIC: ::c_int = 0x400;
3380
pub const NLM_F_DUMP: ::c_int = NLM_F_ROOT | NLM_F_MATCH;
3381
3382
pub const NLM_F_REPLACE: ::c_int = 0x100;
3383
pub const NLM_F_EXCL: ::c_int = 0x200;
3384
pub const NLM_F_CREATE: ::c_int = 0x400;
3385
pub const NLM_F_APPEND: ::c_int = 0x800;
3386
3387
pub const NETLINK_ADD_MEMBERSHIP: ::c_int = 1;
3388
pub const NETLINK_DROP_MEMBERSHIP: ::c_int = 2;
3389
pub const NETLINK_PKTINFO: ::c_int = 3;
3390
pub const NETLINK_BROADCAST_ERROR: ::c_int = 4;
3391
pub const NETLINK_NO_ENOBUFS: ::c_int = 5;
3392
pub const NETLINK_RX_RING: ::c_int = 6;
3393
pub const NETLINK_TX_RING: ::c_int = 7;
3394
pub const NETLINK_LISTEN_ALL_NSID: ::c_int = 8;
3395
pub const NETLINK_LIST_MEMBERSHIPS: ::c_int = 9;
3396
pub const NETLINK_CAP_ACK: ::c_int = 10;
3397
pub const NETLINK_EXT_ACK: ::c_int = 11;
3398
pub const NETLINK_GET_STRICT_CHK: ::c_int = 12;
3399
3400
pub const NLA_F_NESTED: ::c_int = 1 << 15;
3401
pub const NLA_F_NET_BYTEORDER: ::c_int = 1 << 14;
3402
pub const NLA_TYPE_MASK: ::c_int = !(NLA_F_NESTED | NLA_F_NET_BYTEORDER);
3403
3404
// linux/rtnetlink.h
3405
pub const TCA_UNSPEC: ::c_ushort = 0;
3406
pub const TCA_KIND: ::c_ushort = 1;
3407
pub const TCA_OPTIONS: ::c_ushort = 2;
3408
pub const TCA_STATS: ::c_ushort = 3;
3409
pub const TCA_XSTATS: ::c_ushort = 4;
3410
pub const TCA_RATE: ::c_ushort = 5;
3411
pub const TCA_FCNT: ::c_ushort = 6;
3412
pub const TCA_STATS2: ::c_ushort = 7;
3413
pub const TCA_STAB: ::c_ushort = 8;
3414
3415
pub const RTM_NEWLINK: u16 = 16;
3416
pub const RTM_DELLINK: u16 = 17;
3417
pub const RTM_GETLINK: u16 = 18;
3418
pub const RTM_SETLINK: u16 = 19;
3419
pub const RTM_NEWADDR: u16 = 20;
3420
pub const RTM_DELADDR: u16 = 21;
3421
pub const RTM_GETADDR: u16 = 22;
3422
pub const RTM_NEWROUTE: u16 = 24;
3423
pub const RTM_DELROUTE: u16 = 25;
3424
pub const RTM_GETROUTE: u16 = 26;
3425
pub const RTM_NEWNEIGH: u16 = 28;
3426
pub const RTM_DELNEIGH: u16 = 29;
3427
pub const RTM_GETNEIGH: u16 = 30;
3428
pub const RTM_NEWRULE: u16 = 32;
3429
pub const RTM_DELRULE: u16 = 33;
3430
pub const RTM_GETRULE: u16 = 34;
3431
pub const RTM_NEWQDISC: u16 = 36;
3432
pub const RTM_DELQDISC: u16 = 37;
3433
pub const RTM_GETQDISC: u16 = 38;
3434
pub const RTM_NEWTCLASS: u16 = 40;
3435
pub const RTM_DELTCLASS: u16 = 41;
3436
pub const RTM_GETTCLASS: u16 = 42;
3437
pub const RTM_NEWTFILTER: u16 = 44;
3438
pub const RTM_DELTFILTER: u16 = 45;
3439
pub const RTM_GETTFILTER: u16 = 46;
3440
pub const RTM_NEWACTION: u16 = 48;
3441
pub const RTM_DELACTION: u16 = 49;
3442
pub const RTM_GETACTION: u16 = 50;
3443
pub const RTM_NEWPREFIX: u16 = 52;
3444
pub const RTM_GETMULTICAST: u16 = 58;
3445
pub const RTM_GETANYCAST: u16 = 62;
3446
pub const RTM_NEWNEIGHTBL: u16 = 64;
3447
pub const RTM_GETNEIGHTBL: u16 = 66;
3448
pub const RTM_SETNEIGHTBL: u16 = 67;
3449
pub const RTM_NEWNDUSEROPT: u16 = 68;
3450
pub const RTM_NEWADDRLABEL: u16 = 72;
3451
pub const RTM_DELADDRLABEL: u16 = 73;
3452
pub const RTM_GETADDRLABEL: u16 = 74;
3453
pub const RTM_GETDCB: u16 = 78;
3454
pub const RTM_SETDCB: u16 = 79;
3455
pub const RTM_NEWNETCONF: u16 = 80;
3456
pub const RTM_GETNETCONF: u16 = 82;
3457
pub const RTM_NEWMDB: u16 = 84;
3458
pub const RTM_DELMDB: u16 = 85;
3459
pub const RTM_GETMDB: u16 = 86;
3460
pub const RTM_NEWNSID: u16 = 88;
3461
pub const RTM_DELNSID: u16 = 89;
3462
pub const RTM_GETNSID: u16 = 90;
3463
3464
pub const RTM_F_NOTIFY: ::c_uint = 0x100;
3465
pub const RTM_F_CLONED: ::c_uint = 0x200;
3466
pub const RTM_F_EQUALIZE: ::c_uint = 0x400;
3467
pub const RTM_F_PREFIX: ::c_uint = 0x800;
3468
3469
pub const RTA_UNSPEC: ::c_ushort = 0;
3470
pub const RTA_DST: ::c_ushort = 1;
3471
pub const RTA_SRC: ::c_ushort = 2;
3472
pub const RTA_IIF: ::c_ushort = 3;
3473
pub const RTA_OIF: ::c_ushort = 4;
3474
pub const RTA_GATEWAY: ::c_ushort = 5;
3475
pub const RTA_PRIORITY: ::c_ushort = 6;
3476
pub const RTA_PREFSRC: ::c_ushort = 7;
3477
pub const RTA_METRICS: ::c_ushort = 8;
3478
pub const RTA_MULTIPATH: ::c_ushort = 9;
3479
pub const RTA_PROTOINFO: ::c_ushort = 10; // No longer used
3480
pub const RTA_FLOW: ::c_ushort = 11;
3481
pub const RTA_CACHEINFO: ::c_ushort = 12;
3482
pub const RTA_SESSION: ::c_ushort = 13; // No longer used
3483
pub const RTA_MP_ALGO: ::c_ushort = 14; // No longer used
3484
pub const RTA_TABLE: ::c_ushort = 15;
3485
pub const RTA_MARK: ::c_ushort = 16;
3486
pub const RTA_MFC_STATS: ::c_ushort = 17;
3487
3488
pub const RTN_UNSPEC: ::c_uchar = 0;
3489
pub const RTN_UNICAST: ::c_uchar = 1;
3490
pub const RTN_LOCAL: ::c_uchar = 2;
3491
pub const RTN_BROADCAST: ::c_uchar = 3;
3492
pub const RTN_ANYCAST: ::c_uchar = 4;
3493
pub const RTN_MULTICAST: ::c_uchar = 5;
3494
pub const RTN_BLACKHOLE: ::c_uchar = 6;
3495
pub const RTN_UNREACHABLE: ::c_uchar = 7;
3496
pub const RTN_PROHIBIT: ::c_uchar = 8;
3497
pub const RTN_THROW: ::c_uchar = 9;
3498
pub const RTN_NAT: ::c_uchar = 10;
3499
pub const RTN_XRESOLVE: ::c_uchar = 11;
3500
3501
pub const RTPROT_UNSPEC: ::c_uchar = 0;
3502
pub const RTPROT_REDIRECT: ::c_uchar = 1;
3503
pub const RTPROT_KERNEL: ::c_uchar = 2;
3504
pub const RTPROT_BOOT: ::c_uchar = 3;
3505
pub const RTPROT_STATIC: ::c_uchar = 4;
3506
3507
pub const RT_SCOPE_UNIVERSE: ::c_uchar = 0;
3508
pub const RT_SCOPE_SITE: ::c_uchar = 200;
3509
pub const RT_SCOPE_LINK: ::c_uchar = 253;
3510
pub const RT_SCOPE_HOST: ::c_uchar = 254;
3511
pub const RT_SCOPE_NOWHERE: ::c_uchar = 255;
3512
3513
pub const RT_TABLE_UNSPEC: ::c_uchar = 0;
3514
pub const RT_TABLE_COMPAT: ::c_uchar = 252;
3515
pub const RT_TABLE_DEFAULT: ::c_uchar = 253;
3516
pub const RT_TABLE_MAIN: ::c_uchar = 254;
3517
pub const RT_TABLE_LOCAL: ::c_uchar = 255;
3518
3519
pub const RTMSG_OVERRUN: u32 = ::NLMSG_OVERRUN as u32;
3520
pub const RTMSG_NEWDEVICE: u32 = 0x11;
3521
pub const RTMSG_DELDEVICE: u32 = 0x12;
3522
pub const RTMSG_NEWROUTE: u32 = 0x21;
3523
pub const RTMSG_DELROUTE: u32 = 0x22;
3524
pub const RTMSG_NEWRULE: u32 = 0x31;
3525
pub const RTMSG_DELRULE: u32 = 0x32;
3526
pub const RTMSG_CONTROL: u32 = 0x40;
3527
pub const RTMSG_AR_FAILED: u32 = 0x51;
3528
3529
pub const MAX_ADDR_LEN: usize = 7;
3530
pub const ARPD_UPDATE: ::c_ushort = 0x01;
3531
pub const ARPD_LOOKUP: ::c_ushort = 0x02;
3532
pub const ARPD_FLUSH: ::c_ushort = 0x03;
3533
pub const ATF_MAGIC: ::c_int = 0x80;
3534
3535
pub const RTEXT_FILTER_VF: ::c_int = 1 << 0;
3536
pub const RTEXT_FILTER_BRVLAN: ::c_int = 1 << 1;
3537
pub const RTEXT_FILTER_BRVLAN_COMPRESSED: ::c_int = 1 << 2;
3538
pub const RTEXT_FILTER_SKIP_STATS: ::c_int = 1 << 3;
3539
pub const RTEXT_FILTER_MRP: ::c_int = 1 << 4;
3540
pub const RTEXT_FILTER_CFM_CONFIG: ::c_int = 1 << 5;
3541
pub const RTEXT_FILTER_CFM_STATUS: ::c_int = 1 << 6;
3542
3543
// userspace compat definitions for RTNLGRP_*
3544
pub const RTMGRP_LINK: ::c_int = 0x00001;
3545
pub const RTMGRP_NOTIFY: ::c_int = 0x00002;
3546
pub const RTMGRP_NEIGH: ::c_int = 0x00004;
3547
pub const RTMGRP_TC: ::c_int = 0x00008;
3548
pub const RTMGRP_IPV4_IFADDR: ::c_int = 0x00010;
3549
pub const RTMGRP_IPV4_MROUTE: ::c_int = 0x00020;
3550
pub const RTMGRP_IPV4_ROUTE: ::c_int = 0x00040;
3551
pub const RTMGRP_IPV4_RULE: ::c_int = 0x00080;
3552
pub const RTMGRP_IPV6_IFADDR: ::c_int = 0x00100;
3553
pub const RTMGRP_IPV6_MROUTE: ::c_int = 0x00200;
3554
pub const RTMGRP_IPV6_ROUTE: ::c_int = 0x00400;
3555
pub const RTMGRP_IPV6_IFINFO: ::c_int = 0x00800;
3556
pub const RTMGRP_DECnet_IFADDR: ::c_int = 0x01000;
3557
pub const RTMGRP_DECnet_ROUTE: ::c_int = 0x04000;
3558
pub const RTMGRP_IPV6_PREFIX: ::c_int = 0x20000;
3559
3560
// enum rtnetlink_groups
3561
pub const RTNLGRP_NONE: ::c_uint = 0x00;
3562
pub const RTNLGRP_LINK: ::c_uint = 0x01;
3563
pub const RTNLGRP_NOTIFY: ::c_uint = 0x02;
3564
pub const RTNLGRP_NEIGH: ::c_uint = 0x03;
3565
pub const RTNLGRP_TC: ::c_uint = 0x04;
3566
pub const RTNLGRP_IPV4_IFADDR: ::c_uint = 0x05;
3567
pub const RTNLGRP_IPV4_MROUTE: ::c_uint = 0x06;
3568
pub const RTNLGRP_IPV4_ROUTE: ::c_uint = 0x07;
3569
pub const RTNLGRP_IPV4_RULE: ::c_uint = 0x08;
3570
pub const RTNLGRP_IPV6_IFADDR: ::c_uint = 0x09;
3571
pub const RTNLGRP_IPV6_MROUTE: ::c_uint = 0x0a;
3572
pub const RTNLGRP_IPV6_ROUTE: ::c_uint = 0x0b;
3573
pub const RTNLGRP_IPV6_IFINFO: ::c_uint = 0x0c;
3574
pub const RTNLGRP_DECnet_IFADDR: ::c_uint = 0x0d;
3575
pub const RTNLGRP_NOP2: ::c_uint = 0x0e;
3576
pub const RTNLGRP_DECnet_ROUTE: ::c_uint = 0x0f;
3577
pub const RTNLGRP_DECnet_RULE: ::c_uint = 0x10;
3578
pub const RTNLGRP_NOP4: ::c_uint = 0x11;
3579
pub const RTNLGRP_IPV6_PREFIX: ::c_uint = 0x12;
3580
pub const RTNLGRP_IPV6_RULE: ::c_uint = 0x13;
3581
pub const RTNLGRP_ND_USEROPT: ::c_uint = 0x14;
3582
pub const RTNLGRP_PHONET_IFADDR: ::c_uint = 0x15;
3583
pub const RTNLGRP_PHONET_ROUTE: ::c_uint = 0x16;
3584
pub const RTNLGRP_DCB: ::c_uint = 0x17;
3585
pub const RTNLGRP_IPV4_NETCONF: ::c_uint = 0x18;
3586
pub const RTNLGRP_IPV6_NETCONF: ::c_uint = 0x19;
3587
pub const RTNLGRP_MDB: ::c_uint = 0x1a;
3588
pub const RTNLGRP_MPLS_ROUTE: ::c_uint = 0x1b;
3589
pub const RTNLGRP_NSID: ::c_uint = 0x1c;
3590
pub const RTNLGRP_MPLS_NETCONF: ::c_uint = 0x1d;
3591
pub const RTNLGRP_IPV4_MROUTE_R: ::c_uint = 0x1e;
3592
pub const RTNLGRP_IPV6_MROUTE_R: ::c_uint = 0x1f;
3593
pub const RTNLGRP_NEXTHOP: ::c_uint = 0x20;
3594
pub const RTNLGRP_BRVLAN: ::c_uint = 0x21;
3595
pub const RTNLGRP_MCTP_IFADDR: ::c_uint = 0x22;
3596
pub const RTNLGRP_TUNNEL: ::c_uint = 0x23;
3597
pub const RTNLGRP_STATS: ::c_uint = 0x24;
3598
3599
// linux/module.h
3600
pub const MODULE_INIT_IGNORE_MODVERSIONS: ::c_uint = 0x0001;
3601
pub const MODULE_INIT_IGNORE_VERMAGIC: ::c_uint = 0x0002;
3602
3603
// linux/net_tstamp.h
3604
pub const SOF_TIMESTAMPING_TX_HARDWARE: ::c_uint = 1 << 0;
3605
pub const SOF_TIMESTAMPING_TX_SOFTWARE: ::c_uint = 1 << 1;
3606
pub const SOF_TIMESTAMPING_RX_HARDWARE: ::c_uint = 1 << 2;
3607
pub const SOF_TIMESTAMPING_RX_SOFTWARE: ::c_uint = 1 << 3;
3608
pub const SOF_TIMESTAMPING_SOFTWARE: ::c_uint = 1 << 4;
3609
pub const SOF_TIMESTAMPING_SYS_HARDWARE: ::c_uint = 1 << 5;
3610
pub const SOF_TIMESTAMPING_RAW_HARDWARE: ::c_uint = 1 << 6;
3611
pub const SOF_TIMESTAMPING_OPT_ID: ::c_uint = 1 << 7;
3612
pub const SOF_TIMESTAMPING_TX_SCHED: ::c_uint = 1 << 8;
3613
pub const SOF_TIMESTAMPING_TX_ACK: ::c_uint = 1 << 9;
3614
pub const SOF_TIMESTAMPING_OPT_CMSG: ::c_uint = 1 << 10;
3615
pub const SOF_TIMESTAMPING_OPT_TSONLY: ::c_uint = 1 << 11;
3616
pub const SOF_TIMESTAMPING_OPT_STATS: ::c_uint = 1 << 12;
3617
pub const SOF_TIMESTAMPING_OPT_PKTINFO: ::c_uint = 1 << 13;
3618
pub const SOF_TIMESTAMPING_OPT_TX_SWHW: ::c_uint = 1 << 14;
3619
pub const SOF_TXTIME_DEADLINE_MODE: u32 = 1 << 0;
3620
pub const SOF_TXTIME_REPORT_ERRORS: u32 = 1 << 1;
3621
3622
pub const HWTSTAMP_TX_OFF: ::c_uint = 0;
3623
pub const HWTSTAMP_TX_ON: ::c_uint = 1;
3624
pub const HWTSTAMP_TX_ONESTEP_SYNC: ::c_uint = 2;
3625
pub const HWTSTAMP_TX_ONESTEP_P2P: ::c_uint = 3;
3626
3627
pub const HWTSTAMP_FILTER_NONE: ::c_uint = 0;
3628
pub const HWTSTAMP_FILTER_ALL: ::c_uint = 1;
3629
pub const HWTSTAMP_FILTER_SOME: ::c_uint = 2;
3630
pub const HWTSTAMP_FILTER_PTP_V1_L4_EVENT: ::c_uint = 3;
3631
pub const HWTSTAMP_FILTER_PTP_V1_L4_SYNC: ::c_uint = 4;
3632
pub const HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: ::c_uint = 5;
3633
pub const HWTSTAMP_FILTER_PTP_V2_L4_EVENT: ::c_uint = 6;
3634
pub const HWTSTAMP_FILTER_PTP_V2_L4_SYNC: ::c_uint = 7;
3635
pub const HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: ::c_uint = 8;
3636
pub const HWTSTAMP_FILTER_PTP_V2_L2_EVENT: ::c_uint = 9;
3637
pub const HWTSTAMP_FILTER_PTP_V2_L2_SYNC: ::c_uint = 10;
3638
pub const HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: ::c_uint = 11;
3639
pub const HWTSTAMP_FILTER_PTP_V2_EVENT: ::c_uint = 12;
3640
pub const HWTSTAMP_FILTER_PTP_V2_SYNC: ::c_uint = 13;
3641
pub const HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: ::c_uint = 14;
3642
pub const HWTSTAMP_FILTER_NTP_ALL: ::c_uint = 15;
3643
3644
// linux/tls.h
3645
pub const TLS_TX: ::c_int = 1;
3646
pub const TLS_RX: ::c_int = 2;
3647
3648
pub const TLS_1_2_VERSION_MAJOR: ::__u8 = 0x3;
3649
pub const TLS_1_2_VERSION_MINOR: ::__u8 = 0x3;
3650
pub const TLS_1_2_VERSION: ::__u16 =
3651
    ((TLS_1_2_VERSION_MAJOR as ::__u16) << 8) | (TLS_1_2_VERSION_MINOR as ::__u16);
3652
3653
pub const TLS_1_3_VERSION_MAJOR: ::__u8 = 0x3;
3654
pub const TLS_1_3_VERSION_MINOR: ::__u8 = 0x4;
3655
pub const TLS_1_3_VERSION: ::__u16 =
3656
    ((TLS_1_3_VERSION_MAJOR as ::__u16) << 8) | (TLS_1_3_VERSION_MINOR as ::__u16);
3657
3658
pub const TLS_CIPHER_AES_GCM_128: ::__u16 = 51;
3659
pub const TLS_CIPHER_AES_GCM_128_IV_SIZE: usize = 8;
3660
pub const TLS_CIPHER_AES_GCM_128_KEY_SIZE: usize = 16;
3661
pub const TLS_CIPHER_AES_GCM_128_SALT_SIZE: usize = 4;
3662
pub const TLS_CIPHER_AES_GCM_128_TAG_SIZE: usize = 16;
3663
pub const TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE: usize = 8;
3664
3665
pub const TLS_CIPHER_AES_GCM_256: ::__u16 = 52;
3666
pub const TLS_CIPHER_AES_GCM_256_IV_SIZE: usize = 8;
3667
pub const TLS_CIPHER_AES_GCM_256_KEY_SIZE: usize = 32;
3668
pub const TLS_CIPHER_AES_GCM_256_SALT_SIZE: usize = 4;
3669
pub const TLS_CIPHER_AES_GCM_256_TAG_SIZE: usize = 16;
3670
pub const TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE: usize = 8;
3671
3672
pub const TLS_CIPHER_CHACHA20_POLY1305: ::__u16 = 54;
3673
pub const TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE: usize = 12;
3674
pub const TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE: usize = 32;
3675
pub const TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE: usize = 0;
3676
pub const TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE: usize = 16;
3677
pub const TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE: usize = 8;
3678
3679
pub const TLS_SET_RECORD_TYPE: ::c_int = 1;
3680
pub const TLS_GET_RECORD_TYPE: ::c_int = 2;
3681
3682
pub const SOL_TLS: ::c_int = 282;
3683
3684
// linux/if_alg.h
3685
pub const ALG_SET_KEY: ::c_int = 1;
3686
pub const ALG_SET_IV: ::c_int = 2;
3687
pub const ALG_SET_OP: ::c_int = 3;
3688
pub const ALG_SET_AEAD_ASSOCLEN: ::c_int = 4;
3689
pub const ALG_SET_AEAD_AUTHSIZE: ::c_int = 5;
3690
pub const ALG_SET_DRBG_ENTROPY: ::c_int = 6;
3691
pub const ALG_SET_KEY_BY_KEY_SERIAL: ::c_int = 7;
3692
3693
pub const ALG_OP_DECRYPT: ::c_int = 0;
3694
pub const ALG_OP_ENCRYPT: ::c_int = 1;
3695
3696
// include/uapi/linux/if.h
3697
pub const IF_OPER_UNKNOWN: ::c_int = 0;
3698
pub const IF_OPER_NOTPRESENT: ::c_int = 1;
3699
pub const IF_OPER_DOWN: ::c_int = 2;
3700
pub const IF_OPER_LOWERLAYERDOWN: ::c_int = 3;
3701
pub const IF_OPER_TESTING: ::c_int = 4;
3702
pub const IF_OPER_DORMANT: ::c_int = 5;
3703
pub const IF_OPER_UP: ::c_int = 6;
3704
3705
pub const IF_LINK_MODE_DEFAULT: ::c_int = 0;
3706
pub const IF_LINK_MODE_DORMANT: ::c_int = 1;
3707
pub const IF_LINK_MODE_TESTING: ::c_int = 2;
3708
3709
// include/uapi/linux/udp.h
3710
pub const UDP_CORK: ::c_int = 1;
3711
pub const UDP_ENCAP: ::c_int = 100;
3712
pub const UDP_NO_CHECK6_TX: ::c_int = 101;
3713
pub const UDP_NO_CHECK6_RX: ::c_int = 102;
3714
3715
// include/uapi/linux/mman.h
3716
pub const MAP_SHARED_VALIDATE: ::c_int = 0x3;
3717
3718
// include/uapi/asm-generic/mman-common.h
3719
pub const MAP_FIXED_NOREPLACE: ::c_int = 0x100000;
3720
pub const MLOCK_ONFAULT: ::c_uint = 0x01;
3721
3722
// uapi/linux/vm_sockets.h
3723
pub const VMADDR_CID_ANY: ::c_uint = 0xFFFFFFFF;
3724
pub const VMADDR_CID_HYPERVISOR: ::c_uint = 0;
3725
#[deprecated(
3726
    since = "0.2.74",
3727
    note = "VMADDR_CID_RESERVED is removed since Linux v5.6 and \
3728
            replaced with VMADDR_CID_LOCAL"
3729
)]
3730
pub const VMADDR_CID_RESERVED: ::c_uint = 1;
3731
pub const VMADDR_CID_LOCAL: ::c_uint = 1;
3732
pub const VMADDR_CID_HOST: ::c_uint = 2;
3733
pub const VMADDR_PORT_ANY: ::c_uint = 0xFFFFFFFF;
3734
3735
// uapi/linux/inotify.h
3736
pub const IN_ACCESS: u32 = 0x0000_0001;
3737
pub const IN_MODIFY: u32 = 0x0000_0002;
3738
pub const IN_ATTRIB: u32 = 0x0000_0004;
3739
pub const IN_CLOSE_WRITE: u32 = 0x0000_0008;
3740
pub const IN_CLOSE_NOWRITE: u32 = 0x0000_0010;
3741
pub const IN_CLOSE: u32 = IN_CLOSE_WRITE | IN_CLOSE_NOWRITE;
3742
pub const IN_OPEN: u32 = 0x0000_0020;
3743
pub const IN_MOVED_FROM: u32 = 0x0000_0040;
3744
pub const IN_MOVED_TO: u32 = 0x0000_0080;
3745
pub const IN_MOVE: u32 = IN_MOVED_FROM | IN_MOVED_TO;
3746
pub const IN_CREATE: u32 = 0x0000_0100;
3747
pub const IN_DELETE: u32 = 0x0000_0200;
3748
pub const IN_DELETE_SELF: u32 = 0x0000_0400;
3749
pub const IN_MOVE_SELF: u32 = 0x0000_0800;
3750
pub const IN_UNMOUNT: u32 = 0x0000_2000;
3751
pub const IN_Q_OVERFLOW: u32 = 0x0000_4000;
3752
pub const IN_IGNORED: u32 = 0x0000_8000;
3753
pub const IN_ONLYDIR: u32 = 0x0100_0000;
3754
pub const IN_DONT_FOLLOW: u32 = 0x0200_0000;
3755
pub const IN_EXCL_UNLINK: u32 = 0x0400_0000;
3756
3757
// linux/keyctl.h
3758
pub const KEY_SPEC_THREAD_KEYRING: i32 = -1;
3759
pub const KEY_SPEC_PROCESS_KEYRING: i32 = -2;
3760
pub const KEY_SPEC_SESSION_KEYRING: i32 = -3;
3761
pub const KEY_SPEC_USER_KEYRING: i32 = -4;
3762
pub const KEY_SPEC_USER_SESSION_KEYRING: i32 = -5;
3763
pub const KEY_SPEC_GROUP_KEYRING: i32 = -6;
3764
pub const KEY_SPEC_REQKEY_AUTH_KEY: i32 = -7;
3765
pub const KEY_SPEC_REQUESTOR_KEYRING: i32 = -8;
3766
3767
pub const KEY_REQKEY_DEFL_NO_CHANGE: i32 = -1;
3768
pub const KEY_REQKEY_DEFL_DEFAULT: i32 = 0;
3769
pub const KEY_REQKEY_DEFL_THREAD_KEYRING: i32 = 1;
3770
pub const KEY_REQKEY_DEFL_PROCESS_KEYRING: i32 = 2;
3771
pub const KEY_REQKEY_DEFL_SESSION_KEYRING: i32 = 3;
3772
pub const KEY_REQKEY_DEFL_USER_KEYRING: i32 = 4;
3773
pub const KEY_REQKEY_DEFL_USER_SESSION_KEYRING: i32 = 5;
3774
pub const KEY_REQKEY_DEFL_GROUP_KEYRING: i32 = 6;
3775
pub const KEY_REQKEY_DEFL_REQUESTOR_KEYRING: i32 = 7;
3776
3777
pub const KEYCTL_GET_KEYRING_ID: u32 = 0;
3778
pub const KEYCTL_JOIN_SESSION_KEYRING: u32 = 1;
3779
pub const KEYCTL_UPDATE: u32 = 2;
3780
pub const KEYCTL_REVOKE: u32 = 3;
3781
pub const KEYCTL_CHOWN: u32 = 4;
3782
pub const KEYCTL_SETPERM: u32 = 5;
3783
pub const KEYCTL_DESCRIBE: u32 = 6;
3784
pub const KEYCTL_CLEAR: u32 = 7;
3785
pub const KEYCTL_LINK: u32 = 8;
3786
pub const KEYCTL_UNLINK: u32 = 9;
3787
pub const KEYCTL_SEARCH: u32 = 10;
3788
pub const KEYCTL_READ: u32 = 11;
3789
pub const KEYCTL_INSTANTIATE: u32 = 12;
3790
pub const KEYCTL_NEGATE: u32 = 13;
3791
pub const KEYCTL_SET_REQKEY_KEYRING: u32 = 14;
3792
pub const KEYCTL_SET_TIMEOUT: u32 = 15;
3793
pub const KEYCTL_ASSUME_AUTHORITY: u32 = 16;
3794
pub const KEYCTL_GET_SECURITY: u32 = 17;
3795
pub const KEYCTL_SESSION_TO_PARENT: u32 = 18;
3796
pub const KEYCTL_REJECT: u32 = 19;
3797
pub const KEYCTL_INSTANTIATE_IOV: u32 = 20;
3798
pub const KEYCTL_INVALIDATE: u32 = 21;
3799
pub const KEYCTL_GET_PERSISTENT: u32 = 22;
3800
3801
pub const IN_MASK_CREATE: u32 = 0x1000_0000;
3802
pub const IN_MASK_ADD: u32 = 0x2000_0000;
3803
pub const IN_ISDIR: u32 = 0x4000_0000;
3804
pub const IN_ONESHOT: u32 = 0x8000_0000;
3805
3806
pub const IN_ALL_EVENTS: u32 = IN_ACCESS
3807
    | IN_MODIFY
3808
    | IN_ATTRIB
3809
    | IN_CLOSE_WRITE
3810
    | IN_CLOSE_NOWRITE
3811
    | IN_OPEN
3812
    | IN_MOVED_FROM
3813
    | IN_MOVED_TO
3814
    | IN_DELETE
3815
    | IN_CREATE
3816
    | IN_DELETE_SELF
3817
    | IN_MOVE_SELF;
3818
3819
pub const IN_CLOEXEC: ::c_int = O_CLOEXEC;
3820
pub const IN_NONBLOCK: ::c_int = O_NONBLOCK;
3821
3822
// uapi/linux/mount.h
3823
pub const OPEN_TREE_CLONE: ::c_uint = 0x01;
3824
pub const OPEN_TREE_CLOEXEC: ::c_uint = O_CLOEXEC as ::c_uint;
3825
3826
// uapi/linux/netfilter/nf_tables.h
3827
pub const NFT_TABLE_MAXNAMELEN: ::c_int = 256;
3828
pub const NFT_CHAIN_MAXNAMELEN: ::c_int = 256;
3829
pub const NFT_SET_MAXNAMELEN: ::c_int = 256;
3830
pub const NFT_OBJ_MAXNAMELEN: ::c_int = 256;
3831
pub const NFT_USERDATA_MAXLEN: ::c_int = 256;
3832
3833
pub const NFT_REG_VERDICT: ::c_int = 0;
3834
pub const NFT_REG_1: ::c_int = 1;
3835
pub const NFT_REG_2: ::c_int = 2;
3836
pub const NFT_REG_3: ::c_int = 3;
3837
pub const NFT_REG_4: ::c_int = 4;
3838
pub const __NFT_REG_MAX: ::c_int = 5;
3839
pub const NFT_REG32_00: ::c_int = 8;
3840
pub const NFT_REG32_01: ::c_int = 9;
3841
pub const NFT_REG32_02: ::c_int = 10;
3842
pub const NFT_REG32_03: ::c_int = 11;
3843
pub const NFT_REG32_04: ::c_int = 12;
3844
pub const NFT_REG32_05: ::c_int = 13;
3845
pub const NFT_REG32_06: ::c_int = 14;
3846
pub const NFT_REG32_07: ::c_int = 15;
3847
pub const NFT_REG32_08: ::c_int = 16;
3848
pub const NFT_REG32_09: ::c_int = 17;
3849
pub const NFT_REG32_10: ::c_int = 18;
3850
pub const NFT_REG32_11: ::c_int = 19;
3851
pub const NFT_REG32_12: ::c_int = 20;
3852
pub const NFT_REG32_13: ::c_int = 21;
3853
pub const NFT_REG32_14: ::c_int = 22;
3854
pub const NFT_REG32_15: ::c_int = 23;
3855
3856
pub const NFT_REG_SIZE: ::c_int = 16;
3857
pub const NFT_REG32_SIZE: ::c_int = 4;
3858
3859
pub const NFT_CONTINUE: ::c_int = -1;
3860
pub const NFT_BREAK: ::c_int = -2;
3861
pub const NFT_JUMP: ::c_int = -3;
3862
pub const NFT_GOTO: ::c_int = -4;
3863
pub const NFT_RETURN: ::c_int = -5;
3864
3865
pub const NFT_MSG_NEWTABLE: ::c_int = 0;
3866
pub const NFT_MSG_GETTABLE: ::c_int = 1;
3867
pub const NFT_MSG_DELTABLE: ::c_int = 2;
3868
pub const NFT_MSG_NEWCHAIN: ::c_int = 3;
3869
pub const NFT_MSG_GETCHAIN: ::c_int = 4;
3870
pub const NFT_MSG_DELCHAIN: ::c_int = 5;
3871
pub const NFT_MSG_NEWRULE: ::c_int = 6;
3872
pub const NFT_MSG_GETRULE: ::c_int = 7;
3873
pub const NFT_MSG_DELRULE: ::c_int = 8;
3874
pub const NFT_MSG_NEWSET: ::c_int = 9;
3875
pub const NFT_MSG_GETSET: ::c_int = 10;
3876
pub const NFT_MSG_DELSET: ::c_int = 11;
3877
pub const NFT_MSG_NEWSETELEM: ::c_int = 12;
3878
pub const NFT_MSG_GETSETELEM: ::c_int = 13;
3879
pub const NFT_MSG_DELSETELEM: ::c_int = 14;
3880
pub const NFT_MSG_NEWGEN: ::c_int = 15;
3881
pub const NFT_MSG_GETGEN: ::c_int = 16;
3882
pub const NFT_MSG_TRACE: ::c_int = 17;
3883
cfg_if! {
3884
    if #[cfg(not(target_arch = "sparc64"))] {
3885
        pub const NFT_MSG_NEWOBJ: ::c_int = 18;
3886
        pub const NFT_MSG_GETOBJ: ::c_int = 19;
3887
        pub const NFT_MSG_DELOBJ: ::c_int = 20;
3888
        pub const NFT_MSG_GETOBJ_RESET: ::c_int = 21;
3889
    }
3890
}
3891
pub const NFT_MSG_MAX: ::c_int = 25;
3892
3893
pub const NFT_SET_ANONYMOUS: ::c_int = 0x1;
3894
pub const NFT_SET_CONSTANT: ::c_int = 0x2;
3895
pub const NFT_SET_INTERVAL: ::c_int = 0x4;
3896
pub const NFT_SET_MAP: ::c_int = 0x8;
3897
pub const NFT_SET_TIMEOUT: ::c_int = 0x10;
3898
pub const NFT_SET_EVAL: ::c_int = 0x20;
3899
3900
pub const NFT_SET_POL_PERFORMANCE: ::c_int = 0;
3901
pub const NFT_SET_POL_MEMORY: ::c_int = 1;
3902
3903
pub const NFT_SET_ELEM_INTERVAL_END: ::c_int = 0x1;
3904
3905
pub const NFT_DATA_VALUE: ::c_uint = 0;
3906
pub const NFT_DATA_VERDICT: ::c_uint = 0xffffff00;
3907
3908
pub const NFT_DATA_RESERVED_MASK: ::c_uint = 0xffffff00;
3909
3910
pub const NFT_DATA_VALUE_MAXLEN: ::c_int = 64;
3911
3912
pub const NFT_BYTEORDER_NTOH: ::c_int = 0;
3913
pub const NFT_BYTEORDER_HTON: ::c_int = 1;
3914
3915
pub const NFT_CMP_EQ: ::c_int = 0;
3916
pub const NFT_CMP_NEQ: ::c_int = 1;
3917
pub const NFT_CMP_LT: ::c_int = 2;
3918
pub const NFT_CMP_LTE: ::c_int = 3;
3919
pub const NFT_CMP_GT: ::c_int = 4;
3920
pub const NFT_CMP_GTE: ::c_int = 5;
3921
3922
pub const NFT_RANGE_EQ: ::c_int = 0;
3923
pub const NFT_RANGE_NEQ: ::c_int = 1;
3924
3925
pub const NFT_LOOKUP_F_INV: ::c_int = 1 << 0;
3926
3927
pub const NFT_DYNSET_OP_ADD: ::c_int = 0;
3928
pub const NFT_DYNSET_OP_UPDATE: ::c_int = 1;
3929
3930
pub const NFT_DYNSET_F_INV: ::c_int = 1 << 0;
3931
3932
pub const NFT_PAYLOAD_LL_HEADER: ::c_int = 0;
3933
pub const NFT_PAYLOAD_NETWORK_HEADER: ::c_int = 1;
3934
pub const NFT_PAYLOAD_TRANSPORT_HEADER: ::c_int = 2;
3935
3936
pub const NFT_PAYLOAD_CSUM_NONE: ::c_int = 0;
3937
pub const NFT_PAYLOAD_CSUM_INET: ::c_int = 1;
3938
3939
pub const NFT_META_LEN: ::c_int = 0;
3940
pub const NFT_META_PROTOCOL: ::c_int = 1;
3941
pub const NFT_META_PRIORITY: ::c_int = 2;
3942
pub const NFT_META_MARK: ::c_int = 3;
3943
pub const NFT_META_IIF: ::c_int = 4;
3944
pub const NFT_META_OIF: ::c_int = 5;
3945
pub const NFT_META_IIFNAME: ::c_int = 6;
3946
pub const NFT_META_OIFNAME: ::c_int = 7;
3947
pub const NFT_META_IIFTYPE: ::c_int = 8;
3948
pub const NFT_META_OIFTYPE: ::c_int = 9;
3949
pub const NFT_META_SKUID: ::c_int = 10;
3950
pub const NFT_META_SKGID: ::c_int = 11;
3951
pub const NFT_META_NFTRACE: ::c_int = 12;
3952
pub const NFT_META_RTCLASSID: ::c_int = 13;
3953
pub const NFT_META_SECMARK: ::c_int = 14;
3954
pub const NFT_META_NFPROTO: ::c_int = 15;
3955
pub const NFT_META_L4PROTO: ::c_int = 16;
3956
pub const NFT_META_BRI_IIFNAME: ::c_int = 17;
3957
pub const NFT_META_BRI_OIFNAME: ::c_int = 18;
3958
pub const NFT_META_PKTTYPE: ::c_int = 19;
3959
pub const NFT_META_CPU: ::c_int = 20;
3960
pub const NFT_META_IIFGROUP: ::c_int = 21;
3961
pub const NFT_META_OIFGROUP: ::c_int = 22;
3962
pub const NFT_META_CGROUP: ::c_int = 23;
3963
pub const NFT_META_PRANDOM: ::c_int = 24;
3964
3965
pub const NFT_CT_STATE: ::c_int = 0;
3966
pub const NFT_CT_DIRECTION: ::c_int = 1;
3967
pub const NFT_CT_STATUS: ::c_int = 2;
3968
pub const NFT_CT_MARK: ::c_int = 3;
3969
pub const NFT_CT_SECMARK: ::c_int = 4;
3970
pub const NFT_CT_EXPIRATION: ::c_int = 5;
3971
pub const NFT_CT_HELPER: ::c_int = 6;
3972
pub const NFT_CT_L3PROTOCOL: ::c_int = 7;
3973
pub const NFT_CT_SRC: ::c_int = 8;
3974
pub const NFT_CT_DST: ::c_int = 9;
3975
pub const NFT_CT_PROTOCOL: ::c_int = 10;
3976
pub const NFT_CT_PROTO_SRC: ::c_int = 11;
3977
pub const NFT_CT_PROTO_DST: ::c_int = 12;
3978
pub const NFT_CT_LABELS: ::c_int = 13;
3979
pub const NFT_CT_PKTS: ::c_int = 14;
3980
pub const NFT_CT_BYTES: ::c_int = 15;
3981
3982
pub const NFT_LIMIT_PKTS: ::c_int = 0;
3983
pub const NFT_LIMIT_PKT_BYTES: ::c_int = 1;
3984
3985
pub const NFT_LIMIT_F_INV: ::c_int = 1 << 0;
3986
3987
pub const NFT_QUEUE_FLAG_BYPASS: ::c_int = 0x01;
3988
pub const NFT_QUEUE_FLAG_CPU_FANOUT: ::c_int = 0x02;
3989
pub const NFT_QUEUE_FLAG_MASK: ::c_int = 0x03;
3990
3991
pub const NFT_QUOTA_F_INV: ::c_int = 1 << 0;
3992
3993
pub const NFT_REJECT_ICMP_UNREACH: ::c_int = 0;
3994
pub const NFT_REJECT_TCP_RST: ::c_int = 1;
3995
pub const NFT_REJECT_ICMPX_UNREACH: ::c_int = 2;
3996
3997
pub const NFT_REJECT_ICMPX_NO_ROUTE: ::c_int = 0;
3998
pub const NFT_REJECT_ICMPX_PORT_UNREACH: ::c_int = 1;
3999
pub const NFT_REJECT_ICMPX_HOST_UNREACH: ::c_int = 2;
4000
pub const NFT_REJECT_ICMPX_ADMIN_PROHIBITED: ::c_int = 3;
4001
4002
pub const NFT_NAT_SNAT: ::c_int = 0;
4003
pub const NFT_NAT_DNAT: ::c_int = 1;
4004
4005
pub const NFT_TRACETYPE_UNSPEC: ::c_int = 0;
4006
pub const NFT_TRACETYPE_POLICY: ::c_int = 1;
4007
pub const NFT_TRACETYPE_RETURN: ::c_int = 2;
4008
pub const NFT_TRACETYPE_RULE: ::c_int = 3;
4009
4010
pub const NFT_NG_INCREMENTAL: ::c_int = 0;
4011
pub const NFT_NG_RANDOM: ::c_int = 1;
4012
4013
// linux/input.h
4014
pub const FF_MAX: ::__u16 = 0x7f;
4015
pub const FF_CNT: usize = FF_MAX as usize + 1;
4016
4017
// linux/input-event-codes.h
4018
pub const INPUT_PROP_MAX: ::__u16 = 0x1f;
4019
pub const INPUT_PROP_CNT: usize = INPUT_PROP_MAX as usize + 1;
4020
pub const EV_MAX: ::__u16 = 0x1f;
4021
pub const EV_CNT: usize = EV_MAX as usize + 1;
4022
pub const SYN_MAX: ::__u16 = 0xf;
4023
pub const SYN_CNT: usize = SYN_MAX as usize + 1;
4024
pub const KEY_MAX: ::__u16 = 0x2ff;
4025
pub const KEY_CNT: usize = KEY_MAX as usize + 1;
4026
pub const REL_MAX: ::__u16 = 0x0f;
4027
pub const REL_CNT: usize = REL_MAX as usize + 1;
4028
pub const ABS_MAX: ::__u16 = 0x3f;
4029
pub const ABS_CNT: usize = ABS_MAX as usize + 1;
4030
pub const SW_MAX: ::__u16 = 0x10;
4031
pub const SW_CNT: usize = SW_MAX as usize + 1;
4032
pub const MSC_MAX: ::__u16 = 0x07;
4033
pub const MSC_CNT: usize = MSC_MAX as usize + 1;
4034
pub const LED_MAX: ::__u16 = 0x0f;
4035
pub const LED_CNT: usize = LED_MAX as usize + 1;
4036
pub const REP_MAX: ::__u16 = 0x01;
4037
pub const REP_CNT: usize = REP_MAX as usize + 1;
4038
pub const SND_MAX: ::__u16 = 0x07;
4039
pub const SND_CNT: usize = SND_MAX as usize + 1;
4040
4041
// linux/uinput.h
4042
pub const UINPUT_VERSION: ::c_uint = 5;
4043
pub const UINPUT_MAX_NAME_SIZE: usize = 80;
4044
4045
// uapi/linux/fanotify.h
4046
pub const FAN_ACCESS: u64 = 0x0000_0001;
4047
pub const FAN_MODIFY: u64 = 0x0000_0002;
4048
pub const FAN_ATTRIB: u64 = 0x0000_0004;
4049
pub const FAN_CLOSE_WRITE: u64 = 0x0000_0008;
4050
pub const FAN_CLOSE_NOWRITE: u64 = 0x0000_0010;
4051
pub const FAN_OPEN: u64 = 0x0000_0020;
4052
pub const FAN_MOVED_FROM: u64 = 0x0000_0040;
4053
pub const FAN_MOVED_TO: u64 = 0x0000_0080;
4054
pub const FAN_CREATE: u64 = 0x0000_0100;
4055
pub const FAN_DELETE: u64 = 0x0000_0200;
4056
pub const FAN_DELETE_SELF: u64 = 0x0000_0400;
4057
pub const FAN_MOVE_SELF: u64 = 0x0000_0800;
4058
pub const FAN_OPEN_EXEC: u64 = 0x0000_1000;
4059
4060
pub const FAN_Q_OVERFLOW: u64 = 0x0000_4000;
4061
pub const FAN_FS_ERROR: u64 = 0x0000_8000;
4062
4063
pub const FAN_OPEN_PERM: u64 = 0x0001_0000;
4064
pub const FAN_ACCESS_PERM: u64 = 0x0002_0000;
4065
pub const FAN_OPEN_EXEC_PERM: u64 = 0x0004_0000;
4066
4067
pub const FAN_EVENT_ON_CHILD: u64 = 0x0800_0000;
4068
4069
pub const FAN_RENAME: u64 = 0x1000_0000;
4070
4071
pub const FAN_ONDIR: u64 = 0x4000_0000;
4072
4073
pub const FAN_CLOSE: u64 = FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE;
4074
pub const FAN_MOVE: u64 = FAN_MOVED_FROM | FAN_MOVED_TO;
4075
4076
pub const FAN_CLOEXEC: ::c_uint = 0x0000_0001;
4077
pub const FAN_NONBLOCK: ::c_uint = 0x0000_0002;
4078
4079
pub const FAN_CLASS_NOTIF: ::c_uint = 0x0000_0000;
4080
pub const FAN_CLASS_CONTENT: ::c_uint = 0x0000_0004;
4081
pub const FAN_CLASS_PRE_CONTENT: ::c_uint = 0x0000_0008;
4082
4083
pub const FAN_UNLIMITED_QUEUE: ::c_uint = 0x0000_0010;
4084
pub const FAN_UNLIMITED_MARKS: ::c_uint = 0x0000_0020;
4085
pub const FAN_ENABLE_AUDIT: ::c_uint = 0x0000_0040;
4086
4087
pub const FAN_REPORT_PIDFD: ::c_uint = 0x0000_0080;
4088
pub const FAN_REPORT_TID: ::c_uint = 0x0000_0100;
4089
pub const FAN_REPORT_FID: ::c_uint = 0x0000_0200;
4090
pub const FAN_REPORT_DIR_FID: ::c_uint = 0x0000_0400;
4091
pub const FAN_REPORT_NAME: ::c_uint = 0x0000_0800;
4092
pub const FAN_REPORT_TARGET_FID: ::c_uint = 0x0000_1000;
4093
4094
pub const FAN_REPORT_DFID_NAME: ::c_uint = FAN_REPORT_DIR_FID | FAN_REPORT_NAME;
4095
pub const FAN_REPORT_DFID_NAME_TARGET: ::c_uint =
4096
    FAN_REPORT_DFID_NAME | FAN_REPORT_FID | FAN_REPORT_TARGET_FID;
4097
4098
pub const FAN_MARK_ADD: ::c_uint = 0x0000_0001;
4099
pub const FAN_MARK_REMOVE: ::c_uint = 0x0000_0002;
4100
pub const FAN_MARK_DONT_FOLLOW: ::c_uint = 0x0000_0004;
4101
pub const FAN_MARK_ONLYDIR: ::c_uint = 0x0000_0008;
4102
pub const FAN_MARK_IGNORED_MASK: ::c_uint = 0x0000_0020;
4103
pub const FAN_MARK_IGNORED_SURV_MODIFY: ::c_uint = 0x0000_0040;
4104
pub const FAN_MARK_FLUSH: ::c_uint = 0x0000_0080;
4105
pub const FAN_MARK_EVICTABLE: ::c_uint = 0x0000_0200;
4106
pub const FAN_MARK_IGNORE: ::c_uint = 0x0000_0400;
4107
4108
pub const FAN_MARK_INODE: ::c_uint = 0x0000_0000;
4109
pub const FAN_MARK_MOUNT: ::c_uint = 0x0000_0010;
4110
pub const FAN_MARK_FILESYSTEM: ::c_uint = 0x0000_0100;
4111
4112
pub const FAN_MARK_IGNORE_SURV: ::c_uint = FAN_MARK_IGNORE | FAN_MARK_IGNORED_SURV_MODIFY;
4113
4114
pub const FANOTIFY_METADATA_VERSION: u8 = 3;
4115
4116
pub const FAN_EVENT_INFO_TYPE_FID: u8 = 1;
4117
pub const FAN_EVENT_INFO_TYPE_DFID_NAME: u8 = 2;
4118
pub const FAN_EVENT_INFO_TYPE_DFID: u8 = 3;
4119
pub const FAN_EVENT_INFO_TYPE_PIDFD: u8 = 4;
4120
pub const FAN_EVENT_INFO_TYPE_ERROR: u8 = 5;
4121
4122
pub const FAN_EVENT_INFO_TYPE_OLD_DFID_NAME: u8 = 10;
4123
pub const FAN_EVENT_INFO_TYPE_NEW_DFID_NAME: u8 = 12;
4124
4125
pub const FAN_RESPONSE_INFO_NONE: u8 = 0;
4126
pub const FAN_RESPONSE_INFO_AUDIT_RULE: u8 = 1;
4127
4128
pub const FAN_ALLOW: u32 = 0x01;
4129
pub const FAN_DENY: u32 = 0x02;
4130
pub const FAN_AUDIT: u32 = 0x10;
4131
pub const FAN_INFO: u32 = 0x20;
4132
4133
pub const FAN_NOFD: ::c_int = -1;
4134
pub const FAN_NOPIDFD: ::c_int = FAN_NOFD;
4135
pub const FAN_EPIDFD: ::c_int = -2;
4136
4137
pub const FUTEX_WAIT: ::c_int = 0;
4138
pub const FUTEX_WAKE: ::c_int = 1;
4139
pub const FUTEX_FD: ::c_int = 2;
4140
pub const FUTEX_REQUEUE: ::c_int = 3;
4141
pub const FUTEX_CMP_REQUEUE: ::c_int = 4;
4142
pub const FUTEX_WAKE_OP: ::c_int = 5;
4143
pub const FUTEX_LOCK_PI: ::c_int = 6;
4144
pub const FUTEX_UNLOCK_PI: ::c_int = 7;
4145
pub const FUTEX_TRYLOCK_PI: ::c_int = 8;
4146
pub const FUTEX_WAIT_BITSET: ::c_int = 9;
4147
pub const FUTEX_WAKE_BITSET: ::c_int = 10;
4148
pub const FUTEX_WAIT_REQUEUE_PI: ::c_int = 11;
4149
pub const FUTEX_CMP_REQUEUE_PI: ::c_int = 12;
4150
pub const FUTEX_LOCK_PI2: ::c_int = 13;
4151
4152
pub const FUTEX_PRIVATE_FLAG: ::c_int = 128;
4153
pub const FUTEX_CLOCK_REALTIME: ::c_int = 256;
4154
pub const FUTEX_CMD_MASK: ::c_int = !(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME);
4155
4156
pub const FUTEX_BITSET_MATCH_ANY: ::c_int = 0xffffffff;
4157
4158
pub const FUTEX_OP_SET: ::c_int = 0;
4159
pub const FUTEX_OP_ADD: ::c_int = 1;
4160
pub const FUTEX_OP_OR: ::c_int = 2;
4161
pub const FUTEX_OP_ANDN: ::c_int = 3;
4162
pub const FUTEX_OP_XOR: ::c_int = 4;
4163
4164
pub const FUTEX_OP_OPARG_SHIFT: ::c_int = 8;
4165
4166
pub const FUTEX_OP_CMP_EQ: ::c_int = 0;
4167
pub const FUTEX_OP_CMP_NE: ::c_int = 1;
4168
pub const FUTEX_OP_CMP_LT: ::c_int = 2;
4169
pub const FUTEX_OP_CMP_LE: ::c_int = 3;
4170
pub const FUTEX_OP_CMP_GT: ::c_int = 4;
4171
pub const FUTEX_OP_CMP_GE: ::c_int = 5;
4172
4173
0
pub fn FUTEX_OP(op: ::c_int, oparg: ::c_int, cmp: ::c_int, cmparg: ::c_int) -> ::c_int {
4174
0
    ((op & 0xf) << 28) | ((cmp & 0xf) << 24) | ((oparg & 0xfff) << 12) | (cmparg & 0xfff)
4175
0
}
4176
4177
// linux/kexec.h
4178
pub const KEXEC_ON_CRASH: ::c_int = 0x00000001;
4179
pub const KEXEC_PRESERVE_CONTEXT: ::c_int = 0x00000002;
4180
pub const KEXEC_ARCH_MASK: ::c_int = 0xffff0000;
4181
pub const KEXEC_FILE_UNLOAD: ::c_int = 0x00000001;
4182
pub const KEXEC_FILE_ON_CRASH: ::c_int = 0x00000002;
4183
pub const KEXEC_FILE_NO_INITRAMFS: ::c_int = 0x00000004;
4184
4185
// linux/reboot.h
4186
pub const LINUX_REBOOT_MAGIC1: ::c_int = 0xfee1dead;
4187
pub const LINUX_REBOOT_MAGIC2: ::c_int = 672274793;
4188
pub const LINUX_REBOOT_MAGIC2A: ::c_int = 85072278;
4189
pub const LINUX_REBOOT_MAGIC2B: ::c_int = 369367448;
4190
pub const LINUX_REBOOT_MAGIC2C: ::c_int = 537993216;
4191
4192
pub const LINUX_REBOOT_CMD_RESTART: ::c_int = 0x01234567;
4193
pub const LINUX_REBOOT_CMD_HALT: ::c_int = 0xCDEF0123;
4194
pub const LINUX_REBOOT_CMD_CAD_ON: ::c_int = 0x89ABCDEF;
4195
pub const LINUX_REBOOT_CMD_CAD_OFF: ::c_int = 0x00000000;
4196
pub const LINUX_REBOOT_CMD_POWER_OFF: ::c_int = 0x4321FEDC;
4197
pub const LINUX_REBOOT_CMD_RESTART2: ::c_int = 0xA1B2C3D4;
4198
pub const LINUX_REBOOT_CMD_SW_SUSPEND: ::c_int = 0xD000FCE2;
4199
pub const LINUX_REBOOT_CMD_KEXEC: ::c_int = 0x45584543;
4200
4201
pub const REG_EXTENDED: ::c_int = 1;
4202
pub const REG_ICASE: ::c_int = 2;
4203
pub const REG_NEWLINE: ::c_int = 4;
4204
pub const REG_NOSUB: ::c_int = 8;
4205
4206
pub const REG_NOTBOL: ::c_int = 1;
4207
pub const REG_NOTEOL: ::c_int = 2;
4208
4209
pub const REG_ENOSYS: ::c_int = -1;
4210
pub const REG_NOMATCH: ::c_int = 1;
4211
pub const REG_BADPAT: ::c_int = 2;
4212
pub const REG_ECOLLATE: ::c_int = 3;
4213
pub const REG_ECTYPE: ::c_int = 4;
4214
pub const REG_EESCAPE: ::c_int = 5;
4215
pub const REG_ESUBREG: ::c_int = 6;
4216
pub const REG_EBRACK: ::c_int = 7;
4217
pub const REG_EPAREN: ::c_int = 8;
4218
pub const REG_EBRACE: ::c_int = 9;
4219
pub const REG_BADBR: ::c_int = 10;
4220
pub const REG_ERANGE: ::c_int = 11;
4221
pub const REG_ESPACE: ::c_int = 12;
4222
pub const REG_BADRPT: ::c_int = 13;
4223
4224
// linux/errqueue.h
4225
pub const SO_EE_ORIGIN_NONE: u8 = 0;
4226
pub const SO_EE_ORIGIN_LOCAL: u8 = 1;
4227
pub const SO_EE_ORIGIN_ICMP: u8 = 2;
4228
pub const SO_EE_ORIGIN_ICMP6: u8 = 3;
4229
pub const SO_EE_ORIGIN_TXSTATUS: u8 = 4;
4230
pub const SO_EE_ORIGIN_TIMESTAMPING: u8 = SO_EE_ORIGIN_TXSTATUS;
4231
4232
// errno.h
4233
pub const EPERM: ::c_int = 1;
4234
pub const ENOENT: ::c_int = 2;
4235
pub const ESRCH: ::c_int = 3;
4236
pub const EINTR: ::c_int = 4;
4237
pub const EIO: ::c_int = 5;
4238
pub const ENXIO: ::c_int = 6;
4239
pub const E2BIG: ::c_int = 7;
4240
pub const ENOEXEC: ::c_int = 8;
4241
pub const EBADF: ::c_int = 9;
4242
pub const ECHILD: ::c_int = 10;
4243
pub const EAGAIN: ::c_int = 11;
4244
pub const ENOMEM: ::c_int = 12;
4245
pub const EACCES: ::c_int = 13;
4246
pub const EFAULT: ::c_int = 14;
4247
pub const ENOTBLK: ::c_int = 15;
4248
pub const EBUSY: ::c_int = 16;
4249
pub const EEXIST: ::c_int = 17;
4250
pub const EXDEV: ::c_int = 18;
4251
pub const ENODEV: ::c_int = 19;
4252
pub const ENOTDIR: ::c_int = 20;
4253
pub const EISDIR: ::c_int = 21;
4254
pub const EINVAL: ::c_int = 22;
4255
pub const ENFILE: ::c_int = 23;
4256
pub const EMFILE: ::c_int = 24;
4257
pub const ENOTTY: ::c_int = 25;
4258
pub const ETXTBSY: ::c_int = 26;
4259
pub const EFBIG: ::c_int = 27;
4260
pub const ENOSPC: ::c_int = 28;
4261
pub const ESPIPE: ::c_int = 29;
4262
pub const EROFS: ::c_int = 30;
4263
pub const EMLINK: ::c_int = 31;
4264
pub const EPIPE: ::c_int = 32;
4265
pub const EDOM: ::c_int = 33;
4266
pub const ERANGE: ::c_int = 34;
4267
pub const EWOULDBLOCK: ::c_int = EAGAIN;
4268
4269
// linux/can.h
4270
pub const CAN_EFF_FLAG: canid_t = 0x80000000;
4271
pub const CAN_RTR_FLAG: canid_t = 0x40000000;
4272
pub const CAN_ERR_FLAG: canid_t = 0x20000000;
4273
pub const CAN_SFF_MASK: canid_t = 0x000007FF;
4274
pub const CAN_EFF_MASK: canid_t = 0x1FFFFFFF;
4275
pub const CAN_ERR_MASK: canid_t = 0x1FFFFFFF;
4276
pub const CANXL_PRIO_MASK: ::canid_t = CAN_SFF_MASK;
4277
4278
pub const CAN_SFF_ID_BITS: ::c_int = 11;
4279
pub const CAN_EFF_ID_BITS: ::c_int = 29;
4280
pub const CANXL_PRIO_BITS: ::c_int = CAN_SFF_ID_BITS;
4281
4282
pub const CAN_MAX_DLC: ::c_int = 8;
4283
pub const CAN_MAX_DLEN: usize = 8;
4284
pub const CANFD_MAX_DLC: ::c_int = 15;
4285
pub const CANFD_MAX_DLEN: usize = 64;
4286
4287
pub const CANFD_BRS: ::c_int = 0x01;
4288
pub const CANFD_ESI: ::c_int = 0x02;
4289
4290
pub const CANXL_MIN_DLC: ::c_int = 0;
4291
pub const CANXL_MAX_DLC: ::c_int = 2047;
4292
pub const CANXL_MAX_DLC_MASK: ::c_int = 0x07FF;
4293
pub const CANXL_MIN_DLEN: usize = 1;
4294
pub const CANXL_MAX_DLEN: usize = 2048;
4295
4296
pub const CANXL_XLF: ::c_int = 0x80;
4297
pub const CANXL_SEC: ::c_int = 0x01;
4298
4299
cfg_if! {
4300
    if #[cfg(libc_align)] {
4301
        pub const CAN_MTU: usize = ::mem::size_of::<can_frame>();
4302
        pub const CANFD_MTU: usize = ::mem::size_of::<canfd_frame>();
4303
        pub const CANXL_MTU: usize = ::mem::size_of::<canxl_frame>();
4304
        // FIXME: use `core::mem::offset_of!` once that is available
4305
        // https://github.com/rust-lang/rfcs/pull/3308
4306
        // pub const CANXL_HDR_SIZE: usize = core::mem::offset_of!(canxl_frame, data);
4307
        pub const CANXL_HDR_SIZE: usize = 12;
4308
        pub const CANXL_MIN_MTU: usize = CANXL_HDR_SIZE + 64;
4309
        pub const CANXL_MAX_MTU: usize = CANXL_MTU;
4310
    }
4311
}
4312
4313
pub const CAN_RAW: ::c_int = 1;
4314
pub const CAN_BCM: ::c_int = 2;
4315
pub const CAN_TP16: ::c_int = 3;
4316
pub const CAN_TP20: ::c_int = 4;
4317
pub const CAN_MCNET: ::c_int = 5;
4318
pub const CAN_ISOTP: ::c_int = 6;
4319
pub const CAN_J1939: ::c_int = 7;
4320
pub const CAN_NPROTO: ::c_int = 8;
4321
4322
pub const SOL_CAN_BASE: ::c_int = 100;
4323
4324
pub const CAN_INV_FILTER: canid_t = 0x20000000;
4325
pub const CAN_RAW_FILTER_MAX: ::c_int = 512;
4326
4327
// linux/can/raw.h
4328
pub const SOL_CAN_RAW: ::c_int = SOL_CAN_BASE + CAN_RAW;
4329
pub const CAN_RAW_FILTER: ::c_int = 1;
4330
pub const CAN_RAW_ERR_FILTER: ::c_int = 2;
4331
pub const CAN_RAW_LOOPBACK: ::c_int = 3;
4332
pub const CAN_RAW_RECV_OWN_MSGS: ::c_int = 4;
4333
pub const CAN_RAW_FD_FRAMES: ::c_int = 5;
4334
pub const CAN_RAW_JOIN_FILTERS: ::c_int = 6;
4335
pub const CAN_RAW_XL_FRAMES: ::c_int = 7;
4336
4337
// linux/can/j1939.h
4338
pub const SOL_CAN_J1939: ::c_int = SOL_CAN_BASE + CAN_J1939;
4339
4340
pub const J1939_MAX_UNICAST_ADDR: ::c_uchar = 0xfd;
4341
pub const J1939_IDLE_ADDR: ::c_uchar = 0xfe;
4342
pub const J1939_NO_ADDR: ::c_uchar = 0xff;
4343
pub const J1939_NO_NAME: ::c_ulong = 0;
4344
pub const J1939_PGN_REQUEST: ::c_uint = 0x0ea00;
4345
pub const J1939_PGN_ADDRESS_CLAIMED: ::c_uint = 0x0ee00;
4346
pub const J1939_PGN_ADDRESS_COMMANDED: ::c_uint = 0x0fed8;
4347
pub const J1939_PGN_PDU1_MAX: ::c_uint = 0x3ff00;
4348
pub const J1939_PGN_MAX: ::c_uint = 0x3ffff;
4349
pub const J1939_NO_PGN: ::c_uint = 0x40000;
4350
4351
pub const SO_J1939_FILTER: ::c_int = 1;
4352
pub const SO_J1939_PROMISC: ::c_int = 2;
4353
pub const SO_J1939_SEND_PRIO: ::c_int = 3;
4354
pub const SO_J1939_ERRQUEUE: ::c_int = 4;
4355
4356
pub const SCM_J1939_DEST_ADDR: ::c_int = 1;
4357
pub const SCM_J1939_DEST_NAME: ::c_int = 2;
4358
pub const SCM_J1939_PRIO: ::c_int = 3;
4359
pub const SCM_J1939_ERRQUEUE: ::c_int = 4;
4360
4361
pub const J1939_NLA_PAD: ::c_int = 0;
4362
pub const J1939_NLA_BYTES_ACKED: ::c_int = 1;
4363
pub const J1939_NLA_TOTAL_SIZE: ::c_int = 2;
4364
pub const J1939_NLA_PGN: ::c_int = 3;
4365
pub const J1939_NLA_SRC_NAME: ::c_int = 4;
4366
pub const J1939_NLA_DEST_NAME: ::c_int = 5;
4367
pub const J1939_NLA_SRC_ADDR: ::c_int = 6;
4368
pub const J1939_NLA_DEST_ADDR: ::c_int = 7;
4369
4370
pub const J1939_EE_INFO_NONE: ::c_int = 0;
4371
pub const J1939_EE_INFO_TX_ABORT: ::c_int = 1;
4372
pub const J1939_EE_INFO_RX_RTS: ::c_int = 2;
4373
pub const J1939_EE_INFO_RX_DPO: ::c_int = 3;
4374
pub const J1939_EE_INFO_RX_ABORT: ::c_int = 4;
4375
4376
pub const J1939_FILTER_MAX: ::c_int = 512;
4377
4378
// linux/sctp.h
4379
pub const SCTP_FUTURE_ASSOC: ::c_int = 0;
4380
pub const SCTP_CURRENT_ASSOC: ::c_int = 1;
4381
pub const SCTP_ALL_ASSOC: ::c_int = 2;
4382
pub const SCTP_RTOINFO: ::c_int = 0;
4383
pub const SCTP_ASSOCINFO: ::c_int = 1;
4384
pub const SCTP_INITMSG: ::c_int = 2;
4385
pub const SCTP_NODELAY: ::c_int = 3;
4386
pub const SCTP_AUTOCLOSE: ::c_int = 4;
4387
pub const SCTP_SET_PEER_PRIMARY_ADDR: ::c_int = 5;
4388
pub const SCTP_PRIMARY_ADDR: ::c_int = 6;
4389
pub const SCTP_ADAPTATION_LAYER: ::c_int = 7;
4390
pub const SCTP_DISABLE_FRAGMENTS: ::c_int = 8;
4391
pub const SCTP_PEER_ADDR_PARAMS: ::c_int = 9;
4392
pub const SCTP_DEFAULT_SEND_PARAM: ::c_int = 10;
4393
pub const SCTP_EVENTS: ::c_int = 11;
4394
pub const SCTP_I_WANT_MAPPED_V4_ADDR: ::c_int = 12;
4395
pub const SCTP_MAXSEG: ::c_int = 13;
4396
pub const SCTP_STATUS: ::c_int = 14;
4397
pub const SCTP_GET_PEER_ADDR_INFO: ::c_int = 15;
4398
pub const SCTP_DELAYED_ACK_TIME: ::c_int = 16;
4399
pub const SCTP_DELAYED_ACK: ::c_int = SCTP_DELAYED_ACK_TIME;
4400
pub const SCTP_DELAYED_SACK: ::c_int = SCTP_DELAYED_ACK_TIME;
4401
pub const SCTP_CONTEXT: ::c_int = 17;
4402
pub const SCTP_FRAGMENT_INTERLEAVE: ::c_int = 18;
4403
pub const SCTP_PARTIAL_DELIVERY_POINT: ::c_int = 19;
4404
pub const SCTP_MAX_BURST: ::c_int = 20;
4405
pub const SCTP_AUTH_CHUNK: ::c_int = 21;
4406
pub const SCTP_HMAC_IDENT: ::c_int = 22;
4407
pub const SCTP_AUTH_KEY: ::c_int = 23;
4408
pub const SCTP_AUTH_ACTIVE_KEY: ::c_int = 24;
4409
pub const SCTP_AUTH_DELETE_KEY: ::c_int = 25;
4410
pub const SCTP_PEER_AUTH_CHUNKS: ::c_int = 26;
4411
pub const SCTP_LOCAL_AUTH_CHUNKS: ::c_int = 27;
4412
pub const SCTP_GET_ASSOC_NUMBER: ::c_int = 28;
4413
pub const SCTP_GET_ASSOC_ID_LIST: ::c_int = 29;
4414
pub const SCTP_AUTO_ASCONF: ::c_int = 30;
4415
pub const SCTP_PEER_ADDR_THLDS: ::c_int = 31;
4416
pub const SCTP_RECVRCVINFO: ::c_int = 32;
4417
pub const SCTP_RECVNXTINFO: ::c_int = 33;
4418
pub const SCTP_DEFAULT_SNDINFO: ::c_int = 34;
4419
pub const SCTP_AUTH_DEACTIVATE_KEY: ::c_int = 35;
4420
pub const SCTP_REUSE_PORT: ::c_int = 36;
4421
pub const SCTP_PEER_ADDR_THLDS_V2: ::c_int = 37;
4422
pub const SCTP_PR_SCTP_NONE: ::c_int = 0x0000;
4423
pub const SCTP_PR_SCTP_TTL: ::c_int = 0x0010;
4424
pub const SCTP_PR_SCTP_RTX: ::c_int = 0x0020;
4425
pub const SCTP_PR_SCTP_PRIO: ::c_int = 0x0030;
4426
pub const SCTP_PR_SCTP_MAX: ::c_int = SCTP_PR_SCTP_PRIO;
4427
pub const SCTP_PR_SCTP_MASK: ::c_int = 0x0030;
4428
pub const SCTP_ENABLE_RESET_STREAM_REQ: ::c_int = 0x01;
4429
pub const SCTP_ENABLE_RESET_ASSOC_REQ: ::c_int = 0x02;
4430
pub const SCTP_ENABLE_CHANGE_ASSOC_REQ: ::c_int = 0x04;
4431
pub const SCTP_ENABLE_STRRESET_MASK: ::c_int = 0x07;
4432
pub const SCTP_STREAM_RESET_INCOMING: ::c_int = 0x01;
4433
pub const SCTP_STREAM_RESET_OUTGOING: ::c_int = 0x02;
4434
4435
pub const SCTP_INIT: ::c_int = 0;
4436
pub const SCTP_SNDRCV: ::c_int = 1;
4437
pub const SCTP_SNDINFO: ::c_int = 2;
4438
pub const SCTP_RCVINFO: ::c_int = 3;
4439
pub const SCTP_NXTINFO: ::c_int = 4;
4440
pub const SCTP_PRINFO: ::c_int = 5;
4441
pub const SCTP_AUTHINFO: ::c_int = 6;
4442
pub const SCTP_DSTADDRV4: ::c_int = 7;
4443
pub const SCTP_DSTADDRV6: ::c_int = 8;
4444
4445
pub const SCTP_UNORDERED: ::c_int = 1 << 0;
4446
pub const SCTP_ADDR_OVER: ::c_int = 1 << 1;
4447
pub const SCTP_ABORT: ::c_int = 1 << 2;
4448
pub const SCTP_SACK_IMMEDIATELY: ::c_int = 1 << 3;
4449
pub const SCTP_SENDALL: ::c_int = 1 << 6;
4450
pub const SCTP_PR_SCTP_ALL: ::c_int = 1 << 7;
4451
pub const SCTP_NOTIFICATION: ::c_int = MSG_NOTIFICATION;
4452
pub const SCTP_EOF: ::c_int = ::MSG_FIN;
4453
4454
/* DCCP socket options */
4455
pub const DCCP_SOCKOPT_PACKET_SIZE: ::c_int = 1;
4456
pub const DCCP_SOCKOPT_SERVICE: ::c_int = 2;
4457
pub const DCCP_SOCKOPT_CHANGE_L: ::c_int = 3;
4458
pub const DCCP_SOCKOPT_CHANGE_R: ::c_int = 4;
4459
pub const DCCP_SOCKOPT_GET_CUR_MPS: ::c_int = 5;
4460
pub const DCCP_SOCKOPT_SERVER_TIMEWAIT: ::c_int = 6;
4461
pub const DCCP_SOCKOPT_SEND_CSCOV: ::c_int = 10;
4462
pub const DCCP_SOCKOPT_RECV_CSCOV: ::c_int = 11;
4463
pub const DCCP_SOCKOPT_AVAILABLE_CCIDS: ::c_int = 12;
4464
pub const DCCP_SOCKOPT_CCID: ::c_int = 13;
4465
pub const DCCP_SOCKOPT_TX_CCID: ::c_int = 14;
4466
pub const DCCP_SOCKOPT_RX_CCID: ::c_int = 15;
4467
pub const DCCP_SOCKOPT_QPOLICY_ID: ::c_int = 16;
4468
pub const DCCP_SOCKOPT_QPOLICY_TXQLEN: ::c_int = 17;
4469
pub const DCCP_SOCKOPT_CCID_RX_INFO: ::c_int = 128;
4470
pub const DCCP_SOCKOPT_CCID_TX_INFO: ::c_int = 192;
4471
4472
/// maximum number of services provided on the same listening port
4473
pub const DCCP_SERVICE_LIST_MAX_LEN: ::c_int = 32;
4474
4475
pub const CTL_KERN: ::c_int = 1;
4476
pub const CTL_VM: ::c_int = 2;
4477
pub const CTL_NET: ::c_int = 3;
4478
pub const CTL_FS: ::c_int = 5;
4479
pub const CTL_DEBUG: ::c_int = 6;
4480
pub const CTL_DEV: ::c_int = 7;
4481
pub const CTL_BUS: ::c_int = 8;
4482
pub const CTL_ABI: ::c_int = 9;
4483
pub const CTL_CPU: ::c_int = 10;
4484
4485
pub const CTL_BUS_ISA: ::c_int = 1;
4486
4487
pub const INOTIFY_MAX_USER_INSTANCES: ::c_int = 1;
4488
pub const INOTIFY_MAX_USER_WATCHES: ::c_int = 2;
4489
pub const INOTIFY_MAX_QUEUED_EVENTS: ::c_int = 3;
4490
4491
pub const KERN_OSTYPE: ::c_int = 1;
4492
pub const KERN_OSRELEASE: ::c_int = 2;
4493
pub const KERN_OSREV: ::c_int = 3;
4494
pub const KERN_VERSION: ::c_int = 4;
4495
pub const KERN_SECUREMASK: ::c_int = 5;
4496
pub const KERN_PROF: ::c_int = 6;
4497
pub const KERN_NODENAME: ::c_int = 7;
4498
pub const KERN_DOMAINNAME: ::c_int = 8;
4499
pub const KERN_PANIC: ::c_int = 15;
4500
pub const KERN_REALROOTDEV: ::c_int = 16;
4501
pub const KERN_SPARC_REBOOT: ::c_int = 21;
4502
pub const KERN_CTLALTDEL: ::c_int = 22;
4503
pub const KERN_PRINTK: ::c_int = 23;
4504
pub const KERN_NAMETRANS: ::c_int = 24;
4505
pub const KERN_PPC_HTABRECLAIM: ::c_int = 25;
4506
pub const KERN_PPC_ZEROPAGED: ::c_int = 26;
4507
pub const KERN_PPC_POWERSAVE_NAP: ::c_int = 27;
4508
pub const KERN_MODPROBE: ::c_int = 28;
4509
pub const KERN_SG_BIG_BUFF: ::c_int = 29;
4510
pub const KERN_ACCT: ::c_int = 30;
4511
pub const KERN_PPC_L2CR: ::c_int = 31;
4512
pub const KERN_RTSIGNR: ::c_int = 32;
4513
pub const KERN_RTSIGMAX: ::c_int = 33;
4514
pub const KERN_SHMMAX: ::c_int = 34;
4515
pub const KERN_MSGMAX: ::c_int = 35;
4516
pub const KERN_MSGMNB: ::c_int = 36;
4517
pub const KERN_MSGPOOL: ::c_int = 37;
4518
pub const KERN_SYSRQ: ::c_int = 38;
4519
pub const KERN_MAX_THREADS: ::c_int = 39;
4520
pub const KERN_RANDOM: ::c_int = 40;
4521
pub const KERN_SHMALL: ::c_int = 41;
4522
pub const KERN_MSGMNI: ::c_int = 42;
4523
pub const KERN_SEM: ::c_int = 43;
4524
pub const KERN_SPARC_STOP_A: ::c_int = 44;
4525
pub const KERN_SHMMNI: ::c_int = 45;
4526
pub const KERN_OVERFLOWUID: ::c_int = 46;
4527
pub const KERN_OVERFLOWGID: ::c_int = 47;
4528
pub const KERN_SHMPATH: ::c_int = 48;
4529
pub const KERN_HOTPLUG: ::c_int = 49;
4530
pub const KERN_IEEE_EMULATION_WARNINGS: ::c_int = 50;
4531
pub const KERN_S390_USER_DEBUG_LOGGING: ::c_int = 51;
4532
pub const KERN_CORE_USES_PID: ::c_int = 52;
4533
pub const KERN_TAINTED: ::c_int = 53;
4534
pub const KERN_CADPID: ::c_int = 54;
4535
pub const KERN_PIDMAX: ::c_int = 55;
4536
pub const KERN_CORE_PATTERN: ::c_int = 56;
4537
pub const KERN_PANIC_ON_OOPS: ::c_int = 57;
4538
pub const KERN_HPPA_PWRSW: ::c_int = 58;
4539
pub const KERN_HPPA_UNALIGNED: ::c_int = 59;
4540
pub const KERN_PRINTK_RATELIMIT: ::c_int = 60;
4541
pub const KERN_PRINTK_RATELIMIT_BURST: ::c_int = 61;
4542
pub const KERN_PTY: ::c_int = 62;
4543
pub const KERN_NGROUPS_MAX: ::c_int = 63;
4544
pub const KERN_SPARC_SCONS_PWROFF: ::c_int = 64;
4545
pub const KERN_HZ_TIMER: ::c_int = 65;
4546
pub const KERN_UNKNOWN_NMI_PANIC: ::c_int = 66;
4547
pub const KERN_BOOTLOADER_TYPE: ::c_int = 67;
4548
pub const KERN_RANDOMIZE: ::c_int = 68;
4549
pub const KERN_SETUID_DUMPABLE: ::c_int = 69;
4550
pub const KERN_SPIN_RETRY: ::c_int = 70;
4551
pub const KERN_ACPI_VIDEO_FLAGS: ::c_int = 71;
4552
pub const KERN_IA64_UNALIGNED: ::c_int = 72;
4553
pub const KERN_COMPAT_LOG: ::c_int = 73;
4554
pub const KERN_MAX_LOCK_DEPTH: ::c_int = 74;
4555
pub const KERN_NMI_WATCHDOG: ::c_int = 75;
4556
pub const KERN_PANIC_ON_NMI: ::c_int = 76;
4557
4558
pub const VM_OVERCOMMIT_MEMORY: ::c_int = 5;
4559
pub const VM_PAGE_CLUSTER: ::c_int = 10;
4560
pub const VM_DIRTY_BACKGROUND: ::c_int = 11;
4561
pub const VM_DIRTY_RATIO: ::c_int = 12;
4562
pub const VM_DIRTY_WB_CS: ::c_int = 13;
4563
pub const VM_DIRTY_EXPIRE_CS: ::c_int = 14;
4564
pub const VM_NR_PDFLUSH_THREADS: ::c_int = 15;
4565
pub const VM_OVERCOMMIT_RATIO: ::c_int = 16;
4566
pub const VM_PAGEBUF: ::c_int = 17;
4567
pub const VM_HUGETLB_PAGES: ::c_int = 18;
4568
pub const VM_SWAPPINESS: ::c_int = 19;
4569
pub const VM_LOWMEM_RESERVE_RATIO: ::c_int = 20;
4570
pub const VM_MIN_FREE_KBYTES: ::c_int = 21;
4571
pub const VM_MAX_MAP_COUNT: ::c_int = 22;
4572
pub const VM_LAPTOP_MODE: ::c_int = 23;
4573
pub const VM_BLOCK_DUMP: ::c_int = 24;
4574
pub const VM_HUGETLB_GROUP: ::c_int = 25;
4575
pub const VM_VFS_CACHE_PRESSURE: ::c_int = 26;
4576
pub const VM_LEGACY_VA_LAYOUT: ::c_int = 27;
4577
pub const VM_SWAP_TOKEN_TIMEOUT: ::c_int = 28;
4578
pub const VM_DROP_PAGECACHE: ::c_int = 29;
4579
pub const VM_PERCPU_PAGELIST_FRACTION: ::c_int = 30;
4580
pub const VM_ZONE_RECLAIM_MODE: ::c_int = 31;
4581
pub const VM_MIN_UNMAPPED: ::c_int = 32;
4582
pub const VM_PANIC_ON_OOM: ::c_int = 33;
4583
pub const VM_VDSO_ENABLED: ::c_int = 34;
4584
pub const VM_MIN_SLAB: ::c_int = 35;
4585
4586
pub const NET_CORE: ::c_int = 1;
4587
pub const NET_ETHER: ::c_int = 2;
4588
pub const NET_802: ::c_int = 3;
4589
pub const NET_UNIX: ::c_int = 4;
4590
pub const NET_IPV4: ::c_int = 5;
4591
pub const NET_IPX: ::c_int = 6;
4592
pub const NET_ATALK: ::c_int = 7;
4593
pub const NET_NETROM: ::c_int = 8;
4594
pub const NET_AX25: ::c_int = 9;
4595
pub const NET_BRIDGE: ::c_int = 10;
4596
pub const NET_ROSE: ::c_int = 11;
4597
pub const NET_IPV6: ::c_int = 12;
4598
pub const NET_X25: ::c_int = 13;
4599
pub const NET_TR: ::c_int = 14;
4600
pub const NET_DECNET: ::c_int = 15;
4601
pub const NET_ECONET: ::c_int = 16;
4602
pub const NET_SCTP: ::c_int = 17;
4603
pub const NET_LLC: ::c_int = 18;
4604
pub const NET_NETFILTER: ::c_int = 19;
4605
pub const NET_DCCP: ::c_int = 20;
4606
pub const NET_IRDA: ::c_int = 412;
4607
4608
// include/linux/sched.h
4609
pub const PF_VCPU: ::c_int = 0x00000001;
4610
pub const PF_IDLE: ::c_int = 0x00000002;
4611
pub const PF_EXITING: ::c_int = 0x00000004;
4612
pub const PF_POSTCOREDUMP: ::c_int = 0x00000008;
4613
pub const PF_IO_WORKER: ::c_int = 0x00000010;
4614
pub const PF_WQ_WORKER: ::c_int = 0x00000020;
4615
pub const PF_FORKNOEXEC: ::c_int = 0x00000040;
4616
pub const PF_MCE_PROCESS: ::c_int = 0x00000080;
4617
pub const PF_SUPERPRIV: ::c_int = 0x00000100;
4618
pub const PF_DUMPCORE: ::c_int = 0x00000200;
4619
pub const PF_SIGNALED: ::c_int = 0x00000400;
4620
pub const PF_MEMALLOC: ::c_int = 0x00000800;
4621
pub const PF_NPROC_EXCEEDED: ::c_int = 0x00001000;
4622
pub const PF_USED_MATH: ::c_int = 0x00002000;
4623
pub const PF_USER_WORKER: ::c_int = 0x00004000;
4624
pub const PF_NOFREEZE: ::c_int = 0x00008000;
4625
pub const PF_KSWAPD: ::c_int = 0x00020000;
4626
pub const PF_MEMALLOC_NOFS: ::c_int = 0x00040000;
4627
pub const PF_MEMALLOC_NOIO: ::c_int = 0x00080000;
4628
pub const PF_LOCAL_THROTTLE: ::c_int = 0x00100000;
4629
pub const PF_KTHREAD: ::c_int = 0x00200000;
4630
pub const PF_RANDOMIZE: ::c_int = 0x00400000;
4631
pub const PF_NO_SETAFFINITY: ::c_int = 0x04000000;
4632
pub const PF_MCE_EARLY: ::c_int = 0x08000000;
4633
pub const PF_MEMALLOC_PIN: ::c_int = 0x10000000;
4634
4635
pub const CSIGNAL: ::c_int = 0x000000ff;
4636
4637
pub const SCHED_NORMAL: ::c_int = 0;
4638
pub const SCHED_OTHER: ::c_int = 0;
4639
pub const SCHED_FIFO: ::c_int = 1;
4640
pub const SCHED_RR: ::c_int = 2;
4641
pub const SCHED_BATCH: ::c_int = 3;
4642
pub const SCHED_IDLE: ::c_int = 5;
4643
pub const SCHED_DEADLINE: ::c_int = 6;
4644
4645
pub const SCHED_RESET_ON_FORK: ::c_int = 0x40000000;
4646
4647
pub const CLONE_PIDFD: ::c_int = 0x1000;
4648
4649
pub const SCHED_FLAG_RESET_ON_FORK: ::c_int = 0x01;
4650
pub const SCHED_FLAG_RECLAIM: ::c_int = 0x02;
4651
pub const SCHED_FLAG_DL_OVERRUN: ::c_int = 0x04;
4652
pub const SCHED_FLAG_KEEP_POLICY: ::c_int = 0x08;
4653
pub const SCHED_FLAG_KEEP_PARAMS: ::c_int = 0x10;
4654
pub const SCHED_FLAG_UTIL_CLAMP_MIN: ::c_int = 0x20;
4655
pub const SCHED_FLAG_UTIL_CLAMP_MAX: ::c_int = 0x40;
4656
4657
pub const SCHED_FLAG_KEEP_ALL: ::c_int = SCHED_FLAG_KEEP_POLICY | SCHED_FLAG_KEEP_PARAMS;
4658
4659
pub const SCHED_FLAG_UTIL_CLAMP: ::c_int = SCHED_FLAG_UTIL_CLAMP_MIN | SCHED_FLAG_UTIL_CLAMP_MAX;
4660
4661
pub const SCHED_FLAG_ALL: ::c_int = SCHED_FLAG_RESET_ON_FORK
4662
    | SCHED_FLAG_RECLAIM
4663
    | SCHED_FLAG_DL_OVERRUN
4664
    | SCHED_FLAG_KEEP_ALL
4665
    | SCHED_FLAG_UTIL_CLAMP;
4666
4667
f! {
4668
    pub fn NLA_ALIGN(len: ::c_int) -> ::c_int {
4669
        return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1)
4670
    }
4671
4672
    pub fn CMSG_NXTHDR(mhdr: *const msghdr,
4673
                       cmsg: *const cmsghdr) -> *mut cmsghdr {
4674
        if ((*cmsg).cmsg_len as usize) < ::mem::size_of::<cmsghdr>() {
4675
            return 0 as *mut cmsghdr;
4676
        };
4677
        let next = (cmsg as usize +
4678
                    super::CMSG_ALIGN((*cmsg).cmsg_len as usize))
4679
            as *mut cmsghdr;
4680
        let max = (*mhdr).msg_control as usize
4681
            + (*mhdr).msg_controllen as usize;
4682
        if (next.wrapping_offset(1)) as usize > max ||
4683
            next as usize + super::CMSG_ALIGN((*next).cmsg_len as usize) > max
4684
        {
4685
            0 as *mut cmsghdr
4686
        } else {
4687
            next as *mut cmsghdr
4688
        }
4689
    }
4690
4691
    pub fn CPU_ALLOC_SIZE(count: ::c_int) -> ::size_t {
4692
        let _dummy: cpu_set_t = ::mem::zeroed();
4693
        let size_in_bits = 8 * ::mem::size_of_val(&_dummy.bits[0]);
4694
        ((count as ::size_t + size_in_bits - 1) / 8) as ::size_t
4695
    }
4696
4697
    pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () {
4698
        for slot in cpuset.bits.iter_mut() {
4699
            *slot = 0;
4700
        }
4701
    }
4702
4703
    pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () {
4704
        let size_in_bits
4705
            = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
4706
        let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
4707
        cpuset.bits[idx] |= 1 << offset;
4708
        ()
4709
    }
4710
4711
    pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () {
4712
        let size_in_bits
4713
            = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc
4714
        let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
4715
        cpuset.bits[idx] &= !(1 << offset);
4716
        ()
4717
    }
4718
4719
    pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool {
4720
        let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]);
4721
        let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits);
4722
        0 != (cpuset.bits[idx] & (1 << offset))
4723
    }
4724
4725
    pub fn CPU_COUNT_S(size: usize, cpuset: &cpu_set_t) -> ::c_int {
4726
        let mut s: u32 = 0;
4727
        let size_of_mask = ::mem::size_of_val(&cpuset.bits[0]);
4728
        for i in cpuset.bits[..(size / size_of_mask)].iter() {
4729
            s += i.count_ones();
4730
        };
4731
        s as ::c_int
4732
    }
4733
4734
    pub fn CPU_COUNT(cpuset: &cpu_set_t) -> ::c_int {
4735
        CPU_COUNT_S(::mem::size_of::<cpu_set_t>(), cpuset)
4736
    }
4737
4738
    pub fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool {
4739
        set1.bits == set2.bits
4740
    }
4741
4742
    pub fn SCTP_PR_INDEX(policy: ::c_int) -> ::c_int {
4743
        policy >> 4 - 1
4744
    }
4745
4746
    pub fn SCTP_PR_POLICY(policy: ::c_int) -> ::c_int {
4747
        policy & SCTP_PR_SCTP_MASK
4748
    }
4749
4750
    pub fn SCTP_PR_SET_POLICY(flags: &mut ::c_int, policy: ::c_int) -> () {
4751
        *flags &= !SCTP_PR_SCTP_MASK;
4752
        *flags |= policy;
4753
        ()
4754
    }
4755
4756
    pub fn major(dev: ::dev_t) -> ::c_uint {
4757
        let mut major = 0;
4758
        major |= (dev & 0x00000000000fff00) >> 8;
4759
        major |= (dev & 0xfffff00000000000) >> 32;
4760
        major as ::c_uint
4761
    }
4762
4763
    pub fn minor(dev: ::dev_t) -> ::c_uint {
4764
        let mut minor = 0;
4765
        minor |= (dev & 0x00000000000000ff) >> 0;
4766
        minor |= (dev & 0x00000ffffff00000) >> 12;
4767
        minor as ::c_uint
4768
    }
4769
4770
    pub fn IPTOS_TOS(tos: u8) -> u8 {
4771
        tos & IPTOS_TOS_MASK
4772
    }
4773
4774
    pub fn IPTOS_PREC(tos: u8) -> u8 {
4775
        tos & IPTOS_PREC_MASK
4776
    }
4777
4778
    pub fn RT_TOS(tos: u8) -> u8 {
4779
        tos & ::IPTOS_TOS_MASK
4780
    }
4781
4782
    pub fn RT_ADDRCLASS(flags: u32) -> u32 {
4783
        flags >> 23
4784
    }
4785
4786
    pub fn RT_LOCALADDR(flags: u32) -> bool {
4787
        (flags & RTF_ADDRCLASSMASK) == (RTF_LOCAL | RTF_INTERFACE)
4788
    }
4789
4790
    pub fn SO_EE_OFFENDER(ee: *const ::sock_extended_err) -> *mut ::sockaddr {
4791
        ee.offset(1) as *mut ::sockaddr
4792
    }
4793
4794
    pub fn BPF_RVAL(code: ::__u32) -> ::__u32 {
4795
        code & 0x18
4796
    }
4797
4798
    pub fn BPF_MISCOP(code: ::__u32) -> ::__u32 {
4799
        code & 0xf8
4800
    }
4801
4802
    pub fn BPF_STMT(code: ::__u16, k: ::__u32) -> sock_filter {
4803
        sock_filter{code: code, jt: 0, jf: 0, k: k}
4804
    }
4805
4806
    pub fn BPF_JUMP(code: ::__u16, k: ::__u32, jt: ::__u8, jf: ::__u8) -> sock_filter {
4807
        sock_filter{code: code, jt: jt, jf: jf, k: k}
4808
    }
4809
}
4810
4811
safe_f! {
4812
    pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t {
4813
        let major = major as ::dev_t;
4814
        let minor = minor as ::dev_t;
4815
        let mut dev = 0;
4816
        dev |= (major & 0x00000fff) << 8;
4817
        dev |= (major & 0xfffff000) << 32;
4818
        dev |= (minor & 0x000000ff) << 0;
4819
        dev |= (minor & 0xffffff00) << 12;
4820
        dev
4821
    }
4822
4823
    pub {const} fn SCTP_PR_TTL_ENABLED(policy: ::c_int) -> bool {
4824
        policy == SCTP_PR_SCTP_TTL
4825
    }
4826
4827
    pub {const} fn SCTP_PR_RTX_ENABLED(policy: ::c_int) -> bool {
4828
        policy == SCTP_PR_SCTP_RTX
4829
    }
4830
4831
    pub {const} fn SCTP_PR_PRIO_ENABLED(policy: ::c_int) -> bool {
4832
        policy == SCTP_PR_SCTP_PRIO
4833
    }
4834
}
4835
4836
cfg_if! {
4837
    if #[cfg(all(not(target_env = "uclibc"), not(target_env = "ohos")))] {
4838
        extern "C" {
4839
            pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int;
4840
            pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int;
4841
            pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int;
4842
            pub fn aio_error(aiocbp: *const aiocb) -> ::c_int;
4843
            pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t;
4844
            pub fn aio_suspend(
4845
                aiocb_list: *const *const aiocb,
4846
                nitems: ::c_int,
4847
                timeout: *const ::timespec,
4848
            ) -> ::c_int;
4849
            pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int;
4850
            pub fn lio_listio(
4851
                mode: ::c_int,
4852
                aiocb_list: *const *mut aiocb,
4853
                nitems: ::c_int,
4854
                sevp: *mut ::sigevent,
4855
            ) -> ::c_int;
4856
        }
4857
    }
4858
}
4859
4860
cfg_if! {
4861
    if #[cfg(not(target_env = "uclibc"))] {
4862
        extern "C" {
4863
            pub fn pwritev(
4864
                fd: ::c_int,
4865
                iov: *const ::iovec,
4866
                iovcnt: ::c_int,
4867
                offset: ::off_t,
4868
            ) -> ::ssize_t;
4869
            pub fn preadv(
4870
                fd: ::c_int,
4871
                iov: *const ::iovec,
4872
                iovcnt: ::c_int,
4873
                offset: ::off_t,
4874
            ) -> ::ssize_t;
4875
            pub fn getnameinfo(
4876
                sa: *const ::sockaddr,
4877
                salen: ::socklen_t,
4878
                host: *mut ::c_char,
4879
                hostlen: ::socklen_t,
4880
                serv: *mut ::c_char,
4881
                servlen: ::socklen_t,
4882
                flags: ::c_int,
4883
            ) -> ::c_int;
4884
            pub fn getloadavg(
4885
                loadavg: *mut ::c_double,
4886
                nelem: ::c_int
4887
            ) -> ::c_int;
4888
            pub fn process_vm_readv(
4889
                pid: ::pid_t,
4890
                local_iov: *const ::iovec,
4891
                liovcnt: ::c_ulong,
4892
                remote_iov: *const ::iovec,
4893
                riovcnt: ::c_ulong,
4894
                flags: ::c_ulong,
4895
            ) -> isize;
4896
            pub fn process_vm_writev(
4897
                pid: ::pid_t,
4898
                local_iov: *const ::iovec,
4899
                liovcnt: ::c_ulong,
4900
                remote_iov: *const ::iovec,
4901
                riovcnt: ::c_ulong,
4902
                flags: ::c_ulong,
4903
            ) -> isize;
4904
            pub fn futimes(
4905
                fd: ::c_int,
4906
                times: *const ::timeval
4907
            ) -> ::c_int;
4908
        }
4909
    }
4910
}
4911
4912
// These functions are not available on OpenHarmony
4913
cfg_if! {
4914
    if #[cfg(not(target_env = "ohos"))] {
4915
        extern "C" {
4916
            // Only `getspnam_r` is implemented for musl, out of all of the reenterant
4917
            // functions from `shadow.h`.
4918
            // https://git.musl-libc.org/cgit/musl/tree/include/shadow.h
4919
            pub fn getspnam_r(
4920
                name: *const ::c_char,
4921
                spbuf: *mut spwd,
4922
                buf: *mut ::c_char,
4923
                buflen: ::size_t,
4924
                spbufp: *mut *mut spwd,
4925
            ) -> ::c_int;
4926
4927
            pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int;
4928
            pub fn shm_unlink(name: *const ::c_char) -> ::c_int;
4929
4930
            pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t;
4931
            pub fn mq_close(mqd: ::mqd_t) -> ::c_int;
4932
            pub fn mq_unlink(name: *const ::c_char) -> ::c_int;
4933
            pub fn mq_receive(
4934
                mqd: ::mqd_t,
4935
                msg_ptr: *mut ::c_char,
4936
                msg_len: ::size_t,
4937
                msg_prio: *mut ::c_uint,
4938
            ) -> ::ssize_t;
4939
            pub fn mq_timedreceive(
4940
                mqd: ::mqd_t,
4941
                msg_ptr: *mut ::c_char,
4942
                msg_len: ::size_t,
4943
                msg_prio: *mut ::c_uint,
4944
                abs_timeout: *const ::timespec,
4945
            ) -> ::ssize_t;
4946
            pub fn mq_send(
4947
                mqd: ::mqd_t,
4948
                msg_ptr: *const ::c_char,
4949
                msg_len: ::size_t,
4950
                msg_prio: ::c_uint,
4951
            ) -> ::c_int;
4952
            pub fn mq_timedsend(
4953
                mqd: ::mqd_t,
4954
                msg_ptr: *const ::c_char,
4955
                msg_len: ::size_t,
4956
                msg_prio: ::c_uint,
4957
                abs_timeout: *const ::timespec,
4958
            ) -> ::c_int;
4959
            pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int;
4960
            pub fn mq_setattr(
4961
                mqd: ::mqd_t,
4962
                newattr: *const ::mq_attr,
4963
                oldattr: *mut ::mq_attr
4964
            ) -> ::c_int;
4965
4966
            pub fn pthread_mutex_consistent(mutex: *mut pthread_mutex_t) -> ::c_int;
4967
            pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int;
4968
            pub fn pthread_mutexattr_getrobust(
4969
                attr: *const pthread_mutexattr_t,
4970
                robustness: *mut ::c_int,
4971
            ) -> ::c_int;
4972
            pub fn pthread_mutexattr_setrobust(
4973
                attr: *mut pthread_mutexattr_t,
4974
                robustness: ::c_int,
4975
            ) -> ::c_int;
4976
        }
4977
    }
4978
}
4979
4980
extern "C" {
4981
    #[cfg_attr(
4982
        not(any(target_env = "musl", target_env = "ohos")),
4983
        link_name = "__xpg_strerror_r"
4984
    )]
4985
    pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int;
4986
4987
    pub fn abs(i: ::c_int) -> ::c_int;
4988
    pub fn labs(i: ::c_long) -> ::c_long;
4989
    pub fn rand() -> ::c_int;
4990
    pub fn srand(seed: ::c_uint);
4991
4992
    pub fn drand48() -> ::c_double;
4993
    pub fn erand48(xseed: *mut ::c_ushort) -> ::c_double;
4994
    pub fn lrand48() -> ::c_long;
4995
    pub fn nrand48(xseed: *mut ::c_ushort) -> ::c_long;
4996
    pub fn mrand48() -> ::c_long;
4997
    pub fn jrand48(xseed: *mut ::c_ushort) -> ::c_long;
4998
    pub fn srand48(seed: ::c_long);
4999
    pub fn seed48(xseed: *mut ::c_ushort) -> *mut ::c_ushort;
5000
    pub fn lcong48(p: *mut ::c_ushort);
5001
5002
    pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int;
5003
5004
    pub fn setpwent();
5005
    pub fn endpwent();
5006
    pub fn getpwent() -> *mut passwd;
5007
    pub fn setgrent();
5008
    pub fn endgrent();
5009
    pub fn getgrent() -> *mut ::group;
5010
    pub fn setspent();
5011
    pub fn endspent();
5012
    pub fn getspent() -> *mut spwd;
5013
5014
    pub fn getspnam(name: *const ::c_char) -> *mut spwd;
5015
5016
    // System V IPC
5017
    pub fn shmget(key: ::key_t, size: ::size_t, shmflg: ::c_int) -> ::c_int;
5018
    pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void;
5019
    pub fn shmdt(shmaddr: *const ::c_void) -> ::c_int;
5020
    pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int;
5021
    pub fn ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t;
5022
    pub fn semget(key: ::key_t, nsems: ::c_int, semflag: ::c_int) -> ::c_int;
5023
    pub fn semop(semid: ::c_int, sops: *mut ::sembuf, nsops: ::size_t) -> ::c_int;
5024
    pub fn semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::c_int;
5025
    pub fn msgctl(msqid: ::c_int, cmd: ::c_int, buf: *mut msqid_ds) -> ::c_int;
5026
    pub fn msgget(key: ::key_t, msgflg: ::c_int) -> ::c_int;
5027
    pub fn msgrcv(
5028
        msqid: ::c_int,
5029
        msgp: *mut ::c_void,
5030
        msgsz: ::size_t,
5031
        msgtyp: ::c_long,
5032
        msgflg: ::c_int,
5033
    ) -> ::ssize_t;
5034
    pub fn msgsnd(
5035
        msqid: ::c_int,
5036
        msgp: *const ::c_void,
5037
        msgsz: ::size_t,
5038
        msgflg: ::c_int,
5039
    ) -> ::c_int;
5040
5041
    pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int;
5042
    pub fn __errno_location() -> *mut ::c_int;
5043
5044
    pub fn fallocate(fd: ::c_int, mode: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int;
5045
    pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int;
5046
    pub fn readahead(fd: ::c_int, offset: ::off64_t, count: ::size_t) -> ::ssize_t;
5047
    pub fn getxattr(
5048
        path: *const c_char,
5049
        name: *const c_char,
5050
        value: *mut ::c_void,
5051
        size: ::size_t,
5052
    ) -> ::ssize_t;
5053
    pub fn lgetxattr(
5054
        path: *const c_char,
5055
        name: *const c_char,
5056
        value: *mut ::c_void,
5057
        size: ::size_t,
5058
    ) -> ::ssize_t;
5059
    pub fn fgetxattr(
5060
        filedes: ::c_int,
5061
        name: *const c_char,
5062
        value: *mut ::c_void,
5063
        size: ::size_t,
5064
    ) -> ::ssize_t;
5065
    pub fn setxattr(
5066
        path: *const c_char,
5067
        name: *const c_char,
5068
        value: *const ::c_void,
5069
        size: ::size_t,
5070
        flags: ::c_int,
5071
    ) -> ::c_int;
5072
    pub fn lsetxattr(
5073
        path: *const c_char,
5074
        name: *const c_char,
5075
        value: *const ::c_void,
5076
        size: ::size_t,
5077
        flags: ::c_int,
5078
    ) -> ::c_int;
5079
    pub fn fsetxattr(
5080
        filedes: ::c_int,
5081
        name: *const c_char,
5082
        value: *const ::c_void,
5083
        size: ::size_t,
5084
        flags: ::c_int,
5085
    ) -> ::c_int;
5086
    pub fn listxattr(path: *const c_char, list: *mut c_char, size: ::size_t) -> ::ssize_t;
5087
    pub fn llistxattr(path: *const c_char, list: *mut c_char, size: ::size_t) -> ::ssize_t;
5088
    pub fn flistxattr(filedes: ::c_int, list: *mut c_char, size: ::size_t) -> ::ssize_t;
5089
    pub fn removexattr(path: *const c_char, name: *const c_char) -> ::c_int;
5090
    pub fn lremovexattr(path: *const c_char, name: *const c_char) -> ::c_int;
5091
    pub fn fremovexattr(filedes: ::c_int, name: *const c_char) -> ::c_int;
5092
    pub fn signalfd(fd: ::c_int, mask: *const ::sigset_t, flags: ::c_int) -> ::c_int;
5093
    pub fn timerfd_create(clockid: ::clockid_t, flags: ::c_int) -> ::c_int;
5094
    pub fn timerfd_gettime(fd: ::c_int, curr_value: *mut itimerspec) -> ::c_int;
5095
    pub fn timerfd_settime(
5096
        fd: ::c_int,
5097
        flags: ::c_int,
5098
        new_value: *const itimerspec,
5099
        old_value: *mut itimerspec,
5100
    ) -> ::c_int;
5101
    pub fn quotactl(
5102
        cmd: ::c_int,
5103
        special: *const ::c_char,
5104
        id: ::c_int,
5105
        data: *mut ::c_char,
5106
    ) -> ::c_int;
5107
    pub fn epoll_pwait(
5108
        epfd: ::c_int,
5109
        events: *mut ::epoll_event,
5110
        maxevents: ::c_int,
5111
        timeout: ::c_int,
5112
        sigmask: *const ::sigset_t,
5113
    ) -> ::c_int;
5114
    pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::c_int) -> ::c_int;
5115
    pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int;
5116
    pub fn mkostemps(template: *mut ::c_char, suffixlen: ::c_int, flags: ::c_int) -> ::c_int;
5117
    pub fn sigtimedwait(
5118
        set: *const sigset_t,
5119
        info: *mut siginfo_t,
5120
        timeout: *const ::timespec,
5121
    ) -> ::c_int;
5122
    pub fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int;
5123
    pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char;
5124
    pub fn accept4(
5125
        fd: ::c_int,
5126
        addr: *mut ::sockaddr,
5127
        len: *mut ::socklen_t,
5128
        flg: ::c_int,
5129
    ) -> ::c_int;
5130
    pub fn pthread_getaffinity_np(
5131
        thread: ::pthread_t,
5132
        cpusetsize: ::size_t,
5133
        cpuset: *mut ::cpu_set_t,
5134
    ) -> ::c_int;
5135
    pub fn pthread_setaffinity_np(
5136
        thread: ::pthread_t,
5137
        cpusetsize: ::size_t,
5138
        cpuset: *const ::cpu_set_t,
5139
    ) -> ::c_int;
5140
    pub fn pthread_setschedprio(native: ::pthread_t, priority: ::c_int) -> ::c_int;
5141
    pub fn reboot(how_to: ::c_int) -> ::c_int;
5142
    pub fn setfsgid(gid: ::gid_t) -> ::c_int;
5143
    pub fn setfsuid(uid: ::uid_t) -> ::c_int;
5144
5145
    // Not available now on Android
5146
    pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int;
5147
    pub fn if_nameindex() -> *mut if_nameindex;
5148
    pub fn if_freenameindex(ptr: *mut if_nameindex);
5149
    pub fn sync_file_range(
5150
        fd: ::c_int,
5151
        offset: ::off64_t,
5152
        nbytes: ::off64_t,
5153
        flags: ::c_uint,
5154
    ) -> ::c_int;
5155
    pub fn mremap(
5156
        addr: *mut ::c_void,
5157
        len: ::size_t,
5158
        new_len: ::size_t,
5159
        flags: ::c_int,
5160
        ...
5161
    ) -> *mut ::c_void;
5162
5163
    pub fn glob(
5164
        pattern: *const c_char,
5165
        flags: ::c_int,
5166
        errfunc: ::Option<extern "C" fn(epath: *const c_char, errno: ::c_int) -> ::c_int>,
5167
        pglob: *mut ::glob_t,
5168
    ) -> ::c_int;
5169
    pub fn globfree(pglob: *mut ::glob_t);
5170
5171
    pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int;
5172
5173
    pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long);
5174
5175
    pub fn telldir(dirp: *mut ::DIR) -> ::c_long;
5176
    pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int;
5177
5178
    pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int;
5179
    pub fn remap_file_pages(
5180
        addr: *mut ::c_void,
5181
        size: ::size_t,
5182
        prot: ::c_int,
5183
        pgoff: ::size_t,
5184
        flags: ::c_int,
5185
    ) -> ::c_int;
5186
    pub fn recvfrom(
5187
        socket: ::c_int,
5188
        buf: *mut ::c_void,
5189
        len: ::size_t,
5190
        flags: ::c_int,
5191
        addr: *mut ::sockaddr,
5192
        addrlen: *mut ::socklen_t,
5193
    ) -> ::ssize_t;
5194
    pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int;
5195
5196
    pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char;
5197
5198
    pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int;
5199
    pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int;
5200
    pub fn vhangup() -> ::c_int;
5201
    pub fn sync();
5202
    pub fn syncfs(fd: ::c_int) -> ::c_int;
5203
    pub fn syscall(num: ::c_long, ...) -> ::c_long;
5204
    pub fn sched_getaffinity(pid: ::pid_t, cpusetsize: ::size_t, cpuset: *mut cpu_set_t)
5205
        -> ::c_int;
5206
    pub fn sched_setaffinity(
5207
        pid: ::pid_t,
5208
        cpusetsize: ::size_t,
5209
        cpuset: *const cpu_set_t,
5210
    ) -> ::c_int;
5211
    pub fn epoll_create(size: ::c_int) -> ::c_int;
5212
    pub fn epoll_create1(flags: ::c_int) -> ::c_int;
5213
    pub fn epoll_wait(
5214
        epfd: ::c_int,
5215
        events: *mut ::epoll_event,
5216
        maxevents: ::c_int,
5217
        timeout: ::c_int,
5218
    ) -> ::c_int;
5219
    pub fn epoll_ctl(epfd: ::c_int, op: ::c_int, fd: ::c_int, event: *mut ::epoll_event)
5220
        -> ::c_int;
5221
    pub fn pthread_getschedparam(
5222
        native: ::pthread_t,
5223
        policy: *mut ::c_int,
5224
        param: *mut ::sched_param,
5225
    ) -> ::c_int;
5226
    pub fn unshare(flags: ::c_int) -> ::c_int;
5227
    pub fn umount(target: *const ::c_char) -> ::c_int;
5228
    pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int;
5229
    pub fn tee(fd_in: ::c_int, fd_out: ::c_int, len: ::size_t, flags: ::c_uint) -> ::ssize_t;
5230
    pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int;
5231
    pub fn splice(
5232
        fd_in: ::c_int,
5233
        off_in: *mut ::loff_t,
5234
        fd_out: ::c_int,
5235
        off_out: *mut ::loff_t,
5236
        len: ::size_t,
5237
        flags: ::c_uint,
5238
    ) -> ::ssize_t;
5239
    pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int;
5240
    pub fn eventfd_read(fd: ::c_int, value: *mut eventfd_t) -> ::c_int;
5241
    pub fn eventfd_write(fd: ::c_int, value: eventfd_t) -> ::c_int;
5242
5243
    pub fn sched_rr_get_interval(pid: ::pid_t, tp: *mut ::timespec) -> ::c_int;
5244
    pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int;
5245
    pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int;
5246
    pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int;
5247
    pub fn setns(fd: ::c_int, nstype: ::c_int) -> ::c_int;
5248
    pub fn swapoff(path: *const ::c_char) -> ::c_int;
5249
    pub fn vmsplice(
5250
        fd: ::c_int,
5251
        iov: *const ::iovec,
5252
        nr_segs: ::size_t,
5253
        flags: ::c_uint,
5254
    ) -> ::ssize_t;
5255
    pub fn mount(
5256
        src: *const ::c_char,
5257
        target: *const ::c_char,
5258
        fstype: *const ::c_char,
5259
        flags: ::c_ulong,
5260
        data: *const ::c_void,
5261
    ) -> ::c_int;
5262
    pub fn personality(persona: ::c_ulong) -> ::c_int;
5263
    pub fn prctl(option: ::c_int, ...) -> ::c_int;
5264
    pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int;
5265
    pub fn ppoll(
5266
        fds: *mut ::pollfd,
5267
        nfds: nfds_t,
5268
        timeout: *const ::timespec,
5269
        sigmask: *const sigset_t,
5270
    ) -> ::c_int;
5271
    pub fn pthread_mutexattr_getprotocol(
5272
        attr: *const pthread_mutexattr_t,
5273
        protocol: *mut ::c_int,
5274
    ) -> ::c_int;
5275
    pub fn pthread_mutexattr_setprotocol(
5276
        attr: *mut pthread_mutexattr_t,
5277
        protocol: ::c_int,
5278
    ) -> ::c_int;
5279
5280
    pub fn pthread_mutex_timedlock(
5281
        lock: *mut pthread_mutex_t,
5282
        abstime: *const ::timespec,
5283
    ) -> ::c_int;
5284
    pub fn pthread_barrierattr_init(attr: *mut ::pthread_barrierattr_t) -> ::c_int;
5285
    pub fn pthread_barrierattr_destroy(attr: *mut ::pthread_barrierattr_t) -> ::c_int;
5286
    pub fn pthread_barrierattr_getpshared(
5287
        attr: *const ::pthread_barrierattr_t,
5288
        shared: *mut ::c_int,
5289
    ) -> ::c_int;
5290
    pub fn pthread_barrierattr_setpshared(
5291
        attr: *mut ::pthread_barrierattr_t,
5292
        shared: ::c_int,
5293
    ) -> ::c_int;
5294
    pub fn pthread_barrier_init(
5295
        barrier: *mut pthread_barrier_t,
5296
        attr: *const ::pthread_barrierattr_t,
5297
        count: ::c_uint,
5298
    ) -> ::c_int;
5299
    pub fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t) -> ::c_int;
5300
    pub fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> ::c_int;
5301
    pub fn pthread_spin_init(lock: *mut ::pthread_spinlock_t, pshared: ::c_int) -> ::c_int;
5302
    pub fn pthread_spin_destroy(lock: *mut ::pthread_spinlock_t) -> ::c_int;
5303
    pub fn pthread_spin_lock(lock: *mut ::pthread_spinlock_t) -> ::c_int;
5304
    pub fn pthread_spin_trylock(lock: *mut ::pthread_spinlock_t) -> ::c_int;
5305
    pub fn pthread_spin_unlock(lock: *mut ::pthread_spinlock_t) -> ::c_int;
5306
    pub fn clone(
5307
        cb: extern "C" fn(*mut ::c_void) -> ::c_int,
5308
        child_stack: *mut ::c_void,
5309
        flags: ::c_int,
5310
        arg: *mut ::c_void,
5311
        ...
5312
    ) -> ::c_int;
5313
    pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int;
5314
    pub fn clock_nanosleep(
5315
        clk_id: ::clockid_t,
5316
        flags: ::c_int,
5317
        rqtp: *const ::timespec,
5318
        rmtp: *mut ::timespec,
5319
    ) -> ::c_int;
5320
    pub fn pthread_attr_getguardsize(
5321
        attr: *const ::pthread_attr_t,
5322
        guardsize: *mut ::size_t,
5323
    ) -> ::c_int;
5324
    pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int;
5325
    pub fn pthread_attr_getinheritsched(
5326
        attr: *const ::pthread_attr_t,
5327
        inheritsched: *mut ::c_int,
5328
    ) -> ::c_int;
5329
    pub fn pthread_attr_setinheritsched(
5330
        attr: *mut ::pthread_attr_t,
5331
        inheritsched: ::c_int,
5332
    ) -> ::c_int;
5333
    pub fn pthread_attr_getschedpolicy(
5334
        attr: *const ::pthread_attr_t,
5335
        policy: *mut ::c_int,
5336
    ) -> ::c_int;
5337
    pub fn pthread_attr_setschedpolicy(attr: *mut ::pthread_attr_t, policy: ::c_int) -> ::c_int;
5338
    pub fn pthread_attr_getschedparam(
5339
        attr: *const ::pthread_attr_t,
5340
        param: *mut ::sched_param,
5341
    ) -> ::c_int;
5342
    pub fn pthread_attr_setschedparam(
5343
        attr: *mut ::pthread_attr_t,
5344
        param: *const ::sched_param,
5345
    ) -> ::c_int;
5346
    pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::c_int;
5347
    pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int;
5348
    pub fn pthread_condattr_getpshared(
5349
        attr: *const pthread_condattr_t,
5350
        pshared: *mut ::c_int,
5351
    ) -> ::c_int;
5352
    pub fn sysinfo(info: *mut ::sysinfo) -> ::c_int;
5353
    pub fn umount2(target: *const ::c_char, flags: ::c_int) -> ::c_int;
5354
    pub fn pthread_setschedparam(
5355
        native: ::pthread_t,
5356
        policy: ::c_int,
5357
        param: *const ::sched_param,
5358
    ) -> ::c_int;
5359
    pub fn swapon(path: *const ::c_char, swapflags: ::c_int) -> ::c_int;
5360
    pub fn sched_setscheduler(
5361
        pid: ::pid_t,
5362
        policy: ::c_int,
5363
        param: *const ::sched_param,
5364
    ) -> ::c_int;
5365
    pub fn sendfile(
5366
        out_fd: ::c_int,
5367
        in_fd: ::c_int,
5368
        offset: *mut off_t,
5369
        count: ::size_t,
5370
    ) -> ::ssize_t;
5371
    pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int;
5372
    pub fn getgrgid_r(
5373
        gid: ::gid_t,
5374
        grp: *mut ::group,
5375
        buf: *mut ::c_char,
5376
        buflen: ::size_t,
5377
        result: *mut *mut ::group,
5378
    ) -> ::c_int;
5379
    pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int;
5380
    pub fn sem_close(sem: *mut sem_t) -> ::c_int;
5381
    pub fn getdtablesize() -> ::c_int;
5382
    pub fn getgrnam_r(
5383
        name: *const ::c_char,
5384
        grp: *mut ::group,
5385
        buf: *mut ::c_char,
5386
        buflen: ::size_t,
5387
        result: *mut *mut ::group,
5388
    ) -> ::c_int;
5389
    pub fn initgroups(user: *const ::c_char, group: ::gid_t) -> ::c_int;
5390
    pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int;
5391
    pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t;
5392
    pub fn getgrnam(name: *const ::c_char) -> *mut ::group;
5393
    pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int;
5394
    pub fn sem_unlink(name: *const ::c_char) -> ::c_int;
5395
    pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int;
5396
    pub fn getpwnam_r(
5397
        name: *const ::c_char,
5398
        pwd: *mut passwd,
5399
        buf: *mut ::c_char,
5400
        buflen: ::size_t,
5401
        result: *mut *mut passwd,
5402
    ) -> ::c_int;
5403
    pub fn getpwuid_r(
5404
        uid: ::uid_t,
5405
        pwd: *mut passwd,
5406
        buf: *mut ::c_char,
5407
        buflen: ::size_t,
5408
        result: *mut *mut passwd,
5409
    ) -> ::c_int;
5410
    pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int;
5411
    pub fn pthread_atfork(
5412
        prepare: ::Option<unsafe extern "C" fn()>,
5413
        parent: ::Option<unsafe extern "C" fn()>,
5414
        child: ::Option<unsafe extern "C" fn()>,
5415
    ) -> ::c_int;
5416
    pub fn getgrgid(gid: ::gid_t) -> *mut ::group;
5417
    pub fn getgrouplist(
5418
        user: *const ::c_char,
5419
        group: ::gid_t,
5420
        groups: *mut ::gid_t,
5421
        ngroups: *mut ::c_int,
5422
    ) -> ::c_int;
5423
    pub fn pthread_mutexattr_getpshared(
5424
        attr: *const pthread_mutexattr_t,
5425
        pshared: *mut ::c_int,
5426
    ) -> ::c_int;
5427
    pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE;
5428
    pub fn faccessat(
5429
        dirfd: ::c_int,
5430
        pathname: *const ::c_char,
5431
        mode: ::c_int,
5432
        flags: ::c_int,
5433
    ) -> ::c_int;
5434
    pub fn pthread_create(
5435
        native: *mut ::pthread_t,
5436
        attr: *const ::pthread_attr_t,
5437
        f: extern "C" fn(*mut ::c_void) -> *mut ::c_void,
5438
        value: *mut ::c_void,
5439
    ) -> ::c_int;
5440
    pub fn dl_iterate_phdr(
5441
        callback: ::Option<
5442
            unsafe extern "C" fn(
5443
                info: *mut ::dl_phdr_info,
5444
                size: ::size_t,
5445
                data: *mut ::c_void,
5446
            ) -> ::c_int,
5447
        >,
5448
        data: *mut ::c_void,
5449
    ) -> ::c_int;
5450
5451
    pub fn setmntent(filename: *const ::c_char, ty: *const ::c_char) -> *mut ::FILE;
5452
    pub fn getmntent(stream: *mut ::FILE) -> *mut ::mntent;
5453
    pub fn addmntent(stream: *mut ::FILE, mnt: *const ::mntent) -> ::c_int;
5454
    pub fn endmntent(streamp: *mut ::FILE) -> ::c_int;
5455
    pub fn hasmntopt(mnt: *const ::mntent, opt: *const ::c_char) -> *mut ::c_char;
5456
5457
    pub fn posix_spawn(
5458
        pid: *mut ::pid_t,
5459
        path: *const ::c_char,
5460
        file_actions: *const ::posix_spawn_file_actions_t,
5461
        attrp: *const ::posix_spawnattr_t,
5462
        argv: *const *mut ::c_char,
5463
        envp: *const *mut ::c_char,
5464
    ) -> ::c_int;
5465
    pub fn posix_spawnp(
5466
        pid: *mut ::pid_t,
5467
        file: *const ::c_char,
5468
        file_actions: *const ::posix_spawn_file_actions_t,
5469
        attrp: *const ::posix_spawnattr_t,
5470
        argv: *const *mut ::c_char,
5471
        envp: *const *mut ::c_char,
5472
    ) -> ::c_int;
5473
    pub fn posix_spawnattr_init(attr: *mut posix_spawnattr_t) -> ::c_int;
5474
    pub fn posix_spawnattr_destroy(attr: *mut posix_spawnattr_t) -> ::c_int;
5475
    pub fn posix_spawnattr_getsigdefault(
5476
        attr: *const posix_spawnattr_t,
5477
        default: *mut ::sigset_t,
5478
    ) -> ::c_int;
5479
    pub fn posix_spawnattr_setsigdefault(
5480
        attr: *mut posix_spawnattr_t,
5481
        default: *const ::sigset_t,
5482
    ) -> ::c_int;
5483
    pub fn posix_spawnattr_getsigmask(
5484
        attr: *const posix_spawnattr_t,
5485
        default: *mut ::sigset_t,
5486
    ) -> ::c_int;
5487
    pub fn posix_spawnattr_setsigmask(
5488
        attr: *mut posix_spawnattr_t,
5489
        default: *const ::sigset_t,
5490
    ) -> ::c_int;
5491
    pub fn posix_spawnattr_getflags(
5492
        attr: *const posix_spawnattr_t,
5493
        flags: *mut ::c_short,
5494
    ) -> ::c_int;
5495
    pub fn posix_spawnattr_setflags(attr: *mut posix_spawnattr_t, flags: ::c_short) -> ::c_int;
5496
    pub fn posix_spawnattr_getpgroup(
5497
        attr: *const posix_spawnattr_t,
5498
        flags: *mut ::pid_t,
5499
    ) -> ::c_int;
5500
    pub fn posix_spawnattr_setpgroup(attr: *mut posix_spawnattr_t, flags: ::pid_t) -> ::c_int;
5501
    pub fn posix_spawnattr_getschedpolicy(
5502
        attr: *const posix_spawnattr_t,
5503
        flags: *mut ::c_int,
5504
    ) -> ::c_int;
5505
    pub fn posix_spawnattr_setschedpolicy(attr: *mut posix_spawnattr_t, flags: ::c_int) -> ::c_int;
5506
    pub fn posix_spawnattr_getschedparam(
5507
        attr: *const posix_spawnattr_t,
5508
        param: *mut ::sched_param,
5509
    ) -> ::c_int;
5510
    pub fn posix_spawnattr_setschedparam(
5511
        attr: *mut posix_spawnattr_t,
5512
        param: *const ::sched_param,
5513
    ) -> ::c_int;
5514
5515
    pub fn posix_spawn_file_actions_init(actions: *mut posix_spawn_file_actions_t) -> ::c_int;
5516
    pub fn posix_spawn_file_actions_destroy(actions: *mut posix_spawn_file_actions_t) -> ::c_int;
5517
    pub fn posix_spawn_file_actions_addopen(
5518
        actions: *mut posix_spawn_file_actions_t,
5519
        fd: ::c_int,
5520
        path: *const ::c_char,
5521
        oflag: ::c_int,
5522
        mode: ::mode_t,
5523
    ) -> ::c_int;
5524
    pub fn posix_spawn_file_actions_addclose(
5525
        actions: *mut posix_spawn_file_actions_t,
5526
        fd: ::c_int,
5527
    ) -> ::c_int;
5528
    pub fn posix_spawn_file_actions_adddup2(
5529
        actions: *mut posix_spawn_file_actions_t,
5530
        fd: ::c_int,
5531
        newfd: ::c_int,
5532
    ) -> ::c_int;
5533
    pub fn fread_unlocked(
5534
        buf: *mut ::c_void,
5535
        size: ::size_t,
5536
        nobj: ::size_t,
5537
        stream: *mut ::FILE,
5538
    ) -> ::size_t;
5539
    pub fn inotify_rm_watch(fd: ::c_int, wd: ::c_int) -> ::c_int;
5540
    pub fn inotify_init() -> ::c_int;
5541
    pub fn inotify_init1(flags: ::c_int) -> ::c_int;
5542
    pub fn inotify_add_watch(fd: ::c_int, path: *const ::c_char, mask: u32) -> ::c_int;
5543
    pub fn fanotify_init(flags: ::c_uint, event_f_flags: ::c_uint) -> ::c_int;
5544
5545
    pub fn regcomp(preg: *mut ::regex_t, pattern: *const ::c_char, cflags: ::c_int) -> ::c_int;
5546
5547
    pub fn regexec(
5548
        preg: *const ::regex_t,
5549
        input: *const ::c_char,
5550
        nmatch: ::size_t,
5551
        pmatch: *mut regmatch_t,
5552
        eflags: ::c_int,
5553
    ) -> ::c_int;
5554
5555
    pub fn regerror(
5556
        errcode: ::c_int,
5557
        preg: *const ::regex_t,
5558
        errbuf: *mut ::c_char,
5559
        errbuf_size: ::size_t,
5560
    ) -> ::size_t;
5561
5562
    pub fn regfree(preg: *mut ::regex_t);
5563
5564
    pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t;
5565
    pub fn iconv(
5566
        cd: iconv_t,
5567
        inbuf: *mut *mut ::c_char,
5568
        inbytesleft: *mut ::size_t,
5569
        outbuf: *mut *mut ::c_char,
5570
        outbytesleft: *mut ::size_t,
5571
    ) -> ::size_t;
5572
    pub fn iconv_close(cd: iconv_t) -> ::c_int;
5573
5574
    pub fn gettid() -> ::pid_t;
5575
5576
    pub fn timer_create(
5577
        clockid: ::clockid_t,
5578
        sevp: *mut ::sigevent,
5579
        timerid: *mut ::timer_t,
5580
    ) -> ::c_int;
5581
    pub fn timer_delete(timerid: ::timer_t) -> ::c_int;
5582
    pub fn timer_getoverrun(timerid: ::timer_t) -> ::c_int;
5583
    pub fn timer_gettime(timerid: ::timer_t, curr_value: *mut ::itimerspec) -> ::c_int;
5584
    pub fn timer_settime(
5585
        timerid: ::timer_t,
5586
        flags: ::c_int,
5587
        new_value: *const ::itimerspec,
5588
        old_value: *mut ::itimerspec,
5589
    ) -> ::c_int;
5590
5591
    pub fn gethostid() -> ::c_long;
5592
5593
    pub fn pthread_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int;
5594
    pub fn memmem(
5595
        haystack: *const ::c_void,
5596
        haystacklen: ::size_t,
5597
        needle: *const ::c_void,
5598
        needlelen: ::size_t,
5599
    ) -> *mut ::c_void;
5600
    pub fn sched_getcpu() -> ::c_int;
5601
5602
    pub fn pthread_getname_np(thread: ::pthread_t, name: *mut ::c_char, len: ::size_t) -> ::c_int;
5603
    pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int;
5604
    pub fn getopt_long(
5605
        argc: ::c_int,
5606
        argv: *const *mut c_char,
5607
        optstring: *const c_char,
5608
        longopts: *const option,
5609
        longindex: *mut ::c_int,
5610
    ) -> ::c_int;
5611
5612
    pub fn pthread_once(control: *mut pthread_once_t, routine: extern "C" fn()) -> ::c_int;
5613
5614
    pub fn copy_file_range(
5615
        fd_in: ::c_int,
5616
        off_in: *mut ::off64_t,
5617
        fd_out: ::c_int,
5618
        off_out: *mut ::off64_t,
5619
        len: ::size_t,
5620
        flags: ::c_uint,
5621
    ) -> ::ssize_t;
5622
}
5623
5624
// LFS64 extensions
5625
//
5626
// * musl has 64-bit versions only so aliases the LFS64 symbols to the standard ones
5627
cfg_if! {
5628
    if #[cfg(not(target_env = "musl"))] {
5629
        extern "C" {
5630
            pub fn fallocate64(
5631
                fd: ::c_int,
5632
                mode: ::c_int,
5633
                offset: ::off64_t,
5634
                len: ::off64_t
5635
            ) -> ::c_int;
5636
            pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int;
5637
            pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut ::FILE;
5638
            pub fn freopen64(
5639
                filename: *const c_char,
5640
                mode: *const c_char,
5641
                file: *mut ::FILE,
5642
            ) -> *mut ::FILE;
5643
            pub fn fseeko64(stream: *mut ::FILE, offset: ::off64_t, whence: ::c_int) -> ::c_int;
5644
            pub fn fsetpos64(stream: *mut ::FILE, ptr: *const fpos64_t) -> ::c_int;
5645
            pub fn ftello64(stream: *mut ::FILE) -> ::off64_t;
5646
            pub fn posix_fallocate64(fd: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int;
5647
            pub fn sendfile64(
5648
                out_fd: ::c_int,
5649
                in_fd: ::c_int,
5650
                offset: *mut off64_t,
5651
                count: ::size_t,
5652
            ) -> ::ssize_t;
5653
            pub fn tmpfile64() -> *mut ::FILE;
5654
        }
5655
    }
5656
}
5657
5658
cfg_if! {
5659
    if #[cfg(target_env = "uclibc")] {
5660
        mod uclibc;
5661
        pub use self::uclibc::*;
5662
    } else if #[cfg(any(target_env = "musl", target_env = "ohos"))] {
5663
        mod musl;
5664
        pub use self::musl::*;
5665
    } else if #[cfg(target_env = "gnu")] {
5666
        mod gnu;
5667
        pub use self::gnu::*;
5668
    }
5669
}
5670
5671
mod arch;
5672
pub use self::arch::*;
5673
5674
cfg_if! {
5675
    if #[cfg(libc_align)] {
5676
        #[macro_use]
5677
        mod align;
5678
    } else {
5679
        #[macro_use]
5680
        mod no_align;
5681
    }
5682
}
5683
expand_align!();
5684
5685
cfg_if! {
5686
    if #[cfg(libc_non_exhaustive)] {
5687
        mod non_exhaustive;
5688
        pub use self::non_exhaustive::*;
5689
    }
5690
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/lru-0.12.3/src/lib.rs
Line
Count
Source
1
// MIT License
2
3
// Copyright (c) 2016 Jerome Froelich
4
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
6
// of this software and associated documentation files (the "Software"), to deal
7
// in the Software without restriction, including without limitation the rights
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the Software is
10
// furnished to do so, subject to the following conditions:
11
12
// The above copyright notice and this permission notice shall be included in all
13
// copies or substantial portions of the Software.
14
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
// SOFTWARE.
22
23
//! An implementation of a LRU cache. The cache supports `get`, `get_mut`, `put`,
24
//! and `pop` operations, all of which are O(1). This crate was heavily influenced
25
//! by the [LRU Cache implementation in an earlier version of Rust's std::collections crate](https://doc.rust-lang.org/0.12.0/std/collections/lru_cache/struct.LruCache.html).
26
//!
27
//! ## Example
28
//!
29
//! ```rust
30
//! extern crate lru;
31
//!
32
//! use lru::LruCache;
33
//! use std::num::NonZeroUsize;
34
//!
35
//! fn main() {
36
//!         let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
37
//!         cache.put("apple", 3);
38
//!         cache.put("banana", 2);
39
//!
40
//!         assert_eq!(*cache.get(&"apple").unwrap(), 3);
41
//!         assert_eq!(*cache.get(&"banana").unwrap(), 2);
42
//!         assert!(cache.get(&"pear").is_none());
43
//!
44
//!         assert_eq!(cache.put("banana", 4), Some(2));
45
//!         assert_eq!(cache.put("pear", 5), None);
46
//!
47
//!         assert_eq!(*cache.get(&"pear").unwrap(), 5);
48
//!         assert_eq!(*cache.get(&"banana").unwrap(), 4);
49
//!         assert!(cache.get(&"apple").is_none());
50
//!
51
//!         {
52
//!             let v = cache.get_mut(&"banana").unwrap();
53
//!             *v = 6;
54
//!         }
55
//!
56
//!         assert_eq!(*cache.get(&"banana").unwrap(), 6);
57
//! }
58
//! ```
59
60
#![no_std]
61
62
#[cfg(feature = "hashbrown")]
63
extern crate hashbrown;
64
65
#[cfg(test)]
66
extern crate scoped_threadpool;
67
68
use alloc::borrow::Borrow;
69
use alloc::boxed::Box;
70
use core::fmt;
71
use core::hash::{BuildHasher, Hash, Hasher};
72
use core::iter::FusedIterator;
73
use core::marker::PhantomData;
74
use core::mem;
75
use core::num::NonZeroUsize;
76
use core::ptr::{self, NonNull};
77
use core::usize;
78
79
#[cfg(any(test, not(feature = "hashbrown")))]
80
extern crate std;
81
82
#[cfg(feature = "hashbrown")]
83
use hashbrown::HashMap;
84
#[cfg(not(feature = "hashbrown"))]
85
use std::collections::HashMap;
86
87
extern crate alloc;
88
89
// Struct used to hold a reference to a key
90
struct KeyRef<K> {
91
    k: *const K,
92
}
93
94
impl<K: Hash> Hash for KeyRef<K> {
95
0
    fn hash<H: Hasher>(&self, state: &mut H) {
96
0
        unsafe { (*self.k).hash(state) }
97
0
    }
Unexecuted instantiation: _RINvXCs9xc8CxQ35gK_3lruINtB3_6KeyRefAhj20_ENtNtCsbQ8arDwx5Xq_4core4hash4Hash4hashNtNtCseb6QmliwlWD_5ahash13fallback_hash7AHasherECs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RINvXINICs9xc8CxQ35gK_3lru0pEINtB6_6KeyRefpENtNtCsbQ8arDwx5Xq_4core4hash4Hash4hashpEB6_
98
}
99
100
impl<K: PartialEq> PartialEq for KeyRef<K> {
101
    // NB: The unconditional_recursion lint was added in 1.76.0 and can be removed
102
    // once the current stable version of Rust is 1.76.0 or higher.
103
    #![allow(unknown_lints)]
104
    #[allow(clippy::unconditional_recursion)]
105
0
    fn eq(&self, other: &KeyRef<K>) -> bool {
106
0
        unsafe { (*self.k).eq(&*other.k) }
107
0
    }
Unexecuted instantiation: _RNvXs_Cs9xc8CxQ35gK_3lruINtB4_6KeyRefAhj20_ENtNtCsbQ8arDwx5Xq_4core3cmp9PartialEq2eqCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXINICs9xc8CxQ35gK_3lrus_0pEINtB5_6KeyRefpENtNtCsbQ8arDwx5Xq_4core3cmp9PartialEq2eqB5_
108
}
109
110
impl<K: Eq> Eq for KeyRef<K> {}
111
112
// This type exists to allow a "blanket" Borrow impl for KeyRef without conflicting with the
113
//  stdlib blanket impl
114
#[repr(transparent)]
115
struct KeyWrapper<K: ?Sized>(K);
116
117
impl<K: ?Sized> KeyWrapper<K> {
118
0
    fn from_ref(key: &K) -> &Self {
119
0
        // safety: KeyWrapper is transparent, so casting the ref like this is allowable
120
0
        unsafe { &*(key as *const K as *const KeyWrapper<K>) }
121
0
    }
122
}
123
124
impl<K: ?Sized + Hash> Hash for KeyWrapper<K> {
125
0
    fn hash<H: Hasher>(&self, state: &mut H) {
126
0
        self.0.hash(state)
127
0
    }
128
}
129
130
impl<K: ?Sized + PartialEq> PartialEq for KeyWrapper<K> {
131
    // NB: The unconditional_recursion lint was added in 1.76.0 and can be removed
132
    // once the current stable version of Rust is 1.76.0 or higher.
133
    #![allow(unknown_lints)]
134
    #[allow(clippy::unconditional_recursion)]
135
0
    fn eq(&self, other: &Self) -> bool {
136
0
        self.0.eq(&other.0)
137
0
    }
138
}
139
140
impl<K: ?Sized + Eq> Eq for KeyWrapper<K> {}
141
142
impl<K, Q> Borrow<KeyWrapper<Q>> for KeyRef<K>
143
where
144
    K: Borrow<Q>,
145
    Q: ?Sized,
146
{
147
0
    fn borrow(&self) -> &KeyWrapper<Q> {
148
0
        let key = unsafe { &*self.k }.borrow();
149
0
        KeyWrapper::from_ref(key)
150
0
    }
151
}
152
153
// Struct used to hold a key value pair. Also contains references to previous and next entries
154
// so we can maintain the entries in a linked list ordered by their use.
155
struct LruEntry<K, V> {
156
    key: mem::MaybeUninit<K>,
157
    val: mem::MaybeUninit<V>,
158
    prev: *mut LruEntry<K, V>,
159
    next: *mut LruEntry<K, V>,
160
}
161
162
impl<K, V> LruEntry<K, V> {
163
0
    fn new(key: K, val: V) -> Self {
164
0
        LruEntry {
165
0
            key: mem::MaybeUninit::new(key),
166
0
            val: mem::MaybeUninit::new(val),
167
0
            prev: ptr::null_mut(),
168
0
            next: ptr::null_mut(),
169
0
        }
170
0
    }
Unexecuted instantiation: _RNvMs6_Cs9xc8CxQ35gK_3lruINtB5_8LruEntryAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE3newBM_
Unexecuted instantiation: _RNvMs6_Cs9xc8CxQ35gK_3lruINtB5_8LruEntryppE3newB5_
171
172
0
    fn new_sigil() -> Self {
173
0
        LruEntry {
174
0
            key: mem::MaybeUninit::uninit(),
175
0
            val: mem::MaybeUninit::uninit(),
176
0
            prev: ptr::null_mut(),
177
0
            next: ptr::null_mut(),
178
0
        }
179
0
    }
Unexecuted instantiation: _RNvMs6_Cs9xc8CxQ35gK_3lruINtB5_8LruEntryAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE9new_sigilBM_
Unexecuted instantiation: _RNvMs6_Cs9xc8CxQ35gK_3lruINtB5_8LruEntryppE9new_sigilB5_
180
}
181
182
#[cfg(feature = "hashbrown")]
183
pub type DefaultHasher = hashbrown::hash_map::DefaultHashBuilder;
184
#[cfg(not(feature = "hashbrown"))]
185
pub type DefaultHasher = std::collections::hash_map::RandomState;
186
187
/// An LRU Cache
188
pub struct LruCache<K, V, S = DefaultHasher> {
189
    map: HashMap<KeyRef<K>, NonNull<LruEntry<K, V>>, S>,
190
    cap: NonZeroUsize,
191
192
    // head and tail are sigil nodes to facilitate inserting entries
193
    head: *mut LruEntry<K, V>,
194
    tail: *mut LruEntry<K, V>,
195
}
196
197
impl<K, V> Clone for LruCache<K, V>
198
where
199
    K: Hash + PartialEq + Eq + Clone,
200
    V: Clone,
201
{
202
0
    fn clone(&self) -> Self {
203
0
        let mut new_lru = LruCache::new(self.cap());
204
205
0
        for (key, value) in self.iter().rev() {
206
0
            new_lru.push(key.clone(), value.clone());
207
0
        }
208
209
0
        new_lru
210
0
    }
Unexecuted instantiation: _RNvXs7_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementENtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneBM_
Unexecuted instantiation: _RNvXINICs9xc8CxQ35gK_3lrus7_0ppEINtB5_8LruCacheppENtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB5_
211
}
212
213
impl<K: Hash + Eq, V> LruCache<K, V> {
214
    /// Creates a new LRU Cache that holds at most `cap` items.
215
    ///
216
    /// # Example
217
    ///
218
    /// ```
219
    /// use lru::LruCache;
220
    /// use std::num::NonZeroUsize;
221
    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(10).unwrap());
222
    /// ```
223
0
    pub fn new(cap: NonZeroUsize) -> LruCache<K, V> {
224
0
        LruCache::construct(cap, HashMap::with_capacity(cap.get()))
225
0
    }
Unexecuted instantiation: _RNvMs8_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE3newBM_
Unexecuted instantiation: _RNvMs8_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheppE3newB5_
226
227
    /// Creates a new LRU Cache that never automatically evicts items.
228
    ///
229
    /// # Example
230
    ///
231
    /// ```
232
    /// use lru::LruCache;
233
    /// use std::num::NonZeroUsize;
234
    /// let mut cache: LruCache<isize, &str> = LruCache::unbounded();
235
    /// ```
236
0
    pub fn unbounded() -> LruCache<K, V> {
237
0
        LruCache::construct(NonZeroUsize::new(usize::MAX).unwrap(), HashMap::default())
238
0
    }
239
}
240
241
impl<K: Hash + Eq, V, S: BuildHasher> LruCache<K, V, S> {
242
    /// Creates a new LRU Cache that holds at most `cap` items and
243
    /// uses the provided hash builder to hash keys.
244
    ///
245
    /// # Example
246
    ///
247
    /// ```
248
    /// use lru::{LruCache, DefaultHasher};
249
    /// use std::num::NonZeroUsize;
250
    ///
251
    /// let s = DefaultHasher::default();
252
    /// let mut cache: LruCache<isize, &str> = LruCache::with_hasher(NonZeroUsize::new(10).unwrap(), s);
253
    /// ```
254
0
    pub fn with_hasher(cap: NonZeroUsize, hash_builder: S) -> LruCache<K, V, S> {
255
0
        LruCache::construct(
256
0
            cap,
257
0
            HashMap::with_capacity_and_hasher(cap.into(), hash_builder),
258
0
        )
259
0
    }
260
261
    /// Creates a new LRU Cache that never automatically evicts items and
262
    /// uses the provided hash builder to hash keys.
263
    ///
264
    /// # Example
265
    ///
266
    /// ```
267
    /// use lru::{LruCache, DefaultHasher};
268
    ///
269
    /// let s = DefaultHasher::default();
270
    /// let mut cache: LruCache<isize, &str> = LruCache::unbounded_with_hasher(s);
271
    /// ```
272
0
    pub fn unbounded_with_hasher(hash_builder: S) -> LruCache<K, V, S> {
273
0
        LruCache::construct(
274
0
            NonZeroUsize::new(usize::MAX).unwrap(),
275
0
            HashMap::with_hasher(hash_builder),
276
0
        )
277
0
    }
278
279
    /// Creates a new LRU Cache with the given capacity.
280
0
    fn construct(
281
0
        cap: NonZeroUsize,
282
0
        map: HashMap<KeyRef<K>, NonNull<LruEntry<K, V>>, S>,
283
0
    ) -> LruCache<K, V, S> {
284
0
        // NB: The compiler warns that cache does not need to be marked as mutable if we
285
0
        // declare it as such since we only mutate it inside the unsafe block.
286
0
        let cache = LruCache {
287
0
            map,
288
0
            cap,
289
0
            head: Box::into_raw(Box::new(LruEntry::new_sigil())),
290
0
            tail: Box::into_raw(Box::new(LruEntry::new_sigil())),
291
0
        };
292
0
293
0
        unsafe {
294
0
            (*cache.head).next = cache.tail;
295
0
            (*cache.tail).prev = cache.head;
296
0
        }
297
0
298
0
        cache
299
0
    }
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE9constructBM_
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCachepppE9constructB5_
300
301
    /// Puts a key-value pair into cache. If the key already exists in the cache, then it updates
302
    /// the key's value and returns the old value. Otherwise, `None` is returned.
303
    ///
304
    /// # Example
305
    ///
306
    /// ```
307
    /// use lru::LruCache;
308
    /// use std::num::NonZeroUsize;
309
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
310
    ///
311
    /// assert_eq!(None, cache.put(1, "a"));
312
    /// assert_eq!(None, cache.put(2, "b"));
313
    /// assert_eq!(Some("b"), cache.put(2, "beta"));
314
    ///
315
    /// assert_eq!(cache.get(&1), Some(&"a"));
316
    /// assert_eq!(cache.get(&2), Some(&"beta"));
317
    /// ```
318
0
    pub fn put(&mut self, k: K, v: V) -> Option<V> {
319
0
        self.capturing_put(k, v, false).map(|(_, v)| v)
320
0
    }
321
322
    /// Pushes a key-value pair into the cache. If an entry with key `k` already exists in
323
    /// the cache or another cache entry is removed (due to the lru's capacity),
324
    /// then it returns the old entry's key-value pair. Otherwise, returns `None`.
325
    ///
326
    /// # Example
327
    ///
328
    /// ```
329
    /// use lru::LruCache;
330
    /// use std::num::NonZeroUsize;
331
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
332
    ///
333
    /// assert_eq!(None, cache.push(1, "a"));
334
    /// assert_eq!(None, cache.push(2, "b"));
335
    ///
336
    /// // This push call returns (2, "b") because that was previously 2's entry in the cache.
337
    /// assert_eq!(Some((2, "b")), cache.push(2, "beta"));
338
    ///
339
    /// // This push call returns (1, "a") because the cache is at capacity and 1's entry was the lru entry.
340
    /// assert_eq!(Some((1, "a")), cache.push(3, "alpha"));
341
    ///
342
    /// assert_eq!(cache.get(&1), None);
343
    /// assert_eq!(cache.get(&2), Some(&"beta"));
344
    /// assert_eq!(cache.get(&3), Some(&"alpha"));
345
    /// ```
346
0
    pub fn push(&mut self, k: K, v: V) -> Option<(K, V)> {
347
0
        self.capturing_put(k, v, true)
348
0
    }
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE4pushBM_
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCachepppE4pushB5_
349
350
    // Used internally by `put` and `push` to add a new entry to the lru.
351
    // Takes ownership of and returns entries replaced due to the cache's capacity
352
    // when `capture` is true.
353
0
    fn capturing_put(&mut self, k: K, mut v: V, capture: bool) -> Option<(K, V)> {
354
0
        let node_ref = self.map.get_mut(&KeyRef { k: &k });
355
0
356
0
        match node_ref {
357
0
            Some(node_ref) => {
358
0
                // if the key is already in the cache just update its value and move it to the
359
0
                // front of the list
360
0
                let node_ptr: *mut LruEntry<K, V> = node_ref.as_ptr();
361
0
362
0
                // gets a reference to the node to perform a swap and drops it right after
363
0
                let node_ref = unsafe { &mut (*(*node_ptr).val.as_mut_ptr()) };
364
0
                mem::swap(&mut v, node_ref);
365
0
                let _ = node_ref;
366
0
367
0
                self.detach(node_ptr);
368
0
                self.attach(node_ptr);
369
0
                Some((k, v))
370
            }
371
            None => {
372
0
                let (replaced, node) = self.replace_or_create_node(k, v);
373
0
                let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
374
0
375
0
                self.attach(node_ptr);
376
0
377
0
                let keyref = unsafe { (*node_ptr).key.as_ptr() };
378
0
                self.map.insert(KeyRef { k: keyref }, node);
379
0
380
0
                replaced.filter(|_| capture)
Unexecuted instantiation: _RNCNvMs9_Cs9xc8CxQ35gK_3lruINtB7_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE13capturing_put0BO_
Unexecuted instantiation: _RNCNvMs9_Cs9xc8CxQ35gK_3lruINtB7_8LruCachepppE13capturing_put0B7_
381
            }
382
        }
383
0
    }
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE13capturing_putBM_
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCachepppE13capturing_putB5_
384
385
    // Used internally to swap out a node if the cache is full or to create a new node if space
386
    // is available. Shared between `put`, `push`, `get_or_insert`, and `get_or_insert_mut`.
387
    #[allow(clippy::type_complexity)]
388
0
    fn replace_or_create_node(&mut self, k: K, v: V) -> (Option<(K, V)>, NonNull<LruEntry<K, V>>) {
389
0
        if self.len() == self.cap().get() {
390
            // if the cache is full, remove the last entry so we can use it for the new key
391
0
            let old_key = KeyRef {
392
0
                k: unsafe { &(*(*(*self.tail).prev).key.as_ptr()) },
393
0
            };
394
0
            let old_node = self.map.remove(&old_key).unwrap();
395
0
            let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
396
0
397
0
            // read out the node's old key and value and then replace it
398
0
            let replaced = unsafe {
399
0
                (
400
0
                    mem::replace(&mut (*node_ptr).key, mem::MaybeUninit::new(k)).assume_init(),
401
0
                    mem::replace(&mut (*node_ptr).val, mem::MaybeUninit::new(v)).assume_init(),
402
0
                )
403
0
            };
404
0
405
0
            self.detach(node_ptr);
406
0
407
0
            (Some(replaced), old_node)
408
        } else {
409
            // if the cache is not full allocate a new LruEntry
410
            // Safety: We allocate, turn into raw, and get NonNull all in one step.
411
0
            (None, unsafe {
412
0
                NonNull::new_unchecked(Box::into_raw(Box::new(LruEntry::new(k, v))))
413
0
            })
414
        }
415
0
    }
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE22replace_or_create_nodeBM_
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCachepppE22replace_or_create_nodeB5_
416
417
    /// Returns a reference to the value of the key in the cache or `None` if it is not
418
    /// present in the cache. Moves the key to the head of the LRU list if it exists.
419
    ///
420
    /// # Example
421
    ///
422
    /// ```
423
    /// use lru::LruCache;
424
    /// use std::num::NonZeroUsize;
425
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
426
    ///
427
    /// cache.put(1, "a");
428
    /// cache.put(2, "b");
429
    /// cache.put(2, "c");
430
    /// cache.put(3, "d");
431
    ///
432
    /// assert_eq!(cache.get(&1), None);
433
    /// assert_eq!(cache.get(&2), Some(&"c"));
434
    /// assert_eq!(cache.get(&3), Some(&"d"));
435
    /// ```
436
0
    pub fn get<'a, Q>(&'a mut self, k: &Q) -> Option<&'a V>
437
0
    where
438
0
        K: Borrow<Q>,
439
0
        Q: Hash + Eq + ?Sized,
440
0
    {
441
0
        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
442
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
443
0
444
0
            self.detach(node_ptr);
445
0
            self.attach(node_ptr);
446
0
447
0
            Some(unsafe { &*(*node_ptr).val.as_ptr() })
448
        } else {
449
0
            None
450
        }
451
0
    }
452
453
    /// Returns a mutable reference to the value of the key in the cache or `None` if it
454
    /// is not present in the cache. Moves the key to the head of the LRU list if it exists.
455
    ///
456
    /// # Example
457
    ///
458
    /// ```
459
    /// use lru::LruCache;
460
    /// use std::num::NonZeroUsize;
461
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
462
    ///
463
    /// cache.put("apple", 8);
464
    /// cache.put("banana", 4);
465
    /// cache.put("banana", 6);
466
    /// cache.put("pear", 2);
467
    ///
468
    /// assert_eq!(cache.get_mut(&"apple"), None);
469
    /// assert_eq!(cache.get_mut(&"banana"), Some(&mut 6));
470
    /// assert_eq!(cache.get_mut(&"pear"), Some(&mut 2));
471
    /// ```
472
0
    pub fn get_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V>
473
0
    where
474
0
        K: Borrow<Q>,
475
0
        Q: Hash + Eq + ?Sized,
476
0
    {
477
0
        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
478
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
479
0
480
0
            self.detach(node_ptr);
481
0
            self.attach(node_ptr);
482
0
483
0
            Some(unsafe { &mut *(*node_ptr).val.as_mut_ptr() })
484
        } else {
485
0
            None
486
        }
487
0
    }
488
489
    /// Returns a key-value references pair of the key in the cache or `None` if it is not
490
    /// present in the cache. Moves the key to the head of the LRU list if it exists.
491
    ///
492
    /// # Example
493
    ///
494
    /// ```
495
    /// use lru::LruCache;
496
    /// use std::num::NonZeroUsize;
497
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
498
    ///
499
    /// cache.put(String::from("1"), "a");
500
    /// cache.put(String::from("2"), "b");
501
    /// cache.put(String::from("2"), "c");
502
    /// cache.put(String::from("3"), "d");
503
    ///
504
    /// assert_eq!(cache.get_key_value("1"), None);
505
    /// assert_eq!(cache.get_key_value("2"), Some((&String::from("2"), &"c")));
506
    /// assert_eq!(cache.get_key_value("3"), Some((&String::from("3"), &"d")));
507
    /// ```
508
0
    pub fn get_key_value<'a, Q>(&'a mut self, k: &Q) -> Option<(&'a K, &'a V)>
509
0
    where
510
0
        K: Borrow<Q>,
511
0
        Q: Hash + Eq + ?Sized,
512
0
    {
513
0
        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
514
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
515
0
516
0
            self.detach(node_ptr);
517
0
            self.attach(node_ptr);
518
0
519
0
            Some(unsafe { (&*(*node_ptr).key.as_ptr(), &*(*node_ptr).val.as_ptr()) })
520
        } else {
521
0
            None
522
        }
523
0
    }
524
525
    /// Returns a key-value references pair of the key in the cache or `None` if it is not
526
    /// present in the cache. The reference to the value of the key is mutable. Moves the key to
527
    /// the head of the LRU list if it exists.
528
    ///
529
    /// # Example
530
    ///
531
    /// ```
532
    /// use lru::LruCache;
533
    /// use std::num::NonZeroUsize;
534
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
535
    ///
536
    /// cache.put(1, "a");
537
    /// cache.put(2, "b");
538
    /// let (k, v) = cache.get_key_value_mut(&1).unwrap();
539
    /// assert_eq!(k, &1);
540
    /// assert_eq!(v, &mut "a");
541
    /// *v = "aa";
542
    /// cache.put(3, "c");
543
    /// assert_eq!(cache.get_key_value(&2), None);
544
    /// assert_eq!(cache.get_key_value(&1), Some((&1, &"aa")));
545
    /// assert_eq!(cache.get_key_value(&3), Some((&3, &"c")));
546
    /// ```
547
0
    pub fn get_key_value_mut<'a, Q>(&'a mut self, k: &Q) -> Option<(&'a K, &'a mut V)>
548
0
    where
549
0
        K: Borrow<Q>,
550
0
        Q: Hash + Eq + ?Sized,
551
0
    {
552
0
        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
553
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
554
0
555
0
            self.detach(node_ptr);
556
0
            self.attach(node_ptr);
557
0
558
0
            Some(unsafe {
559
0
                (
560
0
                    &*(*node_ptr).key.as_ptr(),
561
0
                    &mut *(*node_ptr).val.as_mut_ptr(),
562
0
                )
563
0
            })
564
        } else {
565
0
            None
566
        }
567
0
    }
568
569
    /// Returns a reference to the value of the key in the cache if it is
570
    /// present in the cache and moves the key to the head of the LRU list.
571
    /// If the key does not exist the provided `FnOnce` is used to populate
572
    /// the list and a reference is returned.
573
    ///
574
    /// # Example
575
    ///
576
    /// ```
577
    /// use lru::LruCache;
578
    /// use std::num::NonZeroUsize;
579
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
580
    ///
581
    /// cache.put(1, "a");
582
    /// cache.put(2, "b");
583
    /// cache.put(2, "c");
584
    /// cache.put(3, "d");
585
    ///
586
    /// assert_eq!(cache.get_or_insert(2, ||"a"), &"c");
587
    /// assert_eq!(cache.get_or_insert(3, ||"a"), &"d");
588
    /// assert_eq!(cache.get_or_insert(1, ||"a"), &"a");
589
    /// assert_eq!(cache.get_or_insert(1, ||"b"), &"a");
590
    /// ```
591
0
    pub fn get_or_insert<F>(&mut self, k: K, f: F) -> &V
592
0
    where
593
0
        F: FnOnce() -> V,
594
0
    {
595
0
        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
596
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
597
0
598
0
            self.detach(node_ptr);
599
0
            self.attach(node_ptr);
600
0
601
0
            unsafe { &*(*node_ptr).val.as_ptr() }
602
        } else {
603
0
            let v = f();
604
0
            let (_, node) = self.replace_or_create_node(k, v);
605
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
606
0
607
0
            self.attach(node_ptr);
608
0
609
0
            let keyref = unsafe { (*node_ptr).key.as_ptr() };
610
0
            self.map.insert(KeyRef { k: keyref }, node);
611
0
            unsafe { &*(*node_ptr).val.as_ptr() }
612
        }
613
0
    }
614
615
    /// Returns a reference to the value of the key in the cache if it is
616
    /// present in the cache and moves the key to the head of the LRU list.
617
    /// If the key does not exist the provided `FnOnce` is used to populate
618
    /// the list and a reference is returned. If `FnOnce` returns `Err`,
619
    /// returns the `Err`.
620
    ///
621
    /// # Example
622
    ///
623
    /// ```
624
    /// use lru::LruCache;
625
    /// use std::num::NonZeroUsize;
626
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
627
    ///
628
    /// cache.put(1, "a");
629
    /// cache.put(2, "b");
630
    /// cache.put(2, "c");
631
    /// cache.put(3, "d");
632
    ///
633
    /// let f = ||->Result<&str, String> {Err("failed".to_owned())};
634
    /// let a = ||->Result<&str, String> {Ok("a")};
635
    /// let b = ||->Result<&str, String> {Ok("b")};
636
    /// assert_eq!(cache.try_get_or_insert(2, a), Ok(&"c"));
637
    /// assert_eq!(cache.try_get_or_insert(3, a), Ok(&"d"));
638
    /// assert_eq!(cache.try_get_or_insert(4, f), Err("failed".to_owned()));
639
    /// assert_eq!(cache.try_get_or_insert(5, b), Ok(&"b"));
640
    /// assert_eq!(cache.try_get_or_insert(5, a), Ok(&"b"));
641
    /// ```
642
0
    pub fn try_get_or_insert<F, E>(&mut self, k: K, f: F) -> Result<&V, E>
643
0
    where
644
0
        F: FnOnce() -> Result<V, E>,
645
0
    {
646
0
        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
647
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
648
0
649
0
            self.detach(node_ptr);
650
0
            self.attach(node_ptr);
651
0
652
0
            unsafe { Ok(&*(*node_ptr).val.as_ptr()) }
653
        } else {
654
0
            let v = f()?;
655
0
            let (_, node) = self.replace_or_create_node(k, v);
656
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
657
0
658
0
            self.attach(node_ptr);
659
0
660
0
            let keyref = unsafe { (*node_ptr).key.as_ptr() };
661
0
            self.map.insert(KeyRef { k: keyref }, node);
662
0
            Ok(unsafe { &*(*node_ptr).val.as_ptr() })
663
        }
664
0
    }
665
666
    /// Returns a mutable reference to the value of the key in the cache if it is
667
    /// present in the cache and moves the key to the head of the LRU list.
668
    /// If the key does not exist the provided `FnOnce` is used to populate
669
    /// the list and a mutable reference is returned.
670
    ///
671
    /// # Example
672
    ///
673
    /// ```
674
    /// use lru::LruCache;
675
    /// use std::num::NonZeroUsize;
676
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
677
    ///
678
    /// cache.put(1, "a");
679
    /// cache.put(2, "b");
680
    ///
681
    /// let v = cache.get_or_insert_mut(2, ||"c");
682
    /// assert_eq!(v, &"b");
683
    /// *v = "d";
684
    /// assert_eq!(cache.get_or_insert_mut(2, ||"e"), &mut "d");
685
    /// assert_eq!(cache.get_or_insert_mut(3, ||"f"), &mut "f");
686
    /// assert_eq!(cache.get_or_insert_mut(3, ||"e"), &mut "f");
687
    /// ```
688
0
    pub fn get_or_insert_mut<F>(&mut self, k: K, f: F) -> &mut V
689
0
    where
690
0
        F: FnOnce() -> V,
691
0
    {
692
0
        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
693
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
694
0
695
0
            self.detach(node_ptr);
696
0
            self.attach(node_ptr);
697
0
698
0
            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
699
        } else {
700
0
            let v = f();
701
0
            let (_, node) = self.replace_or_create_node(k, v);
702
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
703
0
704
0
            self.attach(node_ptr);
705
0
706
0
            let keyref = unsafe { (*node_ptr).key.as_ptr() };
707
0
            self.map.insert(KeyRef { k: keyref }, node);
708
0
            unsafe { &mut *(*node_ptr).val.as_mut_ptr() }
709
        }
710
0
    }
711
712
    /// Returns a mutable reference to the value of the key in the cache if it is
713
    /// present in the cache and moves the key to the head of the LRU list.
714
    /// If the key does not exist the provided `FnOnce` is used to populate
715
    /// the list and a mutable reference is returned. If `FnOnce` returns `Err`,
716
    /// returns the `Err`.
717
    ///
718
    /// # Example
719
    ///
720
    /// ```
721
    /// use lru::LruCache;
722
    /// use std::num::NonZeroUsize;
723
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
724
    ///
725
    /// cache.put(1, "a");
726
    /// cache.put(2, "b");
727
    /// cache.put(2, "c");
728
    ///
729
    /// let f = ||->Result<&str, String> {Err("failed".to_owned())};
730
    /// let a = ||->Result<&str, String> {Ok("a")};
731
    /// let b = ||->Result<&str, String> {Ok("b")};
732
    /// if let Ok(v) = cache.try_get_or_insert_mut(2, a) {
733
    ///     *v = "d";
734
    /// }
735
    /// assert_eq!(cache.try_get_or_insert_mut(2, a), Ok(&mut "d"));
736
    /// assert_eq!(cache.try_get_or_insert_mut(3, f), Err("failed".to_owned()));
737
    /// assert_eq!(cache.try_get_or_insert_mut(4, b), Ok(&mut "b"));
738
    /// assert_eq!(cache.try_get_or_insert_mut(4, a), Ok(&mut "b"));
739
    /// ```
740
0
    pub fn try_get_or_insert_mut<F, E>(&mut self, k: K, f: F) -> Result<&mut V, E>
741
0
    where
742
0
        F: FnOnce() -> Result<V, E>,
743
0
    {
744
0
        if let Some(node) = self.map.get_mut(&KeyRef { k: &k }) {
745
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
746
0
747
0
            self.detach(node_ptr);
748
0
            self.attach(node_ptr);
749
0
750
0
            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
751
        } else {
752
0
            let v = f()?;
753
0
            let (_, node) = self.replace_or_create_node(k, v);
754
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
755
0
756
0
            self.attach(node_ptr);
757
0
758
0
            let keyref = unsafe { (*node_ptr).key.as_ptr() };
759
0
            self.map.insert(KeyRef { k: keyref }, node);
760
0
            unsafe { Ok(&mut *(*node_ptr).val.as_mut_ptr()) }
761
        }
762
0
    }
763
764
    /// Returns a reference to the value corresponding to the key in the cache or `None` if it is
765
    /// not present in the cache. Unlike `get`, `peek` does not update the LRU list so the key's
766
    /// position will be unchanged.
767
    ///
768
    /// # Example
769
    ///
770
    /// ```
771
    /// use lru::LruCache;
772
    /// use std::num::NonZeroUsize;
773
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
774
    ///
775
    /// cache.put(1, "a");
776
    /// cache.put(2, "b");
777
    ///
778
    /// assert_eq!(cache.peek(&1), Some(&"a"));
779
    /// assert_eq!(cache.peek(&2), Some(&"b"));
780
    /// ```
781
0
    pub fn peek<'a, Q>(&'a self, k: &Q) -> Option<&'a V>
782
0
    where
783
0
        K: Borrow<Q>,
784
0
        Q: Hash + Eq + ?Sized,
785
0
    {
786
0
        self.map
787
0
            .get(KeyWrapper::from_ref(k))
788
0
            .map(|node| unsafe { &*node.as_ref().val.as_ptr() })
789
0
    }
790
791
    /// Returns a mutable reference to the value corresponding to the key in the cache or `None`
792
    /// if it is not present in the cache. Unlike `get_mut`, `peek_mut` does not update the LRU
793
    /// list so the key's position will be unchanged.
794
    ///
795
    /// # Example
796
    ///
797
    /// ```
798
    /// use lru::LruCache;
799
    /// use std::num::NonZeroUsize;
800
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
801
    ///
802
    /// cache.put(1, "a");
803
    /// cache.put(2, "b");
804
    ///
805
    /// assert_eq!(cache.peek_mut(&1), Some(&mut "a"));
806
    /// assert_eq!(cache.peek_mut(&2), Some(&mut "b"));
807
    /// ```
808
0
    pub fn peek_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V>
809
0
    where
810
0
        K: Borrow<Q>,
811
0
        Q: Hash + Eq + ?Sized,
812
0
    {
813
0
        match self.map.get_mut(KeyWrapper::from_ref(k)) {
814
0
            None => None,
815
0
            Some(node) => Some(unsafe { &mut *(*node.as_ptr()).val.as_mut_ptr() }),
816
        }
817
0
    }
818
819
    /// Returns the value corresponding to the least recently used item or `None` if the
820
    /// cache is empty. Like `peek`, `peek_lru` does not update the LRU list so the item's
821
    /// position will be unchanged.
822
    ///
823
    /// # Example
824
    ///
825
    /// ```
826
    /// use lru::LruCache;
827
    /// use std::num::NonZeroUsize;
828
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
829
    ///
830
    /// cache.put(1, "a");
831
    /// cache.put(2, "b");
832
    ///
833
    /// assert_eq!(cache.peek_lru(), Some((&1, &"a")));
834
    /// ```
835
0
    pub fn peek_lru(&self) -> Option<(&K, &V)> {
836
0
        if self.is_empty() {
837
0
            return None;
838
0
        }
839
0
840
0
        let (key, val);
841
0
        unsafe {
842
0
            let node = (*self.tail).prev;
843
0
            key = &(*(*node).key.as_ptr()) as &K;
844
0
            val = &(*(*node).val.as_ptr()) as &V;
845
0
        }
846
0
847
0
        Some((key, val))
848
0
    }
849
850
    /// Returns a bool indicating whether the given key is in the cache. Does not update the
851
    /// LRU list.
852
    ///
853
    /// # Example
854
    ///
855
    /// ```
856
    /// use lru::LruCache;
857
    /// use std::num::NonZeroUsize;
858
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
859
    ///
860
    /// cache.put(1, "a");
861
    /// cache.put(2, "b");
862
    /// cache.put(3, "c");
863
    ///
864
    /// assert!(!cache.contains(&1));
865
    /// assert!(cache.contains(&2));
866
    /// assert!(cache.contains(&3));
867
    /// ```
868
0
    pub fn contains<Q>(&self, k: &Q) -> bool
869
0
    where
870
0
        K: Borrow<Q>,
871
0
        Q: Hash + Eq + ?Sized,
872
0
    {
873
0
        self.map.contains_key(KeyWrapper::from_ref(k))
874
0
    }
875
876
    /// Removes and returns the value corresponding to the key from the cache or
877
    /// `None` if it does not exist.
878
    ///
879
    /// # Example
880
    ///
881
    /// ```
882
    /// use lru::LruCache;
883
    /// use std::num::NonZeroUsize;
884
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
885
    ///
886
    /// cache.put(2, "a");
887
    ///
888
    /// assert_eq!(cache.pop(&1), None);
889
    /// assert_eq!(cache.pop(&2), Some("a"));
890
    /// assert_eq!(cache.pop(&2), None);
891
    /// assert_eq!(cache.len(), 0);
892
    /// ```
893
0
    pub fn pop<Q>(&mut self, k: &Q) -> Option<V>
894
0
    where
895
0
        K: Borrow<Q>,
896
0
        Q: Hash + Eq + ?Sized,
897
0
    {
898
0
        match self.map.remove(KeyWrapper::from_ref(k)) {
899
0
            None => None,
900
0
            Some(old_node) => {
901
0
                let mut old_node = unsafe {
902
0
                    let mut old_node = *Box::from_raw(old_node.as_ptr());
903
0
                    ptr::drop_in_place(old_node.key.as_mut_ptr());
904
0
905
0
                    old_node
906
0
                };
907
0
908
0
                self.detach(&mut old_node);
909
0
910
0
                let LruEntry { key: _, val, .. } = old_node;
911
0
                unsafe { Some(val.assume_init()) }
912
            }
913
        }
914
0
    }
915
916
    /// Removes and returns the key and the value corresponding to the key from the cache or
917
    /// `None` if it does not exist.
918
    ///
919
    /// # Example
920
    ///
921
    /// ```
922
    /// use lru::LruCache;
923
    /// use std::num::NonZeroUsize;
924
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
925
    ///
926
    /// cache.put(1, "a");
927
    /// cache.put(2, "a");
928
    ///
929
    /// assert_eq!(cache.pop(&1), Some("a"));
930
    /// assert_eq!(cache.pop_entry(&2), Some((2, "a")));
931
    /// assert_eq!(cache.pop(&1), None);
932
    /// assert_eq!(cache.pop_entry(&2), None);
933
    /// assert_eq!(cache.len(), 0);
934
    /// ```
935
0
    pub fn pop_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
936
0
    where
937
0
        K: Borrow<Q>,
938
0
        Q: Hash + Eq + ?Sized,
939
0
    {
940
0
        match self.map.remove(KeyWrapper::from_ref(k)) {
941
0
            None => None,
942
0
            Some(old_node) => {
943
0
                let mut old_node = unsafe { *Box::from_raw(old_node.as_ptr()) };
944
0
945
0
                self.detach(&mut old_node);
946
0
947
0
                let LruEntry { key, val, .. } = old_node;
948
0
                unsafe { Some((key.assume_init(), val.assume_init())) }
949
            }
950
        }
951
0
    }
952
953
    /// Removes and returns the key and value corresponding to the least recently
954
    /// used item or `None` if the cache is empty.
955
    ///
956
    /// # Example
957
    ///
958
    /// ```
959
    /// use lru::LruCache;
960
    /// use std::num::NonZeroUsize;
961
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
962
    ///
963
    /// cache.put(2, "a");
964
    /// cache.put(3, "b");
965
    /// cache.put(4, "c");
966
    /// cache.get(&3);
967
    ///
968
    /// assert_eq!(cache.pop_lru(), Some((4, "c")));
969
    /// assert_eq!(cache.pop_lru(), Some((3, "b")));
970
    /// assert_eq!(cache.pop_lru(), None);
971
    /// assert_eq!(cache.len(), 0);
972
    /// ```
973
0
    pub fn pop_lru(&mut self) -> Option<(K, V)> {
974
0
        let node = self.remove_last()?;
975
        // N.B.: Can't destructure directly because of https://github.com/rust-lang/rust/issues/28536
976
0
        let node = *node;
977
0
        let LruEntry { key, val, .. } = node;
978
0
        unsafe { Some((key.assume_init(), val.assume_init())) }
979
0
    }
980
981
    /// Marks the key as the most recently used one.
982
    ///
983
    /// # Example
984
    ///
985
    /// ```
986
    /// use lru::LruCache;
987
    /// use std::num::NonZeroUsize;
988
    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
989
    ///
990
    /// cache.put(1, "a");
991
    /// cache.put(2, "b");
992
    /// cache.put(3, "c");
993
    /// cache.get(&1);
994
    /// cache.get(&2);
995
    ///
996
    /// // If we do `pop_lru` now, we would pop 3.
997
    /// // assert_eq!(cache.pop_lru(), Some((3, "c")));
998
    ///
999
    /// // By promoting 3, we make sure it isn't popped.
1000
    /// cache.promote(&3);
1001
    /// assert_eq!(cache.pop_lru(), Some((1, "a")));
1002
    /// ```
1003
0
    pub fn promote<Q>(&mut self, k: &Q)
1004
0
    where
1005
0
        K: Borrow<Q>,
1006
0
        Q: Hash + Eq + ?Sized,
1007
0
    {
1008
0
        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1009
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1010
0
            self.detach(node_ptr);
1011
0
            self.attach(node_ptr);
1012
0
        }
1013
0
    }
1014
1015
    /// Marks the key as the least recently used one.
1016
    ///
1017
    /// # Example
1018
    ///
1019
    /// ```
1020
    /// use lru::LruCache;
1021
    /// use std::num::NonZeroUsize;
1022
    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1023
    ///
1024
    /// cache.put(1, "a");
1025
    /// cache.put(2, "b");
1026
    /// cache.put(3, "c");
1027
    /// cache.get(&1);
1028
    /// cache.get(&2);
1029
    ///
1030
    /// // If we do `pop_lru` now, we would pop 3.
1031
    /// // assert_eq!(cache.pop_lru(), Some((3, "c")));
1032
    ///
1033
    /// // By demoting 1 and 2, we make sure those are popped first.
1034
    /// cache.demote(&2);
1035
    /// cache.demote(&1);
1036
    /// assert_eq!(cache.pop_lru(), Some((1, "a")));
1037
    /// assert_eq!(cache.pop_lru(), Some((2, "b")));
1038
    /// ```
1039
0
    pub fn demote<Q>(&mut self, k: &Q)
1040
0
    where
1041
0
        K: Borrow<Q>,
1042
0
        Q: Hash + Eq + ?Sized,
1043
0
    {
1044
0
        if let Some(node) = self.map.get_mut(KeyWrapper::from_ref(k)) {
1045
0
            let node_ptr: *mut LruEntry<K, V> = node.as_ptr();
1046
0
            self.detach(node_ptr);
1047
0
            self.attach_last(node_ptr);
1048
0
        }
1049
0
    }
1050
1051
    /// Returns the number of key-value pairs that are currently in the the cache.
1052
    ///
1053
    /// # Example
1054
    ///
1055
    /// ```
1056
    /// use lru::LruCache;
1057
    /// use std::num::NonZeroUsize;
1058
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1059
    /// assert_eq!(cache.len(), 0);
1060
    ///
1061
    /// cache.put(1, "a");
1062
    /// assert_eq!(cache.len(), 1);
1063
    ///
1064
    /// cache.put(2, "b");
1065
    /// assert_eq!(cache.len(), 2);
1066
    ///
1067
    /// cache.put(3, "c");
1068
    /// assert_eq!(cache.len(), 2);
1069
    /// ```
1070
0
    pub fn len(&self) -> usize {
1071
0
        self.map.len()
1072
0
    }
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE3lenBM_
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCachepppE3lenB5_
1073
1074
    /// Returns a bool indicating whether the cache is empty or not.
1075
    ///
1076
    /// # Example
1077
    ///
1078
    /// ```
1079
    /// use lru::LruCache;
1080
    /// use std::num::NonZeroUsize;
1081
    /// let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1082
    /// assert!(cache.is_empty());
1083
    ///
1084
    /// cache.put(1, "a");
1085
    /// assert!(!cache.is_empty());
1086
    /// ```
1087
0
    pub fn is_empty(&self) -> bool {
1088
0
        self.map.len() == 0
1089
0
    }
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE8is_emptyBM_
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCachepppE8is_emptyB5_
1090
1091
    /// Returns the maximum number of key-value pairs the cache can hold.
1092
    ///
1093
    /// # Example
1094
    ///
1095
    /// ```
1096
    /// use lru::LruCache;
1097
    /// use std::num::NonZeroUsize;
1098
    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1099
    /// assert_eq!(cache.cap().get(), 2);
1100
    /// ```
1101
0
    pub fn cap(&self) -> NonZeroUsize {
1102
0
        self.cap
1103
0
    }
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE3capBM_
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCachepppE3capB5_
1104
1105
    /// Resizes the cache. If the new capacity is smaller than the size of the current
1106
    /// cache any entries past the new capacity are discarded.
1107
    ///
1108
    /// # Example
1109
    ///
1110
    /// ```
1111
    /// use lru::LruCache;
1112
    /// use std::num::NonZeroUsize;
1113
    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1114
    ///
1115
    /// cache.put(1, "a");
1116
    /// cache.put(2, "b");
1117
    /// cache.resize(NonZeroUsize::new(4).unwrap());
1118
    /// cache.put(3, "c");
1119
    /// cache.put(4, "d");
1120
    ///
1121
    /// assert_eq!(cache.len(), 4);
1122
    /// assert_eq!(cache.get(&1), Some(&"a"));
1123
    /// assert_eq!(cache.get(&2), Some(&"b"));
1124
    /// assert_eq!(cache.get(&3), Some(&"c"));
1125
    /// assert_eq!(cache.get(&4), Some(&"d"));
1126
    /// ```
1127
0
    pub fn resize(&mut self, cap: NonZeroUsize) {
1128
0
        // return early if capacity doesn't change
1129
0
        if cap == self.cap {
1130
0
            return;
1131
0
        }
1132
1133
0
        while self.map.len() > cap.get() {
1134
0
            self.pop_lru();
1135
0
        }
1136
0
        self.map.shrink_to_fit();
1137
0
1138
0
        self.cap = cap;
1139
0
    }
1140
1141
    /// Clears the contents of the cache.
1142
    ///
1143
    /// # Example
1144
    ///
1145
    /// ```
1146
    /// use lru::LruCache;
1147
    /// use std::num::NonZeroUsize;
1148
    /// let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
1149
    /// assert_eq!(cache.len(), 0);
1150
    ///
1151
    /// cache.put(1, "a");
1152
    /// assert_eq!(cache.len(), 1);
1153
    ///
1154
    /// cache.put(2, "b");
1155
    /// assert_eq!(cache.len(), 2);
1156
    ///
1157
    /// cache.clear();
1158
    /// assert_eq!(cache.len(), 0);
1159
    /// ```
1160
0
    pub fn clear(&mut self) {
1161
0
        while self.pop_lru().is_some() {}
1162
0
    }
1163
1164
    /// An iterator visiting all entries in most-recently used order. The iterator element type is
1165
    /// `(&K, &V)`.
1166
    ///
1167
    /// # Examples
1168
    ///
1169
    /// ```
1170
    /// use lru::LruCache;
1171
    /// use std::num::NonZeroUsize;
1172
    ///
1173
    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1174
    /// cache.put("a", 1);
1175
    /// cache.put("b", 2);
1176
    /// cache.put("c", 3);
1177
    ///
1178
    /// for (key, val) in cache.iter() {
1179
    ///     println!("key: {} val: {}", key, val);
1180
    /// }
1181
    /// ```
1182
0
    pub fn iter(&self) -> Iter<'_, K, V> {
1183
0
        Iter {
1184
0
            len: self.len(),
1185
0
            ptr: unsafe { (*self.head).next },
1186
0
            end: unsafe { (*self.tail).prev },
1187
0
            phantom: PhantomData,
1188
0
        }
1189
0
    }
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE4iterBM_
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCachepppE4iterB5_
1190
1191
    /// An iterator visiting all entries in most-recently-used order, giving a mutable reference on
1192
    /// V.  The iterator element type is `(&K, &mut V)`.
1193
    ///
1194
    /// # Examples
1195
    ///
1196
    /// ```
1197
    /// use lru::LruCache;
1198
    /// use std::num::NonZeroUsize;
1199
    ///
1200
    /// struct HddBlock {
1201
    ///     dirty: bool,
1202
    ///     data: [u8; 512]
1203
    /// }
1204
    ///
1205
    /// let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1206
    /// cache.put(0, HddBlock { dirty: false, data: [0x00; 512]});
1207
    /// cache.put(1, HddBlock { dirty: true,  data: [0x55; 512]});
1208
    /// cache.put(2, HddBlock { dirty: true,  data: [0x77; 512]});
1209
    ///
1210
    /// // write dirty blocks to disk.
1211
    /// for (block_id, block) in cache.iter_mut() {
1212
    ///     if block.dirty {
1213
    ///         // write block to disk
1214
    ///         block.dirty = false
1215
    ///     }
1216
    /// }
1217
    /// ```
1218
0
    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
1219
0
        IterMut {
1220
0
            len: self.len(),
1221
0
            ptr: unsafe { (*self.head).next },
1222
0
            end: unsafe { (*self.tail).prev },
1223
0
            phantom: PhantomData,
1224
0
        }
1225
0
    }
1226
1227
0
    fn remove_last(&mut self) -> Option<Box<LruEntry<K, V>>> {
1228
0
        let prev;
1229
0
        unsafe { prev = (*self.tail).prev }
1230
0
        if prev != self.head {
1231
0
            let old_key = KeyRef {
1232
0
                k: unsafe { &(*(*(*self.tail).prev).key.as_ptr()) },
1233
0
            };
1234
0
            let old_node = self.map.remove(&old_key).unwrap();
1235
0
            let node_ptr: *mut LruEntry<K, V> = old_node.as_ptr();
1236
0
            self.detach(node_ptr);
1237
0
            unsafe { Some(Box::from_raw(node_ptr)) }
1238
        } else {
1239
0
            None
1240
        }
1241
0
    }
1242
1243
0
    fn detach(&mut self, node: *mut LruEntry<K, V>) {
1244
0
        unsafe {
1245
0
            (*(*node).prev).next = (*node).next;
1246
0
            (*(*node).next).prev = (*node).prev;
1247
0
        }
1248
0
    }
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE6detachBM_
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCachepppE6detachB5_
1249
1250
    // Attaches `node` after the sigil `self.head` node.
1251
0
    fn attach(&mut self, node: *mut LruEntry<K, V>) {
1252
0
        unsafe {
1253
0
            (*node).next = (*self.head).next;
1254
0
            (*node).prev = self.head;
1255
0
            (*self.head).next = node;
1256
0
            (*(*node).next).prev = node;
1257
0
        }
1258
0
    }
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementE6attachBM_
Unexecuted instantiation: _RNvMs9_Cs9xc8CxQ35gK_3lruINtB5_8LruCachepppE6attachB5_
1259
1260
    // Attaches `node` before the sigil `self.tail` node.
1261
0
    fn attach_last(&mut self, node: *mut LruEntry<K, V>) {
1262
0
        unsafe {
1263
0
            (*node).next = self.tail;
1264
0
            (*node).prev = (*self.tail).prev;
1265
0
            (*self.tail).prev = node;
1266
0
            (*(*node).prev).next = node;
1267
0
        }
1268
0
    }
1269
}
1270
1271
impl<K, V, S> Drop for LruCache<K, V, S> {
1272
0
    fn drop(&mut self) {
1273
0
        self.map.drain().for_each(|(_, node)| unsafe {
1274
0
            let mut node = *Box::from_raw(node.as_ptr());
1275
0
            ptr::drop_in_place((node).key.as_mut_ptr());
1276
0
            ptr::drop_in_place((node).val.as_mut_ptr());
1277
0
        });
Unexecuted instantiation: _RNCNvXsa_Cs9xc8CxQ35gK_3lruINtB7_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4drop0BO_
Unexecuted instantiation: _RNCNvXINICs9xc8CxQ35gK_3lrusa_0pppEINtB7_8LruCachepppENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4drop0B7_
1278
0
        // We rebox the head/tail, and because these are maybe-uninit
1279
0
        // they do not have the absent k/v dropped.
1280
0
1281
0
        let _head = unsafe { *Box::from_raw(self.head) };
1282
0
        let _tail = unsafe { *Box::from_raw(self.tail) };
1283
0
    }
Unexecuted instantiation: _RNvXsa_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropBM_
Unexecuted instantiation: _RNvXINICs9xc8CxQ35gK_3lrusa_0pppEINtB5_8LruCachepppENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropB5_
1284
}
1285
1286
impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a LruCache<K, V, S> {
1287
    type Item = (&'a K, &'a V);
1288
    type IntoIter = Iter<'a, K, V>;
1289
1290
0
    fn into_iter(self) -> Iter<'a, K, V> {
1291
0
        self.iter()
1292
0
    }
1293
}
1294
1295
impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a mut LruCache<K, V, S> {
1296
    type Item = (&'a K, &'a mut V);
1297
    type IntoIter = IterMut<'a, K, V>;
1298
1299
0
    fn into_iter(self) -> IterMut<'a, K, V> {
1300
0
        self.iter_mut()
1301
0
    }
1302
}
1303
1304
// The compiler does not automatically derive Send and Sync for LruCache because it contains
1305
// raw pointers. The raw pointers are safely encapsulated by LruCache though so we can
1306
// implement Send and Sync for it below.
1307
unsafe impl<K: Send, V: Send, S: Send> Send for LruCache<K, V, S> {}
1308
unsafe impl<K: Sync, V: Sync, S: Sync> Sync for LruCache<K, V, S> {}
1309
1310
impl<K: Hash + Eq, V, S: BuildHasher> fmt::Debug for LruCache<K, V, S> {
1311
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1312
0
        f.debug_struct("LruCache")
1313
0
            .field("len", &self.len())
1314
0
            .field("cap", &self.cap())
1315
0
            .finish()
1316
0
    }
Unexecuted instantiation: _RNvXsf_Cs9xc8CxQ35gK_3lruINtB5_8LruCacheAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementENtNtCsbQ8arDwx5Xq_4core3fmt5Debug3fmtBM_
Unexecuted instantiation: _RNvXINICs9xc8CxQ35gK_3lrusf_0pppEINtB5_8LruCachepppENtNtCsbQ8arDwx5Xq_4core3fmt5Debug3fmtB5_
1317
}
1318
1319
/// An iterator over the entries of a `LruCache`.
1320
///
1321
/// This `struct` is created by the [`iter`] method on [`LruCache`][`LruCache`]. See its
1322
/// documentation for more.
1323
///
1324
/// [`iter`]: struct.LruCache.html#method.iter
1325
/// [`LruCache`]: struct.LruCache.html
1326
pub struct Iter<'a, K: 'a, V: 'a> {
1327
    len: usize,
1328
1329
    ptr: *const LruEntry<K, V>,
1330
    end: *const LruEntry<K, V>,
1331
1332
    phantom: PhantomData<&'a K>,
1333
}
1334
1335
impl<'a, K, V> Iterator for Iter<'a, K, V> {
1336
    type Item = (&'a K, &'a V);
1337
1338
0
    fn next(&mut self) -> Option<(&'a K, &'a V)> {
1339
0
        if self.len == 0 {
1340
0
            return None;
1341
0
        }
1342
0
1343
0
        let key = unsafe { &(*(*self.ptr).key.as_ptr()) as &K };
1344
0
        let val = unsafe { &(*(*self.ptr).val.as_ptr()) as &V };
1345
0
1346
0
        self.len -= 1;
1347
0
        self.ptr = unsafe { (*self.ptr).next };
1348
0
1349
0
        Some((key, val))
1350
0
    }
1351
1352
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1353
0
        (self.len, Some(self.len))
1354
0
    }
1355
1356
0
    fn count(self) -> usize {
1357
0
        self.len
1358
0
    }
1359
}
1360
1361
impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
1362
0
    fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
1363
0
        if self.len == 0 {
1364
0
            return None;
1365
0
        }
1366
0
1367
0
        let key = unsafe { &(*(*self.end).key.as_ptr()) as &K };
1368
0
        let val = unsafe { &(*(*self.end).val.as_ptr()) as &V };
1369
0
1370
0
        self.len -= 1;
1371
0
        self.end = unsafe { (*self.end).prev };
1372
0
1373
0
        Some((key, val))
1374
0
    }
Unexecuted instantiation: _RNvXsh_Cs9xc8CxQ35gK_3lruINtB5_4IterAhj20_NtNtCs568wuOlRYFZ_8chia_bls9gtelement9GTElementENtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits12double_ended19DoubleEndedIterator9next_backBI_
Unexecuted instantiation: _RNvXINICs9xc8CxQ35gK_3lrush_0ppEINtB5_4IterppENtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits12double_ended19DoubleEndedIterator9next_backB5_
1375
}
1376
1377
impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {}
1378
impl<'a, K, V> FusedIterator for Iter<'a, K, V> {}
1379
1380
impl<'a, K, V> Clone for Iter<'a, K, V> {
1381
0
    fn clone(&self) -> Iter<'a, K, V> {
1382
0
        Iter {
1383
0
            len: self.len,
1384
0
            ptr: self.ptr,
1385
0
            end: self.end,
1386
0
            phantom: PhantomData,
1387
0
        }
1388
0
    }
1389
}
1390
1391
// The compiler does not automatically derive Send and Sync for Iter because it contains
1392
// raw pointers.
1393
unsafe impl<'a, K: Send, V: Send> Send for Iter<'a, K, V> {}
1394
unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
1395
1396
/// An iterator over mutables entries of a `LruCache`.
1397
///
1398
/// This `struct` is created by the [`iter_mut`] method on [`LruCache`][`LruCache`]. See its
1399
/// documentation for more.
1400
///
1401
/// [`iter_mut`]: struct.LruCache.html#method.iter_mut
1402
/// [`LruCache`]: struct.LruCache.html
1403
pub struct IterMut<'a, K: 'a, V: 'a> {
1404
    len: usize,
1405
1406
    ptr: *mut LruEntry<K, V>,
1407
    end: *mut LruEntry<K, V>,
1408
1409
    phantom: PhantomData<&'a K>,
1410
}
1411
1412
impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1413
    type Item = (&'a K, &'a mut V);
1414
1415
0
    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1416
0
        if self.len == 0 {
1417
0
            return None;
1418
0
        }
1419
0
1420
0
        let key = unsafe { &mut (*(*self.ptr).key.as_mut_ptr()) as &mut K };
1421
0
        let val = unsafe { &mut (*(*self.ptr).val.as_mut_ptr()) as &mut V };
1422
0
1423
0
        self.len -= 1;
1424
0
        self.ptr = unsafe { (*self.ptr).next };
1425
0
1426
0
        Some((key, val))
1427
0
    }
1428
1429
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1430
0
        (self.len, Some(self.len))
1431
0
    }
1432
1433
0
    fn count(self) -> usize {
1434
0
        self.len
1435
0
    }
1436
}
1437
1438
impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
1439
0
    fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
1440
0
        if self.len == 0 {
1441
0
            return None;
1442
0
        }
1443
0
1444
0
        let key = unsafe { &mut (*(*self.end).key.as_mut_ptr()) as &mut K };
1445
0
        let val = unsafe { &mut (*(*self.end).val.as_mut_ptr()) as &mut V };
1446
0
1447
0
        self.len -= 1;
1448
0
        self.end = unsafe { (*self.end).prev };
1449
0
1450
0
        Some((key, val))
1451
0
    }
1452
}
1453
1454
impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {}
1455
impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
1456
1457
// The compiler does not automatically derive Send and Sync for Iter because it contains
1458
// raw pointers.
1459
unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
1460
unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
1461
1462
/// An iterator that moves out of a `LruCache`.
1463
///
1464
/// This `struct` is created by the [`into_iter`] method on [`LruCache`][`LruCache`]. See its
1465
/// documentation for more.
1466
///
1467
/// [`into_iter`]: struct.LruCache.html#method.into_iter
1468
/// [`LruCache`]: struct.LruCache.html
1469
pub struct IntoIter<K, V>
1470
where
1471
    K: Hash + Eq,
1472
{
1473
    cache: LruCache<K, V>,
1474
}
1475
1476
impl<K, V> Iterator for IntoIter<K, V>
1477
where
1478
    K: Hash + Eq,
1479
{
1480
    type Item = (K, V);
1481
1482
0
    fn next(&mut self) -> Option<(K, V)> {
1483
0
        self.cache.pop_lru()
1484
0
    }
1485
1486
0
    fn size_hint(&self) -> (usize, Option<usize>) {
1487
0
        let len = self.cache.len();
1488
0
        (len, Some(len))
1489
0
    }
1490
1491
0
    fn count(self) -> usize {
1492
0
        self.cache.len()
1493
0
    }
1494
}
1495
1496
impl<K, V> ExactSizeIterator for IntoIter<K, V> where K: Hash + Eq {}
1497
impl<K, V> FusedIterator for IntoIter<K, V> where K: Hash + Eq {}
1498
1499
impl<K: Hash + Eq, V> IntoIterator for LruCache<K, V> {
1500
    type Item = (K, V);
1501
    type IntoIter = IntoIter<K, V>;
1502
1503
0
    fn into_iter(self) -> IntoIter<K, V> {
1504
0
        IntoIter { cache: self }
1505
0
    }
1506
}
1507
1508
#[cfg(test)]
1509
mod tests {
1510
    use super::LruCache;
1511
    use core::{fmt::Debug, num::NonZeroUsize};
1512
    use scoped_threadpool::Pool;
1513
    use std::sync::atomic::{AtomicUsize, Ordering};
1514
1515
    fn assert_opt_eq<V: PartialEq + Debug>(opt: Option<&V>, v: V) {
1516
        assert!(opt.is_some());
1517
        assert_eq!(opt.unwrap(), &v);
1518
    }
1519
1520
    fn assert_opt_eq_mut<V: PartialEq + Debug>(opt: Option<&mut V>, v: V) {
1521
        assert!(opt.is_some());
1522
        assert_eq!(opt.unwrap(), &v);
1523
    }
1524
1525
    fn assert_opt_eq_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
1526
        opt: Option<(&K, &V)>,
1527
        kv: (K, V),
1528
    ) {
1529
        assert!(opt.is_some());
1530
        let res = opt.unwrap();
1531
        assert_eq!(res.0, &kv.0);
1532
        assert_eq!(res.1, &kv.1);
1533
    }
1534
1535
    fn assert_opt_eq_mut_tuple<K: PartialEq + Debug, V: PartialEq + Debug>(
1536
        opt: Option<(&K, &mut V)>,
1537
        kv: (K, V),
1538
    ) {
1539
        assert!(opt.is_some());
1540
        let res = opt.unwrap();
1541
        assert_eq!(res.0, &kv.0);
1542
        assert_eq!(res.1, &kv.1);
1543
    }
1544
1545
    #[test]
1546
    fn test_unbounded() {
1547
        let mut cache = LruCache::unbounded();
1548
        for i in 0..13370 {
1549
            cache.put(i, ());
1550
        }
1551
        assert_eq!(cache.len(), 13370);
1552
    }
1553
1554
    #[test]
1555
    #[cfg(feature = "hashbrown")]
1556
    fn test_with_hasher() {
1557
        use core::num::NonZeroUsize;
1558
1559
        use hashbrown::hash_map::DefaultHashBuilder;
1560
1561
        let s = DefaultHashBuilder::default();
1562
        let mut cache = LruCache::with_hasher(NonZeroUsize::new(16).unwrap(), s);
1563
1564
        for i in 0..13370 {
1565
            cache.put(i, ());
1566
        }
1567
        assert_eq!(cache.len(), 16);
1568
    }
1569
1570
    #[test]
1571
    fn test_put_and_get() {
1572
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1573
        assert!(cache.is_empty());
1574
1575
        assert_eq!(cache.put("apple", "red"), None);
1576
        assert_eq!(cache.put("banana", "yellow"), None);
1577
1578
        assert_eq!(cache.cap().get(), 2);
1579
        assert_eq!(cache.len(), 2);
1580
        assert!(!cache.is_empty());
1581
        assert_opt_eq(cache.get(&"apple"), "red");
1582
        assert_opt_eq(cache.get(&"banana"), "yellow");
1583
    }
1584
1585
    #[test]
1586
    fn test_put_and_get_or_insert() {
1587
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1588
        assert!(cache.is_empty());
1589
1590
        assert_eq!(cache.put("apple", "red"), None);
1591
        assert_eq!(cache.put("banana", "yellow"), None);
1592
1593
        assert_eq!(cache.cap().get(), 2);
1594
        assert_eq!(cache.len(), 2);
1595
        assert!(!cache.is_empty());
1596
        assert_eq!(cache.get_or_insert("apple", || "orange"), &"red");
1597
        assert_eq!(cache.get_or_insert("banana", || "orange"), &"yellow");
1598
        assert_eq!(cache.get_or_insert("lemon", || "orange"), &"orange");
1599
        assert_eq!(cache.get_or_insert("lemon", || "red"), &"orange");
1600
    }
1601
1602
    #[test]
1603
    fn test_try_get_or_insert() {
1604
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1605
1606
        assert_eq!(
1607
            cache.try_get_or_insert::<_, &str>("apple", || Ok("red")),
1608
            Ok(&"red")
1609
        );
1610
        assert_eq!(
1611
            cache.try_get_or_insert::<_, &str>("apple", || Err("failed")),
1612
            Ok(&"red")
1613
        );
1614
        assert_eq!(
1615
            cache.try_get_or_insert::<_, &str>("banana", || Ok("orange")),
1616
            Ok(&"orange")
1617
        );
1618
        assert_eq!(
1619
            cache.try_get_or_insert::<_, &str>("lemon", || Err("failed")),
1620
            Err("failed")
1621
        );
1622
        assert_eq!(
1623
            cache.try_get_or_insert::<_, &str>("banana", || Err("failed")),
1624
            Ok(&"orange")
1625
        );
1626
    }
1627
1628
    #[test]
1629
    fn test_put_and_get_or_insert_mut() {
1630
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1631
        assert!(cache.is_empty());
1632
1633
        assert_eq!(cache.put("apple", "red"), None);
1634
        assert_eq!(cache.put("banana", "yellow"), None);
1635
1636
        assert_eq!(cache.cap().get(), 2);
1637
        assert_eq!(cache.len(), 2);
1638
1639
        let v = cache.get_or_insert_mut("apple", || "orange");
1640
        assert_eq!(v, &"red");
1641
        *v = "blue";
1642
1643
        assert_eq!(cache.get_or_insert_mut("apple", || "orange"), &"blue");
1644
        assert_eq!(cache.get_or_insert_mut("banana", || "orange"), &"yellow");
1645
        assert_eq!(cache.get_or_insert_mut("lemon", || "orange"), &"orange");
1646
        assert_eq!(cache.get_or_insert_mut("lemon", || "red"), &"orange");
1647
    }
1648
1649
    #[test]
1650
    fn test_try_get_or_insert_mut() {
1651
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1652
1653
        cache.put(1, "a");
1654
        cache.put(2, "b");
1655
        cache.put(2, "c");
1656
1657
        let f = || -> Result<&str, &str> { Err("failed") };
1658
        let a = || -> Result<&str, &str> { Ok("a") };
1659
        let b = || -> Result<&str, &str> { Ok("b") };
1660
        if let Ok(v) = cache.try_get_or_insert_mut(2, a) {
1661
            *v = "d";
1662
        }
1663
        assert_eq!(cache.try_get_or_insert_mut(2, a), Ok(&mut "d"));
1664
        assert_eq!(cache.try_get_or_insert_mut(3, f), Err("failed"));
1665
        assert_eq!(cache.try_get_or_insert_mut(4, b), Ok(&mut "b"));
1666
        assert_eq!(cache.try_get_or_insert_mut(4, a), Ok(&mut "b"));
1667
    }
1668
1669
    #[test]
1670
    fn test_put_and_get_mut() {
1671
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1672
1673
        cache.put("apple", "red");
1674
        cache.put("banana", "yellow");
1675
1676
        assert_eq!(cache.cap().get(), 2);
1677
        assert_eq!(cache.len(), 2);
1678
        assert_opt_eq_mut(cache.get_mut(&"apple"), "red");
1679
        assert_opt_eq_mut(cache.get_mut(&"banana"), "yellow");
1680
    }
1681
1682
    #[test]
1683
    fn test_get_mut_and_update() {
1684
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1685
1686
        cache.put("apple", 1);
1687
        cache.put("banana", 3);
1688
1689
        {
1690
            let v = cache.get_mut(&"apple").unwrap();
1691
            *v = 4;
1692
        }
1693
1694
        assert_eq!(cache.cap().get(), 2);
1695
        assert_eq!(cache.len(), 2);
1696
        assert_opt_eq_mut(cache.get_mut(&"apple"), 4);
1697
        assert_opt_eq_mut(cache.get_mut(&"banana"), 3);
1698
    }
1699
1700
    #[test]
1701
    fn test_put_update() {
1702
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1703
1704
        assert_eq!(cache.put("apple", "red"), None);
1705
        assert_eq!(cache.put("apple", "green"), Some("red"));
1706
1707
        assert_eq!(cache.len(), 1);
1708
        assert_opt_eq(cache.get(&"apple"), "green");
1709
    }
1710
1711
    #[test]
1712
    fn test_put_removes_oldest() {
1713
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1714
1715
        assert_eq!(cache.put("apple", "red"), None);
1716
        assert_eq!(cache.put("banana", "yellow"), None);
1717
        assert_eq!(cache.put("pear", "green"), None);
1718
1719
        assert!(cache.get(&"apple").is_none());
1720
        assert_opt_eq(cache.get(&"banana"), "yellow");
1721
        assert_opt_eq(cache.get(&"pear"), "green");
1722
1723
        // Even though we inserted "apple" into the cache earlier it has since been removed from
1724
        // the cache so there is no current value for `put` to return.
1725
        assert_eq!(cache.put("apple", "green"), None);
1726
        assert_eq!(cache.put("tomato", "red"), None);
1727
1728
        assert!(cache.get(&"pear").is_none());
1729
        assert_opt_eq(cache.get(&"apple"), "green");
1730
        assert_opt_eq(cache.get(&"tomato"), "red");
1731
    }
1732
1733
    #[test]
1734
    fn test_peek() {
1735
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1736
1737
        cache.put("apple", "red");
1738
        cache.put("banana", "yellow");
1739
1740
        assert_opt_eq(cache.peek(&"banana"), "yellow");
1741
        assert_opt_eq(cache.peek(&"apple"), "red");
1742
1743
        cache.put("pear", "green");
1744
1745
        assert!(cache.peek(&"apple").is_none());
1746
        assert_opt_eq(cache.peek(&"banana"), "yellow");
1747
        assert_opt_eq(cache.peek(&"pear"), "green");
1748
    }
1749
1750
    #[test]
1751
    fn test_peek_mut() {
1752
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1753
1754
        cache.put("apple", "red");
1755
        cache.put("banana", "yellow");
1756
1757
        assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
1758
        assert_opt_eq_mut(cache.peek_mut(&"apple"), "red");
1759
        assert!(cache.peek_mut(&"pear").is_none());
1760
1761
        cache.put("pear", "green");
1762
1763
        assert!(cache.peek_mut(&"apple").is_none());
1764
        assert_opt_eq_mut(cache.peek_mut(&"banana"), "yellow");
1765
        assert_opt_eq_mut(cache.peek_mut(&"pear"), "green");
1766
1767
        {
1768
            let v = cache.peek_mut(&"banana").unwrap();
1769
            *v = "green";
1770
        }
1771
1772
        assert_opt_eq_mut(cache.peek_mut(&"banana"), "green");
1773
    }
1774
1775
    #[test]
1776
    fn test_peek_lru() {
1777
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1778
1779
        assert!(cache.peek_lru().is_none());
1780
1781
        cache.put("apple", "red");
1782
        cache.put("banana", "yellow");
1783
        assert_opt_eq_tuple(cache.peek_lru(), ("apple", "red"));
1784
1785
        cache.get(&"apple");
1786
        assert_opt_eq_tuple(cache.peek_lru(), ("banana", "yellow"));
1787
1788
        cache.clear();
1789
        assert!(cache.peek_lru().is_none());
1790
    }
1791
1792
    #[test]
1793
    fn test_contains() {
1794
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1795
1796
        cache.put("apple", "red");
1797
        cache.put("banana", "yellow");
1798
        cache.put("pear", "green");
1799
1800
        assert!(!cache.contains(&"apple"));
1801
        assert!(cache.contains(&"banana"));
1802
        assert!(cache.contains(&"pear"));
1803
    }
1804
1805
    #[test]
1806
    fn test_pop() {
1807
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1808
1809
        cache.put("apple", "red");
1810
        cache.put("banana", "yellow");
1811
1812
        assert_eq!(cache.len(), 2);
1813
        assert_opt_eq(cache.get(&"apple"), "red");
1814
        assert_opt_eq(cache.get(&"banana"), "yellow");
1815
1816
        let popped = cache.pop(&"apple");
1817
        assert!(popped.is_some());
1818
        assert_eq!(popped.unwrap(), "red");
1819
        assert_eq!(cache.len(), 1);
1820
        assert!(cache.get(&"apple").is_none());
1821
        assert_opt_eq(cache.get(&"banana"), "yellow");
1822
    }
1823
1824
    #[test]
1825
    fn test_pop_entry() {
1826
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1827
        cache.put("apple", "red");
1828
        cache.put("banana", "yellow");
1829
1830
        assert_eq!(cache.len(), 2);
1831
        assert_opt_eq(cache.get(&"apple"), "red");
1832
        assert_opt_eq(cache.get(&"banana"), "yellow");
1833
1834
        let popped = cache.pop_entry(&"apple");
1835
        assert!(popped.is_some());
1836
        assert_eq!(popped.unwrap(), ("apple", "red"));
1837
        assert_eq!(cache.len(), 1);
1838
        assert!(cache.get(&"apple").is_none());
1839
        assert_opt_eq(cache.get(&"banana"), "yellow");
1840
    }
1841
1842
    #[test]
1843
    fn test_pop_lru() {
1844
        let mut cache = LruCache::new(NonZeroUsize::new(200).unwrap());
1845
1846
        for i in 0..75 {
1847
            cache.put(i, "A");
1848
        }
1849
        for i in 0..75 {
1850
            cache.put(i + 100, "B");
1851
        }
1852
        for i in 0..75 {
1853
            cache.put(i + 200, "C");
1854
        }
1855
        assert_eq!(cache.len(), 200);
1856
1857
        for i in 0..75 {
1858
            assert_opt_eq(cache.get(&(74 - i + 100)), "B");
1859
        }
1860
        assert_opt_eq(cache.get(&25), "A");
1861
1862
        for i in 26..75 {
1863
            assert_eq!(cache.pop_lru(), Some((i, "A")));
1864
        }
1865
        for i in 0..75 {
1866
            assert_eq!(cache.pop_lru(), Some((i + 200, "C")));
1867
        }
1868
        for i in 0..75 {
1869
            assert_eq!(cache.pop_lru(), Some((74 - i + 100, "B")));
1870
        }
1871
        assert_eq!(cache.pop_lru(), Some((25, "A")));
1872
        for _ in 0..50 {
1873
            assert_eq!(cache.pop_lru(), None);
1874
        }
1875
    }
1876
1877
    #[test]
1878
    fn test_clear() {
1879
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1880
1881
        cache.put("apple", "red");
1882
        cache.put("banana", "yellow");
1883
1884
        assert_eq!(cache.len(), 2);
1885
        assert_opt_eq(cache.get(&"apple"), "red");
1886
        assert_opt_eq(cache.get(&"banana"), "yellow");
1887
1888
        cache.clear();
1889
        assert_eq!(cache.len(), 0);
1890
    }
1891
1892
    #[test]
1893
    fn test_resize_larger() {
1894
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
1895
1896
        cache.put(1, "a");
1897
        cache.put(2, "b");
1898
        cache.resize(NonZeroUsize::new(4).unwrap());
1899
        cache.put(3, "c");
1900
        cache.put(4, "d");
1901
1902
        assert_eq!(cache.len(), 4);
1903
        assert_eq!(cache.get(&1), Some(&"a"));
1904
        assert_eq!(cache.get(&2), Some(&"b"));
1905
        assert_eq!(cache.get(&3), Some(&"c"));
1906
        assert_eq!(cache.get(&4), Some(&"d"));
1907
    }
1908
1909
    #[test]
1910
    fn test_resize_smaller() {
1911
        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
1912
1913
        cache.put(1, "a");
1914
        cache.put(2, "b");
1915
        cache.put(3, "c");
1916
        cache.put(4, "d");
1917
1918
        cache.resize(NonZeroUsize::new(2).unwrap());
1919
1920
        assert_eq!(cache.len(), 2);
1921
        assert!(cache.get(&1).is_none());
1922
        assert!(cache.get(&2).is_none());
1923
        assert_eq!(cache.get(&3), Some(&"c"));
1924
        assert_eq!(cache.get(&4), Some(&"d"));
1925
    }
1926
1927
    #[test]
1928
    fn test_send() {
1929
        use std::thread;
1930
1931
        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
1932
        cache.put(1, "a");
1933
1934
        let handle = thread::spawn(move || {
1935
            assert_eq!(cache.get(&1), Some(&"a"));
1936
        });
1937
1938
        assert!(handle.join().is_ok());
1939
    }
1940
1941
    #[test]
1942
    fn test_multiple_threads() {
1943
        let mut pool = Pool::new(1);
1944
        let mut cache = LruCache::new(NonZeroUsize::new(4).unwrap());
1945
        cache.put(1, "a");
1946
1947
        let cache_ref = &cache;
1948
        pool.scoped(|scoped| {
1949
            scoped.execute(move || {
1950
                assert_eq!(cache_ref.peek(&1), Some(&"a"));
1951
            });
1952
        });
1953
1954
        assert_eq!((cache_ref).peek(&1), Some(&"a"));
1955
    }
1956
1957
    #[test]
1958
    fn test_iter_forwards() {
1959
        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1960
        cache.put("a", 1);
1961
        cache.put("b", 2);
1962
        cache.put("c", 3);
1963
1964
        {
1965
            // iter const
1966
            let mut iter = cache.iter();
1967
            assert_eq!(iter.len(), 3);
1968
            assert_opt_eq_tuple(iter.next(), ("c", 3));
1969
1970
            assert_eq!(iter.len(), 2);
1971
            assert_opt_eq_tuple(iter.next(), ("b", 2));
1972
1973
            assert_eq!(iter.len(), 1);
1974
            assert_opt_eq_tuple(iter.next(), ("a", 1));
1975
1976
            assert_eq!(iter.len(), 0);
1977
            assert_eq!(iter.next(), None);
1978
        }
1979
        {
1980
            // iter mut
1981
            let mut iter = cache.iter_mut();
1982
            assert_eq!(iter.len(), 3);
1983
            assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
1984
1985
            assert_eq!(iter.len(), 2);
1986
            assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
1987
1988
            assert_eq!(iter.len(), 1);
1989
            assert_opt_eq_mut_tuple(iter.next(), ("a", 1));
1990
1991
            assert_eq!(iter.len(), 0);
1992
            assert_eq!(iter.next(), None);
1993
        }
1994
    }
1995
1996
    #[test]
1997
    fn test_iter_backwards() {
1998
        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
1999
        cache.put("a", 1);
2000
        cache.put("b", 2);
2001
        cache.put("c", 3);
2002
2003
        {
2004
            // iter const
2005
            let mut iter = cache.iter();
2006
            assert_eq!(iter.len(), 3);
2007
            assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2008
2009
            assert_eq!(iter.len(), 2);
2010
            assert_opt_eq_tuple(iter.next_back(), ("b", 2));
2011
2012
            assert_eq!(iter.len(), 1);
2013
            assert_opt_eq_tuple(iter.next_back(), ("c", 3));
2014
2015
            assert_eq!(iter.len(), 0);
2016
            assert_eq!(iter.next_back(), None);
2017
        }
2018
2019
        {
2020
            // iter mut
2021
            let mut iter = cache.iter_mut();
2022
            assert_eq!(iter.len(), 3);
2023
            assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2024
2025
            assert_eq!(iter.len(), 2);
2026
            assert_opt_eq_mut_tuple(iter.next_back(), ("b", 2));
2027
2028
            assert_eq!(iter.len(), 1);
2029
            assert_opt_eq_mut_tuple(iter.next_back(), ("c", 3));
2030
2031
            assert_eq!(iter.len(), 0);
2032
            assert_eq!(iter.next_back(), None);
2033
        }
2034
    }
2035
2036
    #[test]
2037
    fn test_iter_forwards_and_backwards() {
2038
        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2039
        cache.put("a", 1);
2040
        cache.put("b", 2);
2041
        cache.put("c", 3);
2042
2043
        {
2044
            // iter const
2045
            let mut iter = cache.iter();
2046
            assert_eq!(iter.len(), 3);
2047
            assert_opt_eq_tuple(iter.next(), ("c", 3));
2048
2049
            assert_eq!(iter.len(), 2);
2050
            assert_opt_eq_tuple(iter.next_back(), ("a", 1));
2051
2052
            assert_eq!(iter.len(), 1);
2053
            assert_opt_eq_tuple(iter.next(), ("b", 2));
2054
2055
            assert_eq!(iter.len(), 0);
2056
            assert_eq!(iter.next_back(), None);
2057
        }
2058
        {
2059
            // iter mut
2060
            let mut iter = cache.iter_mut();
2061
            assert_eq!(iter.len(), 3);
2062
            assert_opt_eq_mut_tuple(iter.next(), ("c", 3));
2063
2064
            assert_eq!(iter.len(), 2);
2065
            assert_opt_eq_mut_tuple(iter.next_back(), ("a", 1));
2066
2067
            assert_eq!(iter.len(), 1);
2068
            assert_opt_eq_mut_tuple(iter.next(), ("b", 2));
2069
2070
            assert_eq!(iter.len(), 0);
2071
            assert_eq!(iter.next_back(), None);
2072
        }
2073
    }
2074
2075
    #[test]
2076
    fn test_iter_multiple_threads() {
2077
        let mut pool = Pool::new(1);
2078
        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2079
        cache.put("a", 1);
2080
        cache.put("b", 2);
2081
        cache.put("c", 3);
2082
2083
        let mut iter = cache.iter();
2084
        assert_eq!(iter.len(), 3);
2085
        assert_opt_eq_tuple(iter.next(), ("c", 3));
2086
2087
        {
2088
            let iter_ref = &mut iter;
2089
            pool.scoped(|scoped| {
2090
                scoped.execute(move || {
2091
                    assert_eq!(iter_ref.len(), 2);
2092
                    assert_opt_eq_tuple(iter_ref.next(), ("b", 2));
2093
                });
2094
            });
2095
        }
2096
2097
        assert_eq!(iter.len(), 1);
2098
        assert_opt_eq_tuple(iter.next(), ("a", 1));
2099
2100
        assert_eq!(iter.len(), 0);
2101
        assert_eq!(iter.next(), None);
2102
    }
2103
2104
    #[test]
2105
    fn test_iter_clone() {
2106
        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2107
        cache.put("a", 1);
2108
        cache.put("b", 2);
2109
2110
        let mut iter = cache.iter();
2111
        let mut iter_clone = iter.clone();
2112
2113
        assert_eq!(iter.len(), 2);
2114
        assert_opt_eq_tuple(iter.next(), ("b", 2));
2115
        assert_eq!(iter_clone.len(), 2);
2116
        assert_opt_eq_tuple(iter_clone.next(), ("b", 2));
2117
2118
        assert_eq!(iter.len(), 1);
2119
        assert_opt_eq_tuple(iter.next(), ("a", 1));
2120
        assert_eq!(iter_clone.len(), 1);
2121
        assert_opt_eq_tuple(iter_clone.next(), ("a", 1));
2122
2123
        assert_eq!(iter.len(), 0);
2124
        assert_eq!(iter.next(), None);
2125
        assert_eq!(iter_clone.len(), 0);
2126
        assert_eq!(iter_clone.next(), None);
2127
    }
2128
2129
    #[test]
2130
    fn test_into_iter() {
2131
        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2132
        cache.put("a", 1);
2133
        cache.put("b", 2);
2134
        cache.put("c", 3);
2135
2136
        let mut iter = cache.into_iter();
2137
        assert_eq!(iter.len(), 3);
2138
        assert_eq!(iter.next(), Some(("a", 1)));
2139
2140
        assert_eq!(iter.len(), 2);
2141
        assert_eq!(iter.next(), Some(("b", 2)));
2142
2143
        assert_eq!(iter.len(), 1);
2144
        assert_eq!(iter.next(), Some(("c", 3)));
2145
2146
        assert_eq!(iter.len(), 0);
2147
        assert_eq!(iter.next(), None);
2148
    }
2149
2150
    #[test]
2151
    fn test_that_pop_actually_detaches_node() {
2152
        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
2153
2154
        cache.put("a", 1);
2155
        cache.put("b", 2);
2156
        cache.put("c", 3);
2157
        cache.put("d", 4);
2158
        cache.put("e", 5);
2159
2160
        assert_eq!(cache.pop(&"c"), Some(3));
2161
2162
        cache.put("f", 6);
2163
2164
        let mut iter = cache.iter();
2165
        assert_opt_eq_tuple(iter.next(), ("f", 6));
2166
        assert_opt_eq_tuple(iter.next(), ("e", 5));
2167
        assert_opt_eq_tuple(iter.next(), ("d", 4));
2168
        assert_opt_eq_tuple(iter.next(), ("b", 2));
2169
        assert_opt_eq_tuple(iter.next(), ("a", 1));
2170
        assert!(iter.next().is_none());
2171
    }
2172
2173
    #[test]
2174
    fn test_get_with_borrow() {
2175
        use alloc::string::String;
2176
2177
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2178
2179
        let key = String::from("apple");
2180
        cache.put(key, "red");
2181
2182
        assert_opt_eq(cache.get("apple"), "red");
2183
    }
2184
2185
    #[test]
2186
    fn test_get_mut_with_borrow() {
2187
        use alloc::string::String;
2188
2189
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2190
2191
        let key = String::from("apple");
2192
        cache.put(key, "red");
2193
2194
        assert_opt_eq_mut(cache.get_mut("apple"), "red");
2195
    }
2196
2197
    #[test]
2198
    fn test_no_memory_leaks() {
2199
        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2200
2201
        struct DropCounter;
2202
2203
        impl Drop for DropCounter {
2204
            fn drop(&mut self) {
2205
                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2206
            }
2207
        }
2208
2209
        let n = 100;
2210
        for _ in 0..n {
2211
            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2212
            for i in 0..n {
2213
                cache.put(i, DropCounter {});
2214
            }
2215
        }
2216
        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2217
    }
2218
2219
    #[test]
2220
    fn test_no_memory_leaks_with_clear() {
2221
        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2222
2223
        struct DropCounter;
2224
2225
        impl Drop for DropCounter {
2226
            fn drop(&mut self) {
2227
                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2228
            }
2229
        }
2230
2231
        let n = 100;
2232
        for _ in 0..n {
2233
            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2234
            for i in 0..n {
2235
                cache.put(i, DropCounter {});
2236
            }
2237
            cache.clear();
2238
        }
2239
        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2240
    }
2241
2242
    #[test]
2243
    fn test_no_memory_leaks_with_resize() {
2244
        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2245
2246
        struct DropCounter;
2247
2248
        impl Drop for DropCounter {
2249
            fn drop(&mut self) {
2250
                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2251
            }
2252
        }
2253
2254
        let n = 100;
2255
        for _ in 0..n {
2256
            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2257
            for i in 0..n {
2258
                cache.put(i, DropCounter {});
2259
            }
2260
            cache.clear();
2261
        }
2262
        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n);
2263
    }
2264
2265
    #[test]
2266
    fn test_no_memory_leaks_with_pop() {
2267
        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
2268
2269
        #[derive(Hash, Eq)]
2270
        struct KeyDropCounter(usize);
2271
2272
        impl PartialEq for KeyDropCounter {
2273
            fn eq(&self, other: &Self) -> bool {
2274
                self.0.eq(&other.0)
2275
            }
2276
        }
2277
2278
        impl Drop for KeyDropCounter {
2279
            fn drop(&mut self) {
2280
                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
2281
            }
2282
        }
2283
2284
        let n = 100;
2285
        for _ in 0..n {
2286
            let mut cache = LruCache::new(NonZeroUsize::new(1).unwrap());
2287
2288
            for i in 0..100 {
2289
                cache.put(KeyDropCounter(i), i);
2290
                cache.pop(&KeyDropCounter(i));
2291
            }
2292
        }
2293
2294
        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), n * n * 2);
2295
    }
2296
2297
    #[test]
2298
    fn test_promote_and_demote() {
2299
        let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
2300
        for i in 0..5 {
2301
            cache.push(i, i);
2302
        }
2303
        cache.promote(&1);
2304
        cache.promote(&0);
2305
        cache.demote(&3);
2306
        cache.demote(&4);
2307
        assert_eq!(cache.pop_lru(), Some((4, 4)));
2308
        assert_eq!(cache.pop_lru(), Some((3, 3)));
2309
        assert_eq!(cache.pop_lru(), Some((2, 2)));
2310
        assert_eq!(cache.pop_lru(), Some((1, 1)));
2311
        assert_eq!(cache.pop_lru(), Some((0, 0)));
2312
        assert_eq!(cache.pop_lru(), None);
2313
    }
2314
2315
    #[test]
2316
    fn test_get_key_value() {
2317
        use alloc::string::String;
2318
2319
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2320
2321
        let key = String::from("apple");
2322
        cache.put(key, "red");
2323
2324
        assert_eq!(
2325
            cache.get_key_value("apple"),
2326
            Some((&String::from("apple"), &"red"))
2327
        );
2328
        assert_eq!(cache.get_key_value("banana"), None);
2329
    }
2330
2331
    #[test]
2332
    fn test_get_key_value_mut() {
2333
        use alloc::string::String;
2334
2335
        let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
2336
2337
        let key = String::from("apple");
2338
        cache.put(key, "red");
2339
2340
        let (k, v) = cache.get_key_value_mut("apple").unwrap();
2341
        assert_eq!(k, &String::from("apple"));
2342
        assert_eq!(v, &mut "red");
2343
        *v = "green";
2344
2345
        assert_eq!(
2346
            cache.get_key_value("apple"),
2347
            Some((&String::from("apple"), &"green"))
2348
        );
2349
        assert_eq!(cache.get_key_value("banana"), None);
2350
    }
2351
2352
    #[test]
2353
    fn test_clone() {
2354
        let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
2355
        cache.put("a", 1);
2356
        cache.put("b", 2);
2357
        cache.put("c", 3);
2358
2359
        let mut cloned = cache.clone();
2360
2361
        assert_eq!(cache.pop_lru(), Some(("a", 1)));
2362
        assert_eq!(cloned.pop_lru(), Some(("a", 1)));
2363
2364
        assert_eq!(cache.pop_lru(), Some(("b", 2)));
2365
        assert_eq!(cloned.pop_lru(), Some(("b", 2)));
2366
2367
        assert_eq!(cache.pop_lru(), Some(("c", 3)));
2368
        assert_eq!(cloned.pop_lru(), Some(("c", 3)));
2369
2370
        assert_eq!(cache.pop_lru(), None);
2371
        assert_eq!(cloned.pop_lru(), None);
2372
    }
2373
}
2374
2375
/// Doctests for what should *not* compile
2376
///
2377
/// ```compile_fail
2378
/// let mut cache = lru::LruCache::<u32, u32>::unbounded();
2379
/// let _: &'static u32 = cache.get_or_insert(0, || 92);
2380
/// ```
2381
///
2382
/// ```compile_fail
2383
/// let mut cache = lru::LruCache::<u32, u32>::unbounded();
2384
/// let _: Option<(&'static u32, _)> = cache.peek_lru();
2385
/// let _: Option<(_, &'static u32)> = cache.peek_lru();
2386
/// ```
2387
0
fn _test_lifetimes() {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/bigint.rs
Line
Count
Source
1
// `Add`/`Sub` ops may flip from `BigInt` to its `BigUint` magnitude
2
#![allow(clippy::suspicious_arithmetic_impl)]
3
4
use alloc::string::String;
5
use alloc::vec::Vec;
6
use core::cmp::Ordering::{self, Equal};
7
use core::default::Default;
8
use core::fmt;
9
use core::hash;
10
use core::ops::{Neg, Not};
11
use core::str;
12
13
use num_integer::{Integer, Roots};
14
use num_traits::{ConstZero, Num, One, Pow, Signed, Zero};
15
16
use self::Sign::{Minus, NoSign, Plus};
17
18
use crate::big_digit::BigDigit;
19
use crate::biguint::to_str_radix_reversed;
20
use crate::biguint::{BigUint, IntDigits, U32Digits, U64Digits};
21
22
mod addition;
23
mod division;
24
mod multiplication;
25
mod subtraction;
26
27
mod arbitrary;
28
mod bits;
29
mod convert;
30
mod power;
31
mod serde;
32
mod shift;
33
34
/// A `Sign` is a [`BigInt`]'s composing element.
35
#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone, Debug, Hash)]
36
pub enum Sign {
37
    Minus,
38
    NoSign,
39
    Plus,
40
}
41
42
impl Neg for Sign {
43
    type Output = Sign;
44
45
    /// Negate `Sign` value.
46
    #[inline]
47
74.6k
    fn neg(self) -> Sign {
48
74.6k
        match self {
49
5.10k
            Minus => Plus,
50
3.38k
            NoSign => NoSign,
51
66.1k
            Plus => Minus,
52
        }
53
74.6k
    }
_RNvXNtCs72ekIXsOXFl_10num_bigint6bigintNtB2_4SignNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Neg3negCs4RkbDk9WRL5_5clvmr
Line
Count
Source
47
52.2k
    fn neg(self) -> Sign {
48
52.2k
        match self {
49
2.36k
            Minus => Plus,
50
2.93k
            NoSign => NoSign,
51
46.9k
            Plus => Minus,
52
        }
53
52.2k
    }
_RNvXNtCs72ekIXsOXFl_10num_bigint6bigintNtB2_4SignNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Neg3negB4_
Line
Count
Source
47
22.3k
    fn neg(self) -> Sign {
48
22.3k
        match self {
49
2.74k
            Minus => Plus,
50
449
            NoSign => NoSign,
51
19.2k
            Plus => Minus,
52
        }
53
22.3k
    }
54
}
55
56
/// A big signed integer type.
57
pub struct BigInt {
58
    sign: Sign,
59
    data: BigUint,
60
}
61
62
// Note: derived `Clone` doesn't specialize `clone_from`,
63
// but we want to keep the allocation in `data`.
64
impl Clone for BigInt {
65
    #[inline]
66
69.9k
    fn clone(&self) -> Self {
67
69.9k
        BigInt {
68
69.9k
            sign: self.sign,
69
69.9k
            data: self.data.clone(),
70
69.9k
        }
71
69.9k
    }
_RNvXs_NtCs72ekIXsOXFl_10num_bigint6bigintNtB4_6BigIntNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneCs4RkbDk9WRL5_5clvmr
Line
Count
Source
66
56.2k
    fn clone(&self) -> Self {
67
56.2k
        BigInt {
68
56.2k
            sign: self.sign,
69
56.2k
            data: self.data.clone(),
70
56.2k
        }
71
56.2k
    }
_RNvXs_NtCs72ekIXsOXFl_10num_bigint6bigintNtB4_6BigIntNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB6_
Line
Count
Source
66
13.7k
    fn clone(&self) -> Self {
67
13.7k
        BigInt {
68
13.7k
            sign: self.sign,
69
13.7k
            data: self.data.clone(),
70
13.7k
        }
71
13.7k
    }
72
73
    #[inline]
74
10.2k
    fn clone_from(&mut self, other: &Self) {
75
10.2k
        self.sign = other.sign;
76
10.2k
        self.data.clone_from(&other.data);
77
10.2k
    }
78
}
79
80
impl hash::Hash for BigInt {
81
    #[inline]
82
0
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
83
0
        debug_assert!((self.sign != NoSign) ^ self.data.is_zero());
84
0
        self.sign.hash(state);
85
0
        if self.sign != NoSign {
86
0
            self.data.hash(state);
87
0
        }
88
0
    }
89
}
90
91
impl PartialEq for BigInt {
92
    #[inline]
93
0
    fn eq(&self, other: &BigInt) -> bool {
94
0
        debug_assert!((self.sign != NoSign) ^ self.data.is_zero());
95
0
        debug_assert!((other.sign != NoSign) ^ other.data.is_zero());
96
0
        self.sign == other.sign && (self.sign == NoSign || self.data == other.data)
97
0
    }
98
}
99
100
impl Eq for BigInt {}
101
102
impl PartialOrd for BigInt {
103
    #[inline]
104
1.31k
    fn partial_cmp(&self, other: &BigInt) -> Option<Ordering> {
105
1.31k
        Some(self.cmp(other))
106
1.31k
    }
_RNvXs3_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtNtCsbQ8arDwx5Xq_4core3cmp10PartialOrd11partial_cmpCs4RkbDk9WRL5_5clvmr
Line
Count
Source
104
1.31k
    fn partial_cmp(&self, other: &BigInt) -> Option<Ordering> {
105
1.31k
        Some(self.cmp(other))
106
1.31k
    }
Unexecuted instantiation: _RNvXs3_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtNtCsbQ8arDwx5Xq_4core3cmp10PartialOrd11partial_cmpB7_
107
}
108
109
impl Ord for BigInt {
110
    #[inline]
111
1.31k
    fn cmp(&self, other: &BigInt) -> Ordering {
112
1.31k
        debug_assert!((self.sign != NoSign) ^ self.data.is_zero());
113
1.31k
        debug_assert!((other.sign != NoSign) ^ other.data.is_zero());
114
1.31k
        let scmp = self.sign.cmp(&other.sign);
115
1.31k
        if scmp != Equal {
116
763
            return scmp;
117
555
        }
118
555
119
555
        match self.sign {
120
10
            NoSign => Equal,
121
349
            Plus => self.data.cmp(&other.data),
122
196
            Minus => other.data.cmp(&self.data),
123
        }
124
1.31k
    }
_RNvXs4_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtNtCsbQ8arDwx5Xq_4core3cmp3Ord3cmpCs4RkbDk9WRL5_5clvmr
Line
Count
Source
111
1.31k
    fn cmp(&self, other: &BigInt) -> Ordering {
112
1.31k
        debug_assert!((self.sign != NoSign) ^ self.data.is_zero());
113
1.31k
        debug_assert!((other.sign != NoSign) ^ other.data.is_zero());
114
1.31k
        let scmp = self.sign.cmp(&other.sign);
115
1.31k
        if scmp != Equal {
116
763
            return scmp;
117
555
        }
118
555
119
555
        match self.sign {
120
10
            NoSign => Equal,
121
349
            Plus => self.data.cmp(&other.data),
122
196
            Minus => other.data.cmp(&self.data),
123
        }
124
1.31k
    }
Unexecuted instantiation: _RNvXs4_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtNtCsbQ8arDwx5Xq_4core3cmp3Ord3cmpB7_
125
}
126
127
impl Default for BigInt {
128
    #[inline]
129
0
    fn default() -> BigInt {
130
0
        Self::ZERO
131
0
    }
132
}
133
134
impl fmt::Debug for BigInt {
135
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136
0
        fmt::Display::fmt(self, f)
137
0
    }
138
}
139
140
impl fmt::Display for BigInt {
141
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142
0
        f.pad_integral(!self.is_negative(), "", &self.data.to_str_radix(10))
143
0
    }
144
}
145
146
impl fmt::Binary for BigInt {
147
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148
0
        f.pad_integral(!self.is_negative(), "0b", &self.data.to_str_radix(2))
149
0
    }
150
}
151
152
impl fmt::Octal for BigInt {
153
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154
0
        f.pad_integral(!self.is_negative(), "0o", &self.data.to_str_radix(8))
155
0
    }
156
}
157
158
impl fmt::LowerHex for BigInt {
159
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160
0
        f.pad_integral(!self.is_negative(), "0x", &self.data.to_str_radix(16))
161
0
    }
162
}
163
164
impl fmt::UpperHex for BigInt {
165
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166
0
        let mut s = self.data.to_str_radix(16);
167
0
        s.make_ascii_uppercase();
168
0
        f.pad_integral(!self.is_negative(), "0x", &s)
169
0
    }
170
}
171
172
// !-2 = !...f fe = ...0 01 = +1
173
// !-1 = !...f ff = ...0 00 =  0
174
// ! 0 = !...0 00 = ...f ff = -1
175
// !+1 = !...0 01 = ...f fe = -2
176
impl Not for BigInt {
177
    type Output = BigInt;
178
179
1.21k
    fn not(mut self) -> BigInt {
180
1.21k
        match self.sign {
181
849
            NoSign | Plus => {
182
849
                self.data += 1u32;
183
849
                self.sign = Minus;
184
849
            }
185
            Minus => {
186
369
                self.data -= 1u32;
187
369
                self.sign = if self.data.is_zero() { NoSign } else { Plus };
188
            }
189
        }
190
1.21k
        self
191
1.21k
    }
192
}
193
194
impl Not for &BigInt {
195
    type Output = BigInt;
196
197
0
    fn not(self) -> BigInt {
198
0
        match self.sign {
199
0
            NoSign => -BigInt::one(),
200
0
            Plus => -BigInt::from(&self.data + 1u32),
201
0
            Minus => BigInt::from(&self.data - 1u32),
202
        }
203
0
    }
204
}
205
206
impl Zero for BigInt {
207
    #[inline]
208
0
    fn zero() -> BigInt {
209
0
        Self::ZERO
210
0
    }
211
212
    #[inline]
213
2.58k
    fn set_zero(&mut self) {
214
2.58k
        self.data.set_zero();
215
2.58k
        self.sign = NoSign;
216
2.58k
    }
217
218
    #[inline]
219
15.6k
    fn is_zero(&self) -> bool {
220
15.6k
        self.sign == NoSign
221
15.6k
    }
_RNvXse_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero7is_zeroCs4RkbDk9WRL5_5clvmr
Line
Count
Source
219
9.61k
    fn is_zero(&self) -> bool {
220
9.61k
        self.sign == NoSign
221
9.61k
    }
_RNvXse_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero7is_zeroB7_
Line
Count
Source
219
6.01k
    fn is_zero(&self) -> bool {
220
6.01k
        self.sign == NoSign
221
6.01k
    }
222
}
223
224
impl ConstZero for BigInt {
225
    // forward to the inherent const
226
    const ZERO: Self = Self::ZERO;
227
}
228
229
impl One for BigInt {
230
    #[inline]
231
0
    fn one() -> BigInt {
232
0
        BigInt {
233
0
            sign: Plus,
234
0
            data: BigUint::one(),
235
0
        }
236
0
    }
237
238
    #[inline]
239
0
    fn set_one(&mut self) {
240
0
        self.data.set_one();
241
0
        self.sign = Plus;
242
0
    }
243
244
    #[inline]
245
0
    fn is_one(&self) -> bool {
246
0
        self.sign == Plus && self.data.is_one()
247
0
    }
248
}
249
250
impl Signed for BigInt {
251
    #[inline]
252
0
    fn abs(&self) -> BigInt {
253
0
        match self.sign {
254
0
            Plus | NoSign => self.clone(),
255
0
            Minus => BigInt::from(self.data.clone()),
256
        }
257
0
    }
258
259
    #[inline]
260
0
    fn abs_sub(&self, other: &BigInt) -> BigInt {
261
0
        if *self <= *other {
262
0
            Self::ZERO
263
        } else {
264
0
            self - other
265
        }
266
0
    }
267
268
    #[inline]
269
0
    fn signum(&self) -> BigInt {
270
0
        match self.sign {
271
0
            Plus => BigInt::one(),
272
0
            Minus => -BigInt::one(),
273
0
            NoSign => Self::ZERO,
274
        }
275
0
    }
276
277
    #[inline]
278
0
    fn is_positive(&self) -> bool {
279
0
        self.sign == Plus
280
0
    }
281
282
    #[inline]
283
32.3k
    fn is_negative(&self) -> bool {
284
32.3k
        self.sign == Minus
285
32.3k
    }
_RNvXsh_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtNtCs7cG3k8kmkqw_10num_traits4sign6Signed11is_negativeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
283
2.24k
    fn is_negative(&self) -> bool {
284
2.24k
        self.sign == Minus
285
2.24k
    }
_RNvXsh_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtNtCs7cG3k8kmkqw_10num_traits4sign6Signed11is_negativeB7_
Line
Count
Source
283
30.0k
    fn is_negative(&self) -> bool {
284
30.0k
        self.sign == Minus
285
30.0k
    }
286
}
287
288
trait UnsignedAbs {
289
    type Unsigned;
290
291
    fn checked_uabs(self) -> CheckedUnsignedAbs<Self::Unsigned>;
292
}
293
294
enum CheckedUnsignedAbs<T> {
295
    Positive(T),
296
    Negative(T),
297
}
298
use self::CheckedUnsignedAbs::{Negative, Positive};
299
300
macro_rules! impl_unsigned_abs {
301
    ($Signed:ty, $Unsigned:ty) => {
302
        impl UnsignedAbs for $Signed {
303
            type Unsigned = $Unsigned;
304
305
            #[inline]
306
18.1k
            fn checked_uabs(self) -> CheckedUnsignedAbs<Self::Unsigned> {
307
18.1k
                if self >= 0 {
308
18.1k
                    Positive(self as $Unsigned)
309
                } else {
310
0
                    Negative(self.wrapping_neg() as $Unsigned)
311
                }
312
18.1k
            }
_RNvXsB_NtCs72ekIXsOXFl_10num_bigint6bigintlNtB5_11UnsignedAbs12checked_uabsB7_
Line
Count
Source
306
18.1k
            fn checked_uabs(self) -> CheckedUnsignedAbs<Self::Unsigned> {
307
18.1k
                if self >= 0 {
308
18.1k
                    Positive(self as $Unsigned)
309
                } else {
310
0
                    Negative(self.wrapping_neg() as $Unsigned)
311
                }
312
18.1k
            }
Unexecuted instantiation: _RNvXsC_NtCs72ekIXsOXFl_10num_bigint6bigintxNtB5_11UnsignedAbs12checked_uabsB7_
Unexecuted instantiation: _RNvXsD_NtCs72ekIXsOXFl_10num_bigint6bigintnNtB5_11UnsignedAbs12checked_uabsB7_
Unexecuted instantiation: _RNvXsz_NtCs72ekIXsOXFl_10num_bigint6bigintaNtB5_11UnsignedAbs12checked_uabsB7_
Unexecuted instantiation: _RNvXsA_NtCs72ekIXsOXFl_10num_bigint6bigintsNtB5_11UnsignedAbs12checked_uabsB7_
Unexecuted instantiation: _RNvXsE_NtCs72ekIXsOXFl_10num_bigint6bigintiNtB5_11UnsignedAbs12checked_uabsB7_
313
        }
314
    };
315
}
316
impl_unsigned_abs!(i8, u8);
317
impl_unsigned_abs!(i16, u16);
318
impl_unsigned_abs!(i32, u32);
319
impl_unsigned_abs!(i64, u64);
320
impl_unsigned_abs!(i128, u128);
321
impl_unsigned_abs!(isize, usize);
322
323
impl Neg for BigInt {
324
    type Output = BigInt;
325
326
    #[inline]
327
53.4k
    fn neg(mut self) -> BigInt {
328
53.4k
        self.sign = -self.sign;
329
53.4k
        self
330
53.4k
    }
_RNvXsi_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Neg3negCs4RkbDk9WRL5_5clvmr
Line
Count
Source
327
48.6k
    fn neg(mut self) -> BigInt {
328
48.6k
        self.sign = -self.sign;
329
48.6k
        self
330
48.6k
    }
_RNvXsi_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Neg3negB7_
Line
Count
Source
327
4.89k
    fn neg(mut self) -> BigInt {
328
4.89k
        self.sign = -self.sign;
329
4.89k
        self
330
4.89k
    }
331
}
332
333
impl Neg for &BigInt {
334
    type Output = BigInt;
335
336
    #[inline]
337
0
    fn neg(self) -> BigInt {
338
0
        -self.clone()
339
0
    }
340
}
341
342
impl Integer for BigInt {
343
    #[inline]
344
0
    fn div_rem(&self, other: &BigInt) -> (BigInt, BigInt) {
345
0
        // r.sign == self.sign
346
0
        let (d_ui, r_ui) = self.data.div_rem(&other.data);
347
0
        let d = BigInt::from_biguint(self.sign, d_ui);
348
0
        let r = BigInt::from_biguint(self.sign, r_ui);
349
0
        if other.is_negative() {
350
0
            (-d, r)
351
        } else {
352
0
            (d, r)
353
        }
354
0
    }
355
356
    #[inline]
357
10.0k
    fn div_floor(&self, other: &BigInt) -> BigInt {
358
10.0k
        let (d_ui, m) = self.data.div_mod_floor(&other.data);
359
10.0k
        let d = BigInt::from(d_ui);
360
10.0k
        match (self.sign, other.sign) {
361
7.94k
            (Plus, Plus) | (NoSign, Plus) | (Minus, Minus) => d,
362
            (Plus, Minus) | (NoSign, Minus) | (Minus, Plus) => {
363
2.12k
                if m.is_zero() {
364
852
                    -d
365
                } else {
366
1.27k
                    -d - 1u32
367
                }
368
            }
369
0
            (_, NoSign) => unreachable!(),
370
        }
371
10.0k
    }
_RNvXsk_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtCsd1gRxjdwU23_11num_integer7Integer9div_floorCs4RkbDk9WRL5_5clvmr
Line
Count
Source
357
10.0k
    fn div_floor(&self, other: &BigInt) -> BigInt {
358
10.0k
        let (d_ui, m) = self.data.div_mod_floor(&other.data);
359
10.0k
        let d = BigInt::from(d_ui);
360
10.0k
        match (self.sign, other.sign) {
361
7.94k
            (Plus, Plus) | (NoSign, Plus) | (Minus, Minus) => d,
362
            (Plus, Minus) | (NoSign, Minus) | (Minus, Plus) => {
363
2.12k
                if m.is_zero() {
364
852
                    -d
365
                } else {
366
1.27k
                    -d - 1u32
367
                }
368
            }
369
0
            (_, NoSign) => unreachable!(),
370
        }
371
10.0k
    }
Unexecuted instantiation: _RNvXsk_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtCsd1gRxjdwU23_11num_integer7Integer9div_floorB7_
372
373
    #[inline]
374
30.9k
    fn mod_floor(&self, other: &BigInt) -> BigInt {
375
30.9k
        // m.sign == other.sign
376
30.9k
        let m_ui = self.data.mod_floor(&other.data);
377
30.9k
        let m = BigInt::from_biguint(other.sign, m_ui);
378
30.9k
        match (self.sign, other.sign) {
379
21.3k
            (Plus, Plus) | (NoSign, Plus) | (Minus, Minus) => m,
380
            (Plus, Minus) | (NoSign, Minus) | (Minus, Plus) => {
381
9.61k
                if m.is_zero() {
382
3.07k
                    m
383
                } else {
384
6.53k
                    other - m
385
                }
386
            }
387
0
            (_, NoSign) => unreachable!(),
388
        }
389
30.9k
    }
_RNvXsk_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtCsd1gRxjdwU23_11num_integer7Integer9mod_floorCs4RkbDk9WRL5_5clvmr
Line
Count
Source
374
30.9k
    fn mod_floor(&self, other: &BigInt) -> BigInt {
375
30.9k
        // m.sign == other.sign
376
30.9k
        let m_ui = self.data.mod_floor(&other.data);
377
30.9k
        let m = BigInt::from_biguint(other.sign, m_ui);
378
30.9k
        match (self.sign, other.sign) {
379
21.3k
            (Plus, Plus) | (NoSign, Plus) | (Minus, Minus) => m,
380
            (Plus, Minus) | (NoSign, Minus) | (Minus, Plus) => {
381
9.61k
                if m.is_zero() {
382
3.07k
                    m
383
                } else {
384
6.53k
                    other - m
385
                }
386
            }
387
0
            (_, NoSign) => unreachable!(),
388
        }
389
30.9k
    }
Unexecuted instantiation: _RNvXsk_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigIntNtCsd1gRxjdwU23_11num_integer7Integer9mod_floorB7_
390
391
2.36k
    fn div_mod_floor(&self, other: &BigInt) -> (BigInt, BigInt) {
392
2.36k
        // m.sign == other.sign
393
2.36k
        let (d_ui, m_ui) = self.data.div_mod_floor(&other.data);
394
2.36k
        let d = BigInt::from(d_ui);
395
2.36k
        let m = BigInt::from_biguint(other.sign, m_ui);
396
2.36k
        match (self.sign, other.sign) {
397
1.38k
            (Plus, Plus) | (NoSign, Plus) | (Minus, Minus) => (d, m),
398
            (Plus, Minus) | (NoSign, Minus) | (Minus, Plus) => {
399
981
                if m.is_zero() {
400
423
                    (-d, m)
401
                } else {
402
558
                    (-d - 1u32, other - m)
403
                }
404
            }
405
0
            (_, NoSign) => unreachable!(),
406
        }
407
2.36k
    }
408
409
    #[inline]
410
0
    fn div_ceil(&self, other: &Self) -> Self {
411
0
        let (d_ui, m) = self.data.div_mod_floor(&other.data);
412
0
        let d = BigInt::from(d_ui);
413
0
        match (self.sign, other.sign) {
414
0
            (Plus, Minus) | (NoSign, Minus) | (Minus, Plus) => -d,
415
            (Plus, Plus) | (NoSign, Plus) | (Minus, Minus) => {
416
0
                if m.is_zero() {
417
0
                    d
418
                } else {
419
0
                    d + 1u32
420
                }
421
            }
422
0
            (_, NoSign) => unreachable!(),
423
        }
424
0
    }
425
426
    /// Calculates the Greatest Common Divisor (GCD) of the number and `other`.
427
    ///
428
    /// The result is always positive.
429
    #[inline]
430
0
    fn gcd(&self, other: &BigInt) -> BigInt {
431
0
        BigInt::from(self.data.gcd(&other.data))
432
0
    }
433
434
    /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
435
    #[inline]
436
0
    fn lcm(&self, other: &BigInt) -> BigInt {
437
0
        BigInt::from(self.data.lcm(&other.data))
438
0
    }
439
440
    /// Calculates the Greatest Common Divisor (GCD) and
441
    /// Lowest Common Multiple (LCM) together.
442
    #[inline]
443
0
    fn gcd_lcm(&self, other: &BigInt) -> (BigInt, BigInt) {
444
0
        let (gcd, lcm) = self.data.gcd_lcm(&other.data);
445
0
        (BigInt::from(gcd), BigInt::from(lcm))
446
0
    }
447
448
    /// Greatest common divisor, least common multiple, and Bézout coefficients.
449
    #[inline]
450
0
    fn extended_gcd_lcm(&self, other: &BigInt) -> (num_integer::ExtendedGcd<BigInt>, BigInt) {
451
0
        let egcd = self.extended_gcd(other);
452
0
        let lcm = if egcd.gcd.is_zero() {
453
0
            Self::ZERO
454
        } else {
455
0
            BigInt::from(&self.data / &egcd.gcd.data * &other.data)
456
        };
457
0
        (egcd, lcm)
458
0
    }
459
460
    /// Deprecated, use `is_multiple_of` instead.
461
    #[inline]
462
0
    fn divides(&self, other: &BigInt) -> bool {
463
0
        self.is_multiple_of(other)
464
0
    }
465
466
    /// Returns `true` if the number is a multiple of `other`.
467
    #[inline]
468
0
    fn is_multiple_of(&self, other: &BigInt) -> bool {
469
0
        self.data.is_multiple_of(&other.data)
470
0
    }
471
472
    /// Returns `true` if the number is divisible by `2`.
473
    #[inline]
474
0
    fn is_even(&self) -> bool {
475
0
        self.data.is_even()
476
0
    }
477
478
    /// Returns `true` if the number is not divisible by `2`.
479
    #[inline]
480
1.42k
    fn is_odd(&self) -> bool {
481
1.42k
        self.data.is_odd()
482
1.42k
    }
483
484
    /// Rounds up to nearest multiple of argument.
485
    #[inline]
486
0
    fn next_multiple_of(&self, other: &Self) -> Self {
487
0
        let m = self.mod_floor(other);
488
0
        if m.is_zero() {
489
0
            self.clone()
490
        } else {
491
0
            self + (other - m)
492
        }
493
0
    }
494
    /// Rounds down to nearest multiple of argument.
495
    #[inline]
496
0
    fn prev_multiple_of(&self, other: &Self) -> Self {
497
0
        self - self.mod_floor(other)
498
0
    }
499
500
0
    fn dec(&mut self) {
501
0
        *self -= 1u32;
502
0
    }
503
504
0
    fn inc(&mut self) {
505
0
        *self += 1u32;
506
0
    }
507
}
508
509
impl Roots for BigInt {
510
0
    fn nth_root(&self, n: u32) -> Self {
511
0
        assert!(
512
0
            !(self.is_negative() && n.is_even()),
513
0
            "root of degree {} is imaginary",
514
            n
515
        );
516
517
0
        BigInt::from_biguint(self.sign, self.data.nth_root(n))
518
0
    }
519
520
0
    fn sqrt(&self) -> Self {
521
0
        assert!(!self.is_negative(), "square root is imaginary");
522
523
0
        BigInt::from_biguint(self.sign, self.data.sqrt())
524
0
    }
525
526
0
    fn cbrt(&self) -> Self {
527
0
        BigInt::from_biguint(self.sign, self.data.cbrt())
528
0
    }
529
}
530
531
impl IntDigits for BigInt {
532
    #[inline]
533
49.4k
    fn digits(&self) -> &[BigDigit] {
534
49.4k
        self.data.digits()
535
49.4k
    }
536
    #[inline]
537
12.0k
    fn digits_mut(&mut self) -> &mut Vec<BigDigit> {
538
12.0k
        self.data.digits_mut()
539
12.0k
    }
540
    #[inline]
541
12.0k
    fn normalize(&mut self) {
542
12.0k
        self.data.normalize();
543
12.0k
        if self.data.is_zero() {
544
548
            self.sign = NoSign;
545
11.4k
        }
546
12.0k
    }
547
    #[inline]
548
0
    fn capacity(&self) -> usize {
549
0
        self.data.capacity()
550
0
    }
551
    #[inline]
552
0
    fn len(&self) -> usize {
553
0
        self.data.len()
554
0
    }
555
}
556
557
/// A generic trait for converting a value to a [`BigInt`]. This may return
558
/// `None` when converting from `f32` or `f64`, and will always succeed
559
/// when converting from any integer or unsigned primitive, or [`BigUint`].
560
pub trait ToBigInt {
561
    /// Converts the value of `self` to a [`BigInt`].
562
    fn to_bigint(&self) -> Option<BigInt>;
563
}
564
565
impl BigInt {
566
    /// A constant `BigInt` with value 0, useful for static initialization.
567
    pub const ZERO: Self = BigInt {
568
        sign: NoSign,
569
        data: BigUint::ZERO,
570
    };
571
572
    /// Creates and initializes a [`BigInt`].
573
    ///
574
    /// The base 2<sup>32</sup> digits are ordered least significant digit first.
575
    #[inline]
576
0
    pub fn new(sign: Sign, digits: Vec<u32>) -> BigInt {
577
0
        BigInt::from_biguint(sign, BigUint::new(digits))
578
0
    }
579
580
    /// Creates and initializes a [`BigInt`].
581
    ///
582
    /// The base 2<sup>32</sup> digits are ordered least significant digit first.
583
    #[inline]
584
574k
    pub fn from_biguint(mut sign: Sign, mut data: BigUint) -> BigInt {
585
574k
        if sign == NoSign {
586
11.9k
            data.assign_from_slice(&[]);
587
562k
        } else if data.is_zero() {
588
24.7k
            sign = NoSign;
589
537k
        }
590
591
574k
        BigInt { sign, data }
592
574k
    }
_RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt12from_biguintCs4RkbDk9WRL5_5clvmr
Line
Count
Source
584
339k
    pub fn from_biguint(mut sign: Sign, mut data: BigUint) -> BigInt {
585
339k
        if sign == NoSign {
586
6.73k
            data.assign_from_slice(&[]);
587
332k
        } else if data.is_zero() {
588
23.6k
            sign = NoSign;
589
309k
        }
590
591
339k
        BigInt { sign, data }
592
339k
    }
_RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt12from_biguintB7_
Line
Count
Source
584
234k
    pub fn from_biguint(mut sign: Sign, mut data: BigUint) -> BigInt {
585
234k
        if sign == NoSign {
586
5.24k
            data.assign_from_slice(&[]);
587
229k
        } else if data.is_zero() {
588
1.15k
            sign = NoSign;
589
228k
        }
590
591
234k
        BigInt { sign, data }
592
234k
    }
593
594
    /// Creates and initializes a [`BigInt`].
595
    ///
596
    /// The base 2<sup>32</sup> digits are ordered least significant digit first.
597
    #[inline]
598
0
    pub fn from_slice(sign: Sign, slice: &[u32]) -> BigInt {
599
0
        BigInt::from_biguint(sign, BigUint::from_slice(slice))
600
0
    }
601
602
    /// Reinitializes a [`BigInt`].
603
    ///
604
    /// The base 2<sup>32</sup> digits are ordered least significant digit first.
605
    #[inline]
606
0
    pub fn assign_from_slice(&mut self, sign: Sign, slice: &[u32]) {
607
0
        if sign == NoSign {
608
0
            self.set_zero();
609
0
        } else {
610
0
            self.data.assign_from_slice(slice);
611
0
            self.sign = if self.data.is_zero() { NoSign } else { sign };
612
        }
613
0
    }
614
615
    /// Creates and initializes a [`BigInt`].
616
    ///
617
    /// The bytes are in big-endian byte order.
618
    ///
619
    /// # Examples
620
    ///
621
    /// ```
622
    /// use num_bigint::{BigInt, Sign};
623
    ///
624
    /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"A"),
625
    ///            BigInt::parse_bytes(b"65", 10).unwrap());
626
    /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"AA"),
627
    ///            BigInt::parse_bytes(b"16705", 10).unwrap());
628
    /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"AB"),
629
    ///            BigInt::parse_bytes(b"16706", 10).unwrap());
630
    /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"Hello world!"),
631
    ///            BigInt::parse_bytes(b"22405534230753963835153736737", 10).unwrap());
632
    /// ```
633
    #[inline]
634
0
    pub fn from_bytes_be(sign: Sign, bytes: &[u8]) -> BigInt {
635
0
        BigInt::from_biguint(sign, BigUint::from_bytes_be(bytes))
636
0
    }
637
638
    /// Creates and initializes a [`BigInt`].
639
    ///
640
    /// The bytes are in little-endian byte order.
641
    #[inline]
642
0
    pub fn from_bytes_le(sign: Sign, bytes: &[u8]) -> BigInt {
643
0
        BigInt::from_biguint(sign, BigUint::from_bytes_le(bytes))
644
0
    }
645
646
    /// Creates and initializes a [`BigInt`] from an array of bytes in
647
    /// two's complement binary representation.
648
    ///
649
    /// The digits are in big-endian base 2<sup>8</sup>.
650
    #[inline]
651
228k
    pub fn from_signed_bytes_be(digits: &[u8]) -> BigInt {
652
228k
        convert::from_signed_bytes_be(digits)
653
228k
    }
_RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt20from_signed_bytes_beCs4RkbDk9WRL5_5clvmr
Line
Count
Source
651
228k
    pub fn from_signed_bytes_be(digits: &[u8]) -> BigInt {
652
228k
        convert::from_signed_bytes_be(digits)
653
228k
    }
Unexecuted instantiation: _RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt20from_signed_bytes_beB7_
654
655
    /// Creates and initializes a [`BigInt`] from an array of bytes in two's complement.
656
    ///
657
    /// The digits are in little-endian base 2<sup>8</sup>.
658
    #[inline]
659
0
    pub fn from_signed_bytes_le(digits: &[u8]) -> BigInt {
660
0
        convert::from_signed_bytes_le(digits)
661
0
    }
662
663
    /// Creates and initializes a [`BigInt`].
664
    ///
665
    /// # Examples
666
    ///
667
    /// ```
668
    /// use num_bigint::{BigInt, ToBigInt};
669
    ///
670
    /// assert_eq!(BigInt::parse_bytes(b"1234", 10), ToBigInt::to_bigint(&1234));
671
    /// assert_eq!(BigInt::parse_bytes(b"ABCD", 16), ToBigInt::to_bigint(&0xABCD));
672
    /// assert_eq!(BigInt::parse_bytes(b"G", 16), None);
673
    /// ```
674
    #[inline]
675
0
    pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigInt> {
676
0
        let s = str::from_utf8(buf).ok()?;
677
0
        BigInt::from_str_radix(s, radix).ok()
678
0
    }
679
680
    /// Creates and initializes a [`BigInt`]. Each `u8` of the input slice is
681
    /// interpreted as one digit of the number
682
    /// and must therefore be less than `radix`.
683
    ///
684
    /// The bytes are in big-endian byte order.
685
    /// `radix` must be in the range `2...256`.
686
    ///
687
    /// # Examples
688
    ///
689
    /// ```
690
    /// use num_bigint::{BigInt, Sign};
691
    ///
692
    /// let inbase190 = vec![15, 33, 125, 12, 14];
693
    /// let a = BigInt::from_radix_be(Sign::Minus, &inbase190, 190).unwrap();
694
    /// assert_eq!(a.to_radix_be(190), (Sign:: Minus, inbase190));
695
    /// ```
696
0
    pub fn from_radix_be(sign: Sign, buf: &[u8], radix: u32) -> Option<BigInt> {
697
0
        let u = BigUint::from_radix_be(buf, radix)?;
698
0
        Some(BigInt::from_biguint(sign, u))
699
0
    }
700
701
    /// Creates and initializes a [`BigInt`]. Each `u8` of the input slice is
702
    /// interpreted as one digit of the number
703
    /// and must therefore be less than `radix`.
704
    ///
705
    /// The bytes are in little-endian byte order.
706
    /// `radix` must be in the range `2...256`.
707
    ///
708
    /// # Examples
709
    ///
710
    /// ```
711
    /// use num_bigint::{BigInt, Sign};
712
    ///
713
    /// let inbase190 = vec![14, 12, 125, 33, 15];
714
    /// let a = BigInt::from_radix_be(Sign::Minus, &inbase190, 190).unwrap();
715
    /// assert_eq!(a.to_radix_be(190), (Sign::Minus, inbase190));
716
    /// ```
717
0
    pub fn from_radix_le(sign: Sign, buf: &[u8], radix: u32) -> Option<BigInt> {
718
0
        let u = BigUint::from_radix_le(buf, radix)?;
719
0
        Some(BigInt::from_biguint(sign, u))
720
0
    }
721
722
    /// Returns the sign and the byte representation of the [`BigInt`] in big-endian byte order.
723
    ///
724
    /// # Examples
725
    ///
726
    /// ```
727
    /// use num_bigint::{ToBigInt, Sign};
728
    ///
729
    /// let i = -1125.to_bigint().unwrap();
730
    /// assert_eq!(i.to_bytes_be(), (Sign::Minus, vec![4, 101]));
731
    /// ```
732
    #[inline]
733
14.0k
    pub fn to_bytes_be(&self) -> (Sign, Vec<u8>) {
734
14.0k
        (self.sign, self.data.to_bytes_be())
735
14.0k
    }
_RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt11to_bytes_beCs4RkbDk9WRL5_5clvmr
Line
Count
Source
733
14.0k
    pub fn to_bytes_be(&self) -> (Sign, Vec<u8>) {
734
14.0k
        (self.sign, self.data.to_bytes_be())
735
14.0k
    }
Unexecuted instantiation: _RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt11to_bytes_beB7_
736
737
    /// Returns the sign and the byte representation of the [`BigInt`] in little-endian byte order.
738
    ///
739
    /// # Examples
740
    ///
741
    /// ```
742
    /// use num_bigint::{ToBigInt, Sign};
743
    ///
744
    /// let i = -1125.to_bigint().unwrap();
745
    /// assert_eq!(i.to_bytes_le(), (Sign::Minus, vec![101, 4]));
746
    /// ```
747
    #[inline]
748
0
    pub fn to_bytes_le(&self) -> (Sign, Vec<u8>) {
749
0
        (self.sign, self.data.to_bytes_le())
750
0
    }
751
752
    /// Returns the sign and the `u32` digits representation of the [`BigInt`] ordered least
753
    /// significant digit first.
754
    ///
755
    /// # Examples
756
    ///
757
    /// ```
758
    /// use num_bigint::{BigInt, Sign};
759
    ///
760
    /// assert_eq!(BigInt::from(-1125).to_u32_digits(), (Sign::Minus, vec![1125]));
761
    /// assert_eq!(BigInt::from(4294967295u32).to_u32_digits(), (Sign::Plus, vec![4294967295]));
762
    /// assert_eq!(BigInt::from(4294967296u64).to_u32_digits(), (Sign::Plus, vec![0, 1]));
763
    /// assert_eq!(BigInt::from(-112500000000i64).to_u32_digits(), (Sign::Minus, vec![830850304, 26]));
764
    /// assert_eq!(BigInt::from(112500000000i64).to_u32_digits(), (Sign::Plus, vec![830850304, 26]));
765
    /// ```
766
    #[inline]
767
0
    pub fn to_u32_digits(&self) -> (Sign, Vec<u32>) {
768
0
        (self.sign, self.data.to_u32_digits())
769
0
    }
770
771
    /// Returns the sign and the `u64` digits representation of the [`BigInt`] ordered least
772
    /// significant digit first.
773
    ///
774
    /// # Examples
775
    ///
776
    /// ```
777
    /// use num_bigint::{BigInt, Sign};
778
    ///
779
    /// assert_eq!(BigInt::from(-1125).to_u64_digits(), (Sign::Minus, vec![1125]));
780
    /// assert_eq!(BigInt::from(4294967295u32).to_u64_digits(), (Sign::Plus, vec![4294967295]));
781
    /// assert_eq!(BigInt::from(4294967296u64).to_u64_digits(), (Sign::Plus, vec![4294967296]));
782
    /// assert_eq!(BigInt::from(-112500000000i64).to_u64_digits(), (Sign::Minus, vec![112500000000]));
783
    /// assert_eq!(BigInt::from(112500000000i64).to_u64_digits(), (Sign::Plus, vec![112500000000]));
784
    /// assert_eq!(BigInt::from(1u128 << 64).to_u64_digits(), (Sign::Plus, vec![0, 1]));
785
    /// ```
786
    #[inline]
787
0
    pub fn to_u64_digits(&self) -> (Sign, Vec<u64>) {
788
0
        (self.sign, self.data.to_u64_digits())
789
0
    }
790
791
    /// Returns an iterator of `u32` digits representation of the [`BigInt`] ordered least
792
    /// significant digit first.
793
    ///
794
    /// # Examples
795
    ///
796
    /// ```
797
    /// use num_bigint::BigInt;
798
    ///
799
    /// assert_eq!(BigInt::from(-1125).iter_u32_digits().collect::<Vec<u32>>(), vec![1125]);
800
    /// assert_eq!(BigInt::from(4294967295u32).iter_u32_digits().collect::<Vec<u32>>(), vec![4294967295]);
801
    /// assert_eq!(BigInt::from(4294967296u64).iter_u32_digits().collect::<Vec<u32>>(), vec![0, 1]);
802
    /// assert_eq!(BigInt::from(-112500000000i64).iter_u32_digits().collect::<Vec<u32>>(), vec![830850304, 26]);
803
    /// assert_eq!(BigInt::from(112500000000i64).iter_u32_digits().collect::<Vec<u32>>(), vec![830850304, 26]);
804
    /// ```
805
    #[inline]
806
0
    pub fn iter_u32_digits(&self) -> U32Digits<'_> {
807
0
        self.data.iter_u32_digits()
808
0
    }
809
810
    /// Returns an iterator of `u64` digits representation of the [`BigInt`] ordered least
811
    /// significant digit first.
812
    ///
813
    /// # Examples
814
    ///
815
    /// ```
816
    /// use num_bigint::BigInt;
817
    ///
818
    /// assert_eq!(BigInt::from(-1125).iter_u64_digits().collect::<Vec<u64>>(), vec![1125u64]);
819
    /// assert_eq!(BigInt::from(4294967295u32).iter_u64_digits().collect::<Vec<u64>>(), vec![4294967295u64]);
820
    /// assert_eq!(BigInt::from(4294967296u64).iter_u64_digits().collect::<Vec<u64>>(), vec![4294967296u64]);
821
    /// assert_eq!(BigInt::from(-112500000000i64).iter_u64_digits().collect::<Vec<u64>>(), vec![112500000000u64]);
822
    /// assert_eq!(BigInt::from(112500000000i64).iter_u64_digits().collect::<Vec<u64>>(), vec![112500000000u64]);
823
    /// assert_eq!(BigInt::from(1u128 << 64).iter_u64_digits().collect::<Vec<u64>>(), vec![0, 1]);
824
    /// ```
825
    #[inline]
826
0
    pub fn iter_u64_digits(&self) -> U64Digits<'_> {
827
0
        self.data.iter_u64_digits()
828
0
    }
829
830
    /// Returns the two's-complement byte representation of the [`BigInt`] in big-endian byte order.
831
    ///
832
    /// # Examples
833
    ///
834
    /// ```
835
    /// use num_bigint::ToBigInt;
836
    ///
837
    /// let i = -1125.to_bigint().unwrap();
838
    /// assert_eq!(i.to_signed_bytes_be(), vec![251, 155]);
839
    /// ```
840
    #[inline]
841
129k
    pub fn to_signed_bytes_be(&self) -> Vec<u8> {
842
129k
        convert::to_signed_bytes_be(self)
843
129k
    }
_RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt18to_signed_bytes_beCs4RkbDk9WRL5_5clvmr
Line
Count
Source
841
129k
    pub fn to_signed_bytes_be(&self) -> Vec<u8> {
842
129k
        convert::to_signed_bytes_be(self)
843
129k
    }
Unexecuted instantiation: _RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt18to_signed_bytes_beB7_
844
845
    /// Returns the two's-complement byte representation of the [`BigInt`] in little-endian byte order.
846
    ///
847
    /// # Examples
848
    ///
849
    /// ```
850
    /// use num_bigint::ToBigInt;
851
    ///
852
    /// let i = -1125.to_bigint().unwrap();
853
    /// assert_eq!(i.to_signed_bytes_le(), vec![155, 251]);
854
    /// ```
855
    #[inline]
856
0
    pub fn to_signed_bytes_le(&self) -> Vec<u8> {
857
0
        convert::to_signed_bytes_le(self)
858
0
    }
859
860
    /// Returns the integer formatted as a string in the given radix.
861
    /// `radix` must be in the range `2...36`.
862
    ///
863
    /// # Examples
864
    ///
865
    /// ```
866
    /// use num_bigint::BigInt;
867
    ///
868
    /// let i = BigInt::parse_bytes(b"ff", 16).unwrap();
869
    /// assert_eq!(i.to_str_radix(16), "ff");
870
    /// ```
871
    #[inline]
872
0
    pub fn to_str_radix(&self, radix: u32) -> String {
873
0
        let mut v = to_str_radix_reversed(&self.data, radix);
874
0
875
0
        if self.is_negative() {
876
0
            v.push(b'-');
877
0
        }
878
879
0
        v.reverse();
880
0
        unsafe { String::from_utf8_unchecked(v) }
881
0
    }
882
883
    /// Returns the integer in the requested base in big-endian digit order.
884
    /// The output is not given in a human readable alphabet but as a zero
885
    /// based `u8` number.
886
    /// `radix` must be in the range `2...256`.
887
    ///
888
    /// # Examples
889
    ///
890
    /// ```
891
    /// use num_bigint::{BigInt, Sign};
892
    ///
893
    /// assert_eq!(BigInt::from(-0xFFFFi64).to_radix_be(159),
894
    ///            (Sign::Minus, vec![2, 94, 27]));
895
    /// // 0xFFFF = 65535 = 2*(159^2) + 94*159 + 27
896
    /// ```
897
    #[inline]
898
0
    pub fn to_radix_be(&self, radix: u32) -> (Sign, Vec<u8>) {
899
0
        (self.sign, self.data.to_radix_be(radix))
900
0
    }
901
902
    /// Returns the integer in the requested base in little-endian digit order.
903
    /// The output is not given in a human readable alphabet but as a zero
904
    /// based `u8` number.
905
    /// `radix` must be in the range `2...256`.
906
    ///
907
    /// # Examples
908
    ///
909
    /// ```
910
    /// use num_bigint::{BigInt, Sign};
911
    ///
912
    /// assert_eq!(BigInt::from(-0xFFFFi64).to_radix_le(159),
913
    ///            (Sign::Minus, vec![27, 94, 2]));
914
    /// // 0xFFFF = 65535 = 27 + 94*159 + 2*(159^2)
915
    /// ```
916
    #[inline]
917
0
    pub fn to_radix_le(&self, radix: u32) -> (Sign, Vec<u8>) {
918
0
        (self.sign, self.data.to_radix_le(radix))
919
0
    }
920
921
    /// Returns the sign of the [`BigInt`] as a [`Sign`].
922
    ///
923
    /// # Examples
924
    ///
925
    /// ```
926
    /// use num_bigint::{BigInt, Sign};
927
    ///
928
    /// assert_eq!(BigInt::from(1234).sign(), Sign::Plus);
929
    /// assert_eq!(BigInt::from(-4321).sign(), Sign::Minus);
930
    /// assert_eq!(BigInt::ZERO.sign(), Sign::NoSign);
931
    /// ```
932
    #[inline]
933
103k
    pub fn sign(&self) -> Sign {
934
103k
        self.sign
935
103k
    }
_RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt4signCs4RkbDk9WRL5_5clvmr
Line
Count
Source
933
58.3k
    pub fn sign(&self) -> Sign {
934
58.3k
        self.sign
935
58.3k
    }
_RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt4signB7_
Line
Count
Source
933
45.3k
    pub fn sign(&self) -> Sign {
934
45.3k
        self.sign
935
45.3k
    }
936
937
    /// Returns the magnitude of the [`BigInt`] as a [`BigUint`].
938
    ///
939
    /// # Examples
940
    ///
941
    /// ```
942
    /// use num_bigint::{BigInt, BigUint};
943
    /// use num_traits::Zero;
944
    ///
945
    /// assert_eq!(BigInt::from(1234).magnitude(), &BigUint::from(1234u32));
946
    /// assert_eq!(BigInt::from(-4321).magnitude(), &BigUint::from(4321u32));
947
    /// assert!(BigInt::ZERO.magnitude().is_zero());
948
    /// ```
949
    #[inline]
950
0
    pub fn magnitude(&self) -> &BigUint {
951
0
        &self.data
952
0
    }
953
954
    /// Convert this [`BigInt`] into its [`Sign`] and [`BigUint`] magnitude,
955
    /// the reverse of [`BigInt::from_biguint()`].
956
    ///
957
    /// # Examples
958
    ///
959
    /// ```
960
    /// use num_bigint::{BigInt, BigUint, Sign};
961
    ///
962
    /// assert_eq!(BigInt::from(1234).into_parts(), (Sign::Plus, BigUint::from(1234u32)));
963
    /// assert_eq!(BigInt::from(-4321).into_parts(), (Sign::Minus, BigUint::from(4321u32)));
964
    /// assert_eq!(BigInt::ZERO.into_parts(), (Sign::NoSign, BigUint::ZERO));
965
    /// ```
966
    #[inline]
967
0
    pub fn into_parts(self) -> (Sign, BigUint) {
968
0
        (self.sign, self.data)
969
0
    }
970
971
    /// Determines the fewest bits necessary to express the [`BigInt`],
972
    /// not including the sign.
973
    #[inline]
974
62.0k
    pub fn bits(&self) -> u64 {
975
62.0k
        self.data.bits()
976
62.0k
    }
_RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt4bitsCs4RkbDk9WRL5_5clvmr
Line
Count
Source
974
62.0k
    pub fn bits(&self) -> u64 {
975
62.0k
        self.data.bits()
976
62.0k
    }
Unexecuted instantiation: _RNvMsn_NtCs72ekIXsOXFl_10num_bigint6bigintNtB5_6BigInt4bitsB7_
977
978
    /// Converts this [`BigInt`] into a [`BigUint`], if it's not negative.
979
    #[inline]
980
0
    pub fn to_biguint(&self) -> Option<BigUint> {
981
0
        match self.sign {
982
0
            Plus => Some(self.data.clone()),
983
0
            NoSign => Some(BigUint::ZERO),
984
0
            Minus => None,
985
        }
986
0
    }
987
988
    #[inline]
989
0
    pub fn checked_add(&self, v: &BigInt) -> Option<BigInt> {
990
0
        Some(self + v)
991
0
    }
992
993
    #[inline]
994
0
    pub fn checked_sub(&self, v: &BigInt) -> Option<BigInt> {
995
0
        Some(self - v)
996
0
    }
997
998
    #[inline]
999
0
    pub fn checked_mul(&self, v: &BigInt) -> Option<BigInt> {
1000
0
        Some(self * v)
1001
0
    }
1002
1003
    #[inline]
1004
0
    pub fn checked_div(&self, v: &BigInt) -> Option<BigInt> {
1005
0
        if v.is_zero() {
1006
0
            return None;
1007
0
        }
1008
0
        Some(self / v)
1009
0
    }
1010
1011
    /// Returns `self ^ exponent`.
1012
0
    pub fn pow(&self, exponent: u32) -> Self {
1013
0
        Pow::pow(self, exponent)
1014
0
    }
1015
1016
    /// Returns `(self ^ exponent) mod modulus`
1017
    ///
1018
    /// Note that this rounds like `mod_floor`, not like the `%` operator,
1019
    /// which makes a difference when given a negative `self` or `modulus`.
1020
    /// The result will be in the interval `[0, modulus)` for `modulus > 0`,
1021
    /// or in the interval `(modulus, 0]` for `modulus < 0`
1022
    ///
1023
    /// Panics if the exponent is negative or the modulus is zero.
1024
5.03k
    pub fn modpow(&self, exponent: &Self, modulus: &Self) -> Self {
1025
5.03k
        power::modpow(self, exponent, modulus)
1026
5.03k
    }
1027
1028
    /// Returns the modular multiplicative inverse if it exists, otherwise `None`.
1029
    ///
1030
    /// This solves for `x` such that `self * x ≡ 1 (mod modulus)`.
1031
    /// Note that this rounds like `mod_floor`, not like the `%` operator,
1032
    /// which makes a difference when given a negative `self` or `modulus`.
1033
    /// The solution will be in the interval `[0, modulus)` for `modulus > 0`,
1034
    /// or in the interval `(modulus, 0]` for `modulus < 0`,
1035
    /// and it exists if and only if `gcd(self, modulus) == 1`.
1036
    ///
1037
    /// ```
1038
    /// use num_bigint::BigInt;
1039
    /// use num_integer::Integer;
1040
    /// use num_traits::{One, Zero};
1041
    ///
1042
    /// let m = BigInt::from(383);
1043
    ///
1044
    /// // Trivial cases
1045
    /// assert_eq!(BigInt::zero().modinv(&m), None);
1046
    /// assert_eq!(BigInt::one().modinv(&m), Some(BigInt::one()));
1047
    /// let neg1 = &m - 1u32;
1048
    /// assert_eq!(neg1.modinv(&m), Some(neg1));
1049
    ///
1050
    /// // Positive self and modulus
1051
    /// let a = BigInt::from(271);
1052
    /// let x = a.modinv(&m).unwrap();
1053
    /// assert_eq!(x, BigInt::from(106));
1054
    /// assert_eq!(x.modinv(&m).unwrap(), a);
1055
    /// assert_eq!((&a * x).mod_floor(&m), BigInt::one());
1056
    ///
1057
    /// // Negative self and positive modulus
1058
    /// let b = -&a;
1059
    /// let x = b.modinv(&m).unwrap();
1060
    /// assert_eq!(x, BigInt::from(277));
1061
    /// assert_eq!((&b * x).mod_floor(&m), BigInt::one());
1062
    ///
1063
    /// // Positive self and negative modulus
1064
    /// let n = -&m;
1065
    /// let x = a.modinv(&n).unwrap();
1066
    /// assert_eq!(x, BigInt::from(-277));
1067
    /// assert_eq!((&a * x).mod_floor(&n), &n + 1);
1068
    ///
1069
    /// // Negative self and modulus
1070
    /// let x = b.modinv(&n).unwrap();
1071
    /// assert_eq!(x, BigInt::from(-106));
1072
    /// assert_eq!((&b * x).mod_floor(&n), &n + 1);
1073
    /// ```
1074
0
    pub fn modinv(&self, modulus: &Self) -> Option<Self> {
1075
0
        let result = self.data.modinv(&modulus.data)?;
1076
        // The sign of the result follows the modulus, like `mod_floor`.
1077
0
        let (sign, mag) = match (self.is_negative(), modulus.is_negative()) {
1078
0
            (false, false) => (Plus, result),
1079
0
            (true, false) => (Plus, &modulus.data - result),
1080
0
            (false, true) => (Minus, &modulus.data - result),
1081
0
            (true, true) => (Minus, result),
1082
        };
1083
0
        Some(BigInt::from_biguint(sign, mag))
1084
0
    }
1085
1086
    /// Returns the truncated principal square root of `self` --
1087
    /// see [`num_integer::Roots::sqrt()`].
1088
0
    pub fn sqrt(&self) -> Self {
1089
0
        Roots::sqrt(self)
1090
0
    }
1091
1092
    /// Returns the truncated principal cube root of `self` --
1093
    /// see [`num_integer::Roots::cbrt()`].
1094
0
    pub fn cbrt(&self) -> Self {
1095
0
        Roots::cbrt(self)
1096
0
    }
1097
1098
    /// Returns the truncated principal `n`th root of `self` --
1099
    /// See [`num_integer::Roots::nth_root()`].
1100
0
    pub fn nth_root(&self, n: u32) -> Self {
1101
0
        Roots::nth_root(self, n)
1102
0
    }
1103
1104
    /// Returns the number of least-significant bits that are zero,
1105
    /// or `None` if the entire number is zero.
1106
4.48k
    pub fn trailing_zeros(&self) -> Option<u64> {
1107
4.48k
        self.data.trailing_zeros()
1108
4.48k
    }
1109
1110
    /// Returns whether the bit in position `bit` is set,
1111
    /// using the two's complement for negative numbers
1112
0
    pub fn bit(&self, bit: u64) -> bool {
1113
0
        if self.is_negative() {
1114
            // Let the binary representation of a number be
1115
            //   ... 0  x 1 0 ... 0
1116
            // Then the two's complement is
1117
            //   ... 1 !x 1 0 ... 0
1118
            // where !x is obtained from x by flipping each bit
1119
0
            if bit >= u64::from(crate::big_digit::BITS) * self.len() as u64 {
1120
0
                true
1121
            } else {
1122
0
                let trailing_zeros = self.data.trailing_zeros().unwrap();
1123
0
                match Ord::cmp(&bit, &trailing_zeros) {
1124
0
                    Ordering::Less => false,
1125
0
                    Ordering::Equal => true,
1126
0
                    Ordering::Greater => !self.data.bit(bit),
1127
                }
1128
            }
1129
        } else {
1130
0
            self.data.bit(bit)
1131
        }
1132
0
    }
1133
1134
    /// Sets or clears the bit in the given position,
1135
    /// using the two's complement for negative numbers
1136
    ///
1137
    /// Note that setting/clearing a bit (for positive/negative numbers,
1138
    /// respectively) greater than the current bit length, a reallocation
1139
    /// may be needed to store the new digits
1140
0
    pub fn set_bit(&mut self, bit: u64, value: bool) {
1141
0
        match self.sign {
1142
0
            Sign::Plus => self.data.set_bit(bit, value),
1143
0
            Sign::Minus => bits::set_negative_bit(self, bit, value),
1144
            Sign::NoSign => {
1145
0
                if value {
1146
0
                    self.data.set_bit(bit, true);
1147
0
                    self.sign = Sign::Plus;
1148
0
                } else {
1149
0
                    // Clearing a bit for zero is a no-op
1150
0
                }
1151
            }
1152
        }
1153
        // The top bit may have been cleared, so normalize
1154
0
        self.normalize();
1155
0
    }
1156
}
1157
1158
impl num_traits::FromBytes for BigInt {
1159
    type Bytes = [u8];
1160
1161
0
    fn from_be_bytes(bytes: &Self::Bytes) -> Self {
1162
0
        Self::from_signed_bytes_be(bytes)
1163
0
    }
1164
1165
0
    fn from_le_bytes(bytes: &Self::Bytes) -> Self {
1166
0
        Self::from_signed_bytes_le(bytes)
1167
0
    }
1168
}
1169
1170
impl num_traits::ToBytes for BigInt {
1171
    type Bytes = Vec<u8>;
1172
1173
0
    fn to_be_bytes(&self) -> Self::Bytes {
1174
0
        self.to_signed_bytes_be()
1175
0
    }
1176
1177
0
    fn to_le_bytes(&self) -> Self::Bytes {
1178
0
        self.to_signed_bytes_le()
1179
0
    }
1180
}
1181
1182
#[test]
1183
fn test_from_biguint() {
1184
    fn check(inp_s: Sign, inp_n: usize, ans_s: Sign, ans_n: usize) {
1185
        let inp = BigInt::from_biguint(inp_s, BigUint::from(inp_n));
1186
        let ans = BigInt {
1187
            sign: ans_s,
1188
            data: BigUint::from(ans_n),
1189
        };
1190
        assert_eq!(inp, ans);
1191
    }
1192
    check(Plus, 1, Plus, 1);
1193
    check(Plus, 0, NoSign, 0);
1194
    check(Minus, 1, Minus, 1);
1195
    check(NoSign, 1, NoSign, 0);
1196
}
1197
1198
#[test]
1199
fn test_from_slice() {
1200
    fn check(inp_s: Sign, inp_n: u32, ans_s: Sign, ans_n: u32) {
1201
        let inp = BigInt::from_slice(inp_s, &[inp_n]);
1202
        let ans = BigInt {
1203
            sign: ans_s,
1204
            data: BigUint::from(ans_n),
1205
        };
1206
        assert_eq!(inp, ans);
1207
    }
1208
    check(Plus, 1, Plus, 1);
1209
    check(Plus, 0, NoSign, 0);
1210
    check(Minus, 1, Minus, 1);
1211
    check(NoSign, 1, NoSign, 0);
1212
}
1213
1214
#[test]
1215
fn test_assign_from_slice() {
1216
    fn check(inp_s: Sign, inp_n: u32, ans_s: Sign, ans_n: u32) {
1217
        let mut inp = BigInt::from_slice(Minus, &[2627_u32, 0_u32, 9182_u32, 42_u32]);
1218
        inp.assign_from_slice(inp_s, &[inp_n]);
1219
        let ans = BigInt {
1220
            sign: ans_s,
1221
            data: BigUint::from(ans_n),
1222
        };
1223
        assert_eq!(inp, ans);
1224
    }
1225
    check(Plus, 1, Plus, 1);
1226
    check(Plus, 0, NoSign, 0);
1227
    check(Minus, 1, Minus, 1);
1228
    check(NoSign, 1, NoSign, 0);
1229
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/bigint/addition.rs
Line
Count
Source
1
use super::CheckedUnsignedAbs::{Negative, Positive};
2
use super::Sign::{Minus, NoSign, Plus};
3
use super::{BigInt, UnsignedAbs};
4
5
use crate::{IsizePromotion, UsizePromotion};
6
7
use core::cmp::Ordering::{Equal, Greater, Less};
8
use core::iter::Sum;
9
use core::mem;
10
use core::ops::{Add, AddAssign};
11
use num_traits::CheckedAdd;
12
13
// We want to forward to BigUint::add, but it's not clear how that will go until
14
// we compare both sign and magnitude.  So we duplicate this body for every
15
// val/ref combination, deferring that decision to BigUint's own forwarding.
16
macro_rules! bigint_add {
17
    ($a:expr, $a_owned:expr, $a_data:expr, $b:expr, $b_owned:expr, $b_data:expr) => {
18
        match ($a.sign, $b.sign) {
19
            (_, NoSign) => $a_owned,
20
            (NoSign, _) => $b_owned,
21
            // same sign => keep the sign with the sum of magnitudes
22
            (Plus, Plus) | (Minus, Minus) => BigInt::from_biguint($a.sign, $a_data + $b_data),
23
            // opposite signs => keep the sign of the larger with the difference of magnitudes
24
            (Plus, Minus) | (Minus, Plus) => match $a.data.cmp(&$b.data) {
25
                Less => BigInt::from_biguint($b.sign, $b_data - $a_data),
26
                Greater => BigInt::from_biguint($a.sign, $a_data - $b_data),
27
                Equal => BigInt::ZERO,
28
            },
29
        }
30
    };
31
}
32
33
impl Add<&BigInt> for &BigInt {
34
    type Output = BigInt;
35
36
    #[inline]
37
18.1k
    fn add(self, other: &BigInt) -> BigInt {
38
18.1k
        bigint_add!(
39
            self,
40
852
            self.clone(),
41
17.2k
            &self.data,
42
            other,
43
0
            other.clone(),
44
17.2k
            &other.data
45
        )
46
18.1k
    }
47
}
48
49
impl Add<BigInt> for &BigInt {
50
    type Output = BigInt;
51
52
    #[inline]
53
0
    fn add(self, other: BigInt) -> BigInt {
54
0
        bigint_add!(self, self.clone(), &self.data, other, other, other.data)
55
0
    }
56
}
57
58
impl Add<&BigInt> for BigInt {
59
    type Output = BigInt;
60
61
    #[inline]
62
87.7k
    fn add(self, other: &BigInt) -> BigInt {
63
87.7k
        bigint_add!(self, self, self.data, other, other.clone(), &other.data)
64
87.7k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRBP_E3addCs4RkbDk9WRL5_5clvmr
Line
Count
Source
62
78.7k
    fn add(self, other: &BigInt) -> BigInt {
63
78.7k
        bigint_add!(self, self, self.data, other, other.clone(), &other.data)
64
78.7k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRBP_E3addB9_
Line
Count
Source
62
9.06k
    fn add(self, other: &BigInt) -> BigInt {
63
9.06k
        bigint_add!(self, self, self.data, other, other.clone(), &other.data)
64
9.06k
    }
65
}
66
67
impl Add<BigInt> for BigInt {
68
    type Output = BigInt;
69
70
    #[inline]
71
45.3k
    fn add(self, other: BigInt) -> BigInt {
72
45.3k
        bigint_add!(self, self, self.data, other, other, other.data)
73
45.3k
    }
74
}
75
76
impl AddAssign<&BigInt> for BigInt {
77
    #[inline]
78
87.7k
    fn add_assign(&mut self, other: &BigInt) {
79
87.7k
        let n = mem::replace(self, Self::ZERO);
80
87.7k
        *self = n + other;
81
87.7k
    }
_RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignRBP_E10add_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
78
78.7k
    fn add_assign(&mut self, other: &BigInt) {
79
78.7k
        let n = mem::replace(self, Self::ZERO);
80
78.7k
        *self = n + other;
81
78.7k
    }
_RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignRBP_E10add_assignB9_
Line
Count
Source
78
9.06k
    fn add_assign(&mut self, other: &BigInt) {
79
9.06k
        let n = mem::replace(self, Self::ZERO);
80
9.06k
        *self = n + other;
81
9.06k
    }
82
}
83
forward_val_assign!(impl AddAssign for BigInt, add_assign);
84
85
promote_all_scalars!(impl Add for BigInt, add);
86
promote_all_scalars_assign!(impl AddAssign for BigInt, add_assign);
87
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u32> for BigInt, add);
88
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u64> for BigInt, add);
89
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u128> for BigInt, add);
90
91
impl Add<u32> for BigInt {
92
    type Output = BigInt;
93
94
    #[inline]
95
73.3k
    fn add(self, other: u32) -> BigInt {
96
73.3k
        match self.sign {
97
29.8k
            NoSign => From::from(other),
98
26.5k
            Plus => BigInt::from(self.data + other),
99
16.8k
            Minus => match self.data.cmp(&From::from(other)) {
100
161
                Equal => Self::ZERO,
101
2.26k
                Less => BigInt::from(other - self.data),
102
14.4k
                Greater => -BigInt::from(self.data - other),
103
            },
104
        }
105
73.3k
    }
_RNvXs3_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddmE3addCs4RkbDk9WRL5_5clvmr
Line
Count
Source
95
73.3k
    fn add(self, other: u32) -> BigInt {
96
73.3k
        match self.sign {
97
29.8k
            NoSign => From::from(other),
98
26.5k
            Plus => BigInt::from(self.data + other),
99
16.8k
            Minus => match self.data.cmp(&From::from(other)) {
100
161
                Equal => Self::ZERO,
101
2.26k
                Less => BigInt::from(other - self.data),
102
14.4k
                Greater => -BigInt::from(self.data - other),
103
            },
104
        }
105
73.3k
    }
Unexecuted instantiation: _RNvXs3_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddmE3addB9_
106
}
107
108
impl AddAssign<u32> for BigInt {
109
    #[inline]
110
73.3k
    fn add_assign(&mut self, other: u32) {
111
73.3k
        let n = mem::replace(self, Self::ZERO);
112
73.3k
        *self = n + other;
113
73.3k
    }
_RNvXs4_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignmE10add_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
110
73.3k
    fn add_assign(&mut self, other: u32) {
111
73.3k
        let n = mem::replace(self, Self::ZERO);
112
73.3k
        *self = n + other;
113
73.3k
    }
Unexecuted instantiation: _RNvXs4_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignmE10add_assignB9_
114
}
115
116
impl Add<u64> for BigInt {
117
    type Output = BigInt;
118
119
    #[inline]
120
0
    fn add(self, other: u64) -> BigInt {
121
0
        match self.sign {
122
0
            NoSign => From::from(other),
123
0
            Plus => BigInt::from(self.data + other),
124
0
            Minus => match self.data.cmp(&From::from(other)) {
125
0
                Equal => Self::ZERO,
126
0
                Less => BigInt::from(other - self.data),
127
0
                Greater => -BigInt::from(self.data - other),
128
            },
129
        }
130
0
    }
131
}
132
133
impl AddAssign<u64> for BigInt {
134
    #[inline]
135
0
    fn add_assign(&mut self, other: u64) {
136
0
        let n = mem::replace(self, Self::ZERO);
137
0
        *self = n + other;
138
0
    }
139
}
140
141
impl Add<u128> for BigInt {
142
    type Output = BigInt;
143
144
    #[inline]
145
0
    fn add(self, other: u128) -> BigInt {
146
0
        match self.sign {
147
0
            NoSign => BigInt::from(other),
148
0
            Plus => BigInt::from(self.data + other),
149
0
            Minus => match self.data.cmp(&From::from(other)) {
150
0
                Equal => Self::ZERO,
151
0
                Less => BigInt::from(other - self.data),
152
0
                Greater => -BigInt::from(self.data - other),
153
            },
154
        }
155
0
    }
156
}
157
impl AddAssign<u128> for BigInt {
158
    #[inline]
159
0
    fn add_assign(&mut self, other: u128) {
160
0
        let n = mem::replace(self, Self::ZERO);
161
0
        *self = n + other;
162
0
    }
163
}
164
165
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i32> for BigInt, add);
166
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i64> for BigInt, add);
167
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i128> for BigInt, add);
168
169
impl Add<i32> for BigInt {
170
    type Output = BigInt;
171
172
    #[inline]
173
0
    fn add(self, other: i32) -> BigInt {
174
0
        match other.checked_uabs() {
175
0
            Positive(u) => self + u,
176
0
            Negative(u) => self - u,
177
        }
178
0
    }
179
}
180
impl AddAssign<i32> for BigInt {
181
    #[inline]
182
0
    fn add_assign(&mut self, other: i32) {
183
0
        match other.checked_uabs() {
184
0
            Positive(u) => *self += u,
185
0
            Negative(u) => *self -= u,
186
        }
187
0
    }
188
}
189
190
impl Add<i64> for BigInt {
191
    type Output = BigInt;
192
193
    #[inline]
194
0
    fn add(self, other: i64) -> BigInt {
195
0
        match other.checked_uabs() {
196
0
            Positive(u) => self + u,
197
0
            Negative(u) => self - u,
198
        }
199
0
    }
200
}
201
impl AddAssign<i64> for BigInt {
202
    #[inline]
203
0
    fn add_assign(&mut self, other: i64) {
204
0
        match other.checked_uabs() {
205
0
            Positive(u) => *self += u,
206
0
            Negative(u) => *self -= u,
207
        }
208
0
    }
209
}
210
211
impl Add<i128> for BigInt {
212
    type Output = BigInt;
213
214
    #[inline]
215
0
    fn add(self, other: i128) -> BigInt {
216
0
        match other.checked_uabs() {
217
0
            Positive(u) => self + u,
218
0
            Negative(u) => self - u,
219
        }
220
0
    }
221
}
222
impl AddAssign<i128> for BigInt {
223
    #[inline]
224
0
    fn add_assign(&mut self, other: i128) {
225
0
        match other.checked_uabs() {
226
0
            Positive(u) => *self += u,
227
0
            Negative(u) => *self -= u,
228
        }
229
0
    }
230
}
231
232
impl CheckedAdd for BigInt {
233
    #[inline]
234
0
    fn checked_add(&self, v: &BigInt) -> Option<BigInt> {
235
0
        Some(self.add(v))
236
0
    }
237
}
238
239
impl_sum_iter_type!(BigInt);
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/bigint/bits.rs
Line
Count
Source
1
use super::BigInt;
2
use super::Sign::{Minus, NoSign, Plus};
3
4
use crate::big_digit::{self, BigDigit, DoubleBigDigit};
5
use crate::biguint::IntDigits;
6
7
use alloc::vec::Vec;
8
use core::cmp::Ordering::{Equal, Greater, Less};
9
use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign};
10
use num_traits::{ToPrimitive, Zero};
11
12
// Negation in two's complement.
13
// acc must be initialized as 1 for least-significant digit.
14
//
15
// When negating, a carry (acc == 1) means that all the digits
16
// considered to this point were zero. This means that if all the
17
// digits of a negative BigInt have been considered, carry must be
18
// zero as we cannot have negative zero.
19
//
20
//    01 -> ...f    ff
21
//    ff -> ...f    01
22
// 01 00 -> ...f ff 00
23
// 01 01 -> ...f fe ff
24
// 01 ff -> ...f fe 01
25
// ff 00 -> ...f 01 00
26
// ff 01 -> ...f 00 ff
27
// ff ff -> ...f 00 01
28
#[inline]
29
1.45M
fn negate_carry(a: BigDigit, acc: &mut DoubleBigDigit) -> BigDigit {
30
1.45M
    *acc += DoubleBigDigit::from(!a);
31
1.45M
    let lo = *acc as BigDigit;
32
1.45M
    *acc >>= big_digit::BITS;
33
1.45M
    lo
34
1.45M
}
35
36
// + 1 & -ff = ...0 01 & ...f 01 = ...0 01 = + 1
37
// +ff & - 1 = ...0 ff & ...f ff = ...0 ff = +ff
38
// answer is pos, has length of a
39
748
fn bitand_pos_neg(a: &mut [BigDigit], b: &[BigDigit]) {
40
748
    let mut carry_b = 1;
41
2.95k
    for (ai, &bi) in a.iter_mut().zip(b.iter()) {
42
2.95k
        let twos_b = negate_carry(bi, &mut carry_b);
43
2.95k
        *ai &= twos_b;
44
2.95k
    }
45
748
    debug_assert!(b.len() > a.len() || carry_b == 0);
46
748
}
47
48
// - 1 & +ff = ...f ff & ...0 ff = ...0 ff = +ff
49
// -ff & + 1 = ...f 01 & ...0 01 = ...0 01 = + 1
50
// answer is pos, has length of b
51
2.96k
fn bitand_neg_pos(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
52
2.96k
    let mut carry_a = 1;
53
4.06k
    for (ai, &bi) in a.iter_mut().zip(b.iter()) {
54
4.06k
        let twos_a = negate_carry(*ai, &mut carry_a);
55
4.06k
        *ai = twos_a & bi;
56
4.06k
    }
57
2.96k
    debug_assert!(a.len() > b.len() || carry_a == 0);
58
2.96k
    match Ord::cmp(&a.len(), &b.len()) {
59
569
        Greater => a.truncate(b.len()),
60
1.24k
        Equal => {}
61
1.15k
        Less => {
62
1.15k
            let extra = &b[a.len()..];
63
1.15k
            a.extend(extra.iter().cloned());
64
1.15k
        }
65
    }
66
2.96k
}
67
68
// - 1 & -ff = ...f ff & ...f 01 = ...f 01 = - ff
69
// -ff & - 1 = ...f 01 & ...f ff = ...f 01 = - ff
70
// -ff & -fe = ...f 01 & ...f 02 = ...f 00 = -100
71
// answer is neg, has length of longest with a possible carry
72
2.30k
fn bitand_neg_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
73
2.30k
    let mut carry_a = 1;
74
2.30k
    let mut carry_b = 1;
75
2.30k
    let mut carry_and = 1;
76
4.67k
    for (ai, &bi) in a.iter_mut().zip(b.iter()) {
77
4.67k
        let twos_a = negate_carry(*ai, &mut carry_a);
78
4.67k
        let twos_b = negate_carry(bi, &mut carry_b);
79
4.67k
        *ai = negate_carry(twos_a & twos_b, &mut carry_and);
80
4.67k
    }
81
2.30k
    debug_assert!(a.len() > b.len() || carry_a == 0);
82
2.30k
    debug_assert!(b.len() > a.len() || carry_b == 0);
83
2.30k
    match Ord::cmp(&a.len(), &b.len()) {
84
        Greater => {
85
11.6k
            for ai in a[b.len()..].iter_mut() {
86
11.6k
                let twos_a = negate_carry(*ai, &mut carry_a);
87
11.6k
                *ai = negate_carry(twos_a, &mut carry_and);
88
11.6k
            }
89
276
            debug_assert!(carry_a == 0);
90
        }
91
404
        Equal => {}
92
        Less => {
93
1.62k
            let extra = &b[a.len()..];
94
88.1k
            a.extend(extra.iter().map(|&bi| {
95
88.1k
                let twos_b = negate_carry(bi, &mut carry_b);
96
88.1k
                negate_carry(twos_b, &mut carry_and)
97
88.1k
            }));
98
1.62k
            debug_assert!(carry_b == 0);
99
        }
100
    }
101
2.30k
    if carry_and != 0 {
102
3
        a.push(1);
103
2.29k
    }
104
2.30k
}
105
106
forward_val_val_binop!(impl BitAnd for BigInt, bitand);
107
forward_ref_val_binop!(impl BitAnd for BigInt, bitand);
108
109
// do not use forward_ref_ref_binop_commutative! for bitand so that we can
110
// clone as needed, avoiding over-allocation
111
impl BitAnd<&BigInt> for &BigInt {
112
    type Output = BigInt;
113
114
    #[inline]
115
0
    fn bitand(self, other: &BigInt) -> BigInt {
116
0
        match (self.sign, other.sign) {
117
0
            (NoSign, _) | (_, NoSign) => BigInt::ZERO,
118
0
            (Plus, Plus) => BigInt::from(&self.data & &other.data),
119
0
            (Plus, Minus) => self.clone() & other,
120
0
            (Minus, Plus) => other.clone() & self,
121
            (Minus, Minus) => {
122
                // forward to val-ref, choosing the larger to clone
123
0
                if self.len() >= other.len() {
124
0
                    self.clone() & other
125
                } else {
126
0
                    other.clone() & self
127
                }
128
            }
129
        }
130
0
    }
131
}
132
133
impl BitAnd<&BigInt> for BigInt {
134
    type Output = BigInt;
135
136
    #[inline]
137
0
    fn bitand(mut self, other: &BigInt) -> BigInt {
138
0
        self &= other;
139
0
        self
140
0
    }
141
}
142
143
forward_val_assign!(impl BitAndAssign for BigInt, bitand_assign);
144
145
impl BitAndAssign<&BigInt> for BigInt {
146
13.5k
    fn bitand_assign(&mut self, other: &BigInt) {
147
13.5k
        match (self.sign, other.sign) {
148
3.70k
            (NoSign, _) => {}
149
2.58k
            (_, NoSign) => self.set_zero(),
150
            (Plus, Plus) => {
151
1.19k
                self.data &= &other.data;
152
1.19k
                if self.data.is_zero() {
153
287
                    self.sign = NoSign;
154
909
                }
155
            }
156
748
            (Plus, Minus) => {
157
748
                bitand_pos_neg(self.digits_mut(), other.digits());
158
748
                self.normalize();
159
748
            }
160
2.96k
            (Minus, Plus) => {
161
2.96k
                bitand_neg_pos(self.digits_mut(), other.digits());
162
2.96k
                self.sign = Plus;
163
2.96k
                self.normalize();
164
2.96k
            }
165
2.30k
            (Minus, Minus) => {
166
2.30k
                bitand_neg_neg(self.digits_mut(), other.digits());
167
2.30k
                self.normalize();
168
2.30k
            }
169
        }
170
13.5k
    }
171
}
172
173
// + 1 | -ff = ...0 01 | ...f 01 = ...f 01 = -ff
174
// +ff | - 1 = ...0 ff | ...f ff = ...f ff = - 1
175
// answer is neg, has length of b
176
762
fn bitor_pos_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
177
762
    let mut carry_b = 1;
178
762
    let mut carry_or = 1;
179
2.97k
    for (ai, &bi) in a.iter_mut().zip(b.iter()) {
180
2.97k
        let twos_b = negate_carry(bi, &mut carry_b);
181
2.97k
        *ai = negate_carry(*ai | twos_b, &mut carry_or);
182
2.97k
    }
183
762
    debug_assert!(b.len() > a.len() || carry_b == 0);
184
762
    match Ord::cmp(&a.len(), &b.len()) {
185
106
        Greater => {
186
106
            a.truncate(b.len());
187
106
        }
188
72
        Equal => {}
189
        Less => {
190
584
            let extra = &b[a.len()..];
191
9.38k
            a.extend(extra.iter().map(|&bi| {
192
9.38k
                let twos_b = negate_carry(bi, &mut carry_b);
193
9.38k
                negate_carry(twos_b, &mut carry_or)
194
9.38k
            }));
195
584
            debug_assert!(carry_b == 0);
196
        }
197
    }
198
    // for carry_or to be non-zero, we would need twos_b == 0
199
762
    debug_assert!(carry_or == 0);
200
762
}
201
202
// - 1 | +ff = ...f ff | ...0 ff = ...f ff = - 1
203
// -ff | + 1 = ...f 01 | ...0 01 = ...f 01 = -ff
204
// answer is neg, has length of a
205
1.64k
fn bitor_neg_pos(a: &mut [BigDigit], b: &[BigDigit]) {
206
1.64k
    let mut carry_a = 1;
207
1.64k
    let mut carry_or = 1;
208
4.43k
    for (ai, &bi) in a.iter_mut().zip(b.iter()) {
209
4.43k
        let twos_a = negate_carry(*ai, &mut carry_a);
210
4.43k
        *ai = negate_carry(twos_a | bi, &mut carry_or);
211
4.43k
    }
212
1.64k
    debug_assert!(a.len() > b.len() || carry_a == 0);
213
1.64k
    if a.len() > b.len() {
214
458k
        for ai in a[b.len()..].iter_mut() {
215
458k
            let twos_a = negate_carry(*ai, &mut carry_a);
216
458k
            *ai = negate_carry(twos_a, &mut carry_or);
217
458k
        }
218
1.30k
        debug_assert!(carry_a == 0);
219
334
    }
220
    // for carry_or to be non-zero, we would need twos_a == 0
221
1.64k
    debug_assert!(carry_or == 0);
222
1.64k
}
223
224
// - 1 | -ff = ...f ff | ...f 01 = ...f ff = -1
225
// -ff | - 1 = ...f 01 | ...f ff = ...f ff = -1
226
// answer is neg, has length of shortest
227
724
fn bitor_neg_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
228
724
    let mut carry_a = 1;
229
724
    let mut carry_b = 1;
230
724
    let mut carry_or = 1;
231
3.68k
    for (ai, &bi) in a.iter_mut().zip(b.iter()) {
232
3.68k
        let twos_a = negate_carry(*ai, &mut carry_a);
233
3.68k
        let twos_b = negate_carry(bi, &mut carry_b);
234
3.68k
        *ai = negate_carry(twos_a | twos_b, &mut carry_or);
235
3.68k
    }
236
724
    debug_assert!(a.len() > b.len() || carry_a == 0);
237
724
    debug_assert!(b.len() > a.len() || carry_b == 0);
238
724
    if a.len() > b.len() {
239
228
        a.truncate(b.len());
240
496
    }
241
    // for carry_or to be non-zero, we would need twos_a == 0 or twos_b == 0
242
724
    debug_assert!(carry_or == 0);
243
724
}
244
245
forward_val_val_binop!(impl BitOr for BigInt, bitor);
246
forward_ref_val_binop!(impl BitOr for BigInt, bitor);
247
248
// do not use forward_ref_ref_binop_commutative! for bitor so that we can
249
// clone as needed, avoiding over-allocation
250
impl BitOr<&BigInt> for &BigInt {
251
    type Output = BigInt;
252
253
    #[inline]
254
0
    fn bitor(self, other: &BigInt) -> BigInt {
255
0
        match (self.sign, other.sign) {
256
0
            (NoSign, _) => other.clone(),
257
0
            (_, NoSign) => self.clone(),
258
0
            (Plus, Plus) => BigInt::from(&self.data | &other.data),
259
0
            (Plus, Minus) => other.clone() | self,
260
0
            (Minus, Plus) => self.clone() | other,
261
            (Minus, Minus) => {
262
                // forward to val-ref, choosing the smaller to clone
263
0
                if self.len() <= other.len() {
264
0
                    self.clone() | other
265
                } else {
266
0
                    other.clone() | self
267
                }
268
            }
269
        }
270
0
    }
271
}
272
273
impl BitOr<&BigInt> for BigInt {
274
    type Output = BigInt;
275
276
    #[inline]
277
0
    fn bitor(mut self, other: &BigInt) -> BigInt {
278
0
        self |= other;
279
0
        self
280
0
    }
281
}
282
283
forward_val_assign!(impl BitOrAssign for BigInt, bitor_assign);
284
285
impl BitOrAssign<&BigInt> for BigInt {
286
12.7k
    fn bitor_assign(&mut self, other: &BigInt) {
287
12.7k
        match (self.sign, other.sign) {
288
3.07k
            (_, NoSign) => {}
289
5.19k
            (NoSign, _) => self.clone_from(other),
290
1.37k
            (Plus, Plus) => self.data |= &other.data,
291
762
            (Plus, Minus) => {
292
762
                bitor_pos_neg(self.digits_mut(), other.digits());
293
762
                self.sign = Minus;
294
762
                self.normalize();
295
762
            }
296
1.64k
            (Minus, Plus) => {
297
1.64k
                bitor_neg_pos(self.digits_mut(), other.digits());
298
1.64k
                self.normalize();
299
1.64k
            }
300
724
            (Minus, Minus) => {
301
724
                bitor_neg_neg(self.digits_mut(), other.digits());
302
724
                self.normalize();
303
724
            }
304
        }
305
12.7k
    }
306
}
307
308
// + 1 ^ -ff = ...0 01 ^ ...f 01 = ...f 00 = -100
309
// +ff ^ - 1 = ...0 ff ^ ...f ff = ...f 00 = -100
310
// answer is neg, has length of longest with a possible carry
311
920
fn bitxor_pos_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
312
920
    let mut carry_b = 1;
313
920
    let mut carry_xor = 1;
314
4.63k
    for (ai, &bi) in a.iter_mut().zip(b.iter()) {
315
4.63k
        let twos_b = negate_carry(bi, &mut carry_b);
316
4.63k
        *ai = negate_carry(*ai ^ twos_b, &mut carry_xor);
317
4.63k
    }
318
920
    debug_assert!(b.len() > a.len() || carry_b == 0);
319
920
    match Ord::cmp(&a.len(), &b.len()) {
320
        Greater => {
321
2.99k
            for ai in a[b.len()..].iter_mut() {
322
2.99k
                let twos_b = !0;
323
2.99k
                *ai = negate_carry(*ai ^ twos_b, &mut carry_xor);
324
2.99k
            }
325
        }
326
112
        Equal => {}
327
        Less => {
328
600
            let extra = &b[a.len()..];
329
10.9k
            a.extend(extra.iter().map(|&bi| {
330
10.9k
                let twos_b = negate_carry(bi, &mut carry_b);
331
10.9k
                negate_carry(twos_b, &mut carry_xor)
332
10.9k
            }));
333
600
            debug_assert!(carry_b == 0);
334
        }
335
    }
336
920
    if carry_xor != 0 {
337
7
        a.push(1);
338
913
    }
339
920
}
340
341
// - 1 ^ +ff = ...f ff ^ ...0 ff = ...f 00 = -100
342
// -ff ^ + 1 = ...f 01 ^ ...0 01 = ...f 00 = -100
343
// answer is neg, has length of longest with a possible carry
344
1.08k
fn bitxor_neg_pos(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
345
1.08k
    let mut carry_a = 1;
346
1.08k
    let mut carry_xor = 1;
347
8.97k
    for (ai, &bi) in a.iter_mut().zip(b.iter()) {
348
8.97k
        let twos_a = negate_carry(*ai, &mut carry_a);
349
8.97k
        *ai = negate_carry(twos_a ^ bi, &mut carry_xor);
350
8.97k
    }
351
1.08k
    debug_assert!(a.len() > b.len() || carry_a == 0);
352
1.08k
    match Ord::cmp(&a.len(), &b.len()) {
353
        Greater => {
354
20.6k
            for ai in a[b.len()..].iter_mut() {
355
20.6k
                let twos_a = negate_carry(*ai, &mut carry_a);
356
20.6k
                *ai = negate_carry(twos_a, &mut carry_xor);
357
20.6k
            }
358
768
            debug_assert!(carry_a == 0);
359
        }
360
151
        Equal => {}
361
162
        Less => {
362
162
            let extra = &b[a.len()..];
363
9.62k
            a.extend(extra.iter().map(|&bi| {
364
9.62k
                let twos_a = !0;
365
9.62k
                negate_carry(twos_a ^ bi, &mut carry_xor)
366
9.62k
            }));
367
162
        }
368
    }
369
1.08k
    if carry_xor != 0 {
370
4
        a.push(1);
371
1.07k
    }
372
1.08k
}
373
374
// - 1 ^ -ff = ...f ff ^ ...f 01 = ...0 fe = +fe
375
// -ff & - 1 = ...f 01 ^ ...f ff = ...0 fe = +fe
376
// answer is pos, has length of longest
377
859
fn bitxor_neg_neg(a: &mut Vec<BigDigit>, b: &[BigDigit]) {
378
859
    let mut carry_a = 1;
379
859
    let mut carry_b = 1;
380
4.94k
    for (ai, &bi) in a.iter_mut().zip(b.iter()) {
381
4.94k
        let twos_a = negate_carry(*ai, &mut carry_a);
382
4.94k
        let twos_b = negate_carry(bi, &mut carry_b);
383
4.94k
        *ai = twos_a ^ twos_b;
384
4.94k
    }
385
859
    debug_assert!(a.len() > b.len() || carry_a == 0);
386
859
    debug_assert!(b.len() > a.len() || carry_b == 0);
387
859
    match Ord::cmp(&a.len(), &b.len()) {
388
        Greater => {
389
6.95k
            for ai in a[b.len()..].iter_mut() {
390
6.95k
                let twos_a = negate_carry(*ai, &mut carry_a);
391
6.95k
                let twos_b = !0;
392
6.95k
                *ai = twos_a ^ twos_b;
393
6.95k
            }
394
271
            debug_assert!(carry_a == 0);
395
        }
396
220
        Equal => {}
397
        Less => {
398
368
            let extra = &b[a.len()..];
399
157k
            a.extend(extra.iter().map(|&bi| {
400
157k
                let twos_a = !0;
401
157k
                let twos_b = negate_carry(bi, &mut carry_b);
402
157k
                twos_a ^ twos_b
403
157k
            }));
404
368
            debug_assert!(carry_b == 0);
405
        }
406
    }
407
859
}
408
409
forward_all_binop_to_val_ref_commutative!(impl BitXor for BigInt, bitxor);
410
411
impl BitXor<&BigInt> for BigInt {
412
    type Output = BigInt;
413
414
    #[inline]
415
0
    fn bitxor(mut self, other: &BigInt) -> BigInt {
416
0
        self ^= other;
417
0
        self
418
0
    }
419
}
420
421
forward_val_assign!(impl BitXorAssign for BigInt, bitxor_assign);
422
423
impl BitXorAssign<&BigInt> for BigInt {
424
12.7k
    fn bitxor_assign(&mut self, other: &BigInt) {
425
12.7k
        match (self.sign, other.sign) {
426
3.25k
            (_, NoSign) => {}
427
5.05k
            (NoSign, _) => self.clone_from(other),
428
            (Plus, Plus) => {
429
1.60k
                self.data ^= &other.data;
430
1.60k
                if self.data.is_zero() {
431
112
                    self.sign = NoSign;
432
1.48k
                }
433
            }
434
920
            (Plus, Minus) => {
435
920
                bitxor_pos_neg(self.digits_mut(), other.digits());
436
920
                self.sign = Minus;
437
920
                self.normalize();
438
920
            }
439
1.08k
            (Minus, Plus) => {
440
1.08k
                bitxor_neg_pos(self.digits_mut(), other.digits());
441
1.08k
                self.normalize();
442
1.08k
            }
443
859
            (Minus, Minus) => {
444
859
                bitxor_neg_neg(self.digits_mut(), other.digits());
445
859
                self.sign = Plus;
446
859
                self.normalize();
447
859
            }
448
        }
449
12.7k
    }
450
}
451
452
0
pub(super) fn set_negative_bit(x: &mut BigInt, bit: u64, value: bool) {
453
0
    debug_assert_eq!(x.sign, Minus);
454
0
    let data = &mut x.data;
455
0
456
0
    let bits_per_digit = u64::from(big_digit::BITS);
457
0
    if bit >= bits_per_digit * data.len() as u64 {
458
0
        if !value {
459
0
            data.set_bit(bit, true);
460
0
        }
461
    } else {
462
        // If the Uint number is
463
        //   ... 0  x 1 0 ... 0
464
        // then the two's complement is
465
        //   ... 1 !x 1 0 ... 0
466
        //            |-- bit at position 'trailing_zeros'
467
        // where !x is obtained from x by flipping each bit
468
0
        let trailing_zeros = data.trailing_zeros().unwrap();
469
0
        if bit > trailing_zeros {
470
0
            data.set_bit(bit, !value);
471
0
        } else if bit == trailing_zeros && !value {
472
            // Clearing the bit at position `trailing_zeros` is dealt with by doing
473
            // similarly to what `bitand_neg_pos` does, except we start at digit
474
            // `bit_index`. All digits below `bit_index` are guaranteed to be zero,
475
            // so initially we have `carry_in` = `carry_out` = 1. Furthermore, we
476
            // stop traversing the digits when there are no more carries.
477
0
            let bit_index = (bit / bits_per_digit).to_usize().unwrap();
478
0
            let bit_mask = (1 as BigDigit) << (bit % bits_per_digit);
479
0
            let mut digit_iter = data.digits_mut().iter_mut().skip(bit_index);
480
0
            let mut carry_in = 1;
481
0
            let mut carry_out = 1;
482
0
483
0
            let digit = digit_iter.next().unwrap();
484
0
            let twos_in = negate_carry(*digit, &mut carry_in);
485
0
            let twos_out = twos_in & !bit_mask;
486
0
            *digit = negate_carry(twos_out, &mut carry_out);
487
488
0
            for digit in digit_iter {
489
0
                if carry_in == 0 && carry_out == 0 {
490
                    // Exit the loop since no more digits can change
491
0
                    break;
492
0
                }
493
0
                let twos = negate_carry(*digit, &mut carry_in);
494
0
                *digit = negate_carry(twos, &mut carry_out);
495
            }
496
497
0
            if carry_out != 0 {
498
                // All digits have been traversed and there is a carry
499
0
                debug_assert_eq!(carry_in, 0);
500
0
                data.digits_mut().push(1);
501
0
            }
502
0
        } else if bit < trailing_zeros && value {
503
            // Flip each bit from position 'bit' to 'trailing_zeros', both inclusive
504
            //       ... 1 !x 1 0 ... 0 ... 0
505
            //                        |-- bit at position 'bit'
506
            //                |-- bit at position 'trailing_zeros'
507
            // bit_mask:      1 1 ... 1 0 .. 0
508
            // This is done by xor'ing with the bit_mask
509
0
            let index_lo = (bit / bits_per_digit).to_usize().unwrap();
510
0
            let index_hi = (trailing_zeros / bits_per_digit).to_usize().unwrap();
511
0
            let bit_mask_lo = big_digit::MAX << (bit % bits_per_digit);
512
0
            let bit_mask_hi =
513
0
                big_digit::MAX >> (bits_per_digit - 1 - (trailing_zeros % bits_per_digit));
514
0
            let digits = data.digits_mut();
515
0
516
0
            if index_lo == index_hi {
517
0
                digits[index_lo] ^= bit_mask_lo & bit_mask_hi;
518
0
            } else {
519
0
                digits[index_lo] = bit_mask_lo;
520
0
                for digit in &mut digits[index_lo + 1..index_hi] {
521
0
                    *digit = big_digit::MAX;
522
0
                }
523
0
                digits[index_hi] ^= bit_mask_hi;
524
            }
525
0
        } else {
526
0
            // We end up here in two cases:
527
0
            //   bit == trailing_zeros && value: Bit is already set
528
0
            //   bit < trailing_zeros && !value: Bit is already cleared
529
0
        }
530
    }
531
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/bigint/convert.rs
Line
Count
Source
1
use super::Sign::{self, Minus, NoSign, Plus};
2
use super::{BigInt, ToBigInt};
3
4
use crate::TryFromBigIntError;
5
use crate::{BigUint, ParseBigIntError, ToBigUint};
6
7
use alloc::vec::Vec;
8
use core::cmp::Ordering::{Equal, Greater, Less};
9
use core::convert::TryFrom;
10
use core::str::{self, FromStr};
11
use num_traits::{FromPrimitive, Num, One, ToPrimitive, Zero};
12
13
impl FromStr for BigInt {
14
    type Err = ParseBigIntError;
15
16
    #[inline]
17
0
    fn from_str(s: &str) -> Result<BigInt, ParseBigIntError> {
18
0
        BigInt::from_str_radix(s, 10)
19
0
    }
20
}
21
22
impl Num for BigInt {
23
    type FromStrRadixErr = ParseBigIntError;
24
25
    /// Creates and initializes a [`BigInt`].
26
    #[inline]
27
0
    fn from_str_radix(mut s: &str, radix: u32) -> Result<BigInt, ParseBigIntError> {
28
0
        let sign = if let Some(tail) = s.strip_prefix('-') {
29
0
            if !tail.starts_with('+') {
30
0
                s = tail
31
0
            }
32
0
            Minus
33
        } else {
34
0
            Plus
35
        };
36
0
        let bu = BigUint::from_str_radix(s, radix)?;
37
0
        Ok(BigInt::from_biguint(sign, bu))
38
0
    }
39
}
40
41
impl ToPrimitive for BigInt {
42
    #[inline]
43
0
    fn to_i64(&self) -> Option<i64> {
44
0
        match self.sign {
45
0
            Plus => self.data.to_i64(),
46
0
            NoSign => Some(0),
47
            Minus => {
48
0
                let n = self.data.to_u64()?;
49
0
                let m: u64 = 1 << 63;
50
0
                match n.cmp(&m) {
51
0
                    Less => Some(-(n as i64)),
52
0
                    Equal => Some(i64::MIN),
53
0
                    Greater => None,
54
                }
55
            }
56
        }
57
0
    }
58
59
    #[inline]
60
0
    fn to_i128(&self) -> Option<i128> {
61
0
        match self.sign {
62
0
            Plus => self.data.to_i128(),
63
0
            NoSign => Some(0),
64
            Minus => {
65
0
                let n = self.data.to_u128()?;
66
0
                let m: u128 = 1 << 127;
67
0
                match n.cmp(&m) {
68
0
                    Less => Some(-(n as i128)),
69
0
                    Equal => Some(i128::MIN),
70
0
                    Greater => None,
71
                }
72
            }
73
        }
74
0
    }
75
76
    #[inline]
77
353k
    fn to_u64(&self) -> Option<u64> {
78
353k
        match self.sign {
79
202k
            Plus => self.data.to_u64(),
80
73.8k
            NoSign => Some(0),
81
76.8k
            Minus => None,
82
        }
83
353k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_u64Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
77
353k
    fn to_u64(&self) -> Option<u64> {
78
353k
        match self.sign {
79
202k
            Plus => self.data.to_u64(),
80
73.8k
            NoSign => Some(0),
81
76.8k
            Minus => None,
82
        }
83
353k
    }
Unexecuted instantiation: _RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_u64B9_
84
85
    #[inline]
86
0
    fn to_u128(&self) -> Option<u128> {
87
0
        match self.sign {
88
0
            Plus => self.data.to_u128(),
89
0
            NoSign => Some(0),
90
0
            Minus => None,
91
        }
92
0
    }
93
94
    #[inline]
95
0
    fn to_f32(&self) -> Option<f32> {
96
0
        let n = self.data.to_f32()?;
97
0
        Some(if self.sign == Minus { -n } else { n })
98
0
    }
99
100
    #[inline]
101
0
    fn to_f64(&self) -> Option<f64> {
102
0
        let n = self.data.to_f64()?;
103
0
        Some(if self.sign == Minus { -n } else { n })
104
0
    }
105
}
106
107
macro_rules! impl_try_from_bigint {
108
    ($T:ty, $to_ty:path) => {
109
        impl TryFrom<&BigInt> for $T {
110
            type Error = TryFromBigIntError<()>;
111
112
            #[inline]
113
0
            fn try_from(value: &BigInt) -> Result<$T, TryFromBigIntError<()>> {
114
0
                $to_ty(value).ok_or(TryFromBigIntError::new(()))
115
0
            }
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint6bigint7converthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint6bigint7converttINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsh_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertmINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsj_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertyINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsl_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertjINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertoINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertaINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsr_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertsINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXst_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertlINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsv_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertxINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsx_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertiINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsz_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertnINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_6BigIntE8try_fromB9_
116
        }
117
118
        impl TryFrom<BigInt> for $T {
119
            type Error = TryFromBigIntError<BigInt>;
120
121
            #[inline]
122
0
            fn try_from(value: BigInt) -> Result<$T, TryFromBigIntError<BigInt>> {
123
0
                <$T>::try_from(&value).map_err(|_| TryFromBigIntError::new(value))
Unexecuted instantiation: _RNCNvXse_NtNtCs72ekIXsOXFl_10num_bigint6bigint7converthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsg_NtNtCs72ekIXsOXFl_10num_bigint6bigint7converttINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsi_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertmINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsk_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertyINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsm_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertjINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
Unexecuted instantiation: _RNCNvXso_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertoINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsq_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertaINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
Unexecuted instantiation: _RNCNvXss_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertsINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsu_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertlINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsw_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertxINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsy_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertiINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsA_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertnINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_6BigIntE8try_from0Bb_
124
0
            }
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint6bigint7converthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint6bigint7converttINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsi_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertmINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsk_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertyINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertjINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertoINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsq_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertaINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXss_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertsINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsu_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertlINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertxINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsy_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertiINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
Unexecuted instantiation: _RNvXsA_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertnINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_6BigIntE8try_fromB9_
125
        }
126
    };
127
}
128
129
impl_try_from_bigint!(u8, ToPrimitive::to_u8);
130
impl_try_from_bigint!(u16, ToPrimitive::to_u16);
131
impl_try_from_bigint!(u32, ToPrimitive::to_u32);
132
impl_try_from_bigint!(u64, ToPrimitive::to_u64);
133
impl_try_from_bigint!(usize, ToPrimitive::to_usize);
134
impl_try_from_bigint!(u128, ToPrimitive::to_u128);
135
136
impl_try_from_bigint!(i8, ToPrimitive::to_i8);
137
impl_try_from_bigint!(i16, ToPrimitive::to_i16);
138
impl_try_from_bigint!(i32, ToPrimitive::to_i32);
139
impl_try_from_bigint!(i64, ToPrimitive::to_i64);
140
impl_try_from_bigint!(isize, ToPrimitive::to_isize);
141
impl_try_from_bigint!(i128, ToPrimitive::to_i128);
142
143
impl FromPrimitive for BigInt {
144
    #[inline]
145
0
    fn from_i64(n: i64) -> Option<BigInt> {
146
0
        Some(BigInt::from(n))
147
0
    }
148
149
    #[inline]
150
0
    fn from_i128(n: i128) -> Option<BigInt> {
151
0
        Some(BigInt::from(n))
152
0
    }
153
154
    #[inline]
155
0
    fn from_u64(n: u64) -> Option<BigInt> {
156
0
        Some(BigInt::from(n))
157
0
    }
158
159
    #[inline]
160
0
    fn from_u128(n: u128) -> Option<BigInt> {
161
0
        Some(BigInt::from(n))
162
0
    }
163
164
    #[inline]
165
0
    fn from_f64(n: f64) -> Option<BigInt> {
166
0
        if n >= 0.0 {
167
0
            BigUint::from_f64(n).map(BigInt::from)
168
        } else {
169
0
            let x = BigUint::from_f64(-n)?;
170
0
            Some(-BigInt::from(x))
171
        }
172
0
    }
173
}
174
175
impl From<i64> for BigInt {
176
    #[inline]
177
174k
    fn from(n: i64) -> Self {
178
174k
        if n >= 0 {
179
168k
            BigInt::from(n as u64)
180
        } else {
181
6.36k
            let u = u64::MAX - (n as u64) + 1;
182
6.36k
            BigInt {
183
6.36k
                sign: Minus,
184
6.36k
                data: BigUint::from(u),
185
6.36k
            }
186
        }
187
174k
    }
_RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromxE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
177
174k
    fn from(n: i64) -> Self {
178
174k
        if n >= 0 {
179
168k
            BigInt::from(n as u64)
180
        } else {
181
6.36k
            let u = u64::MAX - (n as u64) + 1;
182
6.36k
            BigInt {
183
6.36k
                sign: Minus,
184
6.36k
                data: BigUint::from(u),
185
6.36k
            }
186
        }
187
174k
    }
Unexecuted instantiation: _RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromxE4fromB9_
188
}
189
190
impl From<i128> for BigInt {
191
    #[inline]
192
0
    fn from(n: i128) -> Self {
193
0
        if n >= 0 {
194
0
            BigInt::from(n as u128)
195
        } else {
196
0
            let u = u128::MAX - (n as u128) + 1;
197
0
            BigInt {
198
0
                sign: Minus,
199
0
                data: BigUint::from(u),
200
0
            }
201
        }
202
0
    }
203
}
204
205
macro_rules! impl_bigint_from_int {
206
    ($T:ty) => {
207
        impl From<$T> for BigInt {
208
            #[inline]
209
174k
            fn from(n: $T) -> Self {
210
174k
                BigInt::from(n as i64)
211
174k
            }
_RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromlE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
209
174k
            fn from(n: $T) -> Self {
210
174k
                BigInt::from(n as i64)
211
174k
            }
Unexecuted instantiation: _RNvXsB_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromaE4fromB9_
Unexecuted instantiation: _RNvXsC_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromsE4fromB9_
Unexecuted instantiation: _RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromlE4fromB9_
Unexecuted instantiation: _RNvXsE_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromiE4fromB9_
212
        }
213
    };
214
}
215
216
impl_bigint_from_int!(i8);
217
impl_bigint_from_int!(i16);
218
impl_bigint_from_int!(i32);
219
impl_bigint_from_int!(isize);
220
221
impl From<u64> for BigInt {
222
    #[inline]
223
452k
    fn from(n: u64) -> Self {
224
452k
        if n > 0 {
225
245k
            BigInt {
226
245k
                sign: Plus,
227
245k
                data: BigUint::from(n),
228
245k
            }
229
        } else {
230
206k
            Self::ZERO
231
        }
232
452k
    }
_RNvXs4_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromyE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
223
342k
    fn from(n: u64) -> Self {
224
342k
        if n > 0 {
225
135k
            BigInt {
226
135k
                sign: Plus,
227
135k
                data: BigUint::from(n),
228
135k
            }
229
        } else {
230
206k
            Self::ZERO
231
        }
232
342k
    }
_RNvXs4_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromyE4fromCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
223
109k
    fn from(n: u64) -> Self {
224
109k
        if n > 0 {
225
109k
            BigInt {
226
109k
                sign: Plus,
227
109k
                data: BigUint::from(n),
228
109k
            }
229
        } else {
230
0
            Self::ZERO
231
        }
232
109k
    }
_RNvXs4_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromyE4fromB9_
Line
Count
Source
223
344
    fn from(n: u64) -> Self {
224
344
        if n > 0 {
225
344
            BigInt {
226
344
                sign: Plus,
227
344
                data: BigUint::from(n),
228
344
            }
229
        } else {
230
0
            Self::ZERO
231
        }
232
344
    }
233
}
234
235
impl From<u128> for BigInt {
236
    #[inline]
237
0
    fn from(n: u128) -> Self {
238
0
        if n > 0 {
239
0
            BigInt {
240
0
                sign: Plus,
241
0
                data: BigUint::from(n),
242
0
            }
243
        } else {
244
0
            Self::ZERO
245
        }
246
0
    }
247
}
248
249
macro_rules! impl_bigint_from_uint {
250
    ($T:ty) => {
251
        impl From<$T> for BigInt {
252
            #[inline]
253
174k
            fn from(n: $T) -> Self {
254
174k
                BigInt::from(n as u64)
255
174k
            }
_RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FrommE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
253
165k
            fn from(n: $T) -> Self {
254
165k
                BigInt::from(n as u64)
255
165k
            }
_RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromjE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
253
8.66k
            fn from(n: $T) -> Self {
254
8.66k
                BigInt::from(n as u64)
255
8.66k
            }
_RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FrommE4fromB9_
Line
Count
Source
253
344
            fn from(n: $T) -> Self {
254
344
                BigInt::from(n as u64)
255
344
            }
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromhE4fromB9_
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromtE4fromB9_
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromjE4fromB9_
256
        }
257
    };
258
}
259
260
impl_bigint_from_uint!(u8);
261
impl_bigint_from_uint!(u16);
262
impl_bigint_from_uint!(u32);
263
impl_bigint_from_uint!(usize);
264
265
impl From<BigUint> for BigInt {
266
    #[inline]
267
146k
    fn from(n: BigUint) -> Self {
268
146k
        if n.is_zero() {
269
19.5k
            Self::ZERO
270
        } else {
271
127k
            BigInt {
272
127k
                sign: Plus,
273
127k
                data: n,
274
127k
            }
275
        }
276
146k
    }
_RNvXs6_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtB9_7biguint7BigUintE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
267
89.7k
    fn from(n: BigUint) -> Self {
268
89.7k
        if n.is_zero() {
269
8.71k
            Self::ZERO
270
        } else {
271
81.0k
            BigInt {
272
81.0k
                sign: Plus,
273
81.0k
                data: n,
274
81.0k
            }
275
        }
276
89.7k
    }
_RNvXs6_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertNtB7_6BigIntINtNtCsbQ8arDwx5Xq_4core7convert4FromNtNtB9_7biguint7BigUintE4fromB9_
Line
Count
Source
267
56.9k
    fn from(n: BigUint) -> Self {
268
56.9k
        if n.is_zero() {
269
10.8k
            Self::ZERO
270
        } else {
271
46.1k
            BigInt {
272
46.1k
                sign: Plus,
273
46.1k
                data: n,
274
46.1k
            }
275
        }
276
56.9k
    }
277
}
278
279
impl ToBigInt for BigInt {
280
    #[inline]
281
0
    fn to_bigint(&self) -> Option<BigInt> {
282
0
        Some(self.clone())
283
0
    }
284
}
285
286
impl ToBigInt for BigUint {
287
    #[inline]
288
0
    fn to_bigint(&self) -> Option<BigInt> {
289
0
        if self.is_zero() {
290
0
            Some(BigInt::ZERO)
291
        } else {
292
0
            Some(BigInt {
293
0
                sign: Plus,
294
0
                data: self.clone(),
295
0
            })
296
        }
297
0
    }
298
}
299
300
impl ToBigUint for BigInt {
301
    #[inline]
302
0
    fn to_biguint(&self) -> Option<BigUint> {
303
0
        match self.sign() {
304
0
            Plus => Some(self.data.clone()),
305
0
            NoSign => Some(BigUint::ZERO),
306
0
            Minus => None,
307
        }
308
0
    }
309
}
310
311
impl TryFrom<&BigInt> for BigUint {
312
    type Error = TryFromBigIntError<()>;
313
314
    #[inline]
315
0
    fn try_from(value: &BigInt) -> Result<BigUint, TryFromBigIntError<()>> {
316
0
        value
317
0
            .to_biguint()
318
0
            .ok_or_else(|| TryFromBigIntError::new(()))
319
0
    }
320
}
321
322
impl TryFrom<BigInt> for BigUint {
323
    type Error = TryFromBigIntError<BigInt>;
324
325
    #[inline]
326
0
    fn try_from(value: BigInt) -> Result<BigUint, TryFromBigIntError<BigInt>> {
327
0
        if value.sign() == Sign::Minus {
328
0
            Err(TryFromBigIntError::new(value))
329
        } else {
330
0
            Ok(value.data)
331
        }
332
0
    }
333
}
334
335
macro_rules! impl_to_bigint {
336
    ($T:ty, $from_ty:path) => {
337
        impl ToBigInt for $T {
338
            #[inline]
339
0
            fn to_bigint(&self) -> Option<BigInt> {
340
0
                $from_ty(*self)
341
0
            }
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertiNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertaNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertsNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertlNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertxNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertnNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertjNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint6bigint7converthNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint6bigint7converttNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsS_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertmNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsT_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertyNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsU_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertoNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsV_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertfNtB7_8ToBigInt9to_bigintB9_
Unexecuted instantiation: _RNvXsW_NtNtCs72ekIXsOXFl_10num_bigint6bigint7convertdNtB7_8ToBigInt9to_bigintB9_
342
        }
343
    };
344
}
345
346
impl_to_bigint!(isize, FromPrimitive::from_isize);
347
impl_to_bigint!(i8, FromPrimitive::from_i8);
348
impl_to_bigint!(i16, FromPrimitive::from_i16);
349
impl_to_bigint!(i32, FromPrimitive::from_i32);
350
impl_to_bigint!(i64, FromPrimitive::from_i64);
351
impl_to_bigint!(i128, FromPrimitive::from_i128);
352
353
impl_to_bigint!(usize, FromPrimitive::from_usize);
354
impl_to_bigint!(u8, FromPrimitive::from_u8);
355
impl_to_bigint!(u16, FromPrimitive::from_u16);
356
impl_to_bigint!(u32, FromPrimitive::from_u32);
357
impl_to_bigint!(u64, FromPrimitive::from_u64);
358
impl_to_bigint!(u128, FromPrimitive::from_u128);
359
360
impl_to_bigint!(f32, FromPrimitive::from_f32);
361
impl_to_bigint!(f64, FromPrimitive::from_f64);
362
363
impl From<bool> for BigInt {
364
0
    fn from(x: bool) -> Self {
365
0
        if x {
366
0
            One::one()
367
        } else {
368
0
            Self::ZERO
369
        }
370
0
    }
371
}
372
373
#[inline]
374
228k
pub(super) fn from_signed_bytes_be(digits: &[u8]) -> BigInt {
375
228k
    let sign = match digits.first() {
376
228k
        Some(v) if *v > 0x7f => Sign::Minus,
377
107k
        Some(_) => Sign::Plus,
378
0
        None => return BigInt::ZERO,
379
    };
380
381
228k
    if sign == Sign::Minus {
382
        // two's-complement the content to retrieve the magnitude
383
120k
        let mut digits = Vec::from(digits);
384
120k
        twos_complement_be(&mut digits);
385
120k
        BigInt::from_biguint(sign, BigUint::from_bytes_be(&digits))
386
    } else {
387
107k
        BigInt::from_biguint(sign, BigUint::from_bytes_be(digits))
388
    }
389
228k
}
_RNvNtNtCs72ekIXsOXFl_10num_bigint6bigint7convert20from_signed_bytes_beCs4RkbDk9WRL5_5clvmr
Line
Count
Source
374
228k
pub(super) fn from_signed_bytes_be(digits: &[u8]) -> BigInt {
375
228k
    let sign = match digits.first() {
376
228k
        Some(v) if *v > 0x7f => Sign::Minus,
377
107k
        Some(_) => Sign::Plus,
378
0
        None => return BigInt::ZERO,
379
    };
380
381
228k
    if sign == Sign::Minus {
382
        // two's-complement the content to retrieve the magnitude
383
120k
        let mut digits = Vec::from(digits);
384
120k
        twos_complement_be(&mut digits);
385
120k
        BigInt::from_biguint(sign, BigUint::from_bytes_be(&digits))
386
    } else {
387
107k
        BigInt::from_biguint(sign, BigUint::from_bytes_be(digits))
388
    }
389
228k
}
Unexecuted instantiation: _RNvNtNtCs72ekIXsOXFl_10num_bigint6bigint7convert20from_signed_bytes_beB5_
390
391
#[inline]
392
0
pub(super) fn from_signed_bytes_le(digits: &[u8]) -> BigInt {
393
0
    let sign = match digits.last() {
394
0
        Some(v) if *v > 0x7f => Sign::Minus,
395
0
        Some(_) => Sign::Plus,
396
0
        None => return BigInt::ZERO,
397
    };
398
399
0
    if sign == Sign::Minus {
400
        // two's-complement the content to retrieve the magnitude
401
0
        let mut digits = Vec::from(digits);
402
0
        twos_complement_le(&mut digits);
403
0
        BigInt::from_biguint(sign, BigUint::from_bytes_le(&digits))
404
    } else {
405
0
        BigInt::from_biguint(sign, BigUint::from_bytes_le(digits))
406
    }
407
0
}
408
409
#[inline]
410
129k
pub(super) fn to_signed_bytes_be(x: &BigInt) -> Vec<u8> {
411
129k
    let mut bytes = x.data.to_bytes_be();
412
129k
    let first_byte = bytes.first().cloned().unwrap_or(0);
413
129k
    if first_byte > 0x7f
414
44.1k
        && !(first_byte == 0x80 && bytes.iter().skip(1).all(Zero::is_zero) && x.sign == Sign::Minus)
415
41.4k
    {
416
41.4k
        // msb used by magnitude, extend by 1 byte
417
41.4k
        bytes.insert(0, 0);
418
88.5k
    }
419
129k
    if x.sign == Sign::Minus {
420
76.8k
        twos_complement_be(&mut bytes);
421
76.8k
    }
422
129k
    bytes
423
129k
}
_RNvNtNtCs72ekIXsOXFl_10num_bigint6bigint7convert18to_signed_bytes_beCs4RkbDk9WRL5_5clvmr
Line
Count
Source
410
129k
pub(super) fn to_signed_bytes_be(x: &BigInt) -> Vec<u8> {
411
129k
    let mut bytes = x.data.to_bytes_be();
412
129k
    let first_byte = bytes.first().cloned().unwrap_or(0);
413
129k
    if first_byte > 0x7f
414
44.1k
        && !(first_byte == 0x80 && bytes.iter().skip(1).all(Zero::is_zero) && x.sign == Sign::Minus)
415
41.4k
    {
416
41.4k
        // msb used by magnitude, extend by 1 byte
417
41.4k
        bytes.insert(0, 0);
418
88.5k
    }
419
129k
    if x.sign == Sign::Minus {
420
76.8k
        twos_complement_be(&mut bytes);
421
76.8k
    }
422
129k
    bytes
423
129k
}
Unexecuted instantiation: _RNvNtNtCs72ekIXsOXFl_10num_bigint6bigint7convert18to_signed_bytes_beB5_
424
425
#[inline]
426
0
pub(super) fn to_signed_bytes_le(x: &BigInt) -> Vec<u8> {
427
0
    let mut bytes = x.data.to_bytes_le();
428
0
    let last_byte = bytes.last().cloned().unwrap_or(0);
429
0
    if last_byte > 0x7f
430
0
        && !(last_byte == 0x80
431
0
            && bytes.iter().rev().skip(1).all(Zero::is_zero)
432
0
            && x.sign == Sign::Minus)
433
0
    {
434
0
        // msb used by magnitude, extend by 1 byte
435
0
        bytes.push(0);
436
0
    }
437
0
    if x.sign == Sign::Minus {
438
0
        twos_complement_le(&mut bytes);
439
0
    }
440
0
    bytes
441
0
}
442
443
/// Perform in-place two's complement of the given binary representation,
444
/// in little-endian byte order.
445
#[inline]
446
0
fn twos_complement_le(digits: &mut [u8]) {
447
0
    twos_complement(digits)
448
0
}
449
450
/// Perform in-place two's complement of the given binary representation
451
/// in big-endian byte order.
452
#[inline]
453
197k
fn twos_complement_be(digits: &mut [u8]) {
454
197k
    twos_complement(digits.iter_mut().rev())
455
197k
}
_RNvNtNtCs72ekIXsOXFl_10num_bigint6bigint7convert18twos_complement_beCs4RkbDk9WRL5_5clvmr
Line
Count
Source
453
197k
fn twos_complement_be(digits: &mut [u8]) {
454
197k
    twos_complement(digits.iter_mut().rev())
455
197k
}
Unexecuted instantiation: _RNvNtNtCs72ekIXsOXFl_10num_bigint6bigint7convert18twos_complement_beB5_
456
457
/// Perform in-place two's complement of the given digit iterator
458
/// starting from the least significant byte.
459
#[inline]
460
197k
fn twos_complement<'a, I>(digits: I)
461
197k
where
462
197k
    I: IntoIterator<Item = &'a mut u8>,
463
197k
{
464
197k
    let mut carry = true;
465
88.1M
    for d in digits {
466
87.9M
        *d = !*d;
467
87.9M
        if carry {
468
12.5M
            *d = d.wrapping_add(1);
469
12.5M
            carry = d.is_zero();
470
75.3M
        }
471
    }
472
197k
}
_RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint7convert15twos_complementINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters3rev3RevINtNtNtB1b_5slice4iter7IterMuthEEECs4RkbDk9WRL5_5clvmr
Line
Count
Source
460
197k
fn twos_complement<'a, I>(digits: I)
461
197k
where
462
197k
    I: IntoIterator<Item = &'a mut u8>,
463
197k
{
464
197k
    let mut carry = true;
465
88.1M
    for d in digits {
466
87.9M
        *d = !*d;
467
87.9M
        if carry {
468
12.5M
            *d = d.wrapping_add(1);
469
12.5M
            carry = d.is_zero();
470
75.3M
        }
471
    }
472
197k
}
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint7convert15twos_complementINtNtNtNtCsbQ8arDwx5Xq_4core4iter8adapters3rev3RevINtNtNtB1b_5slice4iter7IterMuthEEEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint7convert15twos_complementQShEB6_
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/bigint/division.rs
Line
Count
Source
1
use super::CheckedUnsignedAbs::{Negative, Positive};
2
use super::Sign::NoSign;
3
use super::{BigInt, UnsignedAbs};
4
5
use crate::{IsizePromotion, UsizePromotion};
6
7
use core::ops::{Div, DivAssign, Rem, RemAssign};
8
use num_integer::Integer;
9
use num_traits::{CheckedDiv, CheckedEuclid, Euclid, Signed, ToPrimitive, Zero};
10
11
forward_all_binop_to_ref_ref!(impl Div for BigInt, div);
12
13
impl Div<&BigInt> for &BigInt {
14
    type Output = BigInt;
15
16
    #[inline]
17
0
    fn div(self, other: &BigInt) -> BigInt {
18
0
        let (q, _) = self.div_rem(other);
19
0
        q
20
0
    }
21
}
22
23
impl DivAssign<&BigInt> for BigInt {
24
    #[inline]
25
0
    fn div_assign(&mut self, other: &BigInt) {
26
0
        *self = &*self / other;
27
0
    }
28
}
29
forward_val_assign!(impl DivAssign for BigInt, div_assign);
30
31
promote_all_scalars!(impl Div for BigInt, div);
32
promote_all_scalars_assign!(impl DivAssign for BigInt, div_assign);
33
forward_all_scalar_binop_to_val_val!(impl Div<u32> for BigInt, div);
34
forward_all_scalar_binop_to_val_val!(impl Div<u64> for BigInt, div);
35
forward_all_scalar_binop_to_val_val!(impl Div<u128> for BigInt, div);
36
37
impl Div<u32> for BigInt {
38
    type Output = BigInt;
39
40
    #[inline]
41
9.06k
    fn div(self, other: u32) -> BigInt {
42
9.06k
        BigInt::from_biguint(self.sign, self.data / other)
43
9.06k
    }
44
}
45
46
impl DivAssign<u32> for BigInt {
47
    #[inline]
48
0
    fn div_assign(&mut self, other: u32) {
49
0
        self.data /= other;
50
0
        if self.data.is_zero() {
51
0
            self.sign = NoSign;
52
0
        }
53
0
    }
54
}
55
56
impl Div<BigInt> for u32 {
57
    type Output = BigInt;
58
59
    #[inline]
60
0
    fn div(self, other: BigInt) -> BigInt {
61
0
        BigInt::from_biguint(other.sign, self / other.data)
62
0
    }
63
}
64
65
impl Div<u64> for BigInt {
66
    type Output = BigInt;
67
68
    #[inline]
69
0
    fn div(self, other: u64) -> BigInt {
70
0
        BigInt::from_biguint(self.sign, self.data / other)
71
0
    }
72
}
73
74
impl DivAssign<u64> for BigInt {
75
    #[inline]
76
0
    fn div_assign(&mut self, other: u64) {
77
0
        self.data /= other;
78
0
        if self.data.is_zero() {
79
0
            self.sign = NoSign;
80
0
        }
81
0
    }
82
}
83
84
impl Div<BigInt> for u64 {
85
    type Output = BigInt;
86
87
    #[inline]
88
0
    fn div(self, other: BigInt) -> BigInt {
89
0
        BigInt::from_biguint(other.sign, self / other.data)
90
0
    }
91
}
92
93
impl Div<u128> for BigInt {
94
    type Output = BigInt;
95
96
    #[inline]
97
0
    fn div(self, other: u128) -> BigInt {
98
0
        BigInt::from_biguint(self.sign, self.data / other)
99
0
    }
100
}
101
102
impl DivAssign<u128> for BigInt {
103
    #[inline]
104
0
    fn div_assign(&mut self, other: u128) {
105
0
        self.data /= other;
106
0
        if self.data.is_zero() {
107
0
            self.sign = NoSign;
108
0
        }
109
0
    }
110
}
111
112
impl Div<BigInt> for u128 {
113
    type Output = BigInt;
114
115
    #[inline]
116
0
    fn div(self, other: BigInt) -> BigInt {
117
0
        BigInt::from_biguint(other.sign, self / other.data)
118
0
    }
119
}
120
121
forward_all_scalar_binop_to_val_val!(impl Div<i32> for BigInt, div);
122
forward_all_scalar_binop_to_val_val!(impl Div<i64> for BigInt, div);
123
forward_all_scalar_binop_to_val_val!(impl Div<i128> for BigInt, div);
124
125
impl Div<i32> for BigInt {
126
    type Output = BigInt;
127
128
    #[inline]
129
0
    fn div(self, other: i32) -> BigInt {
130
0
        match other.checked_uabs() {
131
0
            Positive(u) => self / u,
132
0
            Negative(u) => -self / u,
133
        }
134
0
    }
135
}
136
137
impl DivAssign<i32> for BigInt {
138
    #[inline]
139
0
    fn div_assign(&mut self, other: i32) {
140
0
        match other.checked_uabs() {
141
0
            Positive(u) => *self /= u,
142
0
            Negative(u) => {
143
0
                self.sign = -self.sign;
144
0
                *self /= u;
145
0
            }
146
        }
147
0
    }
148
}
149
150
impl Div<BigInt> for i32 {
151
    type Output = BigInt;
152
153
    #[inline]
154
0
    fn div(self, other: BigInt) -> BigInt {
155
0
        match self.checked_uabs() {
156
0
            Positive(u) => u / other,
157
0
            Negative(u) => u / -other,
158
        }
159
0
    }
160
}
161
162
impl Div<i64> for BigInt {
163
    type Output = BigInt;
164
165
    #[inline]
166
0
    fn div(self, other: i64) -> BigInt {
167
0
        match other.checked_uabs() {
168
0
            Positive(u) => self / u,
169
0
            Negative(u) => -self / u,
170
        }
171
0
    }
172
}
173
174
impl DivAssign<i64> for BigInt {
175
    #[inline]
176
0
    fn div_assign(&mut self, other: i64) {
177
0
        match other.checked_uabs() {
178
0
            Positive(u) => *self /= u,
179
0
            Negative(u) => {
180
0
                self.sign = -self.sign;
181
0
                *self /= u;
182
0
            }
183
        }
184
0
    }
185
}
186
187
impl Div<BigInt> for i64 {
188
    type Output = BigInt;
189
190
    #[inline]
191
0
    fn div(self, other: BigInt) -> BigInt {
192
0
        match self.checked_uabs() {
193
0
            Positive(u) => u / other,
194
0
            Negative(u) => u / -other,
195
        }
196
0
    }
197
}
198
199
impl Div<i128> for BigInt {
200
    type Output = BigInt;
201
202
    #[inline]
203
0
    fn div(self, other: i128) -> BigInt {
204
0
        match other.checked_uabs() {
205
0
            Positive(u) => self / u,
206
0
            Negative(u) => -self / u,
207
        }
208
0
    }
209
}
210
211
impl DivAssign<i128> for BigInt {
212
    #[inline]
213
0
    fn div_assign(&mut self, other: i128) {
214
0
        match other.checked_uabs() {
215
0
            Positive(u) => *self /= u,
216
0
            Negative(u) => {
217
0
                self.sign = -self.sign;
218
0
                *self /= u;
219
0
            }
220
        }
221
0
    }
222
}
223
224
impl Div<BigInt> for i128 {
225
    type Output = BigInt;
226
227
    #[inline]
228
0
    fn div(self, other: BigInt) -> BigInt {
229
0
        match self.checked_uabs() {
230
0
            Positive(u) => u / other,
231
0
            Negative(u) => u / -other,
232
        }
233
0
    }
234
}
235
236
forward_all_binop_to_ref_ref!(impl Rem for BigInt, rem);
237
238
impl Rem<&BigInt> for &BigInt {
239
    type Output = BigInt;
240
241
    #[inline]
242
0
    fn rem(self, other: &BigInt) -> BigInt {
243
0
        if let Some(other) = other.to_u32() {
244
0
            self % other
245
0
        } else if let Some(other) = other.to_i32() {
246
0
            self % other
247
        } else {
248
0
            let (_, r) = self.div_rem(other);
249
0
            r
250
        }
251
0
    }
252
}
253
254
impl RemAssign<&BigInt> for BigInt {
255
    #[inline]
256
0
    fn rem_assign(&mut self, other: &BigInt) {
257
0
        *self = &*self % other;
258
0
    }
259
}
260
forward_val_assign!(impl RemAssign for BigInt, rem_assign);
261
262
promote_all_scalars!(impl Rem for BigInt, rem);
263
promote_all_scalars_assign!(impl RemAssign for BigInt, rem_assign);
264
forward_all_scalar_binop_to_val_val!(impl Rem<u32> for BigInt, rem);
265
forward_all_scalar_binop_to_val_val!(impl Rem<u64> for BigInt, rem);
266
forward_all_scalar_binop_to_val_val!(impl Rem<u128> for BigInt, rem);
267
268
impl Rem<u32> for BigInt {
269
    type Output = BigInt;
270
271
    #[inline]
272
0
    fn rem(self, other: u32) -> BigInt {
273
0
        BigInt::from_biguint(self.sign, self.data % other)
274
0
    }
275
}
276
277
impl RemAssign<u32> for BigInt {
278
    #[inline]
279
0
    fn rem_assign(&mut self, other: u32) {
280
0
        self.data %= other;
281
0
        if self.data.is_zero() {
282
0
            self.sign = NoSign;
283
0
        }
284
0
    }
285
}
286
287
impl Rem<BigInt> for u32 {
288
    type Output = BigInt;
289
290
    #[inline]
291
0
    fn rem(self, other: BigInt) -> BigInt {
292
0
        BigInt::from(self % other.data)
293
0
    }
294
}
295
296
impl Rem<u64> for BigInt {
297
    type Output = BigInt;
298
299
    #[inline]
300
0
    fn rem(self, other: u64) -> BigInt {
301
0
        BigInt::from_biguint(self.sign, self.data % other)
302
0
    }
303
}
304
305
impl RemAssign<u64> for BigInt {
306
    #[inline]
307
0
    fn rem_assign(&mut self, other: u64) {
308
0
        self.data %= other;
309
0
        if self.data.is_zero() {
310
0
            self.sign = NoSign;
311
0
        }
312
0
    }
313
}
314
315
impl Rem<BigInt> for u64 {
316
    type Output = BigInt;
317
318
    #[inline]
319
0
    fn rem(self, other: BigInt) -> BigInt {
320
0
        BigInt::from(self % other.data)
321
0
    }
322
}
323
324
impl Rem<u128> for BigInt {
325
    type Output = BigInt;
326
327
    #[inline]
328
0
    fn rem(self, other: u128) -> BigInt {
329
0
        BigInt::from_biguint(self.sign, self.data % other)
330
0
    }
331
}
332
333
impl RemAssign<u128> for BigInt {
334
    #[inline]
335
0
    fn rem_assign(&mut self, other: u128) {
336
0
        self.data %= other;
337
0
        if self.data.is_zero() {
338
0
            self.sign = NoSign;
339
0
        }
340
0
    }
341
}
342
343
impl Rem<BigInt> for u128 {
344
    type Output = BigInt;
345
346
    #[inline]
347
0
    fn rem(self, other: BigInt) -> BigInt {
348
0
        BigInt::from(self % other.data)
349
0
    }
350
}
351
352
forward_all_scalar_binop_to_val_val!(impl Rem<i32> for BigInt, rem);
353
forward_all_scalar_binop_to_val_val!(impl Rem<i64> for BigInt, rem);
354
forward_all_scalar_binop_to_val_val!(impl Rem<i128> for BigInt, rem);
355
356
impl Rem<i32> for BigInt {
357
    type Output = BigInt;
358
359
    #[inline]
360
0
    fn rem(self, other: i32) -> BigInt {
361
0
        self % other.unsigned_abs()
362
0
    }
363
}
364
365
impl RemAssign<i32> for BigInt {
366
    #[inline]
367
0
    fn rem_assign(&mut self, other: i32) {
368
0
        *self %= other.unsigned_abs();
369
0
    }
370
}
371
372
impl Rem<BigInt> for i32 {
373
    type Output = BigInt;
374
375
    #[inline]
376
0
    fn rem(self, other: BigInt) -> BigInt {
377
0
        match self.checked_uabs() {
378
0
            Positive(u) => u % other,
379
0
            Negative(u) => -(u % other),
380
        }
381
0
    }
382
}
383
384
impl Rem<i64> for BigInt {
385
    type Output = BigInt;
386
387
    #[inline]
388
0
    fn rem(self, other: i64) -> BigInt {
389
0
        self % other.unsigned_abs()
390
0
    }
391
}
392
393
impl RemAssign<i64> for BigInt {
394
    #[inline]
395
0
    fn rem_assign(&mut self, other: i64) {
396
0
        *self %= other.unsigned_abs();
397
0
    }
398
}
399
400
impl Rem<BigInt> for i64 {
401
    type Output = BigInt;
402
403
    #[inline]
404
0
    fn rem(self, other: BigInt) -> BigInt {
405
0
        match self.checked_uabs() {
406
0
            Positive(u) => u % other,
407
0
            Negative(u) => -(u % other),
408
        }
409
0
    }
410
}
411
412
impl Rem<i128> for BigInt {
413
    type Output = BigInt;
414
415
    #[inline]
416
0
    fn rem(self, other: i128) -> BigInt {
417
0
        self % other.unsigned_abs()
418
0
    }
419
}
420
421
impl RemAssign<i128> for BigInt {
422
    #[inline]
423
0
    fn rem_assign(&mut self, other: i128) {
424
0
        *self %= other.unsigned_abs();
425
0
    }
426
}
427
428
impl Rem<BigInt> for i128 {
429
    type Output = BigInt;
430
431
    #[inline]
432
0
    fn rem(self, other: BigInt) -> BigInt {
433
0
        match self.checked_uabs() {
434
0
            Positive(u) => u % other,
435
0
            Negative(u) => -(u % other),
436
        }
437
0
    }
438
}
439
440
impl CheckedDiv for BigInt {
441
    #[inline]
442
0
    fn checked_div(&self, v: &BigInt) -> Option<BigInt> {
443
0
        if v.is_zero() {
444
0
            return None;
445
0
        }
446
0
        Some(self.div(v))
447
0
    }
448
}
449
450
impl CheckedEuclid for BigInt {
451
    #[inline]
452
0
    fn checked_div_euclid(&self, v: &BigInt) -> Option<BigInt> {
453
0
        if v.is_zero() {
454
0
            return None;
455
0
        }
456
0
        Some(self.div_euclid(v))
457
0
    }
458
459
    #[inline]
460
0
    fn checked_rem_euclid(&self, v: &BigInt) -> Option<BigInt> {
461
0
        if v.is_zero() {
462
0
            return None;
463
0
        }
464
0
        Some(self.rem_euclid(v))
465
0
    }
466
467
0
    fn checked_div_rem_euclid(&self, v: &Self) -> Option<(Self, Self)> {
468
0
        Some(self.div_rem_euclid(v))
469
0
    }
470
}
471
472
impl Euclid for BigInt {
473
    #[inline]
474
0
    fn div_euclid(&self, v: &BigInt) -> BigInt {
475
0
        let (q, r) = self.div_rem(v);
476
0
        if r.is_negative() {
477
0
            if v.is_positive() {
478
0
                q - 1
479
            } else {
480
0
                q + 1
481
            }
482
        } else {
483
0
            q
484
        }
485
0
    }
486
487
    #[inline]
488
0
    fn rem_euclid(&self, v: &BigInt) -> BigInt {
489
0
        let r = self % v;
490
0
        if r.is_negative() {
491
0
            if v.is_positive() {
492
0
                r + v
493
            } else {
494
0
                r - v
495
            }
496
        } else {
497
0
            r
498
        }
499
0
    }
500
501
0
    fn div_rem_euclid(&self, v: &Self) -> (Self, Self) {
502
0
        let (q, r) = self.div_rem(v);
503
0
        if r.is_negative() {
504
0
            if v.is_positive() {
505
0
                (q - 1, r + v)
506
            } else {
507
0
                (q + 1, r - v)
508
            }
509
        } else {
510
0
            (q, r)
511
        }
512
0
    }
513
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/bigint/multiplication.rs
Line
Count
Source
1
use super::CheckedUnsignedAbs::{Negative, Positive};
2
use super::Sign::{self, Minus, NoSign, Plus};
3
use super::{BigInt, UnsignedAbs};
4
5
use crate::{IsizePromotion, UsizePromotion};
6
7
use core::iter::Product;
8
use core::ops::{Mul, MulAssign};
9
use num_traits::{CheckedMul, One, Zero};
10
11
impl Mul<Sign> for Sign {
12
    type Output = Sign;
13
14
    #[inline]
15
197k
    fn mul(self, other: Sign) -> Sign {
16
197k
        match (self, other) {
17
7.43k
            (NoSign, _) | (_, NoSign) => NoSign,
18
151k
            (Plus, Plus) | (Minus, Minus) => Plus,
19
38.6k
            (Plus, Minus) | (Minus, Plus) => Minus,
20
        }
21
197k
    }
_RNvXNtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB4_4SignNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mulCs4RkbDk9WRL5_5clvmr
Line
Count
Source
15
9.57k
    fn mul(self, other: Sign) -> Sign {
16
9.57k
        match (self, other) {
17
0
            (NoSign, _) | (_, NoSign) => NoSign,
18
5.39k
            (Plus, Plus) | (Minus, Minus) => Plus,
19
4.18k
            (Plus, Minus) | (Minus, Plus) => Minus,
20
        }
21
9.57k
    }
_RNvXNtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB4_4SignNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mulB6_
Line
Count
Source
15
187k
    fn mul(self, other: Sign) -> Sign {
16
187k
        match (self, other) {
17
7.43k
            (NoSign, _) | (_, NoSign) => NoSign,
18
145k
            (Plus, Plus) | (Minus, Minus) => Plus,
19
34.4k
            (Plus, Minus) | (Minus, Plus) => Minus,
20
        }
21
187k
    }
22
}
23
24
macro_rules! impl_mul {
25
    ($(impl Mul<$Other:ty> for $Self:ty;)*) => {$(
26
        impl Mul<$Other> for $Self {
27
            type Output = BigInt;
28
29
            #[inline]
30
45.3k
            fn mul(self, other: $Other) -> BigInt {
31
45.3k
                // automatically match value/ref
32
45.3k
                let BigInt { data: x, .. } = self;
33
45.3k
                let BigInt { data: y, .. } = other;
34
45.3k
                BigInt::from_biguint(self.sign * other.sign, x * y)
35
45.3k
            }
_RNvXsc_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mulB9_
Line
Count
Source
30
18.1k
            fn mul(self, other: $Other) -> BigInt {
31
18.1k
                // automatically match value/ref
32
18.1k
                let BigInt { data: x, .. } = self;
33
18.1k
                let BigInt { data: y, .. } = other;
34
18.1k
                BigInt::from_biguint(self.sign * other.sign, x * y)
35
18.1k
            }
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulBX_E3mulB9_
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRBW_E3mulB9_
_RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mulB9_
Line
Count
Source
30
27.1k
            fn mul(self, other: $Other) -> BigInt {
31
27.1k
                // automatically match value/ref
32
27.1k
                let BigInt { data: x, .. } = self;
33
27.1k
                let BigInt { data: y, .. } = other;
34
27.1k
                BigInt::from_biguint(self.sign * other.sign, x * y)
35
27.1k
            }
36
        }
37
    )*}
38
}
39
impl_mul! {
40
    impl Mul<BigInt> for BigInt;
41
    impl Mul<BigInt> for &BigInt;
42
    impl Mul<&BigInt> for BigInt;
43
    impl Mul<&BigInt> for &BigInt;
44
}
45
46
macro_rules! impl_mul_assign {
47
    ($(impl MulAssign<$Other:ty> for BigInt;)*) => {$(
48
        impl MulAssign<$Other> for BigInt {
49
            #[inline]
50
18.6k
            fn mul_assign(&mut self, other: $Other) {
51
18.6k
                // automatically match value/ref
52
18.6k
                let BigInt { data: y, .. } = other;
53
18.6k
                self.data *= y;
54
18.6k
                if self.data.is_zero() {
55
9.07k
                    self.sign = NoSign;
56
9.57k
                } else {
57
9.57k
                    self.sign = self.sign * other.sign;
58
9.57k
                }
59
18.6k
            }
_RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssign10mul_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
50
18.6k
            fn mul_assign(&mut self, other: $Other) {
51
18.6k
                // automatically match value/ref
52
18.6k
                let BigInt { data: y, .. } = other;
53
18.6k
                self.data *= y;
54
18.6k
                if self.data.is_zero() {
55
9.07k
                    self.sign = NoSign;
56
9.57k
                } else {
57
9.57k
                    self.sign = self.sign * other.sign;
58
9.57k
                }
59
18.6k
            }
Unexecuted instantiation: _RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssign10mul_assignB9_
Unexecuted instantiation: _RNvXsh_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignRBW_E10mul_assignB9_
60
        }
61
    )*}
62
}
63
impl_mul_assign! {
64
    impl MulAssign<BigInt> for BigInt;
65
    impl MulAssign<&BigInt> for BigInt;
66
}
67
68
promote_all_scalars!(impl Mul for BigInt, mul);
69
promote_all_scalars_assign!(impl MulAssign for BigInt, mul_assign);
70
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<u32> for BigInt, mul);
71
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<u64> for BigInt, mul);
72
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<u128> for BigInt, mul);
73
74
impl Mul<u32> for BigInt {
75
    type Output = BigInt;
76
77
    #[inline]
78
18.1k
    fn mul(self, other: u32) -> BigInt {
79
18.1k
        BigInt::from_biguint(self.sign, self.data * other)
80
18.1k
    }
81
}
82
83
impl MulAssign<u32> for BigInt {
84
    #[inline]
85
19.5k
    fn mul_assign(&mut self, other: u32) {
86
19.5k
        self.data *= other;
87
19.5k
        if self.data.is_zero() {
88
14.2k
            self.sign = NoSign;
89
14.2k
        }
90
19.5k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignmE10mul_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
85
19.5k
    fn mul_assign(&mut self, other: u32) {
86
19.5k
        self.data *= other;
87
19.5k
        if self.data.is_zero() {
88
14.2k
            self.sign = NoSign;
89
14.2k
        }
90
19.5k
    }
Unexecuted instantiation: _RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignmE10mul_assignB9_
91
}
92
93
impl Mul<u64> for BigInt {
94
    type Output = BigInt;
95
96
    #[inline]
97
0
    fn mul(self, other: u64) -> BigInt {
98
0
        BigInt::from_biguint(self.sign, self.data * other)
99
0
    }
100
}
101
102
impl MulAssign<u64> for BigInt {
103
    #[inline]
104
0
    fn mul_assign(&mut self, other: u64) {
105
0
        self.data *= other;
106
0
        if self.data.is_zero() {
107
0
            self.sign = NoSign;
108
0
        }
109
0
    }
110
}
111
112
impl Mul<u128> for BigInt {
113
    type Output = BigInt;
114
115
    #[inline]
116
0
    fn mul(self, other: u128) -> BigInt {
117
0
        BigInt::from_biguint(self.sign, self.data * other)
118
0
    }
119
}
120
121
impl MulAssign<u128> for BigInt {
122
    #[inline]
123
0
    fn mul_assign(&mut self, other: u128) {
124
0
        self.data *= other;
125
0
        if self.data.is_zero() {
126
0
            self.sign = NoSign;
127
0
        }
128
0
    }
129
}
130
131
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<i32> for BigInt, mul);
132
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<i64> for BigInt, mul);
133
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<i128> for BigInt, mul);
134
135
impl Mul<i32> for BigInt {
136
    type Output = BigInt;
137
138
    #[inline]
139
18.1k
    fn mul(self, other: i32) -> BigInt {
140
18.1k
        match other.checked_uabs() {
141
18.1k
            Positive(u) => self * u,
142
0
            Negative(u) => -self * u,
143
        }
144
18.1k
    }
145
}
146
147
impl MulAssign<i32> for BigInt {
148
    #[inline]
149
0
    fn mul_assign(&mut self, other: i32) {
150
0
        match other.checked_uabs() {
151
0
            Positive(u) => *self *= u,
152
0
            Negative(u) => {
153
0
                self.sign = -self.sign;
154
0
                self.data *= u;
155
0
            }
156
        }
157
0
    }
158
}
159
160
impl Mul<i64> for BigInt {
161
    type Output = BigInt;
162
163
    #[inline]
164
0
    fn mul(self, other: i64) -> BigInt {
165
0
        match other.checked_uabs() {
166
0
            Positive(u) => self * u,
167
0
            Negative(u) => -self * u,
168
        }
169
0
    }
170
}
171
172
impl MulAssign<i64> for BigInt {
173
    #[inline]
174
0
    fn mul_assign(&mut self, other: i64) {
175
0
        match other.checked_uabs() {
176
0
            Positive(u) => *self *= u,
177
0
            Negative(u) => {
178
0
                self.sign = -self.sign;
179
0
                self.data *= u;
180
0
            }
181
        }
182
0
    }
183
}
184
185
impl Mul<i128> for BigInt {
186
    type Output = BigInt;
187
188
    #[inline]
189
0
    fn mul(self, other: i128) -> BigInt {
190
0
        match other.checked_uabs() {
191
0
            Positive(u) => self * u,
192
0
            Negative(u) => -self * u,
193
        }
194
0
    }
195
}
196
197
impl MulAssign<i128> for BigInt {
198
    #[inline]
199
0
    fn mul_assign(&mut self, other: i128) {
200
0
        match other.checked_uabs() {
201
0
            Positive(u) => *self *= u,
202
0
            Negative(u) => {
203
0
                self.sign = -self.sign;
204
0
                self.data *= u;
205
0
            }
206
        }
207
0
    }
208
}
209
210
impl CheckedMul for BigInt {
211
    #[inline]
212
0
    fn checked_mul(&self, v: &BigInt) -> Option<BigInt> {
213
0
        Some(self.mul(v))
214
0
    }
215
}
216
217
impl_product_iter_type!(BigInt);
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/bigint/power.rs
Line
Count
Source
1
use super::BigInt;
2
use super::Sign::{self, Minus, Plus};
3
4
use crate::BigUint;
5
6
use num_integer::Integer;
7
use num_traits::{Pow, Signed, Zero};
8
9
/// Help function for pow
10
///
11
/// Computes the effect of the exponent on the sign.
12
#[inline]
13
0
fn powsign<T: Integer>(sign: Sign, other: &T) -> Sign {
14
0
    if other.is_zero() {
15
0
        Plus
16
0
    } else if sign != Minus || other.is_odd() {
17
0
        sign
18
    } else {
19
0
        -sign
20
    }
21
0
}
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5power7powsignNtNtB6_7biguint7BigUintEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5power7powsignhEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5power7powsignjEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5power7powsignmEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5power7powsignoEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5power7powsigntEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5power7powsignyEB6_
22
23
macro_rules! pow_impl {
24
    ($T:ty) => {
25
        impl Pow<$T> for BigInt {
26
            type Output = BigInt;
27
28
            #[inline]
29
0
            fn pow(self, rhs: $T) -> BigInt {
30
0
                BigInt::from_biguint(powsign(self.sign, &rhs), self.data.pow(rhs))
31
0
            }
Unexecuted instantiation: _RNvXNtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB4_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowhE3powB6_
Unexecuted instantiation: _RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowtE3powB9_
Unexecuted instantiation: _RNvXs6_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowmE3powB9_
Unexecuted instantiation: _RNvXsa_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowyE3powB9_
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowjE3powB9_
Unexecuted instantiation: _RNvXsi_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowoE3powB9_
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowNtNtB9_7biguint7BigUintE3powB9_
32
        }
33
34
        impl Pow<&$T> for BigInt {
35
            type Output = BigInt;
36
37
            #[inline]
38
0
            fn pow(self, rhs: &$T) -> BigInt {
39
0
                BigInt::from_biguint(powsign(self.sign, rhs), self.data.pow(rhs))
40
0
            }
Unexecuted instantiation: _RNvXs_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB6_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRtE3powB9_
Unexecuted instantiation: _RNvXs7_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRmE3powB9_
Unexecuted instantiation: _RNvXsb_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRyE3powB9_
Unexecuted instantiation: _RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRjE3powB9_
Unexecuted instantiation: _RNvXsj_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRoE3powB9_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRNtNtB9_7biguint7BigUintE3powB9_
41
        }
42
43
        impl Pow<$T> for &BigInt {
44
            type Output = BigInt;
45
46
            #[inline]
47
0
            fn pow(self, rhs: $T) -> BigInt {
48
0
                BigInt::from_biguint(powsign(self.sign, &rhs), Pow::pow(&self.data, rhs))
49
0
            }
Unexecuted instantiation: _RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowhE3powB9_
Unexecuted instantiation: _RNvXs4_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowtE3powB9_
Unexecuted instantiation: _RNvXs8_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowmE3powB9_
Unexecuted instantiation: _RNvXsc_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowyE3powB9_
Unexecuted instantiation: _RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowjE3powB9_
Unexecuted instantiation: _RNvXsk_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowoE3powB9_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowNtNtB9_7biguint7BigUintE3powB9_
50
        }
51
52
        impl Pow<&$T> for &BigInt {
53
            type Output = BigInt;
54
55
            #[inline]
56
0
            fn pow(self, rhs: &$T) -> BigInt {
57
0
                BigInt::from_biguint(powsign(self.sign, rhs), Pow::pow(&self.data, rhs))
58
0
            }
Unexecuted instantiation: _RNvXs1_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRhE3powB9_
Unexecuted instantiation: _RNvXs5_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRtE3powB9_
Unexecuted instantiation: _RNvXs9_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRmE3powB9_
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRyE3powB9_
Unexecuted instantiation: _RNvXsh_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRjE3powB9_
Unexecuted instantiation: _RNvXsl_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRoE3powB9_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint6bigint5powerRNtB7_6BigIntINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRNtNtB9_7biguint7BigUintE3powB9_
59
        }
60
    };
61
}
62
63
pow_impl!(u8);
64
pow_impl!(u16);
65
pow_impl!(u32);
66
pow_impl!(u64);
67
pow_impl!(usize);
68
pow_impl!(u128);
69
pow_impl!(BigUint);
70
71
5.03k
pub(super) fn modpow(x: &BigInt, exponent: &BigInt, modulus: &BigInt) -> BigInt {
72
5.03k
    assert!(
73
5.03k
        !exponent.is_negative(),
74
0
        "negative exponentiation is not supported!"
75
    );
76
5.03k
    assert!(
77
5.03k
        !modulus.is_zero(),
78
0
        "attempt to calculate with zero modulus!"
79
    );
80
81
5.03k
    let result = x.data.modpow(&exponent.data, &modulus.data);
82
5.03k
    if result.is_zero() {
83
1.57k
        return BigInt::ZERO;
84
3.45k
    }
85
86
    // The sign of the result follows the modulus, like `mod_floor`.
87
3.45k
    let (sign, mag) = match (x.is_negative() && exponent.is_odd(), modulus.is_negative()) {
88
1.62k
        (false, false) => (Plus, result),
89
494
        (true, false) => (Plus, &modulus.data - result),
90
1.09k
        (false, true) => (Minus, &modulus.data - result),
91
243
        (true, true) => (Minus, result),
92
    };
93
3.45k
    BigInt::from_biguint(sign, mag)
94
5.03k
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/bigint/shift.rs
Line
Count
Source
1
use super::BigInt;
2
use super::Sign::NoSign;
3
4
use core::ops::{Shl, ShlAssign, Shr, ShrAssign};
5
use num_traits::{PrimInt, Signed, Zero};
6
7
macro_rules! impl_shift {
8
    (@ref $Shx:ident :: $shx:ident, $ShxAssign:ident :: $shx_assign:ident, $rhs:ty) => {
9
        impl $Shx<&$rhs> for BigInt {
10
            type Output = BigInt;
11
12
            #[inline]
13
0
            fn $shx(self, rhs: &$rhs) -> BigInt {
14
0
                $Shx::$shx(self, *rhs)
15
0
            }
Unexecuted instantiation: _RNvXsy_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRhE3shlB9_
Unexecuted instantiation: _RNvXsB_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRhE3shrB9_
Unexecuted instantiation: _RNvXsE_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRtE3shlB9_
Unexecuted instantiation: _RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRtE3shrB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRmE3shlB9_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRmE3shrB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRyE3shlB9_
Unexecuted instantiation: _RNvXsT_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRyE3shrB9_
Unexecuted instantiation: _RNvXsW_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRoE3shlB9_
Unexecuted instantiation: _RNvXsZ_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRoE3shrB9_
Unexecuted instantiation: _RNvXs12_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRjE3shlBa_
Unexecuted instantiation: _RNvXs15_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRjE3shrBa_
Unexecuted instantiation: _RNvXs1I_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRaE3shlBa_
Unexecuted instantiation: _RNvXs1L_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRaE3shrBa_
Unexecuted instantiation: _RNvXs1O_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRsE3shlBa_
Unexecuted instantiation: _RNvXs1R_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRsE3shrBa_
Unexecuted instantiation: _RNvXs1U_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRlE3shlBa_
Unexecuted instantiation: _RNvXs1X_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRlE3shrBa_
Unexecuted instantiation: _RNvXs20_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRxE3shlBa_
Unexecuted instantiation: _RNvXs23_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRxE3shrBa_
Unexecuted instantiation: _RNvXs26_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRnE3shlBa_
Unexecuted instantiation: _RNvXs29_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRnE3shrBa_
Unexecuted instantiation: _RNvXs2c_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRiE3shlBa_
Unexecuted instantiation: _RNvXs2f_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRiE3shrBa_
16
        }
17
        impl $Shx<&$rhs> for &BigInt {
18
            type Output = BigInt;
19
20
            #[inline]
21
0
            fn $shx(self, rhs: &$rhs) -> BigInt {
22
0
                $Shx::$shx(self, *rhs)
23
0
            }
Unexecuted instantiation: _RNvXsz_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRhE3shlB9_
Unexecuted instantiation: _RNvXsC_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRhE3shrB9_
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRtE3shlB9_
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRtE3shrB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRmE3shlB9_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRmE3shrB9_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRyE3shlB9_
Unexecuted instantiation: _RNvXsU_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRyE3shrB9_
Unexecuted instantiation: _RNvXsX_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRoE3shlB9_
Unexecuted instantiation: _RNvXs10_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRoE3shrBa_
Unexecuted instantiation: _RNvXs13_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRjE3shlBa_
Unexecuted instantiation: _RNvXs16_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRjE3shrBa_
Unexecuted instantiation: _RNvXs1J_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRaE3shlBa_
Unexecuted instantiation: _RNvXs1M_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRaE3shrBa_
Unexecuted instantiation: _RNvXs1P_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRsE3shlBa_
Unexecuted instantiation: _RNvXs1S_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRsE3shrBa_
Unexecuted instantiation: _RNvXs1V_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRlE3shlBa_
Unexecuted instantiation: _RNvXs1Y_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRlE3shrBa_
Unexecuted instantiation: _RNvXs21_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRxE3shlBa_
Unexecuted instantiation: _RNvXs24_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRxE3shrBa_
Unexecuted instantiation: _RNvXs27_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRnE3shlBa_
Unexecuted instantiation: _RNvXs2a_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRnE3shrBa_
Unexecuted instantiation: _RNvXs2d_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRiE3shlBa_
Unexecuted instantiation: _RNvXs2g_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRiE3shrBa_
24
        }
25
        impl $ShxAssign<&$rhs> for BigInt {
26
            #[inline]
27
0
            fn $shx_assign(&mut self, rhs: &$rhs) {
28
0
                $ShxAssign::$shx_assign(self, *rhs);
29
0
            }
Unexecuted instantiation: _RNvXsA_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRhE10shl_assignB9_
Unexecuted instantiation: _RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRhE10shr_assignB9_
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRtE10shl_assignB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRtE10shr_assignB9_
Unexecuted instantiation: _RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRmE10shl_assignB9_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRmE10shr_assignB9_
Unexecuted instantiation: _RNvXsS_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRyE10shl_assignB9_
Unexecuted instantiation: _RNvXsV_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRyE10shr_assignB9_
Unexecuted instantiation: _RNvXsY_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRoE10shl_assignB9_
Unexecuted instantiation: _RNvXs11_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRoE10shr_assignBa_
Unexecuted instantiation: _RNvXs14_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRjE10shl_assignBa_
Unexecuted instantiation: _RNvXs17_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRjE10shr_assignBa_
Unexecuted instantiation: _RNvXs1K_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRaE10shl_assignBa_
Unexecuted instantiation: _RNvXs1N_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRaE10shr_assignBa_
Unexecuted instantiation: _RNvXs1Q_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRsE10shl_assignBa_
Unexecuted instantiation: _RNvXs1T_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRsE10shr_assignBa_
Unexecuted instantiation: _RNvXs1W_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRlE10shl_assignBa_
Unexecuted instantiation: _RNvXs1Z_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRlE10shr_assignBa_
Unexecuted instantiation: _RNvXs22_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRxE10shl_assignBa_
Unexecuted instantiation: _RNvXs25_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRxE10shr_assignBa_
Unexecuted instantiation: _RNvXs28_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRnE10shl_assignBa_
Unexecuted instantiation: _RNvXs2b_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRnE10shr_assignBa_
Unexecuted instantiation: _RNvXs2e_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRiE10shl_assignBa_
Unexecuted instantiation: _RNvXs2h_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRiE10shr_assignBa_
30
        }
31
    };
32
    ($($rhs:ty),+) => {$(
33
        impl Shl<$rhs> for BigInt {
34
            type Output = BigInt;
35
36
            #[inline]
37
21.5k
            fn shl(self, rhs: $rhs) -> BigInt {
38
21.5k
                BigInt::from_biguint(self.sign, self.data << rhs)
39
21.5k
            }
_RNvXs1k_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShllE3shlCs4RkbDk9WRL5_5clvmr
Line
Count
Source
37
21.5k
            fn shl(self, rhs: $rhs) -> BigInt {
38
21.5k
                BigInt::from_biguint(self.sign, self.data << rhs)
39
21.5k
            }
Unexecuted instantiation: _RNvXNtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB4_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlhE3shlB6_
Unexecuted instantiation: _RNvXs4_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShltE3shlB9_
Unexecuted instantiation: _RNvXsa_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlmE3shlB9_
Unexecuted instantiation: _RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlyE3shlB9_
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShloE3shlB9_
Unexecuted instantiation: _RNvXss_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShljE3shlB9_
Unexecuted instantiation: _RNvXs18_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlaE3shlBa_
Unexecuted instantiation: _RNvXs1e_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlsE3shlBa_
Unexecuted instantiation: _RNvXs1k_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShllE3shlBa_
Unexecuted instantiation: _RNvXs1q_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlxE3shlBa_
Unexecuted instantiation: _RNvXs1w_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlnE3shlBa_
Unexecuted instantiation: _RNvXs1C_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShliE3shlBa_
40
        }
41
        impl Shl<$rhs> for &BigInt {
42
            type Output = BigInt;
43
44
            #[inline]
45
9.06k
            fn shl(self, rhs: $rhs) -> BigInt {
46
9.06k
                BigInt::from_biguint(self.sign, &self.data << rhs)
47
9.06k
            }
_RNvXs1l_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShllE3shlBa_
Line
Count
Source
45
9.06k
            fn shl(self, rhs: $rhs) -> BigInt {
46
9.06k
                BigInt::from_biguint(self.sign, &self.data << rhs)
47
9.06k
            }
Unexecuted instantiation: _RNvXs_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB6_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlhE3shlB8_
Unexecuted instantiation: _RNvXs5_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShltE3shlB9_
Unexecuted instantiation: _RNvXsb_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlmE3shlB9_
Unexecuted instantiation: _RNvXsh_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlyE3shlB9_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShloE3shlB9_
Unexecuted instantiation: _RNvXst_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShljE3shlB9_
Unexecuted instantiation: _RNvXs19_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlaE3shlBa_
Unexecuted instantiation: _RNvXs1f_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlsE3shlBa_
Unexecuted instantiation: _RNvXs1r_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlxE3shlBa_
Unexecuted instantiation: _RNvXs1x_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlnE3shlBa_
Unexecuted instantiation: _RNvXs1D_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShliE3shlBa_
48
        }
49
        impl ShlAssign<$rhs> for BigInt {
50
            #[inline]
51
0
            fn shl_assign(&mut self, rhs: $rhs) {
52
0
                self.data <<= rhs
53
0
            }
Unexecuted instantiation: _RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignhE10shl_assignB9_
Unexecuted instantiation: _RNvXs6_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssigntE10shl_assignB9_
Unexecuted instantiation: _RNvXsc_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignmE10shl_assignB9_
Unexecuted instantiation: _RNvXsi_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignyE10shl_assignB9_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignoE10shl_assignB9_
Unexecuted instantiation: _RNvXsu_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignjE10shl_assignB9_
Unexecuted instantiation: _RNvXs1a_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignaE10shl_assignBa_
Unexecuted instantiation: _RNvXs1g_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignsE10shl_assignBa_
Unexecuted instantiation: _RNvXs1m_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignlE10shl_assignBa_
Unexecuted instantiation: _RNvXs1s_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignxE10shl_assignBa_
Unexecuted instantiation: _RNvXs1y_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignnE10shl_assignBa_
Unexecuted instantiation: _RNvXs1E_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssigniE10shl_assignBa_
54
        }
55
        impl_shift! { @ref Shl::shl, ShlAssign::shl_assign, $rhs }
56
57
        impl Shr<$rhs> for BigInt {
58
            type Output = BigInt;
59
60
            #[inline]
61
20.3k
            fn shr(self, rhs: $rhs) -> BigInt {
62
20.3k
                let round_down = shr_round_down(&self, rhs);
63
20.3k
                let data = self.data >> rhs;
64
20.3k
                let data = if round_down { data + 1u8 } else { data };
65
20.3k
                BigInt::from_biguint(self.sign, data)
66
20.3k
            }
_RNvXs1n_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrlE3shrCs4RkbDk9WRL5_5clvmr
Line
Count
Source
61
2.24k
            fn shr(self, rhs: $rhs) -> BigInt {
62
2.24k
                let round_down = shr_round_down(&self, rhs);
63
2.24k
                let data = self.data >> rhs;
64
2.24k
                let data = if round_down { data + 1u8 } else { data };
65
2.24k
                BigInt::from_biguint(self.sign, data)
66
2.24k
            }
Unexecuted instantiation: _RNvXs1_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrhE3shrB9_
Unexecuted instantiation: _RNvXs7_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrtE3shrB9_
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrmE3shrB9_
Unexecuted instantiation: _RNvXsj_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShryE3shrB9_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShroE3shrB9_
Unexecuted instantiation: _RNvXsv_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrjE3shrB9_
Unexecuted instantiation: _RNvXs1b_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShraE3shrBa_
Unexecuted instantiation: _RNvXs1h_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrsE3shrBa_
_RNvXs1n_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrlE3shrBa_
Line
Count
Source
61
18.1k
            fn shr(self, rhs: $rhs) -> BigInt {
62
18.1k
                let round_down = shr_round_down(&self, rhs);
63
18.1k
                let data = self.data >> rhs;
64
18.1k
                let data = if round_down { data + 1u8 } else { data };
65
18.1k
                BigInt::from_biguint(self.sign, data)
66
18.1k
            }
Unexecuted instantiation: _RNvXs1t_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrxE3shrBa_
Unexecuted instantiation: _RNvXs1z_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrnE3shrBa_
Unexecuted instantiation: _RNvXs1F_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShriE3shrBa_
67
        }
68
        impl Shr<$rhs> for &BigInt {
69
            type Output = BigInt;
70
71
            #[inline]
72
0
            fn shr(self, rhs: $rhs) -> BigInt {
73
0
                let round_down = shr_round_down(self, rhs);
74
0
                let data = &self.data >> rhs;
75
0
                let data = if round_down { data + 1u8 } else { data };
76
0
                BigInt::from_biguint(self.sign, data)
77
0
            }
Unexecuted instantiation: _RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrhE3shrB9_
Unexecuted instantiation: _RNvXs8_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrtE3shrB9_
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrmE3shrB9_
Unexecuted instantiation: _RNvXsk_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShryE3shrB9_
Unexecuted instantiation: _RNvXsq_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShroE3shrB9_
Unexecuted instantiation: _RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrjE3shrB9_
Unexecuted instantiation: _RNvXs1c_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShraE3shrBa_
Unexecuted instantiation: _RNvXs1i_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrsE3shrBa_
Unexecuted instantiation: _RNvXs1o_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrlE3shrBa_
Unexecuted instantiation: _RNvXs1u_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrxE3shrBa_
Unexecuted instantiation: _RNvXs1A_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrnE3shrBa_
Unexecuted instantiation: _RNvXs1G_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShriE3shrBa_
78
        }
79
        impl ShrAssign<$rhs> for BigInt {
80
            #[inline]
81
0
            fn shr_assign(&mut self, rhs: $rhs) {
82
0
                let round_down = shr_round_down(self, rhs);
83
0
                self.data >>= rhs;
84
0
                if round_down {
85
0
                    self.data += 1u8;
86
0
                } else if self.data.is_zero() {
87
0
                    self.sign = NoSign;
88
0
                }
89
0
            }
Unexecuted instantiation: _RNvXs3_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignhE10shr_assignB9_
Unexecuted instantiation: _RNvXs9_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssigntE10shr_assignB9_
Unexecuted instantiation: _RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignmE10shr_assignB9_
Unexecuted instantiation: _RNvXsl_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignyE10shr_assignB9_
Unexecuted instantiation: _RNvXsr_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignoE10shr_assignB9_
Unexecuted instantiation: _RNvXsx_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignjE10shr_assignB9_
Unexecuted instantiation: _RNvXs1d_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignaE10shr_assignBa_
Unexecuted instantiation: _RNvXs1j_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignsE10shr_assignBa_
Unexecuted instantiation: _RNvXs1p_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignlE10shr_assignBa_
Unexecuted instantiation: _RNvXs1v_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignxE10shr_assignBa_
Unexecuted instantiation: _RNvXs1B_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignnE10shr_assignBa_
Unexecuted instantiation: _RNvXs1H_NtNtCs72ekIXsOXFl_10num_bigint6bigint5shiftNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssigniE10shr_assignBa_
90
        }
91
        impl_shift! { @ref Shr::shr, ShrAssign::shr_assign, $rhs }
92
    )*};
93
}
94
95
impl_shift! { u8, u16, u32, u64, u128, usize }
96
impl_shift! { i8, i16, i32, i64, i128, isize }
97
98
// Negative values need a rounding adjustment if there are any ones in the
99
// bits that are getting shifted out.
100
20.3k
fn shr_round_down<T: PrimInt>(i: &BigInt, shift: T) -> bool {
101
20.3k
    if i.is_negative() {
102
4.48k
        let zeros = i.trailing_zeros().expect("negative values are non-zero");
103
4.48k
        shift > T::zero() && shift.to_u64().map(|shift| zeros < shift).unwrap_or(true)
_RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downlE0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
103
86
        shift > T::zero() && shift.to_u64().map(|shift| zeros < shift).unwrap_or(true)
Unexecuted instantiation: _RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downaE0B8_
Unexecuted instantiation: _RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downhE0B8_
Unexecuted instantiation: _RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downiE0B8_
Unexecuted instantiation: _RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downjE0B8_
_RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downlE0B8_
Line
Count
Source
103
4.12k
        shift > T::zero() && shift.to_u64().map(|shift| zeros < shift).unwrap_or(true)
Unexecuted instantiation: _RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downmE0B8_
Unexecuted instantiation: _RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downnE0B8_
Unexecuted instantiation: _RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downoE0B8_
Unexecuted instantiation: _RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downsE0B8_
Unexecuted instantiation: _RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downtE0B8_
Unexecuted instantiation: _RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downxE0B8_
Unexecuted instantiation: _RNCINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downyE0B8_
104
    } else {
105
15.8k
        false
106
    }
107
20.3k
}
_RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downlECs4RkbDk9WRL5_5clvmr
Line
Count
Source
100
2.24k
fn shr_round_down<T: PrimInt>(i: &BigInt, shift: T) -> bool {
101
2.24k
    if i.is_negative() {
102
357
        let zeros = i.trailing_zeros().expect("negative values are non-zero");
103
357
        shift > T::zero() && shift.to_u64().map(|shift| zeros < shift).unwrap_or(true)
104
    } else {
105
1.88k
        false
106
    }
107
2.24k
}
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downaEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downhEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downiEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downjEB6_
_RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downlEB6_
Line
Count
Source
100
18.1k
fn shr_round_down<T: PrimInt>(i: &BigInt, shift: T) -> bool {
101
18.1k
    if i.is_negative() {
102
4.12k
        let zeros = i.trailing_zeros().expect("negative values are non-zero");
103
4.12k
        shift > T::zero() && shift.to_u64().map(|shift| zeros < shift).unwrap_or(true)
104
    } else {
105
13.9k
        false
106
    }
107
18.1k
}
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downmEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downnEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downoEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downsEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downtEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downxEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint6bigint5shift14shr_round_downyEB6_
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/bigint/subtraction.rs
Line
Count
Source
1
use super::CheckedUnsignedAbs::{Negative, Positive};
2
use super::Sign::{Minus, NoSign, Plus};
3
use super::{BigInt, UnsignedAbs};
4
5
use crate::{IsizePromotion, UsizePromotion};
6
7
use core::cmp::Ordering::{Equal, Greater, Less};
8
use core::mem;
9
use core::ops::{Sub, SubAssign};
10
use num_traits::CheckedSub;
11
12
// We want to forward to BigUint::sub, but it's not clear how that will go until
13
// we compare both sign and magnitude.  So we duplicate this body for every
14
// val/ref combination, deferring that decision to BigUint's own forwarding.
15
macro_rules! bigint_sub {
16
    ($a:expr, $a_owned:expr, $a_data:expr, $b:expr, $b_owned:expr, $b_data:expr) => {
17
        match ($a.sign, $b.sign) {
18
            (_, NoSign) => $a_owned,
19
            (NoSign, _) => -$b_owned,
20
            // opposite signs => keep the sign of the left with the sum of magnitudes
21
            (Plus, Minus) | (Minus, Plus) => BigInt::from_biguint($a.sign, $a_data + $b_data),
22
            // same sign => keep or toggle the sign of the left with the difference of magnitudes
23
            (Plus, Plus) | (Minus, Minus) => match $a.data.cmp(&$b.data) {
24
                Less => BigInt::from_biguint(-$a.sign, $b_data - $a_data),
25
                Greater => BigInt::from_biguint($a.sign, $a_data - $b_data),
26
                Equal => BigInt::ZERO,
27
            },
28
        }
29
    };
30
}
31
32
impl Sub<&BigInt> for &BigInt {
33
    type Output = BigInt;
34
35
    #[inline]
36
27.1k
    fn sub(self, other: &BigInt) -> BigInt {
37
27.1k
        bigint_sub!(
38
            self,
39
9.51k
            self.clone(),
40
3.45k
            &self.data,
41
            other,
42
3.35k
            other.clone(),
43
3.45k
            &other.data
44
        )
45
27.1k
    }
46
}
47
48
impl Sub<BigInt> for &BigInt {
49
    type Output = BigInt;
50
51
    #[inline]
52
16.1k
    fn sub(self, other: BigInt) -> BigInt {
53
16.1k
        bigint_sub!(self, self.clone(), &self.data, other, other, other.data)
54
16.1k
    }
_RNvXs_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB6_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubBT_E3subCs4RkbDk9WRL5_5clvmr
Line
Count
Source
52
6.53k
    fn sub(self, other: BigInt) -> BigInt {
53
6.53k
        bigint_sub!(self, self.clone(), &self.data, other, other, other.data)
54
6.53k
    }
_RNvXs_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB6_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubBT_E3subB8_
Line
Count
Source
52
9.62k
    fn sub(self, other: BigInt) -> BigInt {
53
9.62k
        bigint_sub!(self, self.clone(), &self.data, other, other, other.data)
54
9.62k
    }
55
}
56
57
impl Sub<&BigInt> for BigInt {
58
    type Output = BigInt;
59
60
    #[inline]
61
51.0k
    fn sub(self, other: &BigInt) -> BigInt {
62
51.0k
        bigint_sub!(self, self, self.data, other, other.clone(), &other.data)
63
51.0k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRBT_E3subCs4RkbDk9WRL5_5clvmr
Line
Count
Source
61
14.7k
    fn sub(self, other: &BigInt) -> BigInt {
62
14.7k
        bigint_sub!(self, self, self.data, other, other.clone(), &other.data)
63
14.7k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRBT_E3subB9_
Line
Count
Source
61
36.2k
    fn sub(self, other: &BigInt) -> BigInt {
62
36.2k
        bigint_sub!(self, self, self.data, other, other.clone(), &other.data)
63
36.2k
    }
64
}
65
66
impl Sub<BigInt> for BigInt {
67
    type Output = BigInt;
68
69
    #[inline]
70
18.1k
    fn sub(self, other: BigInt) -> BigInt {
71
18.1k
        bigint_sub!(self, self, self.data, other, other, other.data)
72
18.1k
    }
73
}
74
75
impl SubAssign<&BigInt> for BigInt {
76
    #[inline]
77
23.8k
    fn sub_assign(&mut self, other: &BigInt) {
78
23.8k
        let n = mem::replace(self, Self::ZERO);
79
23.8k
        *self = n - other;
80
23.8k
    }
_RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssignRBT_E10sub_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
77
14.7k
    fn sub_assign(&mut self, other: &BigInt) {
78
14.7k
        let n = mem::replace(self, Self::ZERO);
79
14.7k
        *self = n - other;
80
14.7k
    }
_RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssignRBT_E10sub_assignB9_
Line
Count
Source
77
9.06k
    fn sub_assign(&mut self, other: &BigInt) {
78
9.06k
        let n = mem::replace(self, Self::ZERO);
79
9.06k
        *self = n - other;
80
9.06k
    }
81
}
82
forward_val_assign!(impl SubAssign for BigInt, sub_assign);
83
84
promote_all_scalars!(impl Sub for BigInt, sub);
85
promote_all_scalars_assign!(impl SubAssign for BigInt, sub_assign);
86
forward_all_scalar_binop_to_val_val!(impl Sub<u32> for BigInt, sub);
87
forward_all_scalar_binop_to_val_val!(impl Sub<u64> for BigInt, sub);
88
forward_all_scalar_binop_to_val_val!(impl Sub<u128> for BigInt, sub);
89
90
impl Sub<u32> for BigInt {
91
    type Output = BigInt;
92
93
    #[inline]
94
38.9k
    fn sub(self, other: u32) -> BigInt {
95
38.9k
        match self.sign {
96
6.99k
            NoSign => -BigInt::from(other),
97
10.2k
            Minus => -BigInt::from(self.data + other),
98
21.6k
            Plus => match self.data.cmp(&From::from(other)) {
99
667
                Equal => Self::ZERO,
100
7.76k
                Greater => BigInt::from(self.data - other),
101
13.2k
                Less => -BigInt::from(other - self.data),
102
            },
103
        }
104
38.9k
    }
_RNvXs3_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubmE3subCs4RkbDk9WRL5_5clvmr
Line
Count
Source
94
38.3k
    fn sub(self, other: u32) -> BigInt {
95
38.3k
        match self.sign {
96
6.65k
            NoSign => -BigInt::from(other),
97
10.0k
            Minus => -BigInt::from(self.data + other),
98
21.6k
            Plus => match self.data.cmp(&From::from(other)) {
99
667
                Equal => Self::ZERO,
100
7.76k
                Greater => BigInt::from(self.data - other),
101
13.2k
                Less => -BigInt::from(other - self.data),
102
            },
103
        }
104
38.3k
    }
_RNvXs3_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubmE3subB9_
Line
Count
Source
94
558
    fn sub(self, other: u32) -> BigInt {
95
558
        match self.sign {
96
344
            NoSign => -BigInt::from(other),
97
214
            Minus => -BigInt::from(self.data + other),
98
0
            Plus => match self.data.cmp(&From::from(other)) {
99
0
                Equal => Self::ZERO,
100
0
                Greater => BigInt::from(self.data - other),
101
0
                Less => -BigInt::from(other - self.data),
102
            },
103
        }
104
558
    }
105
}
106
impl SubAssign<u32> for BigInt {
107
    #[inline]
108
37.1k
    fn sub_assign(&mut self, other: u32) {
109
37.1k
        let n = mem::replace(self, Self::ZERO);
110
37.1k
        *self = n - other;
111
37.1k
    }
_RNvXs4_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssignmE10sub_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
108
37.1k
    fn sub_assign(&mut self, other: u32) {
109
37.1k
        let n = mem::replace(self, Self::ZERO);
110
37.1k
        *self = n - other;
111
37.1k
    }
Unexecuted instantiation: _RNvXs4_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssignmE10sub_assignB9_
112
}
113
114
impl Sub<BigInt> for u32 {
115
    type Output = BigInt;
116
117
    #[inline]
118
0
    fn sub(self, other: BigInt) -> BigInt {
119
0
        -(other - self)
120
0
    }
121
}
122
123
impl Sub<BigInt> for u64 {
124
    type Output = BigInt;
125
126
    #[inline]
127
0
    fn sub(self, other: BigInt) -> BigInt {
128
0
        -(other - self)
129
0
    }
130
}
131
132
impl Sub<BigInt> for u128 {
133
    type Output = BigInt;
134
135
    #[inline]
136
0
    fn sub(self, other: BigInt) -> BigInt {
137
0
        -(other - self)
138
0
    }
139
}
140
141
impl Sub<u64> for BigInt {
142
    type Output = BigInt;
143
144
    #[inline]
145
0
    fn sub(self, other: u64) -> BigInt {
146
0
        match self.sign {
147
0
            NoSign => -BigInt::from(other),
148
0
            Minus => -BigInt::from(self.data + other),
149
0
            Plus => match self.data.cmp(&From::from(other)) {
150
0
                Equal => Self::ZERO,
151
0
                Greater => BigInt::from(self.data - other),
152
0
                Less => -BigInt::from(other - self.data),
153
            },
154
        }
155
0
    }
156
}
157
158
impl SubAssign<u64> for BigInt {
159
    #[inline]
160
0
    fn sub_assign(&mut self, other: u64) {
161
0
        let n = mem::replace(self, Self::ZERO);
162
0
        *self = n - other;
163
0
    }
164
}
165
166
impl Sub<u128> for BigInt {
167
    type Output = BigInt;
168
169
    #[inline]
170
0
    fn sub(self, other: u128) -> BigInt {
171
0
        match self.sign {
172
0
            NoSign => -BigInt::from(other),
173
0
            Minus => -BigInt::from(self.data + other),
174
0
            Plus => match self.data.cmp(&From::from(other)) {
175
0
                Equal => Self::ZERO,
176
0
                Greater => BigInt::from(self.data - other),
177
0
                Less => -BigInt::from(other - self.data),
178
            },
179
        }
180
0
    }
181
}
182
183
impl SubAssign<u128> for BigInt {
184
    #[inline]
185
0
    fn sub_assign(&mut self, other: u128) {
186
0
        let n = mem::replace(self, Self::ZERO);
187
0
        *self = n - other;
188
0
    }
189
}
190
191
forward_all_scalar_binop_to_val_val!(impl Sub<i32> for BigInt, sub);
192
forward_all_scalar_binop_to_val_val!(impl Sub<i64> for BigInt, sub);
193
forward_all_scalar_binop_to_val_val!(impl Sub<i128> for BigInt, sub);
194
195
impl Sub<i32> for BigInt {
196
    type Output = BigInt;
197
198
    #[inline]
199
0
    fn sub(self, other: i32) -> BigInt {
200
0
        match other.checked_uabs() {
201
0
            Positive(u) => self - u,
202
0
            Negative(u) => self + u,
203
        }
204
0
    }
205
}
206
impl SubAssign<i32> for BigInt {
207
    #[inline]
208
0
    fn sub_assign(&mut self, other: i32) {
209
0
        match other.checked_uabs() {
210
0
            Positive(u) => *self -= u,
211
0
            Negative(u) => *self += u,
212
        }
213
0
    }
214
}
215
216
impl Sub<BigInt> for i32 {
217
    type Output = BigInt;
218
219
    #[inline]
220
0
    fn sub(self, other: BigInt) -> BigInt {
221
0
        match self.checked_uabs() {
222
0
            Positive(u) => u - other,
223
0
            Negative(u) => -other - u,
224
        }
225
0
    }
226
}
227
228
impl Sub<i64> for BigInt {
229
    type Output = BigInt;
230
231
    #[inline]
232
0
    fn sub(self, other: i64) -> BigInt {
233
0
        match other.checked_uabs() {
234
0
            Positive(u) => self - u,
235
0
            Negative(u) => self + u,
236
        }
237
0
    }
238
}
239
impl SubAssign<i64> for BigInt {
240
    #[inline]
241
0
    fn sub_assign(&mut self, other: i64) {
242
0
        match other.checked_uabs() {
243
0
            Positive(u) => *self -= u,
244
0
            Negative(u) => *self += u,
245
        }
246
0
    }
247
}
248
249
impl Sub<BigInt> for i64 {
250
    type Output = BigInt;
251
252
    #[inline]
253
0
    fn sub(self, other: BigInt) -> BigInt {
254
0
        match self.checked_uabs() {
255
0
            Positive(u) => u - other,
256
0
            Negative(u) => -other - u,
257
        }
258
0
    }
259
}
260
261
impl Sub<i128> for BigInt {
262
    type Output = BigInt;
263
264
    #[inline]
265
0
    fn sub(self, other: i128) -> BigInt {
266
0
        match other.checked_uabs() {
267
0
            Positive(u) => self - u,
268
0
            Negative(u) => self + u,
269
        }
270
0
    }
271
}
272
273
impl SubAssign<i128> for BigInt {
274
    #[inline]
275
0
    fn sub_assign(&mut self, other: i128) {
276
0
        match other.checked_uabs() {
277
0
            Positive(u) => *self -= u,
278
0
            Negative(u) => *self += u,
279
        }
280
0
    }
281
}
282
283
impl Sub<BigInt> for i128 {
284
    type Output = BigInt;
285
286
    #[inline]
287
0
    fn sub(self, other: BigInt) -> BigInt {
288
0
        match self.checked_uabs() {
289
0
            Positive(u) => u - other,
290
0
            Negative(u) => -other - u,
291
        }
292
0
    }
293
}
294
295
impl CheckedSub for BigInt {
296
    #[inline]
297
0
    fn checked_sub(&self, v: &BigInt) -> Option<BigInt> {
298
0
        Some(self.sub(v))
299
0
    }
300
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint.rs
Line
Count
Source
1
use crate::big_digit::{self, BigDigit};
2
3
use alloc::string::String;
4
use alloc::vec::Vec;
5
use core::cmp;
6
use core::cmp::Ordering;
7
use core::default::Default;
8
use core::fmt;
9
use core::hash;
10
use core::mem;
11
use core::str;
12
13
use num_integer::{Integer, Roots};
14
use num_traits::{ConstZero, Num, One, Pow, ToPrimitive, Unsigned, Zero};
15
16
mod addition;
17
mod division;
18
mod multiplication;
19
mod subtraction;
20
21
mod arbitrary;
22
mod bits;
23
mod convert;
24
mod iter;
25
mod monty;
26
mod power;
27
mod serde;
28
mod shift;
29
30
pub(crate) use self::convert::to_str_radix_reversed;
31
pub use self::iter::{U32Digits, U64Digits};
32
33
/// A big unsigned integer type.
34
pub struct BigUint {
35
    data: Vec<BigDigit>,
36
}
37
38
// Note: derived `Clone` doesn't specialize `clone_from`,
39
// but we want to keep the allocation in `data`.
40
impl Clone for BigUint {
41
    #[inline]
42
351k
    fn clone(&self) -> Self {
43
351k
        BigUint {
44
351k
            data: self.data.clone(),
45
351k
        }
46
351k
    }
_RNvXNtCs72ekIXsOXFl_10num_bigint7biguintNtB2_7BigUintNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneCs4RkbDk9WRL5_5clvmr
Line
Count
Source
42
56.2k
    fn clone(&self) -> Self {
43
56.2k
        BigUint {
44
56.2k
            data: self.data.clone(),
45
56.2k
        }
46
56.2k
    }
_RNvXNtCs72ekIXsOXFl_10num_bigint7biguintNtB2_7BigUintNtNtCsbQ8arDwx5Xq_4core5clone5Clone5cloneB4_
Line
Count
Source
42
295k
    fn clone(&self) -> Self {
43
295k
        BigUint {
44
295k
            data: self.data.clone(),
45
295k
        }
46
295k
    }
47
48
    #[inline]
49
10.2k
    fn clone_from(&mut self, other: &Self) {
50
10.2k
        self.data.clone_from(&other.data);
51
10.2k
    }
52
}
53
54
impl hash::Hash for BigUint {
55
    #[inline]
56
0
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
57
0
        debug_assert!(self.data.last() != Some(&0));
58
0
        self.data.hash(state);
59
0
    }
60
}
61
62
impl PartialEq for BigUint {
63
    #[inline]
64
0
    fn eq(&self, other: &BigUint) -> bool {
65
0
        debug_assert!(self.data.last() != Some(&0));
66
0
        debug_assert!(other.data.last() != Some(&0));
67
0
        self.data == other.data
68
0
    }
69
}
70
impl Eq for BigUint {}
71
72
impl PartialOrd for BigUint {
73
    #[inline]
74
2.15k
    fn partial_cmp(&self, other: &BigUint) -> Option<Ordering> {
75
2.15k
        Some(self.cmp(other))
76
2.15k
    }
77
}
78
79
impl Ord for BigUint {
80
    #[inline]
81
249k
    fn cmp(&self, other: &BigUint) -> Ordering {
82
249k
        cmp_slice(&self.data[..], &other.data[..])
83
249k
    }
_RNvXs3_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUintNtNtCsbQ8arDwx5Xq_4core3cmp3Ord3cmpCs4RkbDk9WRL5_5clvmr
Line
Count
Source
81
72.5k
    fn cmp(&self, other: &BigUint) -> Ordering {
82
72.5k
        cmp_slice(&self.data[..], &other.data[..])
83
72.5k
    }
_RNvXs3_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUintNtNtCsbQ8arDwx5Xq_4core3cmp3Ord3cmpB7_
Line
Count
Source
81
177k
    fn cmp(&self, other: &BigUint) -> Ordering {
82
177k
        cmp_slice(&self.data[..], &other.data[..])
83
177k
    }
84
}
85
86
#[inline]
87
620k
fn cmp_slice(a: &[BigDigit], b: &[BigDigit]) -> Ordering {
88
620k
    debug_assert!(a.last() != Some(&0));
89
620k
    debug_assert!(b.last() != Some(&0));
90
91
620k
    match Ord::cmp(&a.len(), &b.len()) {
92
252k
        Ordering::Equal => Iterator::cmp(a.iter().rev(), b.iter().rev()),
93
367k
        other => other,
94
    }
95
620k
}
_RNvNtCs72ekIXsOXFl_10num_bigint7biguint9cmp_sliceCs4RkbDk9WRL5_5clvmr
Line
Count
Source
87
72.5k
fn cmp_slice(a: &[BigDigit], b: &[BigDigit]) -> Ordering {
88
72.5k
    debug_assert!(a.last() != Some(&0));
89
72.5k
    debug_assert!(b.last() != Some(&0));
90
91
72.5k
    match Ord::cmp(&a.len(), &b.len()) {
92
50.7k
        Ordering::Equal => Iterator::cmp(a.iter().rev(), b.iter().rev()),
93
21.7k
        other => other,
94
    }
95
72.5k
}
_RNvNtCs72ekIXsOXFl_10num_bigint7biguint9cmp_sliceB3_
Line
Count
Source
87
547k
fn cmp_slice(a: &[BigDigit], b: &[BigDigit]) -> Ordering {
88
547k
    debug_assert!(a.last() != Some(&0));
89
547k
    debug_assert!(b.last() != Some(&0));
90
91
547k
    match Ord::cmp(&a.len(), &b.len()) {
92
201k
        Ordering::Equal => Iterator::cmp(a.iter().rev(), b.iter().rev()),
93
346k
        other => other,
94
    }
95
547k
}
96
97
impl Default for BigUint {
98
    #[inline]
99
0
    fn default() -> BigUint {
100
0
        Self::ZERO
101
0
    }
102
}
103
104
impl fmt::Debug for BigUint {
105
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106
0
        fmt::Display::fmt(self, f)
107
0
    }
108
}
109
110
impl fmt::Display for BigUint {
111
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112
0
        f.pad_integral(true, "", &self.to_str_radix(10))
113
0
    }
114
}
115
116
impl fmt::LowerHex for BigUint {
117
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118
0
        f.pad_integral(true, "0x", &self.to_str_radix(16))
119
0
    }
120
}
121
122
impl fmt::UpperHex for BigUint {
123
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124
0
        let mut s = self.to_str_radix(16);
125
0
        s.make_ascii_uppercase();
126
0
        f.pad_integral(true, "0x", &s)
127
0
    }
128
}
129
130
impl fmt::Binary for BigUint {
131
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132
0
        f.pad_integral(true, "0b", &self.to_str_radix(2))
133
0
    }
134
}
135
136
impl fmt::Octal for BigUint {
137
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138
0
        f.pad_integral(true, "0o", &self.to_str_radix(8))
139
0
    }
140
}
141
142
impl Zero for BigUint {
143
    #[inline]
144
0
    fn zero() -> BigUint {
145
0
        Self::ZERO
146
0
    }
147
148
    #[inline]
149
14.0k
    fn set_zero(&mut self) {
150
14.0k
        self.data.clear();
151
14.0k
    }
_RNvXsb_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUintNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroCs4RkbDk9WRL5_5clvmr
Line
Count
Source
149
40
    fn set_zero(&mut self) {
150
40
        self.data.clear();
151
40
    }
_RNvXsb_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUintNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Line
Count
Source
149
13.9k
    fn set_zero(&mut self) {
150
13.9k
        self.data.clear();
151
13.9k
    }
152
153
    #[inline]
154
1.91M
    fn is_zero(&self) -> bool {
155
1.91M
        self.data.is_empty()
156
1.91M
    }
_RNvXsb_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUintNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero7is_zeroCs4RkbDk9WRL5_5clvmr
Line
Count
Source
154
695k
    fn is_zero(&self) -> bool {
155
695k
        self.data.is_empty()
156
695k
    }
_RNvXsb_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUintNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero7is_zeroB7_
Line
Count
Source
154
1.21M
    fn is_zero(&self) -> bool {
155
1.21M
        self.data.is_empty()
156
1.21M
    }
157
}
158
159
impl ConstZero for BigUint {
160
    // forward to the inherent const
161
    const ZERO: Self = Self::ZERO; // BigUint { data: Vec::new() };
162
}
163
164
impl One for BigUint {
165
    #[inline]
166
6.17k
    fn one() -> BigUint {
167
6.17k
        BigUint { data: vec![1] }
168
6.17k
    }
169
170
    #[inline]
171
0
    fn set_one(&mut self) {
172
0
        self.data.clear();
173
0
        self.data.push(1);
174
0
    }
175
176
    #[inline]
177
0
    fn is_one(&self) -> bool {
178
0
        self.data[..] == [1]
179
0
    }
180
}
181
182
impl Unsigned for BigUint {}
183
184
impl Integer for BigUint {
185
    #[inline]
186
121k
    fn div_rem(&self, other: &BigUint) -> (BigUint, BigUint) {
187
121k
        division::div_rem_ref(self, other)
188
121k
    }
189
190
    #[inline]
191
0
    fn div_floor(&self, other: &BigUint) -> BigUint {
192
0
        let (d, _) = division::div_rem_ref(self, other);
193
0
        d
194
0
    }
195
196
    #[inline]
197
30.9k
    fn mod_floor(&self, other: &BigUint) -> BigUint {
198
30.9k
        let (_, m) = division::div_rem_ref(self, other);
199
30.9k
        m
200
30.9k
    }
_RNvXsf_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUintNtCsd1gRxjdwU23_11num_integer7Integer9mod_floorCs4RkbDk9WRL5_5clvmr
Line
Count
Source
197
30.9k
    fn mod_floor(&self, other: &BigUint) -> BigUint {
198
30.9k
        let (_, m) = division::div_rem_ref(self, other);
199
30.9k
        m
200
30.9k
    }
Unexecuted instantiation: _RNvXsf_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUintNtCsd1gRxjdwU23_11num_integer7Integer9mod_floorB7_
201
202
    #[inline]
203
12.4k
    fn div_mod_floor(&self, other: &BigUint) -> (BigUint, BigUint) {
204
12.4k
        division::div_rem_ref(self, other)
205
12.4k
    }
_RNvXsf_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUintNtCsd1gRxjdwU23_11num_integer7Integer13div_mod_floorCs4RkbDk9WRL5_5clvmr
Line
Count
Source
203
10.0k
    fn div_mod_floor(&self, other: &BigUint) -> (BigUint, BigUint) {
204
10.0k
        division::div_rem_ref(self, other)
205
10.0k
    }
_RNvXsf_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUintNtCsd1gRxjdwU23_11num_integer7Integer13div_mod_floorB7_
Line
Count
Source
203
2.36k
    fn div_mod_floor(&self, other: &BigUint) -> (BigUint, BigUint) {
204
2.36k
        division::div_rem_ref(self, other)
205
2.36k
    }
206
207
    #[inline]
208
0
    fn div_ceil(&self, other: &BigUint) -> BigUint {
209
0
        let (d, m) = division::div_rem_ref(self, other);
210
0
        if m.is_zero() {
211
0
            d
212
        } else {
213
0
            d + 1u32
214
        }
215
0
    }
216
217
    /// Calculates the Greatest Common Divisor (GCD) of the number and `other`.
218
    ///
219
    /// The result is always positive.
220
    #[inline]
221
0
    fn gcd(&self, other: &Self) -> Self {
222
        #[inline]
223
0
        fn twos(x: &BigUint) -> u64 {
224
0
            x.trailing_zeros().unwrap_or(0)
225
0
        }
226
227
        // Stein's algorithm
228
0
        if self.is_zero() {
229
0
            return other.clone();
230
0
        }
231
0
        if other.is_zero() {
232
0
            return self.clone();
233
0
        }
234
0
        let mut m = self.clone();
235
0
        let mut n = other.clone();
236
0
237
0
        // find common factors of 2
238
0
        let shift = cmp::min(twos(&n), twos(&m));
239
0
240
0
        // divide m and n by 2 until odd
241
0
        // m inside loop
242
0
        n >>= twos(&n);
243
244
0
        while !m.is_zero() {
245
0
            m >>= twos(&m);
246
0
            if n > m {
247
0
                mem::swap(&mut n, &mut m)
248
0
            }
249
0
            m -= &n;
250
        }
251
252
0
        n << shift
253
0
    }
254
255
    /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
256
    #[inline]
257
0
    fn lcm(&self, other: &BigUint) -> BigUint {
258
0
        if self.is_zero() && other.is_zero() {
259
0
            Self::ZERO
260
        } else {
261
0
            self / self.gcd(other) * other
262
        }
263
0
    }
264
265
    /// Calculates the Greatest Common Divisor (GCD) and
266
    /// Lowest Common Multiple (LCM) together.
267
    #[inline]
268
0
    fn gcd_lcm(&self, other: &Self) -> (Self, Self) {
269
0
        let gcd = self.gcd(other);
270
0
        let lcm = if gcd.is_zero() {
271
0
            Self::ZERO
272
        } else {
273
0
            self / &gcd * other
274
        };
275
0
        (gcd, lcm)
276
0
    }
277
278
    /// Deprecated, use `is_multiple_of` instead.
279
    #[inline]
280
0
    fn divides(&self, other: &BigUint) -> bool {
281
0
        self.is_multiple_of(other)
282
0
    }
283
284
    /// Returns `true` if the number is a multiple of `other`.
285
    #[inline]
286
0
    fn is_multiple_of(&self, other: &BigUint) -> bool {
287
0
        if other.is_zero() {
288
0
            return self.is_zero();
289
0
        }
290
0
        (self % other).is_zero()
291
0
    }
292
293
    /// Returns `true` if the number is divisible by `2`.
294
    #[inline]
295
6.45k
    fn is_even(&self) -> bool {
296
6.45k
        // Considering only the last digit.
297
6.45k
        match self.data.first() {
298
6.04k
            Some(x) => x.is_even(),
299
413
            None => true,
300
        }
301
6.45k
    }
302
303
    /// Returns `true` if the number is not divisible by `2`.
304
    #[inline]
305
6.45k
    fn is_odd(&self) -> bool {
306
6.45k
        !self.is_even()
307
6.45k
    }
308
309
    /// Rounds up to nearest multiple of argument.
310
    #[inline]
311
0
    fn next_multiple_of(&self, other: &Self) -> Self {
312
0
        let m = self.mod_floor(other);
313
0
        if m.is_zero() {
314
0
            self.clone()
315
        } else {
316
0
            self + (other - m)
317
        }
318
0
    }
319
    /// Rounds down to nearest multiple of argument.
320
    #[inline]
321
0
    fn prev_multiple_of(&self, other: &Self) -> Self {
322
0
        self - self.mod_floor(other)
323
0
    }
324
325
0
    fn dec(&mut self) {
326
0
        *self -= 1u32;
327
0
    }
328
329
0
    fn inc(&mut self) {
330
0
        *self += 1u32;
331
0
    }
332
}
333
334
#[inline]
335
0
fn fixpoint<F>(mut x: BigUint, max_bits: u64, f: F) -> BigUint
336
0
where
337
0
    F: Fn(&BigUint) -> BigUint,
338
0
{
339
0
    let mut xn = f(&x);
340
341
    // If the value increased, then the initial guess must have been low.
342
    // Repeat until we reverse course.
343
0
    while x < xn {
344
        // Sometimes an increase will go way too far, especially with large
345
        // powers, and then take a long time to walk back.  We know an upper
346
        // bound based on bit size, so saturate on that.
347
0
        x = if xn.bits() > max_bits {
348
0
            BigUint::one() << max_bits
349
        } else {
350
0
            xn
351
        };
352
0
        xn = f(&x);
353
    }
354
355
    // Now keep repeating while the estimate is decreasing.
356
0
    while x > xn {
357
0
        x = xn;
358
0
        xn = f(&x);
359
0
    }
360
0
    x
361
0
}
Unexecuted instantiation: _RINvNtCs72ekIXsOXFl_10num_bigint7biguint8fixpointNCNvXsg_B2_NtB2_7BigUintNtNtCsd1gRxjdwU23_11num_integer5roots5Roots4cbrt0EB4_
Unexecuted instantiation: _RINvNtCs72ekIXsOXFl_10num_bigint7biguint8fixpointNCNvXsg_B2_NtB2_7BigUintNtNtCsd1gRxjdwU23_11num_integer5roots5Roots4sqrt0EB4_
Unexecuted instantiation: _RINvNtCs72ekIXsOXFl_10num_bigint7biguint8fixpointNCNvXsg_B2_NtB2_7BigUintNtNtCsd1gRxjdwU23_11num_integer5roots5Roots8nth_root0EB4_
362
363
impl Roots for BigUint {
364
    // nth_root, sqrt and cbrt use Newton's method to compute
365
    // principal root of a given degree for a given integer.
366
367
    // Reference:
368
    // Brent & Zimmermann, Modern Computer Arithmetic, v0.5.9, Algorithm 1.14
369
0
    fn nth_root(&self, n: u32) -> Self {
370
0
        assert!(n > 0, "root degree n must be at least 1");
371
372
0
        if self.is_zero() || self.is_one() {
373
0
            return self.clone();
374
0
        }
375
0
376
0
        match n {
377
            // Optimize for small n
378
0
            1 => return self.clone(),
379
0
            2 => return self.sqrt(),
380
0
            3 => return self.cbrt(),
381
0
            _ => (),
382
0
        }
383
0
384
0
        // The root of non-zero values less than 2ⁿ can only be 1.
385
0
        let bits = self.bits();
386
0
        let n64 = u64::from(n);
387
0
        if bits <= n64 {
388
0
            return BigUint::one();
389
0
        }
390
391
        // If we fit in `u64`, compute the root that way.
392
0
        if let Some(x) = self.to_u64() {
393
0
            return x.nth_root(n).into();
394
0
        }
395
0
396
0
        let max_bits = bits / n64 + 1;
397
398
        #[cfg(feature = "std")]
399
0
        let guess = match self.to_f64() {
400
0
            Some(f) if f.is_finite() => {
401
                use num_traits::FromPrimitive;
402
403
                // We fit in `f64` (lossy), so get a better initial guess from that.
404
0
                BigUint::from_f64((f.ln() / f64::from(n)).exp()).unwrap()
405
            }
406
            _ => {
407
                // Try to guess by scaling down such that it does fit in `f64`.
408
                // With some (x * 2ⁿᵏ), its nth root ≈ (ⁿ√x * 2ᵏ)
409
0
                let extra_bits = bits - (f64::MAX_EXP as u64 - 1);
410
0
                let root_scale = Integer::div_ceil(&extra_bits, &n64);
411
0
                let scale = root_scale * n64;
412
0
                if scale < bits && bits - scale > n64 {
413
0
                    (self >> scale).nth_root(n) << root_scale
414
                } else {
415
0
                    BigUint::one() << max_bits
416
                }
417
            }
418
        };
419
420
        #[cfg(not(feature = "std"))]
421
        let guess = BigUint::one() << max_bits;
422
423
0
        let n_min_1 = n - 1;
424
0
        fixpoint(guess, max_bits, move |s| {
425
0
            let q = self / s.pow(n_min_1);
426
0
            let t = n_min_1 * s + q;
427
0
            t / n
428
0
        })
429
0
    }
430
431
    // Reference:
432
    // Brent & Zimmermann, Modern Computer Arithmetic, v0.5.9, Algorithm 1.13
433
0
    fn sqrt(&self) -> Self {
434
0
        if self.is_zero() || self.is_one() {
435
0
            return self.clone();
436
0
        }
437
438
        // If we fit in `u64`, compute the root that way.
439
0
        if let Some(x) = self.to_u64() {
440
0
            return x.sqrt().into();
441
0
        }
442
0
443
0
        let bits = self.bits();
444
0
        let max_bits = bits / 2 + 1;
445
446
        #[cfg(feature = "std")]
447
0
        let guess = match self.to_f64() {
448
0
            Some(f) if f.is_finite() => {
449
                use num_traits::FromPrimitive;
450
451
                // We fit in `f64` (lossy), so get a better initial guess from that.
452
0
                BigUint::from_f64(f.sqrt()).unwrap()
453
            }
454
            _ => {
455
                // Try to guess by scaling down such that it does fit in `f64`.
456
                // With some (x * 2²ᵏ), its sqrt ≈ (√x * 2ᵏ)
457
0
                let extra_bits = bits - (f64::MAX_EXP as u64 - 1);
458
0
                let root_scale = (extra_bits + 1) / 2;
459
0
                let scale = root_scale * 2;
460
0
                (self >> scale).sqrt() << root_scale
461
            }
462
        };
463
464
        #[cfg(not(feature = "std"))]
465
        let guess = BigUint::one() << max_bits;
466
467
0
        fixpoint(guess, max_bits, move |s| {
468
0
            let q = self / s;
469
0
            let t = s + q;
470
0
            t >> 1
471
0
        })
472
0
    }
473
474
0
    fn cbrt(&self) -> Self {
475
0
        if self.is_zero() || self.is_one() {
476
0
            return self.clone();
477
0
        }
478
479
        // If we fit in `u64`, compute the root that way.
480
0
        if let Some(x) = self.to_u64() {
481
0
            return x.cbrt().into();
482
0
        }
483
0
484
0
        let bits = self.bits();
485
0
        let max_bits = bits / 3 + 1;
486
487
        #[cfg(feature = "std")]
488
0
        let guess = match self.to_f64() {
489
0
            Some(f) if f.is_finite() => {
490
                use num_traits::FromPrimitive;
491
492
                // We fit in `f64` (lossy), so get a better initial guess from that.
493
0
                BigUint::from_f64(f.cbrt()).unwrap()
494
            }
495
            _ => {
496
                // Try to guess by scaling down such that it does fit in `f64`.
497
                // With some (x * 2³ᵏ), its cbrt ≈ (∛x * 2ᵏ)
498
0
                let extra_bits = bits - (f64::MAX_EXP as u64 - 1);
499
0
                let root_scale = (extra_bits + 2) / 3;
500
0
                let scale = root_scale * 3;
501
0
                (self >> scale).cbrt() << root_scale
502
            }
503
        };
504
505
        #[cfg(not(feature = "std"))]
506
        let guess = BigUint::one() << max_bits;
507
508
0
        fixpoint(guess, max_bits, move |s| {
509
0
            let q = self / (s * s);
510
0
            let t = (s << 1) + q;
511
0
            t / 3u32
512
0
        })
513
0
    }
514
}
515
516
/// A generic trait for converting a value to a [`BigUint`].
517
pub trait ToBigUint {
518
    /// Converts the value of `self` to a [`BigUint`].
519
    fn to_biguint(&self) -> Option<BigUint>;
520
}
521
522
/// Creates and initializes a [`BigUint`].
523
///
524
/// The digits are in little-endian base matching `BigDigit`.
525
#[inline]
526
867k
pub(crate) fn biguint_from_vec(digits: Vec<BigDigit>) -> BigUint {
527
867k
    BigUint { data: digits }.normalized()
528
867k
}
529
530
impl BigUint {
531
    /// A constant `BigUint` with value 0, useful for static initialization.
532
    pub const ZERO: Self = BigUint { data: Vec::new() };
533
534
    /// Creates and initializes a [`BigUint`].
535
    ///
536
    /// The base 2<sup>32</sup> digits are ordered least significant digit first.
537
    #[inline]
538
0
    pub fn new(digits: Vec<u32>) -> BigUint {
539
0
        let mut big = Self::ZERO;
540
0
541
0
        cfg_digit_expr!(
542
0
            {
543
0
                big.data = digits;
544
0
                big.normalize();
545
0
            },
546
0
            big.assign_from_slice(&digits)
547
0
        );
548
0
549
0
        big
550
0
    }
551
552
    /// Creates and initializes a [`BigUint`].
553
    ///
554
    /// The base 2<sup>32</sup> digits are ordered least significant digit first.
555
    #[inline]
556
0
    pub fn from_slice(slice: &[u32]) -> BigUint {
557
0
        let mut big = Self::ZERO;
558
0
        big.assign_from_slice(slice);
559
0
        big
560
0
    }
561
562
    /// Assign a value to a [`BigUint`].
563
    ///
564
    /// The base 2<sup>32</sup> digits are ordered least significant digit first.
565
    #[inline]
566
11.9k
    pub fn assign_from_slice(&mut self, slice: &[u32]) {
567
11.9k
        self.data.clear();
568
11.9k
569
11.9k
        cfg_digit_expr!(
570
11.9k
            self.data.extend_from_slice(slice),
571
11.9k
            self.data.extend(slice.chunks(2).map(u32_chunk_to_u64))
572
11.9k
        );
573
11.9k
574
11.9k
        self.normalize();
575
11.9k
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint17assign_from_sliceCs4RkbDk9WRL5_5clvmr
Line
Count
Source
566
6.73k
    pub fn assign_from_slice(&mut self, slice: &[u32]) {
567
6.73k
        self.data.clear();
568
6.73k
569
6.73k
        cfg_digit_expr!(
570
6.73k
            self.data.extend_from_slice(slice),
571
6.73k
            self.data.extend(slice.chunks(2).map(u32_chunk_to_u64))
572
6.73k
        );
573
6.73k
574
6.73k
        self.normalize();
575
6.73k
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint17assign_from_sliceB7_
Line
Count
Source
566
5.24k
    pub fn assign_from_slice(&mut self, slice: &[u32]) {
567
5.24k
        self.data.clear();
568
5.24k
569
5.24k
        cfg_digit_expr!(
570
5.24k
            self.data.extend_from_slice(slice),
571
5.24k
            self.data.extend(slice.chunks(2).map(u32_chunk_to_u64))
572
5.24k
        );
573
5.24k
574
5.24k
        self.normalize();
575
5.24k
    }
576
577
    /// Creates and initializes a [`BigUint`].
578
    ///
579
    /// The bytes are in big-endian byte order.
580
    ///
581
    /// # Examples
582
    ///
583
    /// ```
584
    /// use num_bigint::BigUint;
585
    ///
586
    /// assert_eq!(BigUint::from_bytes_be(b"A"),
587
    ///            BigUint::parse_bytes(b"65", 10).unwrap());
588
    /// assert_eq!(BigUint::from_bytes_be(b"AA"),
589
    ///            BigUint::parse_bytes(b"16705", 10).unwrap());
590
    /// assert_eq!(BigUint::from_bytes_be(b"AB"),
591
    ///            BigUint::parse_bytes(b"16706", 10).unwrap());
592
    /// assert_eq!(BigUint::from_bytes_be(b"Hello world!"),
593
    ///            BigUint::parse_bytes(b"22405534230753963835153736737", 10).unwrap());
594
    /// ```
595
    #[inline]
596
233k
    pub fn from_bytes_be(bytes: &[u8]) -> BigUint {
597
233k
        if bytes.is_empty() {
598
1.00k
            Self::ZERO
599
        } else {
600
232k
            let mut v = bytes.to_vec();
601
232k
            v.reverse();
602
232k
            BigUint::from_bytes_le(&v)
603
        }
604
233k
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint13from_bytes_beCs4RkbDk9WRL5_5clvmr
Line
Count
Source
596
233k
    pub fn from_bytes_be(bytes: &[u8]) -> BigUint {
597
233k
        if bytes.is_empty() {
598
1.00k
            Self::ZERO
599
        } else {
600
232k
            let mut v = bytes.to_vec();
601
232k
            v.reverse();
602
232k
            BigUint::from_bytes_le(&v)
603
        }
604
233k
    }
Unexecuted instantiation: _RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint13from_bytes_beB7_
605
606
    /// Creates and initializes a [`BigUint`].
607
    ///
608
    /// The bytes are in little-endian byte order.
609
    #[inline]
610
232k
    pub fn from_bytes_le(bytes: &[u8]) -> BigUint {
611
232k
        if bytes.is_empty() {
612
0
            Self::ZERO
613
        } else {
614
232k
            convert::from_bitwise_digits_le(bytes, 8)
615
        }
616
232k
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint13from_bytes_leCs4RkbDk9WRL5_5clvmr
Line
Count
Source
610
232k
    pub fn from_bytes_le(bytes: &[u8]) -> BigUint {
611
232k
        if bytes.is_empty() {
612
0
            Self::ZERO
613
        } else {
614
232k
            convert::from_bitwise_digits_le(bytes, 8)
615
        }
616
232k
    }
Unexecuted instantiation: _RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint13from_bytes_leB7_
617
618
    /// Creates and initializes a [`BigUint`]. The input slice must contain
619
    /// ascii/utf8 characters in [0-9a-zA-Z].
620
    /// `radix` must be in the range `2...36`.
621
    ///
622
    /// The function `from_str_radix` from the `Num` trait provides the same logic
623
    /// for `&str` buffers.
624
    ///
625
    /// # Examples
626
    ///
627
    /// ```
628
    /// use num_bigint::{BigUint, ToBigUint};
629
    ///
630
    /// assert_eq!(BigUint::parse_bytes(b"1234", 10), ToBigUint::to_biguint(&1234));
631
    /// assert_eq!(BigUint::parse_bytes(b"ABCD", 16), ToBigUint::to_biguint(&0xABCD));
632
    /// assert_eq!(BigUint::parse_bytes(b"G", 16), None);
633
    /// ```
634
    #[inline]
635
0
    pub fn parse_bytes(buf: &[u8], radix: u32) -> Option<BigUint> {
636
0
        let s = str::from_utf8(buf).ok()?;
637
0
        BigUint::from_str_radix(s, radix).ok()
638
0
    }
639
640
    /// Creates and initializes a [`BigUint`]. Each `u8` of the input slice is
641
    /// interpreted as one digit of the number
642
    /// and must therefore be less than `radix`.
643
    ///
644
    /// The bytes are in big-endian byte order.
645
    /// `radix` must be in the range `2...256`.
646
    ///
647
    /// # Examples
648
    ///
649
    /// ```
650
    /// use num_bigint::{BigUint};
651
    ///
652
    /// let inbase190 = &[15, 33, 125, 12, 14];
653
    /// let a = BigUint::from_radix_be(inbase190, 190).unwrap();
654
    /// assert_eq!(a.to_radix_be(190), inbase190);
655
    /// ```
656
0
    pub fn from_radix_be(buf: &[u8], radix: u32) -> Option<BigUint> {
657
0
        convert::from_radix_be(buf, radix)
658
0
    }
659
660
    /// Creates and initializes a [`BigUint`]. Each `u8` of the input slice is
661
    /// interpreted as one digit of the number
662
    /// and must therefore be less than `radix`.
663
    ///
664
    /// The bytes are in little-endian byte order.
665
    /// `radix` must be in the range `2...256`.
666
    ///
667
    /// # Examples
668
    ///
669
    /// ```
670
    /// use num_bigint::{BigUint};
671
    ///
672
    /// let inbase190 = &[14, 12, 125, 33, 15];
673
    /// let a = BigUint::from_radix_be(inbase190, 190).unwrap();
674
    /// assert_eq!(a.to_radix_be(190), inbase190);
675
    /// ```
676
0
    pub fn from_radix_le(buf: &[u8], radix: u32) -> Option<BigUint> {
677
0
        convert::from_radix_le(buf, radix)
678
0
    }
679
680
    /// Returns the byte representation of the [`BigUint`] in big-endian byte order.
681
    ///
682
    /// # Examples
683
    ///
684
    /// ```
685
    /// use num_bigint::BigUint;
686
    ///
687
    /// let i = BigUint::parse_bytes(b"1125", 10).unwrap();
688
    /// assert_eq!(i.to_bytes_be(), vec![4, 101]);
689
    /// ```
690
    #[inline]
691
144k
    pub fn to_bytes_be(&self) -> Vec<u8> {
692
144k
        let mut v = self.to_bytes_le();
693
144k
        v.reverse();
694
144k
        v
695
144k
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint11to_bytes_beCs4RkbDk9WRL5_5clvmr
Line
Count
Source
691
144k
    pub fn to_bytes_be(&self) -> Vec<u8> {
692
144k
        let mut v = self.to_bytes_le();
693
144k
        v.reverse();
694
144k
        v
695
144k
    }
Unexecuted instantiation: _RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint11to_bytes_beB7_
696
697
    /// Returns the byte representation of the [`BigUint`] in little-endian byte order.
698
    ///
699
    /// # Examples
700
    ///
701
    /// ```
702
    /// use num_bigint::BigUint;
703
    ///
704
    /// let i = BigUint::parse_bytes(b"1125", 10).unwrap();
705
    /// assert_eq!(i.to_bytes_le(), vec![101, 4]);
706
    /// ```
707
    #[inline]
708
144k
    pub fn to_bytes_le(&self) -> Vec<u8> {
709
144k
        if self.is_zero() {
710
4.03k
            vec![0]
711
        } else {
712
140k
            convert::to_bitwise_digits_le(self, 8)
713
        }
714
144k
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint11to_bytes_leCs4RkbDk9WRL5_5clvmr
Line
Count
Source
708
144k
    pub fn to_bytes_le(&self) -> Vec<u8> {
709
144k
        if self.is_zero() {
710
4.03k
            vec![0]
711
        } else {
712
140k
            convert::to_bitwise_digits_le(self, 8)
713
        }
714
144k
    }
Unexecuted instantiation: _RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint11to_bytes_leB7_
715
716
    /// Returns the `u32` digits representation of the [`BigUint`] ordered least significant digit
717
    /// first.
718
    ///
719
    /// # Examples
720
    ///
721
    /// ```
722
    /// use num_bigint::BigUint;
723
    ///
724
    /// assert_eq!(BigUint::from(1125u32).to_u32_digits(), vec![1125]);
725
    /// assert_eq!(BigUint::from(4294967295u32).to_u32_digits(), vec![4294967295]);
726
    /// assert_eq!(BigUint::from(4294967296u64).to_u32_digits(), vec![0, 1]);
727
    /// assert_eq!(BigUint::from(112500000000u64).to_u32_digits(), vec![830850304, 26]);
728
    /// ```
729
    #[inline]
730
0
    pub fn to_u32_digits(&self) -> Vec<u32> {
731
0
        self.iter_u32_digits().collect()
732
0
    }
733
734
    /// Returns the `u64` digits representation of the [`BigUint`] ordered least significant digit
735
    /// first.
736
    ///
737
    /// # Examples
738
    ///
739
    /// ```
740
    /// use num_bigint::BigUint;
741
    ///
742
    /// assert_eq!(BigUint::from(1125u32).to_u64_digits(), vec![1125]);
743
    /// assert_eq!(BigUint::from(4294967295u32).to_u64_digits(), vec![4294967295]);
744
    /// assert_eq!(BigUint::from(4294967296u64).to_u64_digits(), vec![4294967296]);
745
    /// assert_eq!(BigUint::from(112500000000u64).to_u64_digits(), vec![112500000000]);
746
    /// assert_eq!(BigUint::from(1u128 << 64).to_u64_digits(), vec![0, 1]);
747
    /// ```
748
    #[inline]
749
0
    pub fn to_u64_digits(&self) -> Vec<u64> {
750
0
        self.iter_u64_digits().collect()
751
0
    }
752
753
    /// Returns an iterator of `u32` digits representation of the [`BigUint`] ordered least
754
    /// significant digit first.
755
    ///
756
    /// # Examples
757
    ///
758
    /// ```
759
    /// use num_bigint::BigUint;
760
    ///
761
    /// assert_eq!(BigUint::from(1125u32).iter_u32_digits().collect::<Vec<u32>>(), vec![1125]);
762
    /// assert_eq!(BigUint::from(4294967295u32).iter_u32_digits().collect::<Vec<u32>>(), vec![4294967295]);
763
    /// assert_eq!(BigUint::from(4294967296u64).iter_u32_digits().collect::<Vec<u32>>(), vec![0, 1]);
764
    /// assert_eq!(BigUint::from(112500000000u64).iter_u32_digits().collect::<Vec<u32>>(), vec![830850304, 26]);
765
    /// ```
766
    #[inline]
767
0
    pub fn iter_u32_digits(&self) -> U32Digits<'_> {
768
0
        U32Digits::new(self.data.as_slice())
769
0
    }
770
771
    /// Returns an iterator of `u64` digits representation of the [`BigUint`] ordered least
772
    /// significant digit first.
773
    ///
774
    /// # Examples
775
    ///
776
    /// ```
777
    /// use num_bigint::BigUint;
778
    ///
779
    /// assert_eq!(BigUint::from(1125u32).iter_u64_digits().collect::<Vec<u64>>(), vec![1125]);
780
    /// assert_eq!(BigUint::from(4294967295u32).iter_u64_digits().collect::<Vec<u64>>(), vec![4294967295]);
781
    /// assert_eq!(BigUint::from(4294967296u64).iter_u64_digits().collect::<Vec<u64>>(), vec![4294967296]);
782
    /// assert_eq!(BigUint::from(112500000000u64).iter_u64_digits().collect::<Vec<u64>>(), vec![112500000000]);
783
    /// assert_eq!(BigUint::from(1u128 << 64).iter_u64_digits().collect::<Vec<u64>>(), vec![0, 1]);
784
    /// ```
785
    #[inline]
786
0
    pub fn iter_u64_digits(&self) -> U64Digits<'_> {
787
0
        U64Digits::new(self.data.as_slice())
788
0
    }
789
790
    /// Returns the integer formatted as a string in the given radix.
791
    /// `radix` must be in the range `2...36`.
792
    ///
793
    /// # Examples
794
    ///
795
    /// ```
796
    /// use num_bigint::BigUint;
797
    ///
798
    /// let i = BigUint::parse_bytes(b"ff", 16).unwrap();
799
    /// assert_eq!(i.to_str_radix(16), "ff");
800
    /// ```
801
    #[inline]
802
0
    pub fn to_str_radix(&self, radix: u32) -> String {
803
0
        let mut v = to_str_radix_reversed(self, radix);
804
0
        v.reverse();
805
0
        unsafe { String::from_utf8_unchecked(v) }
806
0
    }
807
808
    /// Returns the integer in the requested base in big-endian digit order.
809
    /// The output is not given in a human readable alphabet but as a zero
810
    /// based `u8` number.
811
    /// `radix` must be in the range `2...256`.
812
    ///
813
    /// # Examples
814
    ///
815
    /// ```
816
    /// use num_bigint::BigUint;
817
    ///
818
    /// assert_eq!(BigUint::from(0xFFFFu64).to_radix_be(159),
819
    ///            vec![2, 94, 27]);
820
    /// // 0xFFFF = 65535 = 2*(159^2) + 94*159 + 27
821
    /// ```
822
    #[inline]
823
0
    pub fn to_radix_be(&self, radix: u32) -> Vec<u8> {
824
0
        let mut v = convert::to_radix_le(self, radix);
825
0
        v.reverse();
826
0
        v
827
0
    }
828
829
    /// Returns the integer in the requested base in little-endian digit order.
830
    /// The output is not given in a human readable alphabet but as a zero
831
    /// based u8 number.
832
    /// `radix` must be in the range `2...256`.
833
    ///
834
    /// # Examples
835
    ///
836
    /// ```
837
    /// use num_bigint::BigUint;
838
    ///
839
    /// assert_eq!(BigUint::from(0xFFFFu64).to_radix_le(159),
840
    ///            vec![27, 94, 2]);
841
    /// // 0xFFFF = 65535 = 27 + 94*159 + 2*(159^2)
842
    /// ```
843
    #[inline]
844
0
    pub fn to_radix_le(&self, radix: u32) -> Vec<u8> {
845
0
        convert::to_radix_le(self, radix)
846
0
    }
847
848
    /// Determines the fewest bits necessary to express the [`BigUint`].
849
    #[inline]
850
202k
    pub fn bits(&self) -> u64 {
851
202k
        if self.is_zero() {
852
30.1k
            return 0;
853
171k
        }
854
171k
        let zeros: u64 = self.data.last().unwrap().leading_zeros().into();
855
171k
        self.data.len() as u64 * u64::from(big_digit::BITS) - zeros
856
202k
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint4bitsCs4RkbDk9WRL5_5clvmr
Line
Count
Source
850
62.0k
    pub fn bits(&self) -> u64 {
851
62.0k
        if self.is_zero() {
852
30.1k
            return 0;
853
31.9k
        }
854
31.9k
        let zeros: u64 = self.data.last().unwrap().leading_zeros().into();
855
31.9k
        self.data.len() as u64 * u64::from(big_digit::BITS) - zeros
856
62.0k
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint4bitsB7_
Line
Count
Source
850
140k
    pub fn bits(&self) -> u64 {
851
140k
        if self.is_zero() {
852
0
            return 0;
853
140k
        }
854
140k
        let zeros: u64 = self.data.last().unwrap().leading_zeros().into();
855
140k
        self.data.len() as u64 * u64::from(big_digit::BITS) - zeros
856
140k
    }
857
858
    /// Strips off trailing zero bigdigits - comparisons require the last element in the vector to
859
    /// be nonzero.
860
    #[inline]
861
1.75M
    fn normalize(&mut self) {
862
1.75M
        if let Some(&0) = self.data.last() {
863
12.1M
            let len = self.data.iter().rposition(|&d| d != 0).map_or(0, |i| i + 1);
Unexecuted instantiation: _RNCNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB7_7BigUint9normalize0Cs4RkbDk9WRL5_5clvmr
_RNCNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB7_7BigUint9normalize0B9_
Line
Count
Source
863
12.1M
            let len = self.data.iter().rposition(|&d| d != 0).map_or(0, |i| i + 1);
Unexecuted instantiation: _RNCNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB7_7BigUint9normalizes_0Cs4RkbDk9WRL5_5clvmr
_RNCNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB7_7BigUint9normalizes_0B9_
Line
Count
Source
863
651k
            let len = self.data.iter().rposition(|&d| d != 0).map_or(0, |i| i + 1);
864
697k
            self.data.truncate(len);
865
1.05M
        }
866
1.75M
        if self.data.len() < self.data.capacity() / 4 {
867
65.1k
            self.data.shrink_to_fit();
868
1.69M
        }
869
1.75M
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint9normalizeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
861
22.2k
    fn normalize(&mut self) {
862
22.2k
        if let Some(&0) = self.data.last() {
863
0
            let len = self.data.iter().rposition(|&d| d != 0).map_or(0, |i| i + 1);
864
0
            self.data.truncate(len);
865
22.2k
        }
866
22.2k
        if self.data.len() < self.data.capacity() / 4 {
867
0
            self.data.shrink_to_fit();
868
22.2k
        }
869
22.2k
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint9normalizeB7_
Line
Count
Source
861
1.73M
    fn normalize(&mut self) {
862
1.73M
        if let Some(&0) = self.data.last() {
863
697k
            let len = self.data.iter().rposition(|&d| d != 0).map_or(0, |i| i + 1);
864
697k
            self.data.truncate(len);
865
1.03M
        }
866
1.73M
        if self.data.len() < self.data.capacity() / 4 {
867
65.1k
            self.data.shrink_to_fit();
868
1.66M
        }
869
1.73M
    }
870
871
    /// Returns a normalized [`BigUint`].
872
    #[inline]
873
1.15M
    fn normalized(mut self) -> BigUint {
874
1.15M
        self.normalize();
875
1.15M
        self
876
1.15M
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint10normalizedCs4RkbDk9WRL5_5clvmr
Line
Count
Source
873
15.4k
    fn normalized(mut self) -> BigUint {
874
15.4k
        self.normalize();
875
15.4k
        self
876
15.4k
    }
_RNvMsh_NtCs72ekIXsOXFl_10num_bigint7biguintNtB5_7BigUint10normalizedB7_
Line
Count
Source
873
1.13M
    fn normalized(mut self) -> BigUint {
874
1.13M
        self.normalize();
875
1.13M
        self
876
1.13M
    }
877
878
    /// Returns `self ^ exponent`.
879
0
    pub fn pow(&self, exponent: u32) -> Self {
880
0
        Pow::pow(self, exponent)
881
0
    }
882
883
    /// Returns `(self ^ exponent) % modulus`.
884
    ///
885
    /// Panics if the modulus is zero.
886
5.03k
    pub fn modpow(&self, exponent: &Self, modulus: &Self) -> Self {
887
5.03k
        power::modpow(self, exponent, modulus)
888
5.03k
    }
889
890
    /// Returns the modular multiplicative inverse if it exists, otherwise `None`.
891
    ///
892
    /// This solves for `x` in the interval `[0, modulus)` such that `self * x ≡ 1 (mod modulus)`.
893
    /// The solution exists if and only if `gcd(self, modulus) == 1`.
894
    ///
895
    /// ```
896
    /// use num_bigint::BigUint;
897
    /// use num_traits::{One, Zero};
898
    ///
899
    /// let m = BigUint::from(383_u32);
900
    ///
901
    /// // Trivial cases
902
    /// assert_eq!(BigUint::zero().modinv(&m), None);
903
    /// assert_eq!(BigUint::one().modinv(&m), Some(BigUint::one()));
904
    /// let neg1 = &m - 1u32;
905
    /// assert_eq!(neg1.modinv(&m), Some(neg1));
906
    ///
907
    /// let a = BigUint::from(271_u32);
908
    /// let x = a.modinv(&m).unwrap();
909
    /// assert_eq!(x, BigUint::from(106_u32));
910
    /// assert_eq!(x.modinv(&m).unwrap(), a);
911
    /// assert!((a * x % m).is_one());
912
    /// ```
913
0
    pub fn modinv(&self, modulus: &Self) -> Option<Self> {
914
0
        // Based on the inverse pseudocode listed here:
915
0
        // https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers
916
0
        // TODO: consider Binary or Lehmer's GCD algorithms for optimization.
917
0
918
0
        assert!(
919
0
            !modulus.is_zero(),
920
0
            "attempt to calculate with zero modulus!"
921
        );
922
0
        if modulus.is_one() {
923
0
            return Some(Self::zero());
924
0
        }
925
0
926
0
        let mut r0; // = modulus.clone();
927
0
        let mut r1 = self % modulus;
928
0
        let mut t0; // = Self::zero();
929
0
        let mut t1; // = Self::one();
930
0
931
0
        // Lift and simplify the first iteration to avoid some initial allocations.
932
0
        if r1.is_zero() {
933
0
            return None;
934
0
        } else if r1.is_one() {
935
0
            return Some(r1);
936
        } else {
937
0
            let (q, r2) = modulus.div_rem(&r1);
938
0
            if r2.is_zero() {
939
0
                return None;
940
0
            }
941
0
            r0 = r1;
942
0
            r1 = r2;
943
0
            t0 = Self::one();
944
0
            t1 = modulus - q;
945
        }
946
947
0
        while !r1.is_zero() {
948
0
            let (q, r2) = r0.div_rem(&r1);
949
0
            r0 = r1;
950
0
            r1 = r2;
951
0
952
0
            // let t2 = (t0 - q * t1) % modulus;
953
0
            let qt1 = q * &t1 % modulus;
954
0
            let t2 = if t0 < qt1 {
955
0
                t0 + (modulus - qt1)
956
            } else {
957
0
                t0 - qt1
958
            };
959
0
            t0 = t1;
960
0
            t1 = t2;
961
        }
962
963
0
        if r0.is_one() {
964
0
            Some(t0)
965
        } else {
966
0
            None
967
        }
968
0
    }
969
970
    /// Returns the truncated principal square root of `self` --
971
    /// see [Roots::sqrt](https://docs.rs/num-integer/0.1/num_integer/trait.Roots.html#method.sqrt)
972
0
    pub fn sqrt(&self) -> Self {
973
0
        Roots::sqrt(self)
974
0
    }
975
976
    /// Returns the truncated principal cube root of `self` --
977
    /// see [Roots::cbrt](https://docs.rs/num-integer/0.1/num_integer/trait.Roots.html#method.cbrt).
978
0
    pub fn cbrt(&self) -> Self {
979
0
        Roots::cbrt(self)
980
0
    }
981
982
    /// Returns the truncated principal `n`th root of `self` --
983
    /// see [Roots::nth_root](https://docs.rs/num-integer/0.1/num_integer/trait.Roots.html#tymethod.nth_root).
984
0
    pub fn nth_root(&self, n: u32) -> Self {
985
0
        Roots::nth_root(self, n)
986
0
    }
987
988
    /// Returns the number of least-significant bits that are zero,
989
    /// or `None` if the entire number is zero.
990
4.48k
    pub fn trailing_zeros(&self) -> Option<u64> {
991
1.23M
        let i = self.data.iter().position(|&digit| digit != 0)?;
992
4.48k
        let zeros: u64 = self.data[i].trailing_zeros().into();
993
4.48k
        Some(i as u64 * u64::from(big_digit::BITS) + zeros)
994
4.48k
    }
995
996
    /// Returns the number of least-significant bits that are ones.
997
0
    pub fn trailing_ones(&self) -> u64 {
998
0
        if let Some(i) = self.data.iter().position(|&digit| !digit != 0) {
999
0
            let ones: u64 = self.data[i].trailing_ones().into();
1000
0
            i as u64 * u64::from(big_digit::BITS) + ones
1001
        } else {
1002
0
            self.data.len() as u64 * u64::from(big_digit::BITS)
1003
        }
1004
0
    }
1005
1006
    /// Returns the number of one bits.
1007
0
    pub fn count_ones(&self) -> u64 {
1008
0
        self.data.iter().map(|&d| u64::from(d.count_ones())).sum()
1009
0
    }
1010
1011
    /// Returns whether the bit in the given position is set
1012
0
    pub fn bit(&self, bit: u64) -> bool {
1013
0
        let bits_per_digit = u64::from(big_digit::BITS);
1014
0
        if let Some(digit_index) = (bit / bits_per_digit).to_usize() {
1015
0
            if let Some(digit) = self.data.get(digit_index) {
1016
0
                let bit_mask = (1 as BigDigit) << (bit % bits_per_digit);
1017
0
                return (digit & bit_mask) != 0;
1018
0
            }
1019
0
        }
1020
0
        false
1021
0
    }
1022
1023
    /// Sets or clears the bit in the given position
1024
    ///
1025
    /// Note that setting a bit greater than the current bit length, a reallocation may be needed
1026
    /// to store the new digits
1027
0
    pub fn set_bit(&mut self, bit: u64, value: bool) {
1028
0
        // Note: we're saturating `digit_index` and `new_len` -- any such case is guaranteed to
1029
0
        // fail allocation, and that's more consistent than adding our own overflow panics.
1030
0
        let bits_per_digit = u64::from(big_digit::BITS);
1031
0
        let digit_index = (bit / bits_per_digit).to_usize().unwrap_or(usize::MAX);
1032
0
        let bit_mask = (1 as BigDigit) << (bit % bits_per_digit);
1033
0
        if value {
1034
0
            if digit_index >= self.data.len() {
1035
0
                let new_len = digit_index.saturating_add(1);
1036
0
                self.data.resize(new_len, 0);
1037
0
            }
1038
0
            self.data[digit_index] |= bit_mask;
1039
0
        } else if digit_index < self.data.len() {
1040
0
            self.data[digit_index] &= !bit_mask;
1041
0
            // the top bit may have been cleared, so normalize
1042
0
            self.normalize();
1043
0
        }
1044
0
    }
1045
}
1046
1047
impl num_traits::FromBytes for BigUint {
1048
    type Bytes = [u8];
1049
1050
0
    fn from_be_bytes(bytes: &Self::Bytes) -> Self {
1051
0
        Self::from_bytes_be(bytes)
1052
0
    }
1053
1054
0
    fn from_le_bytes(bytes: &Self::Bytes) -> Self {
1055
0
        Self::from_bytes_le(bytes)
1056
0
    }
1057
}
1058
1059
impl num_traits::ToBytes for BigUint {
1060
    type Bytes = Vec<u8>;
1061
1062
0
    fn to_be_bytes(&self) -> Self::Bytes {
1063
0
        self.to_bytes_be()
1064
0
    }
1065
1066
0
    fn to_le_bytes(&self) -> Self::Bytes {
1067
0
        self.to_bytes_le()
1068
0
    }
1069
}
1070
1071
pub(crate) trait IntDigits {
1072
    fn digits(&self) -> &[BigDigit];
1073
    fn digits_mut(&mut self) -> &mut Vec<BigDigit>;
1074
    fn normalize(&mut self);
1075
    fn capacity(&self) -> usize;
1076
    fn len(&self) -> usize;
1077
}
1078
1079
impl IntDigits for BigUint {
1080
    #[inline]
1081
49.4k
    fn digits(&self) -> &[BigDigit] {
1082
49.4k
        &self.data
1083
49.4k
    }
1084
    #[inline]
1085
12.0k
    fn digits_mut(&mut self) -> &mut Vec<BigDigit> {
1086
12.0k
        &mut self.data
1087
12.0k
    }
1088
    #[inline]
1089
12.0k
    fn normalize(&mut self) {
1090
12.0k
        self.normalize();
1091
12.0k
    }
1092
    #[inline]
1093
62.4k
    fn capacity(&self) -> usize {
1094
62.4k
        self.data.capacity()
1095
62.4k
    }
1096
    #[inline]
1097
34.5k
    fn len(&self) -> usize {
1098
34.5k
        self.data.len()
1099
34.5k
    }
1100
}
1101
1102
/// Convert a `u32` chunk (len is either 1 or 2) to a single `u64` digit
1103
#[inline]
1104
0
fn u32_chunk_to_u64(chunk: &[u32]) -> u64 {
1105
0
    // raw could have odd length
1106
0
    let mut digit = chunk[0] as u64;
1107
0
    if let Some(&hi) = chunk.get(1) {
1108
0
        digit |= (hi as u64) << 32;
1109
0
    }
1110
0
    digit
1111
0
}
Unexecuted instantiation: _RNvNtCs72ekIXsOXFl_10num_bigint7biguint16u32_chunk_to_u64Cs4RkbDk9WRL5_5clvmr
Unexecuted instantiation: _RNvNtCs72ekIXsOXFl_10num_bigint7biguint16u32_chunk_to_u64B3_
1112
1113
cfg_32_or_test!(
1114
    /// Combine four `u32`s into a single `u128`.
1115
    #[inline]
1116
    fn u32_to_u128(a: u32, b: u32, c: u32, d: u32) -> u128 {
1117
        u128::from(d) | (u128::from(c) << 32) | (u128::from(b) << 64) | (u128::from(a) << 96)
1118
    }
1119
);
1120
1121
cfg_32_or_test!(
1122
    /// Split a single `u128` into four `u32`.
1123
    #[inline]
1124
    fn u32_from_u128(n: u128) -> (u32, u32, u32, u32) {
1125
        (
1126
            (n >> 96) as u32,
1127
            (n >> 64) as u32,
1128
            (n >> 32) as u32,
1129
            n as u32,
1130
        )
1131
    }
1132
);
1133
1134
cfg_digit!(
1135
    #[test]
1136
    fn test_from_slice() {
1137
        fn check(slice: &[u32], data: &[BigDigit]) {
1138
            assert_eq!(BigUint::from_slice(slice).data, data);
1139
        }
1140
        check(&[1], &[1]);
1141
        check(&[0, 0, 0], &[]);
1142
        check(&[1, 2, 0, 0], &[1, 2]);
1143
        check(&[0, 0, 1, 2], &[0, 0, 1, 2]);
1144
        check(&[0, 0, 1, 2, 0, 0], &[0, 0, 1, 2]);
1145
        check(&[-1i32 as u32], &[-1i32 as BigDigit]);
1146
    }
1147
1148
    #[test]
1149
    fn test_from_slice() {
1150
        fn check(slice: &[u32], data: &[BigDigit]) {
1151
            assert_eq!(
1152
                BigUint::from_slice(slice).data,
1153
                data,
1154
                "from {:?}, to {:?}",
1155
                slice,
1156
                data
1157
            );
1158
        }
1159
        check(&[1], &[1]);
1160
        check(&[0, 0, 0], &[]);
1161
        check(&[1, 2], &[8_589_934_593]);
1162
        check(&[1, 2, 0, 0], &[8_589_934_593]);
1163
        check(&[0, 0, 1, 2], &[0, 8_589_934_593]);
1164
        check(&[0, 0, 1, 2, 0, 0], &[0, 8_589_934_593]);
1165
        check(&[-1i32 as u32], &[(-1i32 as u32) as BigDigit]);
1166
    }
1167
);
1168
1169
#[test]
1170
fn test_u32_u128() {
1171
    assert_eq!(u32_from_u128(0u128), (0, 0, 0, 0));
1172
    assert_eq!(
1173
        u32_from_u128(u128::MAX),
1174
        (u32::MAX, u32::MAX, u32::MAX, u32::MAX)
1175
    );
1176
1177
    assert_eq!(u32_from_u128(u32::MAX as u128), (0, 0, 0, u32::MAX));
1178
1179
    assert_eq!(u32_from_u128(u64::MAX as u128), (0, 0, u32::MAX, u32::MAX));
1180
1181
    assert_eq!(
1182
        u32_from_u128((u64::MAX as u128) + u32::MAX as u128),
1183
        (0, 1, 0, u32::MAX - 1)
1184
    );
1185
1186
    assert_eq!(u32_from_u128(36_893_488_151_714_070_528), (0, 2, 1, 0));
1187
}
1188
1189
#[test]
1190
fn test_u128_u32_roundtrip() {
1191
    // roundtrips
1192
    let values = vec![
1193
        0u128,
1194
        1u128,
1195
        u64::MAX as u128 * 3,
1196
        u32::MAX as u128,
1197
        u64::MAX as u128,
1198
        (u64::MAX as u128) + u32::MAX as u128,
1199
        u128::MAX,
1200
    ];
1201
1202
    for val in &values {
1203
        let (a, b, c, d) = u32_from_u128(*val);
1204
        assert_eq!(u32_to_u128(a, b, c, d), *val);
1205
    }
1206
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint/addition.rs
Line
Count
Source
1
use super::{BigUint, IntDigits};
2
3
use crate::big_digit::{self, BigDigit};
4
use crate::UsizePromotion;
5
6
use core::iter::Sum;
7
use core::ops::{Add, AddAssign};
8
use num_traits::CheckedAdd;
9
10
#[cfg(target_arch = "x86_64")]
11
use core::arch::x86_64 as arch;
12
13
#[cfg(target_arch = "x86")]
14
use core::arch::x86 as arch;
15
16
// Add with carry:
17
#[cfg(target_arch = "x86_64")]
18
cfg_64!(
19
    #[inline]
20
70.4M
    fn adc(carry: u8, a: u64, b: u64, out: &mut u64) -> u8 {
21
70.4M
        // Safety: There are absolutely no safety concerns with calling `_addcarry_u64`.
22
70.4M
        // It's just unsafe for API consistency with other intrinsics.
23
70.4M
        unsafe { arch::_addcarry_u64(carry, a, b, out) }
24
70.4M
    }
_RNvNtNtCs72ekIXsOXFl_10num_bigint7biguint8addition3adcCs4RkbDk9WRL5_5clvmr
Line
Count
Source
20
2.56M
    fn adc(carry: u8, a: u64, b: u64, out: &mut u64) -> u8 {
21
2.56M
        // Safety: There are absolutely no safety concerns with calling `_addcarry_u64`.
22
2.56M
        // It's just unsafe for API consistency with other intrinsics.
23
2.56M
        unsafe { arch::_addcarry_u64(carry, a, b, out) }
24
2.56M
    }
_RNvNtNtCs72ekIXsOXFl_10num_bigint7biguint8addition3adcB5_
Line
Count
Source
20
67.8M
    fn adc(carry: u8, a: u64, b: u64, out: &mut u64) -> u8 {
21
67.8M
        // Safety: There are absolutely no safety concerns with calling `_addcarry_u64`.
22
67.8M
        // It's just unsafe for API consistency with other intrinsics.
23
67.8M
        unsafe { arch::_addcarry_u64(carry, a, b, out) }
24
67.8M
    }
25
);
26
27
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
28
cfg_32!(
29
    #[inline]
30
    fn adc(carry: u8, a: u32, b: u32, out: &mut u32) -> u8 {
31
        // Safety: There are absolutely no safety concerns with calling `_addcarry_u32`.
32
        // It's just unsafe for API consistency with other intrinsics.
33
        unsafe { arch::_addcarry_u32(carry, a, b, out) }
34
    }
35
);
36
37
// fallback for environments where we don't have an addcarry intrinsic
38
// (copied from the standard library's `carrying_add`)
39
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
40
#[inline]
41
fn adc(carry: u8, lhs: BigDigit, rhs: BigDigit, out: &mut BigDigit) -> u8 {
42
    let (a, b) = lhs.overflowing_add(rhs);
43
    let (c, d) = a.overflowing_add(carry as BigDigit);
44
    *out = c;
45
    u8::from(b || d)
46
}
47
48
/// Two argument addition of raw slices, `a += b`, returning the carry.
49
///
50
/// This is used when the data `Vec` might need to resize to push a non-zero carry, so we perform
51
/// the addition first hoping that it will fit.
52
///
53
/// The caller _must_ ensure that `a` is at least as long as `b`.
54
#[inline]
55
6.14M
pub(super) fn __add2(a: &mut [BigDigit], b: &[BigDigit]) -> BigDigit {
56
6.14M
    debug_assert!(a.len() >= b.len());
57
58
6.14M
    let mut carry = 0;
59
6.14M
    let (a_lo, a_hi) = a.split_at_mut(b.len());
60
61
65.6M
    for (a, b) in a_lo.iter_mut().zip(b) {
62
65.6M
        carry = adc(carry, *a, *b, a);
63
65.6M
    }
64
65
6.14M
    if carry != 0 {
66
4.75M
        for a in a_hi {
67
4.74M
            carry = adc(carry, *a, 0, a);
68
4.74M
            if carry == 0 {
69
234k
                break;
70
4.50M
            }
71
        }
72
5.89M
    }
73
74
6.14M
    carry as BigDigit
75
6.14M
}
_RNvNtNtCs72ekIXsOXFl_10num_bigint7biguint8addition6___add2Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
55
27.9k
pub(super) fn __add2(a: &mut [BigDigit], b: &[BigDigit]) -> BigDigit {
56
27.9k
    debug_assert!(a.len() >= b.len());
57
58
27.9k
    let mut carry = 0;
59
27.9k
    let (a_lo, a_hi) = a.split_at_mut(b.len());
60
61
27.9k
    for (a, b) in a_lo.iter_mut().zip(b) {
62
27.9k
        carry = adc(carry, *a, *b, a);
63
27.9k
    }
64
65
27.9k
    if carry != 0 {
66
2.53M
        for a in a_hi {
67
2.53M
            carry = adc(carry, *a, 0, a);
68
2.53M
            if carry == 0 {
69
2.59k
                break;
70
2.53M
            }
71
        }
72
24.5k
    }
73
74
27.9k
    carry as BigDigit
75
27.9k
}
_RNvNtNtCs72ekIXsOXFl_10num_bigint7biguint8addition6___add2B5_
Line
Count
Source
55
6.11M
pub(super) fn __add2(a: &mut [BigDigit], b: &[BigDigit]) -> BigDigit {
56
6.11M
    debug_assert!(a.len() >= b.len());
57
58
6.11M
    let mut carry = 0;
59
6.11M
    let (a_lo, a_hi) = a.split_at_mut(b.len());
60
61
65.6M
    for (a, b) in a_lo.iter_mut().zip(b) {
62
65.6M
        carry = adc(carry, *a, *b, a);
63
65.6M
    }
64
65
6.11M
    if carry != 0 {
66
2.22M
        for a in a_hi {
67
2.21M
            carry = adc(carry, *a, 0, a);
68
2.21M
            if carry == 0 {
69
231k
                break;
70
1.97M
            }
71
        }
72
5.86M
    }
73
74
6.11M
    carry as BigDigit
75
6.11M
}
76
77
/// Two argument addition of raw slices:
78
/// a += b
79
///
80
/// The caller _must_ ensure that a is big enough to store the result - typically this means
81
/// resizing a to max(a.len(), b.len()) + 1, to fit a possible carry.
82
606k
pub(super) fn add2(a: &mut [BigDigit], b: &[BigDigit]) {
83
606k
    let carry = __add2(a, b);
84
606k
85
606k
    debug_assert!(carry == 0);
86
606k
}
87
88
forward_all_binop_to_val_ref_commutative!(impl Add for BigUint, add);
89
forward_val_assign!(impl AddAssign for BigUint, add_assign);
90
91
impl Add<&BigUint> for BigUint {
92
    type Output = BigUint;
93
94
81.0k
    fn add(mut self, other: &BigUint) -> BigUint {
95
81.0k
        self += other;
96
81.0k
        self
97
81.0k
    }
98
}
99
impl AddAssign<&BigUint> for BigUint {
100
    #[inline]
101
81.0k
    fn add_assign(&mut self, other: &BigUint) {
102
81.0k
        let self_len = self.data.len();
103
81.0k
        let carry = if self_len < other.data.len() {
104
8.79k
            let lo_carry = __add2(&mut self.data[..], &other.data[..self_len]);
105
8.79k
            self.data.extend_from_slice(&other.data[self_len..]);
106
8.79k
            __add2(&mut self.data[self_len..], &[lo_carry])
107
        } else {
108
72.2k
            __add2(&mut self.data[..], &other.data[..])
109
        };
110
81.0k
        if carry != 0 {
111
11.1k
            self.data.push(carry);
112
69.9k
        }
113
81.0k
    }
114
}
115
116
promote_unsigned_scalars!(impl Add for BigUint, add);
117
promote_unsigned_scalars_assign!(impl AddAssign for BigUint, add_assign);
118
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u32> for BigUint, add);
119
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u64> for BigUint, add);
120
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u128> for BigUint, add);
121
122
impl Add<u32> for BigUint {
123
    type Output = BigUint;
124
125
    #[inline]
126
36.9k
    fn add(mut self, other: u32) -> BigUint {
127
36.9k
        self += other;
128
36.9k
        self
129
36.9k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddmE3addCs4RkbDk9WRL5_5clvmr
Line
Count
Source
126
36.7k
    fn add(mut self, other: u32) -> BigUint {
127
36.7k
        self += other;
128
36.7k
        self
129
36.7k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddmE3addB9_
Line
Count
Source
126
214
    fn add(mut self, other: u32) -> BigUint {
127
214
        self += other;
128
214
        self
129
214
    }
130
}
131
132
impl AddAssign<u32> for BigUint {
133
    #[inline]
134
37.7k
    fn add_assign(&mut self, other: u32) {
135
37.7k
        if other != 0 {
136
29.0k
            if self.data.is_empty() {
137
354
                self.data.push(0);
138
28.7k
            }
139
140
29.0k
            let carry = __add2(&mut self.data, &[other as BigDigit]);
141
29.0k
            if carry != 0 {
142
842
                self.data.push(carry);
143
28.2k
            }
144
8.71k
        }
145
37.7k
    }
_RNvXs1_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignmE10add_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
134
36.7k
    fn add_assign(&mut self, other: u32) {
135
36.7k
        if other != 0 {
136
27.9k
            if self.data.is_empty() {
137
18
                self.data.push(0);
138
27.9k
            }
139
140
27.9k
            let carry = __add2(&mut self.data, &[other as BigDigit]);
141
27.9k
            if carry != 0 {
142
842
                self.data.push(carry);
143
27.1k
            }
144
8.71k
        }
145
36.7k
    }
_RNvXs1_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignmE10add_assignB9_
Line
Count
Source
134
1.06k
    fn add_assign(&mut self, other: u32) {
135
1.06k
        if other != 0 {
136
1.06k
            if self.data.is_empty() {
137
336
                self.data.push(0);
138
727
            }
139
140
1.06k
            let carry = __add2(&mut self.data, &[other as BigDigit]);
141
1.06k
            if carry != 0 {
142
0
                self.data.push(carry);
143
1.06k
            }
144
0
        }
145
1.06k
    }
146
}
147
148
impl Add<u64> for BigUint {
149
    type Output = BigUint;
150
151
    #[inline]
152
0
    fn add(mut self, other: u64) -> BigUint {
153
0
        self += other;
154
0
        self
155
0
    }
156
}
157
158
impl AddAssign<u64> for BigUint {
159
    cfg_digit!(
160
        #[inline]
161
        fn add_assign(&mut self, other: u64) {
162
            let (hi, lo) = big_digit::from_doublebigdigit(other);
163
            if hi == 0 {
164
                *self += lo;
165
            } else {
166
                while self.data.len() < 2 {
167
                    self.data.push(0);
168
                }
169
170
                let carry = __add2(&mut self.data, &[lo, hi]);
171
                if carry != 0 {
172
                    self.data.push(carry);
173
                }
174
            }
175
        }
176
177
        #[inline]
178
0
        fn add_assign(&mut self, other: u64) {
179
0
            if other != 0 {
180
0
                if self.data.is_empty() {
181
0
                    self.data.push(0);
182
0
                }
183
184
0
                let carry = __add2(&mut self.data, &[other as BigDigit]);
185
0
                if carry != 0 {
186
0
                    self.data.push(carry);
187
0
                }
188
0
            }
189
0
        }
190
    );
191
}
192
193
impl Add<u128> for BigUint {
194
    type Output = BigUint;
195
196
    #[inline]
197
0
    fn add(mut self, other: u128) -> BigUint {
198
0
        self += other;
199
0
        self
200
0
    }
201
}
202
203
impl AddAssign<u128> for BigUint {
204
    cfg_digit!(
205
        #[inline]
206
        fn add_assign(&mut self, other: u128) {
207
            if other <= u128::from(u64::MAX) {
208
                *self += other as u64
209
            } else {
210
                let (a, b, c, d) = super::u32_from_u128(other);
211
                let carry = if a > 0 {
212
                    while self.data.len() < 4 {
213
                        self.data.push(0);
214
                    }
215
                    __add2(&mut self.data, &[d, c, b, a])
216
                } else {
217
                    debug_assert!(b > 0);
218
                    while self.data.len() < 3 {
219
                        self.data.push(0);
220
                    }
221
                    __add2(&mut self.data, &[d, c, b])
222
                };
223
224
                if carry != 0 {
225
                    self.data.push(carry);
226
                }
227
            }
228
        }
229
230
        #[inline]
231
0
        fn add_assign(&mut self, other: u128) {
232
0
            let (hi, lo) = big_digit::from_doublebigdigit(other);
233
0
            if hi == 0 {
234
0
                *self += lo;
235
0
            } else {
236
0
                while self.data.len() < 2 {
237
0
                    self.data.push(0);
238
0
                }
239
240
0
                let carry = __add2(&mut self.data, &[lo, hi]);
241
0
                if carry != 0 {
242
0
                    self.data.push(carry);
243
0
                }
244
            }
245
0
        }
246
    );
247
}
248
249
impl CheckedAdd for BigUint {
250
    #[inline]
251
0
    fn checked_add(&self, v: &BigUint) -> Option<BigUint> {
252
0
        Some(self.add(v))
253
0
    }
254
}
255
256
impl_sum_iter_type!(BigUint);
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint/bits.rs
Line
Count
Source
1
use super::{BigUint, IntDigits};
2
3
use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign};
4
5
forward_val_val_binop!(impl BitAnd for BigUint, bitand);
6
forward_ref_val_binop!(impl BitAnd for BigUint, bitand);
7
8
// do not use forward_ref_ref_binop_commutative! for bitand so that we can
9
// clone the smaller value rather than the larger, avoiding over-allocation
10
impl BitAnd<&BigUint> for &BigUint {
11
    type Output = BigUint;
12
13
    #[inline]
14
0
    fn bitand(self, other: &BigUint) -> BigUint {
15
0
        // forward to val-ref, choosing the smaller to clone
16
0
        if self.data.len() <= other.data.len() {
17
0
            self.clone() & other
18
        } else {
19
0
            other.clone() & self
20
        }
21
0
    }
22
}
23
24
forward_val_assign!(impl BitAndAssign for BigUint, bitand_assign);
25
26
impl BitAnd<&BigUint> for BigUint {
27
    type Output = BigUint;
28
29
    #[inline]
30
0
    fn bitand(mut self, other: &BigUint) -> BigUint {
31
0
        self &= other;
32
0
        self
33
0
    }
34
}
35
impl BitAndAssign<&BigUint> for BigUint {
36
    #[inline]
37
1.19k
    fn bitand_assign(&mut self, other: &BigUint) {
38
5.05k
        for (ai, &bi) in self.data.iter_mut().zip(other.data.iter()) {
39
5.05k
            *ai &= bi;
40
5.05k
        }
41
1.19k
        self.data.truncate(other.data.len());
42
1.19k
        self.normalize();
43
1.19k
    }
44
}
45
46
forward_all_binop_to_val_ref_commutative!(impl BitOr for BigUint, bitor);
47
forward_val_assign!(impl BitOrAssign for BigUint, bitor_assign);
48
49
impl BitOr<&BigUint> for BigUint {
50
    type Output = BigUint;
51
52
0
    fn bitor(mut self, other: &BigUint) -> BigUint {
53
0
        self |= other;
54
0
        self
55
0
    }
56
}
57
impl BitOrAssign<&BigUint> for BigUint {
58
    #[inline]
59
1.37k
    fn bitor_assign(&mut self, other: &BigUint) {
60
3.24k
        for (ai, &bi) in self.data.iter_mut().zip(other.data.iter()) {
61
3.24k
            *ai |= bi;
62
3.24k
        }
63
1.37k
        if other.data.len() > self.data.len() {
64
503
            let extra = &other.data[self.data.len()..];
65
503
            self.data.extend(extra.iter().cloned());
66
875
        }
67
1.37k
    }
68
}
69
70
forward_all_binop_to_val_ref_commutative!(impl BitXor for BigUint, bitxor);
71
forward_val_assign!(impl BitXorAssign for BigUint, bitxor_assign);
72
73
impl BitXor<&BigUint> for BigUint {
74
    type Output = BigUint;
75
76
0
    fn bitxor(mut self, other: &BigUint) -> BigUint {
77
0
        self ^= other;
78
0
        self
79
0
    }
80
}
81
impl BitXorAssign<&BigUint> for BigUint {
82
    #[inline]
83
1.60k
    fn bitxor_assign(&mut self, other: &BigUint) {
84
4.93k
        for (ai, &bi) in self.data.iter_mut().zip(other.data.iter()) {
85
4.93k
            *ai ^= bi;
86
4.93k
        }
87
1.60k
        if other.data.len() > self.data.len() {
88
415
            let extra = &other.data[self.data.len()..];
89
415
            self.data.extend(extra.iter().cloned());
90
1.18k
        }
91
1.60k
        self.normalize();
92
1.60k
    }
93
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint/convert.rs
Line
Count
Source
1
// This uses stdlib features higher than the MSRV
2
#![allow(clippy::manual_range_contains)] // 1.35
3
4
use super::{biguint_from_vec, BigUint, ToBigUint};
5
6
use super::addition::add2;
7
use super::division::{div_rem_digit, FAST_DIV_WIDE};
8
use super::multiplication::mac_with_carry;
9
10
use crate::big_digit::{self, BigDigit};
11
use crate::ParseBigIntError;
12
use crate::TryFromBigIntError;
13
14
use alloc::vec::Vec;
15
use core::cmp::Ordering::{Equal, Greater, Less};
16
use core::convert::TryFrom;
17
use core::mem;
18
use core::str::FromStr;
19
use num_integer::{Integer, Roots};
20
use num_traits::float::FloatCore;
21
use num_traits::{FromPrimitive, Num, One, PrimInt, ToPrimitive, Zero};
22
23
/// Find last set bit
24
/// fls(0) == 0, fls(u32::MAX) == 32
25
0
fn fls<T: PrimInt>(v: T) -> u8 {
26
0
    mem::size_of::<T>() as u8 * 8 - v.leading_zeros() as u8
27
0
}
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint7convert3flsmEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint7convert3flsyEB6_
28
29
0
fn ilog2<T: PrimInt>(v: T) -> u8 {
30
0
    fls(v) - 1
31
0
}
32
33
impl FromStr for BigUint {
34
    type Err = ParseBigIntError;
35
36
    #[inline]
37
0
    fn from_str(s: &str) -> Result<BigUint, ParseBigIntError> {
38
0
        BigUint::from_str_radix(s, 10)
39
0
    }
40
}
41
42
// Convert from a power of two radix (bits == ilog2(radix)) where bits evenly divides
43
// BigDigit::BITS
44
232k
pub(super) fn from_bitwise_digits_le(v: &[u8], bits: u8) -> BigUint {
45
232k
    debug_assert!(!v.is_empty() && bits <= 8 && big_digit::BITS % bits == 0);
46
190M
    debug_assert!(v.iter().all(|&c| BigDigit::from(c) < (1 << bits)));
47
48
232k
    let digits_per_big_digit = big_digit::BITS / bits;
49
232k
50
232k
    let data = v
51
232k
        .chunks(digits_per_big_digit.into())
52
23.9M
        .map(|chunk| {
53
23.9M
            chunk
54
23.9M
                .iter()
55
23.9M
                .rev()
56
190M
                .fold(0, |acc, &c| (acc << bits) | BigDigit::from(c))
57
23.9M
        })
58
232k
        .collect();
59
232k
60
232k
    biguint_from_vec(data)
61
232k
}
62
63
// Convert from a power of two radix (bits == ilog2(radix)) where bits doesn't evenly divide
64
// BigDigit::BITS
65
0
fn from_inexact_bitwise_digits_le(v: &[u8], bits: u8) -> BigUint {
66
0
    debug_assert!(!v.is_empty() && bits <= 8 && big_digit::BITS % bits != 0);
67
0
    debug_assert!(v.iter().all(|&c| BigDigit::from(c) < (1 << bits)));
68
69
0
    let total_bits = (v.len() as u64).saturating_mul(bits.into());
70
0
    let big_digits = Integer::div_ceil(&total_bits, &big_digit::BITS.into())
71
0
        .to_usize()
72
0
        .unwrap_or(usize::MAX);
73
0
    let mut data = Vec::with_capacity(big_digits);
74
0
75
0
    let mut d = 0;
76
0
    let mut dbits = 0; // number of bits we currently have in d
77
78
    // walk v accumululating bits in d; whenever we accumulate big_digit::BITS in d, spit out a
79
    // big_digit:
80
0
    for &c in v {
81
0
        d |= BigDigit::from(c) << dbits;
82
0
        dbits += bits;
83
0
84
0
        if dbits >= big_digit::BITS {
85
0
            data.push(d);
86
0
            dbits -= big_digit::BITS;
87
0
            // if dbits was > big_digit::BITS, we dropped some of the bits in c (they couldn't fit
88
0
            // in d) - grab the bits we lost here:
89
0
            d = BigDigit::from(c) >> (bits - dbits);
90
0
        }
91
    }
92
93
0
    if dbits > 0 {
94
0
        debug_assert!(dbits < big_digit::BITS);
95
0
        data.push(d as BigDigit);
96
0
    }
97
98
0
    biguint_from_vec(data)
99
0
}
100
101
// Read little-endian radix digits
102
0
fn from_radix_digits_be(v: &[u8], radix: u32) -> BigUint {
103
0
    debug_assert!(!v.is_empty() && !radix.is_power_of_two());
104
0
    debug_assert!(v.iter().all(|&c| u32::from(c) < radix));
105
106
    // Estimate how big the result will be, so we can pre-allocate it.
107
    #[cfg(feature = "std")]
108
0
    let big_digits = {
109
0
        let radix_log2 = f64::from(radix).log2();
110
0
        let bits = radix_log2 * v.len() as f64;
111
0
        (bits / big_digit::BITS as f64).ceil()
112
0
    };
113
0
    #[cfg(not(feature = "std"))]
114
0
    let big_digits = {
115
0
        let radix_log2 = ilog2(radix.next_power_of_two()) as usize;
116
0
        let bits = radix_log2 * v.len();
117
0
        (bits / big_digit::BITS as usize) + 1
118
0
    };
119
0
120
0
    let mut data = Vec::with_capacity(big_digits.to_usize().unwrap_or(0));
121
0
122
0
    let (base, power) = get_radix_base(radix);
123
0
    let radix = radix as BigDigit;
124
0
125
0
    let r = v.len() % power;
126
0
    let i = if r == 0 { power } else { r };
127
0
    let (head, tail) = v.split_at(i);
128
0
129
0
    let first = head
130
0
        .iter()
131
0
        .fold(0, |acc, &d| acc * radix + BigDigit::from(d));
132
0
    data.push(first);
133
0
134
0
    debug_assert!(tail.len() % power == 0);
135
0
    for chunk in tail.chunks(power) {
136
0
        if data.last() != Some(&0) {
137
0
            data.push(0);
138
0
        }
139
140
0
        let mut carry = 0;
141
0
        for d in data.iter_mut() {
142
0
            *d = mac_with_carry(0, *d, base, &mut carry);
143
0
        }
144
0
        debug_assert!(carry == 0);
145
146
0
        let n = chunk
147
0
            .iter()
148
0
            .fold(0, |acc, &d| acc * radix + BigDigit::from(d));
149
0
        add2(&mut data, &[n]);
150
0
    }
151
152
0
    biguint_from_vec(data)
153
0
}
154
155
0
pub(super) fn from_radix_be(buf: &[u8], radix: u32) -> Option<BigUint> {
156
0
    assert!(
157
0
        2 <= radix && radix <= 256,
158
0
        "The radix must be within 2...256"
159
    );
160
161
0
    if buf.is_empty() {
162
0
        return Some(BigUint::ZERO);
163
0
    }
164
0
165
0
    if radix != 256 && buf.iter().any(|&b| b >= radix as u8) {
166
0
        return None;
167
0
    }
168
169
0
    let res = if radix.is_power_of_two() {
170
        // Powers of two can use bitwise masks and shifting instead of multiplication
171
0
        let bits = ilog2(radix);
172
0
        let mut v = Vec::from(buf);
173
0
        v.reverse();
174
0
        if big_digit::BITS % bits == 0 {
175
0
            from_bitwise_digits_le(&v, bits)
176
        } else {
177
0
            from_inexact_bitwise_digits_le(&v, bits)
178
        }
179
    } else {
180
0
        from_radix_digits_be(buf, radix)
181
    };
182
183
0
    Some(res)
184
0
}
185
186
0
pub(super) fn from_radix_le(buf: &[u8], radix: u32) -> Option<BigUint> {
187
0
    assert!(
188
0
        2 <= radix && radix <= 256,
189
0
        "The radix must be within 2...256"
190
    );
191
192
0
    if buf.is_empty() {
193
0
        return Some(BigUint::ZERO);
194
0
    }
195
0
196
0
    if radix != 256 && buf.iter().any(|&b| b >= radix as u8) {
197
0
        return None;
198
0
    }
199
200
0
    let res = if radix.is_power_of_two() {
201
        // Powers of two can use bitwise masks and shifting instead of multiplication
202
0
        let bits = ilog2(radix);
203
0
        if big_digit::BITS % bits == 0 {
204
0
            from_bitwise_digits_le(buf, bits)
205
        } else {
206
0
            from_inexact_bitwise_digits_le(buf, bits)
207
        }
208
    } else {
209
0
        let mut v = Vec::from(buf);
210
0
        v.reverse();
211
0
        from_radix_digits_be(&v, radix)
212
    };
213
214
0
    Some(res)
215
0
}
216
217
impl Num for BigUint {
218
    type FromStrRadixErr = ParseBigIntError;
219
220
    /// Creates and initializes a `BigUint`.
221
0
    fn from_str_radix(s: &str, radix: u32) -> Result<BigUint, ParseBigIntError> {
222
0
        assert!(2 <= radix && radix <= 36, "The radix must be within 2...36");
223
0
        let mut s = s;
224
0
        if let Some(tail) = s.strip_prefix('+') {
225
0
            if !tail.starts_with('+') {
226
0
                s = tail
227
0
            }
228
0
        }
229
230
0
        if s.is_empty() {
231
0
            return Err(ParseBigIntError::empty());
232
0
        }
233
0
234
0
        if s.starts_with('_') {
235
            // Must lead with a real digit!
236
0
            return Err(ParseBigIntError::invalid());
237
0
        }
238
0
239
0
        // First normalize all characters to plain digit values
240
0
        let mut v = Vec::with_capacity(s.len());
241
0
        for b in s.bytes() {
242
0
            let d = match b {
243
0
                b'0'..=b'9' => b - b'0',
244
0
                b'a'..=b'z' => b - b'a' + 10,
245
0
                b'A'..=b'Z' => b - b'A' + 10,
246
0
                b'_' => continue,
247
0
                _ => u8::MAX,
248
            };
249
0
            if d < radix as u8 {
250
0
                v.push(d);
251
0
            } else {
252
0
                return Err(ParseBigIntError::invalid());
253
            }
254
        }
255
256
0
        let res = if radix.is_power_of_two() {
257
            // Powers of two can use bitwise masks and shifting instead of multiplication
258
0
            let bits = ilog2(radix);
259
0
            v.reverse();
260
0
            if big_digit::BITS % bits == 0 {
261
0
                from_bitwise_digits_le(&v, bits)
262
            } else {
263
0
                from_inexact_bitwise_digits_le(&v, bits)
264
            }
265
        } else {
266
0
            from_radix_digits_be(&v, radix)
267
        };
268
0
        Ok(res)
269
0
    }
270
}
271
272
0
fn high_bits_to_u64(v: &BigUint) -> u64 {
273
0
    match v.data.len() {
274
0
        0 => 0,
275
        1 => {
276
            // XXX Conversion is useless if already 64-bit.
277
            #[allow(clippy::useless_conversion)]
278
0
            let v0 = u64::from(v.data[0]);
279
0
            v0
280
        }
281
        _ => {
282
0
            let mut bits = v.bits();
283
0
            let mut ret = 0u64;
284
0
            let mut ret_bits = 0;
285
286
0
            for d in v.data.iter().rev() {
287
0
                let digit_bits = (bits - 1) % u64::from(big_digit::BITS) + 1;
288
0
                let bits_want = Ord::min(64 - ret_bits, digit_bits);
289
0
290
0
                if bits_want != 0 {
291
0
                    if bits_want != 64 {
292
0
                        ret <<= bits_want;
293
0
                    }
294
                    // XXX Conversion is useless if already 64-bit.
295
                    #[allow(clippy::useless_conversion)]
296
0
                    let d0 = u64::from(*d) >> (digit_bits - bits_want);
297
0
                    ret |= d0;
298
0
                }
299
300
                // Implement round-to-odd: If any lower bits are 1, set LSB to 1
301
                // so that rounding again to floating point value using
302
                // nearest-ties-to-even is correct.
303
                //
304
                // See: https://en.wikipedia.org/wiki/Rounding#Rounding_to_prepare_for_shorter_precision
305
306
0
                if digit_bits - bits_want != 0 {
307
0
                    // XXX Conversion is useless if already 64-bit.
308
0
                    #[allow(clippy::useless_conversion)]
309
0
                    let masked = u64::from(*d) << (64 - (digit_bits - bits_want) as u32);
310
0
                    ret |= (masked != 0) as u64;
311
0
                }
312
313
0
                ret_bits += bits_want;
314
0
                bits -= bits_want;
315
            }
316
317
0
            ret
318
        }
319
    }
320
0
}
321
322
impl ToPrimitive for BigUint {
323
    #[inline]
324
0
    fn to_i64(&self) -> Option<i64> {
325
0
        self.to_u64().as_ref().and_then(u64::to_i64)
326
0
    }
327
328
    #[inline]
329
0
    fn to_i128(&self) -> Option<i128> {
330
0
        self.to_u128().as_ref().and_then(u128::to_i128)
331
0
    }
332
333
    #[allow(clippy::useless_conversion)]
334
    #[inline]
335
358k
    fn to_u64(&self) -> Option<u64> {
336
358k
        let mut ret: u64 = 0;
337
358k
        let mut bits = 0;
338
339
502k
        for i in self.data.iter() {
340
502k
            if bits >= 64 {
341
144k
                return None;
342
358k
            }
343
358k
344
358k
            // XXX Conversion is useless if already 64-bit.
345
358k
            ret += u64::from(*i) << bits;
346
358k
            bits += big_digit::BITS;
347
        }
348
349
214k
        Some(ret)
350
358k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_u64Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
335
202k
    fn to_u64(&self) -> Option<u64> {
336
202k
        let mut ret: u64 = 0;
337
202k
        let mut bits = 0;
338
339
236k
        for i in self.data.iter() {
340
236k
            if bits >= 64 {
341
33.6k
                return None;
342
202k
            }
343
202k
344
202k
            // XXX Conversion is useless if already 64-bit.
345
202k
            ret += u64::from(*i) << bits;
346
202k
            bits += big_digit::BITS;
347
        }
348
349
169k
        Some(ret)
350
202k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_u64B9_
Line
Count
Source
335
155k
    fn to_u64(&self) -> Option<u64> {
336
155k
        let mut ret: u64 = 0;
337
155k
        let mut bits = 0;
338
339
266k
        for i in self.data.iter() {
340
266k
            if bits >= 64 {
341
110k
                return None;
342
155k
            }
343
155k
344
155k
            // XXX Conversion is useless if already 64-bit.
345
155k
            ret += u64::from(*i) << bits;
346
155k
            bits += big_digit::BITS;
347
        }
348
349
45.6k
        Some(ret)
350
155k
    }
351
352
    #[inline]
353
0
    fn to_u128(&self) -> Option<u128> {
354
0
        let mut ret: u128 = 0;
355
0
        let mut bits = 0;
356
357
0
        for i in self.data.iter() {
358
0
            if bits >= 128 {
359
0
                return None;
360
0
            }
361
0
362
0
            ret |= u128::from(*i) << bits;
363
0
            bits += big_digit::BITS;
364
        }
365
366
0
        Some(ret)
367
0
    }
368
369
    #[inline]
370
0
    fn to_f32(&self) -> Option<f32> {
371
0
        let mantissa = high_bits_to_u64(self);
372
0
        let exponent = self.bits() - u64::from(fls(mantissa));
373
0
374
0
        if exponent > f32::MAX_EXP as u64 {
375
0
            Some(f32::INFINITY)
376
        } else {
377
0
            Some((mantissa as f32) * 2.0f32.powi(exponent as i32))
378
        }
379
0
    }
380
381
    #[inline]
382
0
    fn to_f64(&self) -> Option<f64> {
383
0
        let mantissa = high_bits_to_u64(self);
384
0
        let exponent = self.bits() - u64::from(fls(mantissa));
385
0
386
0
        if exponent > f64::MAX_EXP as u64 {
387
0
            Some(f64::INFINITY)
388
        } else {
389
0
            Some((mantissa as f64) * 2.0f64.powi(exponent as i32))
390
        }
391
0
    }
392
}
393
394
macro_rules! impl_try_from_biguint {
395
    ($T:ty, $to_ty:path) => {
396
        impl TryFrom<&BigUint> for $T {
397
            type Error = TryFromBigIntError<()>;
398
399
            #[inline]
400
0
            fn try_from(value: &BigUint) -> Result<$T, TryFromBigIntError<()>> {
401
0
                $to_ty(value).ok_or(TryFromBigIntError::new(()))
402
0
            }
Unexecuted instantiation: _RNvXs6_NtNtCs72ekIXsOXFl_10num_bigint7biguint7converthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXs8_NtNtCs72ekIXsOXFl_10num_bigint7biguint7converttINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsa_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertmINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsc_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertyINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertjINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertoINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsi_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertaINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsk_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertsINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertlINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertxINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsq_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertiINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXss_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertnINtNtCsbQ8arDwx5Xq_4core7convert7TryFromRNtB7_7BigUintE8try_fromB9_
403
        }
404
405
        impl TryFrom<BigUint> for $T {
406
            type Error = TryFromBigIntError<BigUint>;
407
408
            #[inline]
409
0
            fn try_from(value: BigUint) -> Result<$T, TryFromBigIntError<BigUint>> {
410
0
                <$T>::try_from(&value).map_err(|_| TryFromBigIntError::new(value))
Unexecuted instantiation: _RNCNvXs7_NtNtCs72ekIXsOXFl_10num_bigint7biguint7converthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
Unexecuted instantiation: _RNCNvXs9_NtNtCs72ekIXsOXFl_10num_bigint7biguint7converttINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsb_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertmINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsd_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertyINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsf_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertjINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsh_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertoINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsj_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertaINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsl_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertsINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsn_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertlINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsp_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertxINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
Unexecuted instantiation: _RNCNvXsr_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertiINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
Unexecuted instantiation: _RNCNvXst_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertnINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB9_7BigUintE8try_from0Bb_
411
0
            }
Unexecuted instantiation: _RNvXs7_NtNtCs72ekIXsOXFl_10num_bigint7biguint7converthINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXs9_NtNtCs72ekIXsOXFl_10num_bigint7biguint7converttINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsb_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertmINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertyINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertjINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsh_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertoINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsj_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertaINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsl_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertsINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertlINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertxINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXsr_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertiINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
Unexecuted instantiation: _RNvXst_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertnINtNtCsbQ8arDwx5Xq_4core7convert7TryFromNtB7_7BigUintE8try_fromB9_
412
        }
413
    };
414
}
415
416
impl_try_from_biguint!(u8, ToPrimitive::to_u8);
417
impl_try_from_biguint!(u16, ToPrimitive::to_u16);
418
impl_try_from_biguint!(u32, ToPrimitive::to_u32);
419
impl_try_from_biguint!(u64, ToPrimitive::to_u64);
420
impl_try_from_biguint!(usize, ToPrimitive::to_usize);
421
impl_try_from_biguint!(u128, ToPrimitive::to_u128);
422
423
impl_try_from_biguint!(i8, ToPrimitive::to_i8);
424
impl_try_from_biguint!(i16, ToPrimitive::to_i16);
425
impl_try_from_biguint!(i32, ToPrimitive::to_i32);
426
impl_try_from_biguint!(i64, ToPrimitive::to_i64);
427
impl_try_from_biguint!(isize, ToPrimitive::to_isize);
428
impl_try_from_biguint!(i128, ToPrimitive::to_i128);
429
430
impl FromPrimitive for BigUint {
431
    #[inline]
432
0
    fn from_i64(n: i64) -> Option<BigUint> {
433
0
        if n >= 0 {
434
0
            Some(BigUint::from(n as u64))
435
        } else {
436
0
            None
437
        }
438
0
    }
439
440
    #[inline]
441
0
    fn from_i128(n: i128) -> Option<BigUint> {
442
0
        if n >= 0 {
443
0
            Some(BigUint::from(n as u128))
444
        } else {
445
0
            None
446
        }
447
0
    }
448
449
    #[inline]
450
0
    fn from_u64(n: u64) -> Option<BigUint> {
451
0
        Some(BigUint::from(n))
452
0
    }
453
454
    #[inline]
455
0
    fn from_u128(n: u128) -> Option<BigUint> {
456
0
        Some(BigUint::from(n))
457
0
    }
458
459
    #[inline]
460
0
    fn from_f64(mut n: f64) -> Option<BigUint> {
461
0
        // handle NAN, INFINITY, NEG_INFINITY
462
0
        if !n.is_finite() {
463
0
            return None;
464
0
        }
465
0
466
0
        // match the rounding of casting from float to int
467
0
        n = n.trunc();
468
0
469
0
        // handle 0.x, -0.x
470
0
        if n.is_zero() {
471
0
            return Some(Self::ZERO);
472
0
        }
473
0
474
0
        let (mantissa, exponent, sign) = FloatCore::integer_decode(n);
475
0
476
0
        if sign == -1 {
477
0
            return None;
478
0
        }
479
0
480
0
        let mut ret = BigUint::from(mantissa);
481
0
        match exponent.cmp(&0) {
482
0
            Greater => ret <<= exponent as usize,
483
0
            Equal => {}
484
0
            Less => ret >>= (-exponent) as usize,
485
        }
486
0
        Some(ret)
487
0
    }
488
}
489
490
impl From<u64> for BigUint {
491
    #[inline]
492
345k
    fn from(mut n: u64) -> Self {
493
345k
        let mut ret: BigUint = Self::ZERO;
494
495
671k
        while n != 0 {
496
325k
            ret.data.push(n as BigDigit);
497
325k
            // don't overflow if BITS is 64:
498
325k
            n = (n >> 1) >> (big_digit::BITS - 1);
499
325k
        }
500
501
345k
        ret
502
345k
    }
_RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert4FromyE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
492
180k
    fn from(mut n: u64) -> Self {
493
180k
        let mut ret: BigUint = Self::ZERO;
494
495
351k
        while n != 0 {
496
171k
            ret.data.push(n as BigDigit);
497
171k
            // don't overflow if BITS is 64:
498
171k
            n = (n >> 1) >> (big_digit::BITS - 1);
499
171k
        }
500
501
180k
        ret
502
180k
    }
_RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert4FromyE4fromCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
492
109k
    fn from(mut n: u64) -> Self {
493
109k
        let mut ret: BigUint = Self::ZERO;
494
495
218k
        while n != 0 {
496
109k
            ret.data.push(n as BigDigit);
497
109k
            // don't overflow if BITS is 64:
498
109k
            n = (n >> 1) >> (big_digit::BITS - 1);
499
109k
        }
500
501
109k
        ret
502
109k
    }
_RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert4FromyE4fromB9_
Line
Count
Source
492
55.8k
    fn from(mut n: u64) -> Self {
493
55.8k
        let mut ret: BigUint = Self::ZERO;
494
495
100k
        while n != 0 {
496
45.0k
            ret.data.push(n as BigDigit);
497
45.0k
            // don't overflow if BITS is 64:
498
45.0k
            n = (n >> 1) >> (big_digit::BITS - 1);
499
45.0k
        }
500
501
55.8k
        ret
502
55.8k
    }
503
}
504
505
impl From<u128> for BigUint {
506
    #[inline]
507
0
    fn from(mut n: u128) -> Self {
508
0
        let mut ret: BigUint = Self::ZERO;
509
510
0
        while n != 0 {
511
0
            ret.data.push(n as BigDigit);
512
0
            n >>= big_digit::BITS;
513
0
        }
514
515
0
        ret
516
0
    }
517
}
518
519
macro_rules! impl_biguint_from_uint {
520
    ($T:ty) => {
521
        impl From<$T> for BigUint {
522
            #[inline]
523
38.5k
            fn from(n: $T) -> Self {
524
38.5k
                BigUint::from(n as u64)
525
38.5k
            }
_RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert4FrommE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
523
38.5k
            fn from(n: $T) -> Self {
524
38.5k
                BigUint::from(n as u64)
525
38.5k
            }
Unexecuted instantiation: _RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert4FrommE4fromB9_
Unexecuted instantiation: _RNvXsu_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert4FromhE4fromB9_
Unexecuted instantiation: _RNvXsv_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert4FromtE4fromB9_
Unexecuted instantiation: _RNvXsx_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert4FromjE4fromB9_
526
        }
527
    };
528
}
529
530
impl_biguint_from_uint!(u8);
531
impl_biguint_from_uint!(u16);
532
impl_biguint_from_uint!(u32);
533
impl_biguint_from_uint!(usize);
534
535
macro_rules! impl_biguint_try_from_int {
536
    ($T:ty, $from_ty:path) => {
537
        impl TryFrom<$T> for BigUint {
538
            type Error = TryFromBigIntError<()>;
539
540
            #[inline]
541
0
            fn try_from(value: $T) -> Result<BigUint, TryFromBigIntError<()>> {
542
0
                $from_ty(value).ok_or(TryFromBigIntError::new(()))
543
0
            }
Unexecuted instantiation: _RNvXsy_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert7TryFromaE8try_fromB9_
Unexecuted instantiation: _RNvXsz_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert7TryFromsE8try_fromB9_
Unexecuted instantiation: _RNvXsA_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert7TryFromlE8try_fromB9_
Unexecuted instantiation: _RNvXsB_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert7TryFromxE8try_fromB9_
Unexecuted instantiation: _RNvXsC_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert7TryFromiE8try_fromB9_
Unexecuted instantiation: _RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertNtB7_7BigUintINtNtCsbQ8arDwx5Xq_4core7convert7TryFromnE8try_fromB9_
544
        }
545
    };
546
}
547
548
impl_biguint_try_from_int!(i8, FromPrimitive::from_i8);
549
impl_biguint_try_from_int!(i16, FromPrimitive::from_i16);
550
impl_biguint_try_from_int!(i32, FromPrimitive::from_i32);
551
impl_biguint_try_from_int!(i64, FromPrimitive::from_i64);
552
impl_biguint_try_from_int!(isize, FromPrimitive::from_isize);
553
impl_biguint_try_from_int!(i128, FromPrimitive::from_i128);
554
555
impl ToBigUint for BigUint {
556
    #[inline]
557
0
    fn to_biguint(&self) -> Option<BigUint> {
558
0
        Some(self.clone())
559
0
    }
560
}
561
562
macro_rules! impl_to_biguint {
563
    ($T:ty, $from_ty:path) => {
564
        impl ToBigUint for $T {
565
            #[inline]
566
0
            fn to_biguint(&self) -> Option<BigUint> {
567
0
                $from_ty(*self)
568
0
            }
Unexecuted instantiation: _RNvXsE_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertiNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertaNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertsNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertlNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertxNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertnNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertjNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint7biguint7converthNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint7biguint7converttNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertmNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertyNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertoNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertfNtB7_9ToBigUint10to_biguintB9_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint7biguint7convertdNtB7_9ToBigUint10to_biguintB9_
569
        }
570
    };
571
}
572
573
impl_to_biguint!(isize, FromPrimitive::from_isize);
574
impl_to_biguint!(i8, FromPrimitive::from_i8);
575
impl_to_biguint!(i16, FromPrimitive::from_i16);
576
impl_to_biguint!(i32, FromPrimitive::from_i32);
577
impl_to_biguint!(i64, FromPrimitive::from_i64);
578
impl_to_biguint!(i128, FromPrimitive::from_i128);
579
580
impl_to_biguint!(usize, FromPrimitive::from_usize);
581
impl_to_biguint!(u8, FromPrimitive::from_u8);
582
impl_to_biguint!(u16, FromPrimitive::from_u16);
583
impl_to_biguint!(u32, FromPrimitive::from_u32);
584
impl_to_biguint!(u64, FromPrimitive::from_u64);
585
impl_to_biguint!(u128, FromPrimitive::from_u128);
586
587
impl_to_biguint!(f32, FromPrimitive::from_f32);
588
impl_to_biguint!(f64, FromPrimitive::from_f64);
589
590
impl From<bool> for BigUint {
591
0
    fn from(x: bool) -> Self {
592
0
        if x {
593
0
            One::one()
594
        } else {
595
0
            Self::ZERO
596
        }
597
0
    }
598
}
599
600
// Extract bitwise digits that evenly divide BigDigit
601
140k
pub(super) fn to_bitwise_digits_le(u: &BigUint, bits: u8) -> Vec<u8> {
602
140k
    debug_assert!(!u.is_zero() && bits <= 8 && big_digit::BITS % bits == 0);
603
604
140k
    let last_i = u.data.len() - 1;
605
140k
    let mask: BigDigit = (1 << bits) - 1;
606
140k
    let digits_per_big_digit = big_digit::BITS / bits;
607
140k
    let digits = Integer::div_ceil(&u.bits(), &u64::from(bits))
608
140k
        .to_usize()
609
140k
        .unwrap_or(usize::MAX);
610
140k
    let mut res = Vec::with_capacity(digits);
611
612
27.7M
    for mut r in u.data[..last_i].iter().cloned() {
613
221M
        for _ in 0..digits_per_big_digit {
614
221M
            res.push((r & mask) as u8);
615
221M
            r >>= bits;
616
221M
        }
617
    }
618
619
140k
    let mut r = u.data[last_i];
620
814k
    while r != 0 {
621
674k
        res.push((r & mask) as u8);
622
674k
        r >>= bits;
623
674k
    }
624
625
140k
    res
626
140k
}
627
628
// Extract bitwise digits that don't evenly divide BigDigit
629
0
fn to_inexact_bitwise_digits_le(u: &BigUint, bits: u8) -> Vec<u8> {
630
0
    debug_assert!(!u.is_zero() && bits <= 8 && big_digit::BITS % bits != 0);
631
632
0
    let mask: BigDigit = (1 << bits) - 1;
633
0
    let digits = Integer::div_ceil(&u.bits(), &u64::from(bits))
634
0
        .to_usize()
635
0
        .unwrap_or(usize::MAX);
636
0
    let mut res = Vec::with_capacity(digits);
637
0
638
0
    let mut r = 0;
639
0
    let mut rbits = 0;
640
641
0
    for c in &u.data {
642
0
        r |= *c << rbits;
643
0
        rbits += big_digit::BITS;
644
645
0
        while rbits >= bits {
646
0
            res.push((r & mask) as u8);
647
0
            r >>= bits;
648
0
649
0
            // r had more bits than it could fit - grab the bits we lost
650
0
            if rbits > big_digit::BITS {
651
0
                r = *c >> (big_digit::BITS - (rbits - bits));
652
0
            }
653
654
0
            rbits -= bits;
655
        }
656
    }
657
658
0
    if rbits != 0 {
659
0
        res.push(r as u8);
660
0
    }
661
662
0
    while let Some(&0) = res.last() {
663
0
        res.pop();
664
0
    }
665
666
0
    res
667
0
}
668
669
// Extract little-endian radix digits
670
#[inline(always)] // forced inline to get const-prop for radix=10
671
0
pub(super) fn to_radix_digits_le(u: &BigUint, radix: u32) -> Vec<u8> {
672
0
    debug_assert!(!u.is_zero() && !radix.is_power_of_two());
673
674
    #[cfg(feature = "std")]
675
0
    let radix_digits = {
676
0
        let radix_log2 = f64::from(radix).log2();
677
0
        ((u.bits() as f64) / radix_log2).ceil()
678
0
    };
679
0
    #[cfg(not(feature = "std"))]
680
0
    let radix_digits = {
681
0
        let radix_log2 = ilog2(radix) as usize;
682
0
        ((u.bits() as usize) / radix_log2) + 1
683
0
    };
684
0
685
0
    // Estimate how big the result will be, so we can pre-allocate it.
686
0
    let mut res = Vec::with_capacity(radix_digits.to_usize().unwrap_or(0));
687
0
688
0
    let mut digits = u.clone();
689
690
    // X86 DIV can quickly divide by a full digit, otherwise we choose a divisor
691
    // that's suitable for `div_half` to avoid slow `DoubleBigDigit` division.
692
0
    let (base, power) = if FAST_DIV_WIDE {
693
0
        get_radix_base(radix)
694
    } else {
695
0
        get_half_radix_base(radix)
696
    };
697
0
    let radix = radix as BigDigit;
698
0
699
0
    // For very large numbers, the O(n²) loop of repeated `div_rem_digit` dominates the
700
0
    // performance. We can mitigate this by dividing into chunks of a larger base first.
701
0
    // The threshold for this was chosen by anecdotal performance measurements to
702
0
    // approximate where this starts to make a noticeable difference.
703
0
    if digits.data.len() >= 64 {
704
0
        let mut big_base = BigUint::from(base);
705
0
        let mut big_power = 1usize;
706
0
707
0
        // Choose a target base length near √n.
708
0
        let target_len = digits.data.len().sqrt();
709
0
        while big_base.data.len() < target_len {
710
0
            big_base = &big_base * &big_base;
711
0
            big_power *= 2;
712
0
        }
713
714
        // This outer loop will run approximately √n times.
715
0
        while digits > big_base {
716
            // This is still the dominating factor, with n digits divided by √n digits.
717
0
            let (q, mut big_r) = digits.div_rem(&big_base);
718
0
            digits = q;
719
0
720
0
            // This inner loop now has O(√n²)=O(n) behavior altogether.
721
0
            for _ in 0..big_power {
722
0
                let (q, mut r) = div_rem_digit(big_r, base);
723
0
                big_r = q;
724
0
                for _ in 0..power {
725
0
                    res.push((r % radix) as u8);
726
0
                    r /= radix;
727
0
                }
728
            }
729
        }
730
0
    }
731
732
0
    while digits.data.len() > 1 {
733
0
        let (q, mut r) = div_rem_digit(digits, base);
734
0
        for _ in 0..power {
735
0
            res.push((r % radix) as u8);
736
0
            r /= radix;
737
0
        }
738
0
        digits = q;
739
    }
740
741
0
    let mut r = digits.data[0];
742
0
    while r != 0 {
743
0
        res.push((r % radix) as u8);
744
0
        r /= radix;
745
0
    }
746
747
0
    res
748
0
}
749
750
0
pub(super) fn to_radix_le(u: &BigUint, radix: u32) -> Vec<u8> {
751
0
    if u.is_zero() {
752
0
        vec![0]
753
0
    } else if radix.is_power_of_two() {
754
        // Powers of two can use bitwise masks and shifting instead of division
755
0
        let bits = ilog2(radix);
756
0
        if big_digit::BITS % bits == 0 {
757
0
            to_bitwise_digits_le(u, bits)
758
        } else {
759
0
            to_inexact_bitwise_digits_le(u, bits)
760
        }
761
0
    } else if radix == 10 {
762
        // 10 is so common that it's worth separating out for const-propagation.
763
        // Optimizers can often turn constant division into a faster multiplication.
764
0
        to_radix_digits_le(u, 10)
765
    } else {
766
0
        to_radix_digits_le(u, radix)
767
    }
768
0
}
769
770
0
pub(crate) fn to_str_radix_reversed(u: &BigUint, radix: u32) -> Vec<u8> {
771
0
    assert!(2 <= radix && radix <= 36, "The radix must be within 2...36");
772
773
0
    if u.is_zero() {
774
0
        return vec![b'0'];
775
0
    }
776
0
777
0
    let mut res = to_radix_le(u, radix);
778
779
    // Now convert everything to ASCII digits.
780
0
    for r in &mut res {
781
0
        debug_assert!(u32::from(*r) < radix);
782
0
        if *r < 10 {
783
0
            *r += b'0';
784
0
        } else {
785
0
            *r += b'a' - 10;
786
0
        }
787
    }
788
0
    res
789
0
}
790
791
/// Returns the greatest power of the radix for the `BigDigit` bit size
792
#[inline]
793
0
fn get_radix_base(radix: u32) -> (BigDigit, usize) {
794
    static BASES: [(BigDigit, usize); 257] = generate_radix_bases(big_digit::MAX);
795
0
    debug_assert!(!radix.is_power_of_two());
796
0
    debug_assert!((3..256).contains(&radix));
797
0
    BASES[radix as usize]
798
0
}
799
800
/// Returns the greatest power of the radix for half the `BigDigit` bit size
801
#[inline]
802
0
fn get_half_radix_base(radix: u32) -> (BigDigit, usize) {
803
    static BASES: [(BigDigit, usize); 257] = generate_radix_bases(big_digit::HALF);
804
0
    debug_assert!(!radix.is_power_of_two());
805
0
    debug_assert!((3..256).contains(&radix));
806
0
    BASES[radix as usize]
807
0
}
808
809
/// Generate tables of the greatest power of each radix that is less that the given maximum. These
810
/// are returned from `get_radix_base` to batch the multiplication/division of radix conversions on
811
/// full `BigUint` values, operating on primitive integers as much as possible.
812
///
813
/// e.g. BASES_16[3] = (59049, 10) // 3¹⁰ fits in u16, but 3¹¹ is too big
814
///      BASES_32[3] = (3486784401, 20)
815
///      BASES_64[3] = (12157665459056928801, 40)
816
///
817
/// Powers of two are not included, just zeroed, as they're implemented with shifts.
818
0
const fn generate_radix_bases(max: BigDigit) -> [(BigDigit, usize); 257] {
819
0
    let mut bases = [(0, 0); 257];
820
0
821
0
    let mut radix: BigDigit = 3;
822
0
    while radix < 256 {
823
0
        if !radix.is_power_of_two() {
824
0
            let mut power = 1;
825
0
            let mut base = radix;
826
827
0
            while let Some(b) = base.checked_mul(radix) {
828
0
                if b > max {
829
0
                    break;
830
0
                }
831
0
                base = b;
832
0
                power += 1;
833
            }
834
0
            bases[radix as usize] = (base, power)
835
0
        }
836
0
        radix += 1;
837
    }
838
839
0
    bases
840
0
}
841
842
#[test]
843
fn test_radix_bases() {
844
    for radix in 3u32..256 {
845
        if !radix.is_power_of_two() {
846
            let (base, power) = get_radix_base(radix);
847
            let radix = BigDigit::from(radix);
848
            let power = u32::try_from(power).unwrap();
849
            assert_eq!(base, radix.pow(power));
850
            assert!(radix.checked_pow(power + 1).is_none());
851
        }
852
    }
853
}
854
855
#[test]
856
fn test_half_radix_bases() {
857
    for radix in 3u32..256 {
858
        if !radix.is_power_of_two() {
859
            let (base, power) = get_half_radix_base(radix);
860
            let radix = BigDigit::from(radix);
861
            let power = u32::try_from(power).unwrap();
862
            assert_eq!(base, radix.pow(power));
863
            assert!(radix.pow(power + 1) > big_digit::HALF);
864
        }
865
    }
866
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint/division.rs
Line
Count
Source
1
use super::addition::__add2;
2
use super::{cmp_slice, BigUint};
3
4
use crate::big_digit::{self, BigDigit, DoubleBigDigit};
5
use crate::UsizePromotion;
6
7
use core::cmp::Ordering::{Equal, Greater, Less};
8
use core::mem;
9
use core::ops::{Div, DivAssign, Rem, RemAssign};
10
use num_integer::Integer;
11
use num_traits::{CheckedDiv, CheckedEuclid, Euclid, One, ToPrimitive, Zero};
12
13
pub(super) const FAST_DIV_WIDE: bool = cfg!(any(target_arch = "x86", target_arch = "x86_64"));
14
15
/// Divide a two digit numerator by a one digit divisor, returns quotient and remainder:
16
///
17
/// Note: the caller must ensure that both the quotient and remainder will fit into a single digit.
18
/// This is _not_ true for an arbitrary numerator/denominator.
19
///
20
/// (This function also matches what the x86 divide instruction does).
21
#[cfg(any(miri, not(any(target_arch = "x86", target_arch = "x86_64"))))]
22
#[inline]
23
fn div_wide(hi: BigDigit, lo: BigDigit, divisor: BigDigit) -> (BigDigit, BigDigit) {
24
    debug_assert!(hi < divisor);
25
26
    let lhs = big_digit::to_doublebigdigit(hi, lo);
27
    let rhs = DoubleBigDigit::from(divisor);
28
    ((lhs / rhs) as BigDigit, (lhs % rhs) as BigDigit)
29
}
30
31
/// x86 and x86_64 can use a real `div` instruction.
32
#[cfg(all(not(miri), any(target_arch = "x86", target_arch = "x86_64")))]
33
#[inline]
34
4.47M
fn div_wide(hi: BigDigit, lo: BigDigit, divisor: BigDigit) -> (BigDigit, BigDigit) {
35
4.47M
    // This debug assertion covers the potential #DE for divisor==0 or a quotient too large for one
36
4.47M
    // register, otherwise in release mode it will become a target-specific fault like SIGFPE.
37
4.47M
    // This should never occur with the inputs from our few `div_wide` callers.
38
4.47M
    debug_assert!(hi < divisor);
39
40
    // SAFETY: The `div` instruction only affects registers, reading the explicit operand as the
41
    // divisor, and implicitly reading RDX:RAX or EDX:EAX as the dividend. The result is implicitly
42
    // written back to RAX or EAX for the quotient and RDX or EDX for the remainder. No memory is
43
    // used, and flags are not preserved.
44
    unsafe {
45
        let (div, rem);
46
47
        cfg_digit!(
48
            macro_rules! div {
49
                () => {
50
                    "div {0:e}"
51
                };
52
            }
53
            macro_rules! div {
54
                () => {
55
                    "div {0:r}"
56
                };
57
            }
58
        );
59
60
4.47M
        core::arch::asm!(
61
4.47M
            div!(),
62
4.47M
            in(reg) divisor,
63
4.47M
            inout("dx") hi => rem,
64
4.47M
            inout("ax") lo => div,
65
4.47M
            options(pure, nomem, nostack),
66
4.47M
        );
67
4.47M
68
4.47M
        (div, rem)
69
4.47M
    }
70
4.47M
}
71
72
/// For small divisors, we can divide without promoting to `DoubleBigDigit` by
73
/// using half-size pieces of digit, like long-division.
74
#[inline]
75
0
fn div_half(rem: BigDigit, digit: BigDigit, divisor: BigDigit) -> (BigDigit, BigDigit) {
76
    use crate::big_digit::{HALF, HALF_BITS};
77
78
0
    debug_assert!(rem < divisor && divisor <= HALF);
79
0
    let (hi, rem) = ((rem << HALF_BITS) | (digit >> HALF_BITS)).div_rem(&divisor);
80
0
    let (lo, rem) = ((rem << HALF_BITS) | (digit & HALF)).div_rem(&divisor);
81
0
    ((hi << HALF_BITS) | lo, rem)
82
0
}
83
84
#[inline]
85
30.2k
pub(super) fn div_rem_digit(mut a: BigUint, b: BigDigit) -> (BigUint, BigDigit) {
86
30.2k
    if b == 0 {
87
0
        panic!("attempt to divide by zero")
88
30.2k
    }
89
30.2k
90
30.2k
    let mut rem = 0;
91
30.2k
92
30.2k
    if !FAST_DIV_WIDE && b <= big_digit::HALF {
93
0
        for d in a.data.iter_mut().rev() {
94
0
            let (q, r) = div_half(rem, *d, b);
95
0
            *d = q;
96
0
            rem = r;
97
0
        }
98
    } else {
99
3.95M
        for d in a.data.iter_mut().rev() {
100
3.95M
            let (q, r) = div_wide(rem, *d, b);
101
3.95M
            *d = q;
102
3.95M
            rem = r;
103
3.95M
        }
104
    }
105
106
30.2k
    (a.normalized(), rem)
107
30.2k
}
108
109
#[inline]
110
34.2k
fn rem_digit(a: &BigUint, b: BigDigit) -> BigDigit {
111
34.2k
    if b == 0 {
112
0
        panic!("attempt to divide by zero")
113
34.2k
    }
114
34.2k
115
34.2k
    let mut rem = 0;
116
34.2k
117
34.2k
    if !FAST_DIV_WIDE && b <= big_digit::HALF {
118
0
        for &digit in a.data.iter().rev() {
119
0
            let (_, r) = div_half(rem, digit, b);
120
0
            rem = r;
121
0
        }
122
    } else {
123
40.8k
        for &digit in a.data.iter().rev() {
124
40.8k
            let (_, r) = div_wide(rem, digit, b);
125
40.8k
            rem = r;
126
40.8k
        }
127
    }
128
129
34.2k
    rem
130
34.2k
}
131
132
/// Subtract a multiple.
133
/// a -= b * c
134
/// Returns a borrow (if a < b then borrow > 0).
135
477k
fn sub_mul_digit_same_len(a: &mut [BigDigit], b: &[BigDigit], c: BigDigit) -> BigDigit {
136
477k
    debug_assert!(a.len() == b.len());
137
138
    // carry is between -big_digit::MAX and 0, so to avoid overflow we store
139
    // offset_carry = carry + big_digit::MAX
140
477k
    let mut offset_carry = big_digit::MAX;
141
142
2.37M
    for (x, y) in a.iter_mut().zip(b) {
143
2.37M
        // We want to calculate sum = x - y * c + carry.
144
2.37M
        // sum >= -(big_digit::MAX * big_digit::MAX) - big_digit::MAX
145
2.37M
        // sum <= big_digit::MAX
146
2.37M
        // Offsetting sum by (big_digit::MAX << big_digit::BITS) puts it in DoubleBigDigit range.
147
2.37M
        let offset_sum = big_digit::to_doublebigdigit(big_digit::MAX, *x)
148
2.37M
            - big_digit::MAX as DoubleBigDigit
149
2.37M
            + offset_carry as DoubleBigDigit
150
2.37M
            - *y as DoubleBigDigit * c as DoubleBigDigit;
151
2.37M
152
2.37M
        let (new_offset_carry, new_x) = big_digit::from_doublebigdigit(offset_sum);
153
2.37M
        offset_carry = new_offset_carry;
154
2.37M
        *x = new_x;
155
2.37M
    }
156
157
    // Return the borrow.
158
477k
    big_digit::MAX - offset_carry
159
477k
}
160
161
0
fn div_rem(mut u: BigUint, mut d: BigUint) -> (BigUint, BigUint) {
162
0
    if d.is_zero() {
163
0
        panic!("attempt to divide by zero")
164
0
    }
165
0
    if u.is_zero() {
166
0
        return (BigUint::ZERO, BigUint::ZERO);
167
0
    }
168
0
169
0
    if d.data.len() == 1 {
170
0
        if d.data == [1] {
171
0
            return (u, BigUint::ZERO);
172
0
        }
173
0
        let (div, rem) = div_rem_digit(u, d.data[0]);
174
0
        // reuse d
175
0
        d.data.clear();
176
0
        d += rem;
177
0
        return (div, d);
178
0
    }
179
0
180
0
    // Required or the q_len calculation below can underflow:
181
0
    match u.cmp(&d) {
182
0
        Less => return (BigUint::ZERO, u),
183
        Equal => {
184
0
            u.set_one();
185
0
            return (u, BigUint::ZERO);
186
        }
187
0
        Greater => {} // Do nothing
188
0
    }
189
0
190
0
    // This algorithm is from Knuth, TAOCP vol 2 section 4.3, algorithm D:
191
0
    //
192
0
    // First, normalize the arguments so the highest bit in the highest digit of the divisor is
193
0
    // set: the main loop uses the highest digit of the divisor for generating guesses, so we
194
0
    // want it to be the largest number we can efficiently divide by.
195
0
    //
196
0
    let shift = d.data.last().unwrap().leading_zeros() as usize;
197
0
198
0
    if shift == 0 {
199
        // no need to clone d
200
0
        div_rem_core(u, &d.data)
201
    } else {
202
0
        let (q, r) = div_rem_core(u << shift, &(d << shift).data);
203
0
        // renormalize the remainder
204
0
        (q, r >> shift)
205
    }
206
0
}
207
208
165k
pub(super) fn div_rem_ref(u: &BigUint, d: &BigUint) -> (BigUint, BigUint) {
209
165k
    if d.is_zero() {
210
0
        panic!("attempt to divide by zero")
211
165k
    }
212
165k
    if u.is_zero() {
213
43.1k
        return (BigUint::ZERO, BigUint::ZERO);
214
121k
    }
215
121k
216
121k
    if d.data.len() == 1 {
217
25.6k
        if d.data == [1] {
218
4.45k
            return (u.clone(), BigUint::ZERO);
219
21.2k
        }
220
21.2k
221
21.2k
        let (div, rem) = div_rem_digit(u.clone(), d.data[0]);
222
21.2k
        return (div, rem.into());
223
96.2k
    }
224
96.2k
225
96.2k
    // Required or the q_len calculation below can underflow:
226
96.2k
    match u.cmp(d) {
227
9.19k
        Less => return (BigUint::ZERO, u.clone()),
228
1.31k
        Equal => return (One::one(), BigUint::ZERO),
229
85.7k
        Greater => {} // Do nothing
230
85.7k
    }
231
85.7k
232
85.7k
    // This algorithm is from Knuth, TAOCP vol 2 section 4.3, algorithm D:
233
85.7k
    //
234
85.7k
    // First, normalize the arguments so the highest bit in the highest digit of the divisor is
235
85.7k
    // set: the main loop uses the highest digit of the divisor for generating guesses, so we
236
85.7k
    // want it to be the largest number we can efficiently divide by.
237
85.7k
    //
238
85.7k
    let shift = d.data.last().unwrap().leading_zeros() as usize;
239
85.7k
240
85.7k
    if shift == 0 {
241
        // no need to clone d
242
4.72k
        div_rem_core(u.clone(), &d.data)
243
    } else {
244
81.0k
        let (q, r) = div_rem_core(u << shift, &(d << shift).data);
245
81.0k
        // renormalize the remainder
246
81.0k
        (q, r >> shift)
247
    }
248
165k
}
249
250
/// An implementation of the base division algorithm.
251
/// Knuth, TAOCP vol 2 section 4.3.1, algorithm D, with an improvement from exercises 19-21.
252
85.7k
fn div_rem_core(mut a: BigUint, b: &[BigDigit]) -> (BigUint, BigUint) {
253
85.7k
    debug_assert!(a.data.len() >= b.len() && b.len() > 1);
254
85.7k
    debug_assert!(b.last().unwrap().leading_zeros() == 0);
255
256
    // The algorithm works by incrementally calculating "guesses", q0, for the next digit of the
257
    // quotient. Once we have any number q0 such that (q0 << j) * b <= a, we can set
258
    //
259
    //     q += q0 << j
260
    //     a -= (q0 << j) * b
261
    //
262
    // and then iterate until a < b. Then, (q, a) will be our desired quotient and remainder.
263
    //
264
    // q0, our guess, is calculated by dividing the last three digits of a by the last two digits of
265
    // b - this will give us a guess that is close to the actual quotient, but is possibly greater.
266
    // It can only be greater by 1 and only in rare cases, with probability at most
267
    // 2^-(big_digit::BITS-1) for random a, see TAOCP 4.3.1 exercise 21.
268
    //
269
    // If the quotient turns out to be too large, we adjust it by 1:
270
    // q -= 1 << j
271
    // a += b << j
272
273
    // a0 stores an additional extra most significant digit of the dividend, not stored in a.
274
85.7k
    let mut a0 = 0;
275
85.7k
276
85.7k
    // [b1, b0] are the two most significant digits of the divisor. They never change.
277
85.7k
    let b0 = b[b.len() - 1];
278
85.7k
    let b1 = b[b.len() - 2];
279
85.7k
280
85.7k
    let q_len = a.data.len() - b.len() + 1;
281
85.7k
    let mut q = BigUint {
282
85.7k
        data: vec![0; q_len],
283
85.7k
    };
284
285
477k
    for j in (0..q_len).rev() {
286
477k
        debug_assert!(a.data.len() == b.len() + j);
287
288
477k
        let a1 = *a.data.last().unwrap();
289
477k
        let a2 = a.data[a.data.len() - 2];
290
291
        // The first q0 estimate is [a1,a0] / b0. It will never be too small, it may be too large
292
        // by at most 2.
293
477k
        let (mut q0, mut r) = if a0 < b0 {
294
477k
            let (q0, r) = div_wide(a0, a1, b0);
295
477k
            (q0, r as DoubleBigDigit)
296
        } else {
297
40
            debug_assert!(a0 == b0);
298
            // Avoid overflowing q0, we know the quotient fits in BigDigit.
299
            // [a1,a0] = b0 * (1<<BITS - 1) + (a0 + a1)
300
40
            (big_digit::MAX, a0 as DoubleBigDigit + a1 as DoubleBigDigit)
301
        };
302
303
        // r = [a1,a0] - q0 * b0
304
        //
305
        // Now we want to compute a more precise estimate [a2,a1,a0] / [b1,b0] which can only be
306
        // less or equal to the current q0.
307
        //
308
        // q0 is too large if:
309
        // [a2,a1,a0] < q0 * [b1,b0]
310
        // (r << BITS) + a2 < q0 * b1
311
604k
        while r <= big_digit::MAX as DoubleBigDigit
312
549k
            && big_digit::to_doublebigdigit(r as BigDigit, a2)
313
549k
                < q0 as DoubleBigDigit * b1 as DoubleBigDigit
314
127k
        {
315
127k
            q0 -= 1;
316
127k
            r += b0 as DoubleBigDigit;
317
127k
        }
318
319
        // q0 is now either the correct quotient digit, or in rare cases 1 too large.
320
        // Subtract (q0 << j) from a. This may overflow, in which case we will have to correct.
321
322
477k
        let mut borrow = sub_mul_digit_same_len(&mut a.data[j..], b, q0);
323
477k
        if borrow > a0 {
324
43
            // q0 is too large. We need to add back one multiple of b.
325
43
            q0 -= 1;
326
43
            borrow -= __add2(&mut a.data[j..], b);
327
477k
        }
328
        // The top digit of a, stored in a0, has now been zeroed.
329
477k
        debug_assert!(borrow == a0);
330
331
477k
        q.data[j] = q0;
332
477k
333
477k
        // Pop off the next top digit of a.
334
477k
        a0 = a.data.pop().unwrap();
335
    }
336
337
85.7k
    a.data.push(a0);
338
85.7k
    a.normalize();
339
85.7k
340
85.7k
    debug_assert_eq!(cmp_slice(&a.data, b), Less);
341
342
85.7k
    (q.normalized(), a)
343
85.7k
}
344
345
forward_val_ref_binop!(impl Div for BigUint, div);
346
forward_ref_val_binop!(impl Div for BigUint, div);
347
forward_val_assign!(impl DivAssign for BigUint, div_assign);
348
349
impl Div<BigUint> for BigUint {
350
    type Output = BigUint;
351
352
    #[inline]
353
0
    fn div(self, other: BigUint) -> BigUint {
354
0
        let (q, _) = div_rem(self, other);
355
0
        q
356
0
    }
357
}
358
359
impl Div<&BigUint> for &BigUint {
360
    type Output = BigUint;
361
362
    #[inline]
363
0
    fn div(self, other: &BigUint) -> BigUint {
364
0
        let (q, _) = self.div_rem(other);
365
0
        q
366
0
    }
367
}
368
impl DivAssign<&BigUint> for BigUint {
369
    #[inline]
370
0
    fn div_assign(&mut self, other: &BigUint) {
371
0
        *self = &*self / other;
372
0
    }
373
}
374
375
promote_unsigned_scalars!(impl Div for BigUint, div);
376
promote_unsigned_scalars_assign!(impl DivAssign for BigUint, div_assign);
377
forward_all_scalar_binop_to_val_val!(impl Div<u32> for BigUint, div);
378
forward_all_scalar_binop_to_val_val!(impl Div<u64> for BigUint, div);
379
forward_all_scalar_binop_to_val_val!(impl Div<u128> for BigUint, div);
380
381
impl Div<u32> for BigUint {
382
    type Output = BigUint;
383
384
    #[inline]
385
9.06k
    fn div(self, other: u32) -> BigUint {
386
9.06k
        let (q, _) = div_rem_digit(self, other as BigDigit);
387
9.06k
        q
388
9.06k
    }
389
}
390
impl DivAssign<u32> for BigUint {
391
    #[inline]
392
0
    fn div_assign(&mut self, other: u32) {
393
0
        *self = &*self / other;
394
0
    }
395
}
396
397
impl Div<BigUint> for u32 {
398
    type Output = BigUint;
399
400
    #[inline]
401
0
    fn div(self, other: BigUint) -> BigUint {
402
0
        match other.data.len() {
403
0
            0 => panic!("attempt to divide by zero"),
404
0
            1 => From::from(self as BigDigit / other.data[0]),
405
0
            _ => BigUint::ZERO,
406
        }
407
0
    }
408
}
409
410
impl Div<u64> for BigUint {
411
    type Output = BigUint;
412
413
    #[inline]
414
0
    fn div(self, other: u64) -> BigUint {
415
0
        let (q, _) = div_rem(self, From::from(other));
416
0
        q
417
0
    }
418
}
419
impl DivAssign<u64> for BigUint {
420
    #[inline]
421
0
    fn div_assign(&mut self, other: u64) {
422
0
        // a vec of size 0 does not allocate, so this is fairly cheap
423
0
        let temp = mem::replace(self, Self::ZERO);
424
0
        *self = temp / other;
425
0
    }
426
}
427
428
impl Div<BigUint> for u64 {
429
    type Output = BigUint;
430
431
    cfg_digit!(
432
        #[inline]
433
        fn div(self, other: BigUint) -> BigUint {
434
            match other.data.len() {
435
                0 => panic!("attempt to divide by zero"),
436
                1 => From::from(self / u64::from(other.data[0])),
437
                2 => From::from(self / big_digit::to_doublebigdigit(other.data[1], other.data[0])),
438
                _ => BigUint::ZERO,
439
            }
440
        }
441
442
        #[inline]
443
0
        fn div(self, other: BigUint) -> BigUint {
444
0
            match other.data.len() {
445
0
                0 => panic!("attempt to divide by zero"),
446
0
                1 => From::from(self / other.data[0]),
447
0
                _ => BigUint::ZERO,
448
            }
449
0
        }
450
    );
451
}
452
453
impl Div<u128> for BigUint {
454
    type Output = BigUint;
455
456
    #[inline]
457
0
    fn div(self, other: u128) -> BigUint {
458
0
        let (q, _) = div_rem(self, From::from(other));
459
0
        q
460
0
    }
461
}
462
463
impl DivAssign<u128> for BigUint {
464
    #[inline]
465
0
    fn div_assign(&mut self, other: u128) {
466
0
        *self = &*self / other;
467
0
    }
468
}
469
470
impl Div<BigUint> for u128 {
471
    type Output = BigUint;
472
473
    cfg_digit!(
474
        #[inline]
475
        fn div(self, other: BigUint) -> BigUint {
476
            use super::u32_to_u128;
477
            match other.data.len() {
478
                0 => panic!("attempt to divide by zero"),
479
                1 => From::from(self / u128::from(other.data[0])),
480
                2 => From::from(
481
                    self / u128::from(big_digit::to_doublebigdigit(other.data[1], other.data[0])),
482
                ),
483
                3 => From::from(self / u32_to_u128(0, other.data[2], other.data[1], other.data[0])),
484
                4 => From::from(
485
                    self / u32_to_u128(other.data[3], other.data[2], other.data[1], other.data[0]),
486
                ),
487
                _ => BigUint::ZERO,
488
            }
489
        }
490
491
        #[inline]
492
0
        fn div(self, other: BigUint) -> BigUint {
493
0
            match other.data.len() {
494
0
                0 => panic!("attempt to divide by zero"),
495
0
                1 => From::from(self / other.data[0] as u128),
496
0
                2 => From::from(self / big_digit::to_doublebigdigit(other.data[1], other.data[0])),
497
0
                _ => BigUint::ZERO,
498
            }
499
0
        }
500
    );
501
}
502
503
forward_val_ref_binop!(impl Rem for BigUint, rem);
504
forward_ref_val_binop!(impl Rem for BigUint, rem);
505
forward_val_assign!(impl RemAssign for BigUint, rem_assign);
506
507
impl Rem<BigUint> for BigUint {
508
    type Output = BigUint;
509
510
    #[inline]
511
0
    fn rem(self, other: BigUint) -> BigUint {
512
0
        if let Some(other) = other.to_u32() {
513
0
            &self % other
514
        } else {
515
0
            let (_, r) = div_rem(self, other);
516
0
            r
517
        }
518
0
    }
519
}
520
521
impl Rem<&BigUint> for &BigUint {
522
    type Output = BigUint;
523
524
    #[inline]
525
155k
    fn rem(self, other: &BigUint) -> BigUint {
526
155k
        if let Some(other) = other.to_u32() {
527
34.2k
            self % other
528
        } else {
529
121k
            let (_, r) = self.div_rem(other);
530
121k
            r
531
        }
532
155k
    }
533
}
534
impl RemAssign<&BigUint> for BigUint {
535
    #[inline]
536
38.6k
    fn rem_assign(&mut self, other: &BigUint) {
537
38.6k
        *self = &*self % other;
538
38.6k
    }
539
}
540
541
promote_unsigned_scalars!(impl Rem for BigUint, rem);
542
promote_unsigned_scalars_assign!(impl RemAssign for BigUint, rem_assign);
543
forward_all_scalar_binop_to_ref_val!(impl Rem<u32> for BigUint, rem);
544
forward_all_scalar_binop_to_val_val!(impl Rem<u64> for BigUint, rem);
545
forward_all_scalar_binop_to_val_val!(impl Rem<u128> for BigUint, rem);
546
547
impl Rem<u32> for &BigUint {
548
    type Output = BigUint;
549
550
    #[inline]
551
34.2k
    fn rem(self, other: u32) -> BigUint {
552
34.2k
        rem_digit(self, other as BigDigit).into()
553
34.2k
    }
554
}
555
impl RemAssign<u32> for BigUint {
556
    #[inline]
557
0
    fn rem_assign(&mut self, other: u32) {
558
0
        *self = &*self % other;
559
0
    }
560
}
561
562
impl Rem<&BigUint> for u32 {
563
    type Output = BigUint;
564
565
    #[inline]
566
0
    fn rem(mut self, other: &BigUint) -> BigUint {
567
0
        self %= other;
568
0
        From::from(self)
569
0
    }
570
}
571
572
macro_rules! impl_rem_assign_scalar {
573
    ($scalar:ty, $to_scalar:ident) => {
574
        forward_val_assign_scalar!(impl RemAssign for BigUint, $scalar, rem_assign);
575
        impl RemAssign<&BigUint> for $scalar {
576
            #[inline]
577
0
            fn rem_assign(&mut self, other: &BigUint) {
578
0
                *self = match other.$to_scalar() {
579
0
                    None => *self,
580
0
                    Some(0) => panic!("attempt to divide by zero"),
581
0
                    Some(v) => *self % v
582
                };
583
0
            }
Unexecuted instantiation: _RNvXs1X_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs1Z_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs21_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs23_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs25_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs27_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs29_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs2b_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisioniINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs2d_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs2f_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs2h_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs2j_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignRNtB8_7BigUintE10rem_assignBa_
584
        }
585
    }
586
}
587
588
// we can scalar %= BigUint for any scalar, including signed types
589
impl_rem_assign_scalar!(u128, to_u128);
590
impl_rem_assign_scalar!(usize, to_usize);
591
impl_rem_assign_scalar!(u64, to_u64);
592
impl_rem_assign_scalar!(u32, to_u32);
593
impl_rem_assign_scalar!(u16, to_u16);
594
impl_rem_assign_scalar!(u8, to_u8);
595
impl_rem_assign_scalar!(i128, to_i128);
596
impl_rem_assign_scalar!(isize, to_isize);
597
impl_rem_assign_scalar!(i64, to_i64);
598
impl_rem_assign_scalar!(i32, to_i32);
599
impl_rem_assign_scalar!(i16, to_i16);
600
impl_rem_assign_scalar!(i8, to_i8);
601
602
impl Rem<u64> for BigUint {
603
    type Output = BigUint;
604
605
    #[inline]
606
0
    fn rem(self, other: u64) -> BigUint {
607
0
        let (_, r) = div_rem(self, From::from(other));
608
0
        r
609
0
    }
610
}
611
impl RemAssign<u64> for BigUint {
612
    #[inline]
613
0
    fn rem_assign(&mut self, other: u64) {
614
0
        *self = &*self % other;
615
0
    }
616
}
617
618
impl Rem<BigUint> for u64 {
619
    type Output = BigUint;
620
621
    #[inline]
622
0
    fn rem(mut self, other: BigUint) -> BigUint {
623
0
        self %= other;
624
0
        From::from(self)
625
0
    }
626
}
627
628
impl Rem<u128> for BigUint {
629
    type Output = BigUint;
630
631
    #[inline]
632
0
    fn rem(self, other: u128) -> BigUint {
633
0
        let (_, r) = div_rem(self, From::from(other));
634
0
        r
635
0
    }
636
}
637
638
impl RemAssign<u128> for BigUint {
639
    #[inline]
640
0
    fn rem_assign(&mut self, other: u128) {
641
0
        *self = &*self % other;
642
0
    }
643
}
644
645
impl Rem<BigUint> for u128 {
646
    type Output = BigUint;
647
648
    #[inline]
649
0
    fn rem(mut self, other: BigUint) -> BigUint {
650
0
        self %= other;
651
0
        From::from(self)
652
0
    }
653
}
654
655
impl CheckedDiv for BigUint {
656
    #[inline]
657
0
    fn checked_div(&self, v: &BigUint) -> Option<BigUint> {
658
0
        if v.is_zero() {
659
0
            return None;
660
0
        }
661
0
        Some(self.div(v))
662
0
    }
663
}
664
665
impl CheckedEuclid for BigUint {
666
    #[inline]
667
0
    fn checked_div_euclid(&self, v: &BigUint) -> Option<BigUint> {
668
0
        if v.is_zero() {
669
0
            return None;
670
0
        }
671
0
        Some(self.div_euclid(v))
672
0
    }
673
674
    #[inline]
675
0
    fn checked_rem_euclid(&self, v: &BigUint) -> Option<BigUint> {
676
0
        if v.is_zero() {
677
0
            return None;
678
0
        }
679
0
        Some(self.rem_euclid(v))
680
0
    }
681
682
0
    fn checked_div_rem_euclid(&self, v: &Self) -> Option<(Self, Self)> {
683
0
        Some(self.div_rem_euclid(v))
684
0
    }
685
}
686
687
impl Euclid for BigUint {
688
    #[inline]
689
0
    fn div_euclid(&self, v: &BigUint) -> BigUint {
690
0
        // trivially same as regular division
691
0
        self / v
692
0
    }
693
694
    #[inline]
695
0
    fn rem_euclid(&self, v: &BigUint) -> BigUint {
696
0
        // trivially same as regular remainder
697
0
        self % v
698
0
    }
699
700
0
    fn div_rem_euclid(&self, v: &Self) -> (Self, Self) {
701
0
        // trivially same as regular division and remainder
702
0
        self.div_rem(v)
703
0
    }
704
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint/iter.rs
Line
Count
Source
1
use core::iter::FusedIterator;
2
3
cfg_digit!(
4
    /// An iterator of `u32` digits representation of a `BigUint` or `BigInt`,
5
    /// ordered least significant digit first.
6
    pub struct U32Digits<'a> {
7
        it: core::slice::Iter<'a, u32>,
8
    }
9
10
    /// An iterator of `u32` digits representation of a `BigUint` or `BigInt`,
11
    /// ordered least significant digit first.
12
    pub struct U32Digits<'a> {
13
        data: &'a [u64],
14
        next_is_lo: bool,
15
        last_hi_is_zero: bool,
16
    }
17
);
18
19
cfg_digit!(
20
    const _: () = {
21
        impl<'a> U32Digits<'a> {
22
            #[inline]
23
            pub(super) fn new(data: &'a [u32]) -> Self {
24
                Self { it: data.iter() }
25
            }
26
        }
27
28
        impl Iterator for U32Digits<'_> {
29
            type Item = u32;
30
            #[inline]
31
            fn next(&mut self) -> Option<u32> {
32
                self.it.next().cloned()
33
            }
34
35
            #[inline]
36
            fn size_hint(&self) -> (usize, Option<usize>) {
37
                self.it.size_hint()
38
            }
39
40
            #[inline]
41
            fn nth(&mut self, n: usize) -> Option<u32> {
42
                self.it.nth(n).cloned()
43
            }
44
45
            #[inline]
46
            fn last(self) -> Option<u32> {
47
                self.it.last().cloned()
48
            }
49
50
            #[inline]
51
            fn count(self) -> usize {
52
                self.it.count()
53
            }
54
        }
55
56
        impl DoubleEndedIterator for U32Digits<'_> {
57
            fn next_back(&mut self) -> Option<Self::Item> {
58
                self.it.next_back().cloned()
59
            }
60
        }
61
62
        impl ExactSizeIterator for U32Digits<'_> {
63
            #[inline]
64
            fn len(&self) -> usize {
65
                self.it.len()
66
            }
67
        }
68
    };
69
70
    const _: () = {
71
        impl<'a> U32Digits<'a> {
72
            #[inline]
73
0
            pub(super) fn new(data: &'a [u64]) -> Self {
74
0
                let last_hi_is_zero = data
75
0
                    .last()
76
0
                    .map(|&last| {
77
0
                        let last_hi = (last >> 32) as u32;
78
0
                        last_hi == 0
79
0
                    })
80
0
                    .unwrap_or(false);
81
0
                U32Digits {
82
0
                    data,
83
0
                    next_is_lo: true,
84
0
                    last_hi_is_zero,
85
0
                }
86
0
            }
87
        }
88
89
        impl Iterator for U32Digits<'_> {
90
            type Item = u32;
91
            #[inline]
92
0
            fn next(&mut self) -> Option<u32> {
93
0
                match self.data.split_first() {
94
0
                    Some((&first, data)) => {
95
0
                        let next_is_lo = self.next_is_lo;
96
0
                        self.next_is_lo = !next_is_lo;
97
0
                        if next_is_lo {
98
0
                            Some(first as u32)
99
                        } else {
100
0
                            self.data = data;
101
0
                            if data.is_empty() && self.last_hi_is_zero {
102
0
                                self.last_hi_is_zero = false;
103
0
                                None
104
                            } else {
105
0
                                Some((first >> 32) as u32)
106
                            }
107
                        }
108
                    }
109
0
                    None => None,
110
                }
111
0
            }
112
113
            #[inline]
114
0
            fn size_hint(&self) -> (usize, Option<usize>) {
115
0
                let len = self.len();
116
0
                (len, Some(len))
117
0
            }
118
119
            #[inline]
120
0
            fn last(self) -> Option<u32> {
121
0
                self.data.last().map(|&last| {
122
0
                    if self.last_hi_is_zero {
123
0
                        last as u32
124
                    } else {
125
0
                        (last >> 32) as u32
126
                    }
127
0
                })
128
0
            }
129
130
            #[inline]
131
0
            fn count(self) -> usize {
132
0
                self.len()
133
0
            }
134
        }
135
136
        impl DoubleEndedIterator for U32Digits<'_> {
137
0
            fn next_back(&mut self) -> Option<Self::Item> {
138
0
                match self.data.split_last() {
139
0
                    Some((&last, data)) => {
140
0
                        let last_is_lo = self.last_hi_is_zero;
141
0
                        self.last_hi_is_zero = !last_is_lo;
142
0
                        if last_is_lo {
143
0
                            self.data = data;
144
0
                            if data.is_empty() && !self.next_is_lo {
145
0
                                self.next_is_lo = true;
146
0
                                None
147
                            } else {
148
0
                                Some(last as u32)
149
                            }
150
                        } else {
151
0
                            Some((last >> 32) as u32)
152
                        }
153
                    }
154
0
                    None => None,
155
                }
156
0
            }
157
        }
158
159
        impl ExactSizeIterator for U32Digits<'_> {
160
            #[inline]
161
0
            fn len(&self) -> usize {
162
0
                self.data.len() * 2
163
0
                    - usize::from(self.last_hi_is_zero)
164
0
                    - usize::from(!self.next_is_lo)
165
0
            }
166
        }
167
    };
168
);
169
170
impl FusedIterator for U32Digits<'_> {}
171
172
cfg_digit!(
173
    /// An iterator of `u64` digits representation of a `BigUint` or `BigInt`,
174
    /// ordered least significant digit first.
175
    pub struct U64Digits<'a> {
176
        it: core::slice::Chunks<'a, u32>,
177
    }
178
179
    /// An iterator of `u64` digits representation of a `BigUint` or `BigInt`,
180
    /// ordered least significant digit first.
181
    pub struct U64Digits<'a> {
182
        it: core::slice::Iter<'a, u64>,
183
    }
184
);
185
186
cfg_digit!(
187
    const _: () = {
188
        impl<'a> U64Digits<'a> {
189
            #[inline]
190
            pub(super) fn new(data: &'a [u32]) -> Self {
191
                U64Digits { it: data.chunks(2) }
192
            }
193
        }
194
195
        impl Iterator for U64Digits<'_> {
196
            type Item = u64;
197
            #[inline]
198
            fn next(&mut self) -> Option<u64> {
199
                self.it.next().map(super::u32_chunk_to_u64)
200
            }
201
202
            #[inline]
203
            fn size_hint(&self) -> (usize, Option<usize>) {
204
                let len = self.len();
205
                (len, Some(len))
206
            }
207
208
            #[inline]
209
            fn last(self) -> Option<u64> {
210
                self.it.last().map(super::u32_chunk_to_u64)
211
            }
212
213
            #[inline]
214
            fn count(self) -> usize {
215
                self.len()
216
            }
217
        }
218
219
        impl DoubleEndedIterator for U64Digits<'_> {
220
            fn next_back(&mut self) -> Option<Self::Item> {
221
                self.it.next_back().map(super::u32_chunk_to_u64)
222
            }
223
        }
224
    };
225
226
    const _: () = {
227
        impl<'a> U64Digits<'a> {
228
            #[inline]
229
0
            pub(super) fn new(data: &'a [u64]) -> Self {
230
0
                Self { it: data.iter() }
231
0
            }
232
        }
233
234
        impl Iterator for U64Digits<'_> {
235
            type Item = u64;
236
            #[inline]
237
0
            fn next(&mut self) -> Option<u64> {
238
0
                self.it.next().cloned()
239
0
            }
240
241
            #[inline]
242
0
            fn size_hint(&self) -> (usize, Option<usize>) {
243
0
                self.it.size_hint()
244
0
            }
245
246
            #[inline]
247
0
            fn nth(&mut self, n: usize) -> Option<u64> {
248
0
                self.it.nth(n).cloned()
249
0
            }
250
251
            #[inline]
252
0
            fn last(self) -> Option<u64> {
253
0
                self.it.last().cloned()
254
0
            }
255
256
            #[inline]
257
0
            fn count(self) -> usize {
258
0
                self.it.count()
259
0
            }
260
        }
261
262
        impl DoubleEndedIterator for U64Digits<'_> {
263
0
            fn next_back(&mut self) -> Option<Self::Item> {
264
0
                self.it.next_back().cloned()
265
0
            }
266
        }
267
    };
268
);
269
270
impl ExactSizeIterator for U64Digits<'_> {
271
    #[inline]
272
0
    fn len(&self) -> usize {
273
0
        self.it.len()
274
0
    }
275
}
276
277
impl FusedIterator for U64Digits<'_> {}
278
279
#[test]
280
fn test_iter_u32_digits() {
281
    let n = super::BigUint::from(5u8);
282
    let mut it = n.iter_u32_digits();
283
    assert_eq!(it.len(), 1);
284
    assert_eq!(it.next(), Some(5));
285
    assert_eq!(it.len(), 0);
286
    assert_eq!(it.next(), None);
287
    assert_eq!(it.len(), 0);
288
    assert_eq!(it.next(), None);
289
290
    let n = super::BigUint::from(112500000000u64);
291
    let mut it = n.iter_u32_digits();
292
    assert_eq!(it.len(), 2);
293
    assert_eq!(it.next(), Some(830850304));
294
    assert_eq!(it.len(), 1);
295
    assert_eq!(it.next(), Some(26));
296
    assert_eq!(it.len(), 0);
297
    assert_eq!(it.next(), None);
298
}
299
300
#[test]
301
fn test_iter_u64_digits() {
302
    let n = super::BigUint::from(5u8);
303
    let mut it = n.iter_u64_digits();
304
    assert_eq!(it.len(), 1);
305
    assert_eq!(it.next(), Some(5));
306
    assert_eq!(it.len(), 0);
307
    assert_eq!(it.next(), None);
308
    assert_eq!(it.len(), 0);
309
    assert_eq!(it.next(), None);
310
311
    let n = super::BigUint::from(18_446_744_073_709_551_616u128);
312
    let mut it = n.iter_u64_digits();
313
    assert_eq!(it.len(), 2);
314
    assert_eq!(it.next(), Some(0));
315
    assert_eq!(it.len(), 1);
316
    assert_eq!(it.next(), Some(1));
317
    assert_eq!(it.len(), 0);
318
    assert_eq!(it.next(), None);
319
}
320
321
#[test]
322
fn test_iter_u32_digits_be() {
323
    let n = super::BigUint::from(5u8);
324
    let mut it = n.iter_u32_digits();
325
    assert_eq!(it.len(), 1);
326
    assert_eq!(it.next(), Some(5));
327
    assert_eq!(it.len(), 0);
328
    assert_eq!(it.next(), None);
329
    assert_eq!(it.len(), 0);
330
    assert_eq!(it.next(), None);
331
332
    let n = super::BigUint::from(112500000000u64);
333
    let mut it = n.iter_u32_digits();
334
    assert_eq!(it.len(), 2);
335
    assert_eq!(it.next(), Some(830850304));
336
    assert_eq!(it.len(), 1);
337
    assert_eq!(it.next(), Some(26));
338
    assert_eq!(it.len(), 0);
339
    assert_eq!(it.next(), None);
340
}
341
342
#[test]
343
fn test_iter_u64_digits_be() {
344
    let n = super::BigUint::from(5u8);
345
    let mut it = n.iter_u64_digits();
346
    assert_eq!(it.len(), 1);
347
    assert_eq!(it.next_back(), Some(5));
348
    assert_eq!(it.len(), 0);
349
    assert_eq!(it.next(), None);
350
    assert_eq!(it.len(), 0);
351
    assert_eq!(it.next(), None);
352
353
    let n = super::BigUint::from(18_446_744_073_709_551_616u128);
354
    let mut it = n.iter_u64_digits();
355
    assert_eq!(it.len(), 2);
356
    assert_eq!(it.next_back(), Some(1));
357
    assert_eq!(it.len(), 1);
358
    assert_eq!(it.next_back(), Some(0));
359
    assert_eq!(it.len(), 0);
360
    assert_eq!(it.next(), None);
361
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint/monty.rs
Line
Count
Source
1
use alloc::vec::Vec;
2
use core::mem;
3
use core::ops::Shl;
4
use num_traits::One;
5
6
use crate::big_digit::{self, BigDigit, DoubleBigDigit};
7
use crate::biguint::BigUint;
8
9
struct MontyReducer {
10
    n0inv: BigDigit,
11
}
12
13
// k0 = -m**-1 mod 2**BITS. Algorithm from: Dumas, J.G. "On Newton–Raphson
14
// Iteration for Multiplicative Inverses Modulo Prime Powers".
15
2.07k
fn inv_mod_alt(b: BigDigit) -> BigDigit {
16
2.07k
    assert_ne!(b & 1, 0);
17
18
2.07k
    let mut k0 = BigDigit::wrapping_sub(2, b);
19
2.07k
    let mut t = b - 1;
20
2.07k
    let mut i = 1;
21
14.5k
    while i < big_digit::BITS {
22
12.4k
        t = t.wrapping_mul(t);
23
12.4k
        k0 = k0.wrapping_mul(t + 1);
24
12.4k
25
12.4k
        i <<= 1;
26
12.4k
    }
27
2.07k
    debug_assert_eq!(k0.wrapping_mul(b), 1);
28
2.07k
    k0.wrapping_neg()
29
2.07k
}
30
31
impl MontyReducer {
32
2.07k
    fn new(n: &BigUint) -> Self {
33
2.07k
        let n0inv = inv_mod_alt(n.data[0]);
34
2.07k
        MontyReducer { n0inv }
35
2.07k
    }
36
}
37
38
/// Computes z mod m = x * y * 2 ** (-n*_W) mod m
39
/// assuming k = -1/m mod 2**_W
40
/// See Gueron, "Efficient Software Implementations of Modular Exponentiation".
41
/// <https://eprint.iacr.org/2011/239.pdf>
42
/// In the terminology of that paper, this is an "Almost Montgomery Multiplication":
43
/// x and y are required to satisfy 0 <= z < 2**(n*_W) and then the result
44
/// z is guaranteed to satisfy 0 <= z < 2**(n*_W), but it may not be < m.
45
#[allow(clippy::many_single_char_names)]
46
198k
fn montgomery(x: &BigUint, y: &BigUint, m: &BigUint, k: BigDigit, n: usize) -> BigUint {
47
198k
    // This code assumes x, y, m are all the same length, n.
48
198k
    // (required by addMulVVW and the for loop).
49
198k
    // It also assumes that x, y are already reduced mod m,
50
198k
    // or else the result will not be properly reduced.
51
198k
    assert!(
52
198k
        x.data.len() == n && y.data.len() == n && m.data.len() == n,
53
0
        "{:?} {:?} {:?} {}",
54
        x,
55
        y,
56
        m,
57
        n
58
    );
59
60
198k
    let mut z = BigUint::ZERO;
61
198k
    z.data.resize(n * 2, 0);
62
198k
63
198k
    let mut c: BigDigit = 0;
64
419k
    for i in 0..n {
65
419k
        let c2 = add_mul_vvw(&mut z.data[i..n + i], &x.data, y.data[i]);
66
419k
        let t = z.data[i].wrapping_mul(k);
67
419k
        let c3 = add_mul_vvw(&mut z.data[i..n + i], &m.data, t);
68
419k
        let cx = c.wrapping_add(c2);
69
419k
        let cy = cx.wrapping_add(c3);
70
419k
        z.data[n + i] = cy;
71
419k
        if cx < c2 || cy < c3 {
72
3.66k
            c = 1;
73
416k
        } else {
74
416k
            c = 0;
75
416k
        }
76
    }
77
78
198k
    if c == 0 {
79
197k
        z.data = z.data[n..].to_vec();
80
197k
    } else {
81
768
        {
82
768
            let (first, second) = z.data.split_at_mut(n);
83
768
            sub_vv(first, second, &m.data);
84
768
        }
85
768
        z.data = z.data[..n].to_vec();
86
768
    }
87
88
198k
    z
89
198k
}
90
91
#[inline(always)]
92
839k
fn add_mul_vvw(z: &mut [BigDigit], x: &[BigDigit], y: BigDigit) -> BigDigit {
93
839k
    let mut c = 0;
94
4.63M
    for (zi, xi) in z.iter_mut().zip(x.iter()) {
95
4.63M
        let (z1, z0) = mul_add_www(*xi, y, *zi);
96
4.63M
        let (c_, zi_) = add_ww(z0, c, 0);
97
4.63M
        *zi = zi_;
98
4.63M
        c = c_ + z1;
99
4.63M
    }
100
101
839k
    c
102
839k
}
103
104
/// The resulting carry c is either 0 or 1.
105
#[inline(always)]
106
768
fn sub_vv(z: &mut [BigDigit], x: &[BigDigit], y: &[BigDigit]) -> BigDigit {
107
768
    let mut c = 0;
108
6.66k
    for (i, (xi, yi)) in x.iter().zip(y.iter()).enumerate().take(z.len()) {
109
6.66k
        let zi = xi.wrapping_sub(*yi).wrapping_sub(c);
110
6.66k
        z[i] = zi;
111
6.66k
        // see "Hacker's Delight", section 2-12 (overflow detection)
112
6.66k
        c = ((yi & !xi) | ((yi | !xi) & zi)) >> (big_digit::BITS - 1)
113
    }
114
115
768
    c
116
768
}
117
118
/// z1<<_W + z0 = x+y+c, with c == 0 or 1
119
#[inline(always)]
120
4.63M
fn add_ww(x: BigDigit, y: BigDigit, c: BigDigit) -> (BigDigit, BigDigit) {
121
4.63M
    let yc = y.wrapping_add(c);
122
4.63M
    let z0 = x.wrapping_add(yc);
123
4.63M
    let z1 = if z0 < x || yc < y { 1 } else { 0 };
124
125
4.63M
    (z1, z0)
126
4.63M
}
127
128
/// z1 << _W + z0 = x * y + c
129
#[inline(always)]
130
4.63M
fn mul_add_www(x: BigDigit, y: BigDigit, c: BigDigit) -> (BigDigit, BigDigit) {
131
4.63M
    let z = x as DoubleBigDigit * y as DoubleBigDigit + c as DoubleBigDigit;
132
4.63M
    ((z >> big_digit::BITS) as BigDigit, z as BigDigit)
133
4.63M
}
134
135
/// Calculates x ** y mod m using a fixed, 4-bit window.
136
#[allow(clippy::many_single_char_names)]
137
2.07k
pub(super) fn monty_modpow(x: &BigUint, y: &BigUint, m: &BigUint) -> BigUint {
138
2.07k
    assert!(m.data[0] & 1 == 1);
139
2.07k
    let mr = MontyReducer::new(m);
140
2.07k
    let num_words = m.data.len();
141
2.07k
142
2.07k
    let mut x = x.clone();
143
2.07k
144
2.07k
    // We want the lengths of x and m to be equal.
145
2.07k
    // It is OK if x >= m as long as len(x) == len(m).
146
2.07k
    if x.data.len() > num_words {
147
102
        x %= m;
148
102
        // Note: now len(x) <= numWords, not guaranteed ==.
149
1.97k
    }
150
2.07k
    if x.data.len() < num_words {
151
483
        x.data.resize(num_words, 0);
152
1.59k
    }
153
154
    // rr = 2**(2*_W*len(m)) mod m
155
2.07k
    let mut rr = BigUint::one();
156
2.07k
    rr = (rr.shl(2 * num_words as u64 * u64::from(big_digit::BITS))) % m;
157
2.07k
    if rr.data.len() < num_words {
158
633
        rr.data.resize(num_words, 0);
159
1.44k
    }
160
    // one = 1, with equal length to that of m
161
2.07k
    let mut one = BigUint::one();
162
2.07k
    one.data.resize(num_words, 0);
163
2.07k
164
2.07k
    let n = 4;
165
2.07k
    // powers[i] contains x^i
166
2.07k
    let mut powers = Vec::with_capacity(1 << n);
167
2.07k
    powers.push(montgomery(&one, &rr, m, mr.n0inv, num_words));
168
2.07k
    powers.push(montgomery(&x, &rr, m, mr.n0inv, num_words));
169
29.0k
    for i in 2..1 << n {
170
29.0k
        let r = montgomery(&powers[i - 1], &powers[1], m, mr.n0inv, num_words);
171
29.0k
        powers.push(r);
172
29.0k
    }
173
174
    // initialize z = 1 (Montgomery 1)
175
2.07k
    let mut z = powers[0].clone();
176
2.07k
    z.data.resize(num_words, 0);
177
2.07k
    let mut zz = BigUint::ZERO;
178
2.07k
    zz.data.resize(num_words, 0);
179
180
    // same windowed exponent, but with Montgomery multiplications
181
2.10k
    for i in (0..y.data.len()).rev() {
182
2.10k
        let mut yi = y.data[i];
183
2.10k
        let mut j = 0;
184
35.8k
        while j < big_digit::BITS {
185
33.7k
            if i != y.data.len() - 1 || j != 0 {
186
32.3k
                zz = montgomery(&z, &z, m, mr.n0inv, num_words);
187
32.3k
                z = montgomery(&zz, &zz, m, mr.n0inv, num_words);
188
32.3k
                zz = montgomery(&z, &z, m, mr.n0inv, num_words);
189
32.3k
                z = montgomery(&zz, &zz, m, mr.n0inv, num_words);
190
32.3k
            }
191
33.7k
            zz = montgomery(
192
33.7k
                &z,
193
33.7k
                &powers[(yi >> (big_digit::BITS - n)) as usize],
194
33.7k
                m,
195
33.7k
                mr.n0inv,
196
33.7k
                num_words,
197
33.7k
            );
198
33.7k
            mem::swap(&mut z, &mut zz);
199
33.7k
            yi <<= n;
200
33.7k
            j += n;
201
        }
202
    }
203
204
    // convert to regular number
205
2.07k
    zz = montgomery(&z, &one, m, mr.n0inv, num_words);
206
2.07k
207
2.07k
    zz.normalize();
208
2.07k
    // One last reduction, just in case.
209
2.07k
    // See golang.org/issue/13907.
210
2.07k
    if zz >= *m {
211
        // Common case is m has high bit set; in that case,
212
        // since zz is the same length as m, there can be just
213
        // one multiple of m to remove. Just subtract.
214
        // We think that the subtract should be sufficient in general,
215
        // so do that unconditionally, but double-check,
216
        // in case our beliefs are wrong.
217
        // The div is not expected to be reached.
218
79
        zz -= m;
219
79
        if zz >= *m {
220
0
            zz %= m;
221
79
        }
222
1.99k
    }
223
224
2.07k
    zz.normalize();
225
2.07k
    zz
226
2.07k
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint/multiplication.rs
Line
Count
Source
1
use super::addition::{__add2, add2};
2
use super::subtraction::sub2;
3
use super::{biguint_from_vec, cmp_slice, BigUint, IntDigits};
4
5
use crate::big_digit::{self, BigDigit, DoubleBigDigit};
6
use crate::Sign::{self, Minus, NoSign, Plus};
7
use crate::{BigInt, UsizePromotion};
8
9
use core::cmp::Ordering;
10
use core::iter::Product;
11
use core::ops::{Mul, MulAssign};
12
use num_traits::{CheckedMul, FromPrimitive, One, Zero};
13
14
#[inline]
15
160M
pub(super) fn mac_with_carry(
16
160M
    a: BigDigit,
17
160M
    b: BigDigit,
18
160M
    c: BigDigit,
19
160M
    acc: &mut DoubleBigDigit,
20
160M
) -> BigDigit {
21
160M
    *acc += DoubleBigDigit::from(a);
22
160M
    *acc += DoubleBigDigit::from(b) * DoubleBigDigit::from(c);
23
160M
    let lo = *acc as BigDigit;
24
160M
    *acc >>= big_digit::BITS;
25
160M
    lo
26
160M
}
27
28
#[inline]
29
3.22M
fn mul_with_carry(a: BigDigit, b: BigDigit, acc: &mut DoubleBigDigit) -> BigDigit {
30
3.22M
    *acc += DoubleBigDigit::from(a) * DoubleBigDigit::from(b);
31
3.22M
    let lo = *acc as BigDigit;
32
3.22M
    *acc >>= big_digit::BITS;
33
3.22M
    lo
34
3.22M
}
35
36
/// Three argument multiply accumulate:
37
/// acc += b * c
38
6.11M
fn mac_digit(acc: &mut [BigDigit], b: &[BigDigit], c: BigDigit) {
39
6.11M
    if c == 0 {
40
700k
        return;
41
5.41M
    }
42
5.41M
43
5.41M
    let mut carry = 0;
44
5.41M
    let (a_lo, a_hi) = acc.split_at_mut(b.len());
45
46
160M
    for (a, &b) in a_lo.iter_mut().zip(b) {
47
160M
        *a = mac_with_carry(*a, b, c, &mut carry);
48
160M
    }
49
50
5.41M
    let (carry_hi, carry_lo) = big_digit::from_doublebigdigit(carry);
51
52
5.41M
    let final_carry = if carry_hi == 0 {
53
5.41M
        __add2(a_hi, &[carry_lo])
54
    } else {
55
0
        __add2(a_hi, &[carry_hi, carry_lo])
56
    };
57
5.41M
    assert_eq!(final_carry, 0, "carry overflow during multiplication!");
58
6.11M
}
59
60
54.3k
fn bigint_from_slice(slice: &[BigDigit]) -> BigInt {
61
54.3k
    BigInt::from(biguint_from_vec(slice.to_vec()))
62
54.3k
}
63
64
/// Three argument multiply accumulate:
65
/// acc += b * c
66
#[allow(clippy::many_single_char_names)]
67
557k
fn mac3(mut acc: &mut [BigDigit], mut b: &[BigDigit], mut c: &[BigDigit]) {
68
557k
    // Least-significant zeros have no effect on the output.
69
557k
    if let Some(&0) = b.first() {
70
2.57M
        if let Some(nz) = b.iter().position(|&d| d != 0) {
71
51.6k
            b = &b[nz..];
72
51.6k
            acc = &mut acc[nz..];
73
51.6k
        } else {
74
12.6k
            return;
75
        }
76
493k
    }
77
545k
    if let Some(&0) = c.first() {
78
3.08M
        if let Some(nz) = c.iter().position(|&d| d != 0) {
79
49.2k
            c = &c[nz..];
80
49.2k
            acc = &mut acc[nz..];
81
49.2k
        } else {
82
6.68k
            return;
83
        }
84
489k
    }
85
86
538k
    let acc = acc;
87
538k
    let (x, y) = if b.len() < c.len() { (b, c) } else { (c, b) };
88
89
    // We use four algorithms for different input sizes.
90
    //
91
    // - For small inputs, long multiplication is fastest.
92
    // - If y is at least least twice as long as x, split using Half-Karatsuba.
93
    // - Next we use Karatsuba multiplication (Toom-2), which we have optimized
94
    //   to avoid unnecessary allocations for intermediate values.
95
    // - For the largest inputs we use Toom-3, which better optimizes the
96
    //   number of operations, but uses more temporary allocations.
97
    //
98
    // The thresholds are somewhat arbitrary, chosen by evaluating the results
99
    // of `cargo bench --bench bigint multiply`.
100
101
538k
    if x.len() <= 32 {
102
        // Long multiplication:
103
6.11M
        for (i, xi) in x.iter().enumerate() {
104
6.11M
            mac_digit(&mut acc[i..], y, *xi);
105
6.11M
        }
106
158k
    } else if x.len() * 2 <= y.len() {
107
7.15k
        // Karatsuba Multiplication for factors with significant length disparity.
108
7.15k
        //
109
7.15k
        // The Half-Karatsuba Multiplication Algorithm is a specialized case of
110
7.15k
        // the normal Karatsuba multiplication algorithm, designed for the scenario
111
7.15k
        // where y has at least twice as many base digits as x.
112
7.15k
        //
113
7.15k
        // In this case y (the longer input) is split into high2 and low2,
114
7.15k
        // at m2 (half the length of y) and x (the shorter input),
115
7.15k
        // is used directly without splitting.
116
7.15k
        //
117
7.15k
        // The algorithm then proceeds as follows:
118
7.15k
        //
119
7.15k
        // 1. Compute the product z0 = x * low2.
120
7.15k
        // 2. Compute the product temp = x * high2.
121
7.15k
        // 3. Adjust the weight of temp by adding m2 (* NBASE ^ m2)
122
7.15k
        // 4. Add temp and z0 to obtain the final result.
123
7.15k
        //
124
7.15k
        // Proof:
125
7.15k
        //
126
7.15k
        // The algorithm can be derived from the original Karatsuba algorithm by
127
7.15k
        // simplifying the formula when the shorter factor x is not split into
128
7.15k
        // high and low parts, as shown below.
129
7.15k
        //
130
7.15k
        // Original Karatsuba formula:
131
7.15k
        //
132
7.15k
        //     result = (z2 * NBASE ^ (m2 × 2)) + ((z1 - z2 - z0) * NBASE ^ m2) + z0
133
7.15k
        //
134
7.15k
        // Substitutions:
135
7.15k
        //
136
7.15k
        //     low1 = x
137
7.15k
        //     high1 = 0
138
7.15k
        //
139
7.15k
        // Applying substitutions:
140
7.15k
        //
141
7.15k
        //     z0 = (low1 * low2)
142
7.15k
        //        = (x * low2)
143
7.15k
        //
144
7.15k
        //     z1 = ((low1 + high1) * (low2 + high2))
145
7.15k
        //        = ((x + 0) * (low2 + high2))
146
7.15k
        //        = (x * low2) + (x * high2)
147
7.15k
        //
148
7.15k
        //     z2 = (high1 * high2)
149
7.15k
        //        = (0 * high2)
150
7.15k
        //        = 0
151
7.15k
        //
152
7.15k
        // Simplified using the above substitutions:
153
7.15k
        //
154
7.15k
        //     result = (z2 * NBASE ^ (m2 × 2)) + ((z1 - z2 - z0) * NBASE ^ m2) + z0
155
7.15k
        //            = (0 * NBASE ^ (m2 × 2)) + ((z1 - 0 - z0) * NBASE ^ m2) + z0
156
7.15k
        //            = ((z1 - z0) * NBASE ^ m2) + z0
157
7.15k
        //            = ((z1 - z0) * NBASE ^ m2) + z0
158
7.15k
        //            = (x * high2) * NBASE ^ m2 + z0
159
7.15k
        let m2 = y.len() / 2;
160
7.15k
        let (low2, high2) = y.split_at(m2);
161
7.15k
162
7.15k
        // (x * high2) * NBASE ^ m2 + z0
163
7.15k
        mac3(acc, x, low2);
164
7.15k
        mac3(&mut acc[m2..], x, high2);
165
151k
    } else if x.len() <= 256 {
166
        // Karatsuba multiplication:
167
        //
168
        // The idea is that we break x and y up into two smaller numbers that each have about half
169
        // as many digits, like so (note that multiplying by b is just a shift):
170
        //
171
        // x = x0 + x1 * b
172
        // y = y0 + y1 * b
173
        //
174
        // With some algebra, we can compute x * y with three smaller products, where the inputs to
175
        // each of the smaller products have only about half as many digits as x and y:
176
        //
177
        // x * y = (x0 + x1 * b) * (y0 + y1 * b)
178
        //
179
        // x * y = x0 * y0
180
        //       + x0 * y1 * b
181
        //       + x1 * y0 * b
182
        //       + x1 * y1 * b^2
183
        //
184
        // Let p0 = x0 * y0 and p2 = x1 * y1:
185
        //
186
        // x * y = p0
187
        //       + (x0 * y1 + x1 * y0) * b
188
        //       + p2 * b^2
189
        //
190
        // The real trick is that middle term:
191
        //
192
        //         x0 * y1 + x1 * y0
193
        //
194
        //       = x0 * y1 + x1 * y0 - p0 + p0 - p2 + p2
195
        //
196
        //       = x0 * y1 + x1 * y0 - x0 * y0 - x1 * y1 + p0 + p2
197
        //
198
        // Now we complete the square:
199
        //
200
        //       = -(x0 * y0 - x0 * y1 - x1 * y0 + x1 * y1) + p0 + p2
201
        //
202
        //       = -((x1 - x0) * (y1 - y0)) + p0 + p2
203
        //
204
        // Let p1 = (x1 - x0) * (y1 - y0), and substitute back into our original formula:
205
        //
206
        // x * y = p0
207
        //       + (p0 + p2 - p1) * b
208
        //       + p2 * b^2
209
        //
210
        // Where the three intermediate products are:
211
        //
212
        // p0 = x0 * y0
213
        // p1 = (x1 - x0) * (y1 - y0)
214
        // p2 = x1 * y1
215
        //
216
        // In doing the computation, we take great care to avoid unnecessary temporary variables
217
        // (since creating a BigUint requires a heap allocation): thus, we rearrange the formula a
218
        // bit so we can use the same temporary variable for all the intermediate products:
219
        //
220
        // x * y = p2 * b^2 + p2 * b
221
        //       + p0 * b + p0
222
        //       - p1 * b
223
        //
224
        // The other trick we use is instead of doing explicit shifts, we slice acc at the
225
        // appropriate offset when doing the add.
226
227
        // When x is smaller than y, it's significantly faster to pick b such that x is split in
228
        // half, not y:
229
142k
        let b = x.len() / 2;
230
142k
        let (x0, x1) = x.split_at(b);
231
142k
        let (y0, y1) = y.split_at(b);
232
142k
233
142k
        // We reuse the same BigUint for all the intermediate multiplies and have to size p
234
142k
        // appropriately here: x1.len() >= x0.len and y1.len() >= y0.len():
235
142k
        let len = x1.len() + y1.len() + 1;
236
142k
        let mut p = BigUint { data: vec![0; len] };
237
142k
238
142k
        // p2 = x1 * y1
239
142k
        mac3(&mut p.data, x1, y1);
240
142k
241
142k
        // Not required, but the adds go faster if we drop any unneeded 0s from the end:
242
142k
        p.normalize();
243
142k
244
142k
        add2(&mut acc[b..], &p.data);
245
142k
        add2(&mut acc[b * 2..], &p.data);
246
142k
247
142k
        // Zero out p before the next multiply:
248
142k
        p.data.truncate(0);
249
142k
        p.data.resize(len, 0);
250
142k
251
142k
        // p0 = x0 * y0
252
142k
        mac3(&mut p.data, x0, y0);
253
142k
        p.normalize();
254
142k
255
142k
        add2(acc, &p.data);
256
142k
        add2(&mut acc[b..], &p.data);
257
142k
258
142k
        // p1 = (x1 - x0) * (y1 - y0)
259
142k
        // We do this one last, since it may be negative and acc can't ever be negative:
260
142k
        let (j0_sign, j0) = sub_sign(x1, x0);
261
142k
        let (j1_sign, j1) = sub_sign(y1, y0);
262
142k
263
142k
        match j0_sign * j1_sign {
264
105k
            Plus => {
265
105k
                p.data.truncate(0);
266
105k
                p.data.resize(len, 0);
267
105k
268
105k
                mac3(&mut p.data, &j0.data, &j1.data);
269
105k
                p.normalize();
270
105k
271
105k
                sub2(&mut acc[b..], &p.data);
272
105k
            }
273
30.6k
            Minus => {
274
30.6k
                mac3(&mut acc[b..], &j0.data, &j1.data);
275
30.6k
            }
276
6.61k
            NoSign => (),
277
        }
278
    } else {
279
        // Toom-3 multiplication:
280
        //
281
        // Toom-3 is like Karatsuba above, but dividing the inputs into three parts.
282
        // Both are instances of Toom-Cook, using `k=3` and `k=2` respectively.
283
        //
284
        // The general idea is to treat the large integers digits as
285
        // polynomials of a certain degree and determine the coefficients/digits
286
        // of the product of the two via interpolation of the polynomial product.
287
9.06k
        let i = y.len() / 3 + 1;
288
9.06k
289
9.06k
        let x0_len = Ord::min(x.len(), i);
290
9.06k
        let x1_len = Ord::min(x.len() - x0_len, i);
291
9.06k
292
9.06k
        let y0_len = i;
293
9.06k
        let y1_len = Ord::min(y.len() - y0_len, i);
294
9.06k
295
9.06k
        // Break x and y into three parts, representating an order two polynomial.
296
9.06k
        // t is chosen to be the size of a digit so we can use faster shifts
297
9.06k
        // in place of multiplications.
298
9.06k
        //
299
9.06k
        // x(t) = x2*t^2 + x1*t + x0
300
9.06k
        let x0 = bigint_from_slice(&x[..x0_len]);
301
9.06k
        let x1 = bigint_from_slice(&x[x0_len..x0_len + x1_len]);
302
9.06k
        let x2 = bigint_from_slice(&x[x0_len + x1_len..]);
303
9.06k
304
9.06k
        // y(t) = y2*t^2 + y1*t + y0
305
9.06k
        let y0 = bigint_from_slice(&y[..y0_len]);
306
9.06k
        let y1 = bigint_from_slice(&y[y0_len..y0_len + y1_len]);
307
9.06k
        let y2 = bigint_from_slice(&y[y0_len + y1_len..]);
308
9.06k
309
9.06k
        // Let w(t) = x(t) * y(t)
310
9.06k
        //
311
9.06k
        // This gives us the following order-4 polynomial.
312
9.06k
        //
313
9.06k
        // w(t) = w4*t^4 + w3*t^3 + w2*t^2 + w1*t + w0
314
9.06k
        //
315
9.06k
        // We need to find the coefficients w4, w3, w2, w1 and w0. Instead
316
9.06k
        // of simply multiplying the x and y in total, we can evaluate w
317
9.06k
        // at 5 points. An n-degree polynomial is uniquely identified by (n + 1)
318
9.06k
        // points.
319
9.06k
        //
320
9.06k
        // It is arbitrary as to what points we evaluate w at but we use the
321
9.06k
        // following.
322
9.06k
        //
323
9.06k
        // w(t) at t = 0, 1, -1, -2 and inf
324
9.06k
        //
325
9.06k
        // The values for w(t) in terms of x(t)*y(t) at these points are:
326
9.06k
        //
327
9.06k
        // let a = w(0)   = x0 * y0
328
9.06k
        // let b = w(1)   = (x2 + x1 + x0) * (y2 + y1 + y0)
329
9.06k
        // let c = w(-1)  = (x2 - x1 + x0) * (y2 - y1 + y0)
330
9.06k
        // let d = w(-2)  = (4*x2 - 2*x1 + x0) * (4*y2 - 2*y1 + y0)
331
9.06k
        // let e = w(inf) = x2 * y2 as t -> inf
332
9.06k
333
9.06k
        // x0 + x2, avoiding temporaries
334
9.06k
        let p = &x0 + &x2;
335
9.06k
336
9.06k
        // y0 + y2, avoiding temporaries
337
9.06k
        let q = &y0 + &y2;
338
9.06k
339
9.06k
        // x2 - x1 + x0, avoiding temporaries
340
9.06k
        let p2 = &p - &x1;
341
9.06k
342
9.06k
        // y2 - y1 + y0, avoiding temporaries
343
9.06k
        let q2 = &q - &y1;
344
9.06k
345
9.06k
        // w(0)
346
9.06k
        let r0 = &x0 * &y0;
347
9.06k
348
9.06k
        // w(inf)
349
9.06k
        let r4 = &x2 * &y2;
350
9.06k
351
9.06k
        // w(1)
352
9.06k
        let r1 = (p + x1) * (q + y1);
353
9.06k
354
9.06k
        // w(-1)
355
9.06k
        let r2 = &p2 * &q2;
356
9.06k
357
9.06k
        // w(-2)
358
9.06k
        let r3 = ((p2 + x2) * 2 - x0) * ((q2 + y2) * 2 - y0);
359
9.06k
360
9.06k
        // Evaluating these points gives us the following system of linear equations.
361
9.06k
        //
362
9.06k
        //  0  0  0  0  1 | a
363
9.06k
        //  1  1  1  1  1 | b
364
9.06k
        //  1 -1  1 -1  1 | c
365
9.06k
        // 16 -8  4 -2  1 | d
366
9.06k
        //  1  0  0  0  0 | e
367
9.06k
        //
368
9.06k
        // The solved equation (after gaussian elimination or similar)
369
9.06k
        // in terms of its coefficients:
370
9.06k
        //
371
9.06k
        // w0 = w(0)
372
9.06k
        // w1 = w(0)/2 + w(1)/3 - w(-1) + w(-2)/6 - 2*w(inf)
373
9.06k
        // w2 = -w(0) + w(1)/2 + w(-1)/2 - w(inf)
374
9.06k
        // w3 = -w(0)/2 + w(1)/6 + w(-1)/2 - w(-2)/6 + 2*w(inf)
375
9.06k
        // w4 = w(inf)
376
9.06k
        //
377
9.06k
        // This particular sequence is given by Bodrato and is an interpolation
378
9.06k
        // of the above equations.
379
9.06k
        let mut comp3: BigInt = (r3 - &r1) / 3u32;
380
9.06k
        let mut comp1: BigInt = (r1 - &r2) >> 1;
381
9.06k
        let mut comp2: BigInt = r2 - &r0;
382
9.06k
        comp3 = ((&comp2 - comp3) >> 1) + (&r4 << 1);
383
9.06k
        comp2 += &comp1 - &r4;
384
9.06k
        comp1 -= &comp3;
385
386
        // Recomposition. The coefficients of the polynomial are now known.
387
        //
388
        // Evaluate at w(t) where t is our given base to get the result.
389
        //
390
        //     let bits = u64::from(big_digit::BITS) * i as u64;
391
        //     let result = r0
392
        //         + (comp1 << bits)
393
        //         + (comp2 << (2 * bits))
394
        //         + (comp3 << (3 * bits))
395
        //         + (r4 << (4 * bits));
396
        //     let result_pos = result.to_biguint().unwrap();
397
        //     add2(&mut acc[..], &result_pos.data);
398
        //
399
        // But with less intermediate copying:
400
45.3k
        for (j, result) in [&r0, &comp1, &comp2, &comp3, &r4].iter().enumerate().rev() {
401
45.3k
            match result.sign() {
402
37.4k
                Plus => add2(&mut acc[i * j..], result.digits()),
403
0
                Minus => sub2(&mut acc[i * j..], result.digits()),
404
7.82k
                NoSign => {}
405
            }
406
        }
407
    }
408
557k
}
409
410
123k
fn mul3(x: &[BigDigit], y: &[BigDigit]) -> BigUint {
411
123k
    let len = x.len() + y.len() + 1;
412
123k
    let mut prod = BigUint { data: vec![0; len] };
413
123k
414
123k
    mac3(&mut prod.data, x, y);
415
123k
    prod.normalized()
416
123k
}
417
418
84.1k
fn scalar_mul(a: &mut BigUint, b: BigDigit) {
419
84.1k
    match b {
420
11.3k
        0 => a.set_zero(),
421
33.5k
        1 => {}
422
        _ => {
423
39.2k
            if b.is_power_of_two() {
424
20.9k
                *a <<= b.trailing_zeros();
425
20.9k
            } else {
426
18.3k
                let mut carry = 0;
427
3.22M
                for a in a.data.iter_mut() {
428
3.22M
                    *a = mul_with_carry(*a, b, &mut carry);
429
3.22M
                }
430
18.3k
                if carry != 0 {
431
10.1k
                    a.data.push(carry as BigDigit);
432
10.1k
                }
433
            }
434
        }
435
    }
436
84.1k
}
437
438
284k
fn sub_sign(mut a: &[BigDigit], mut b: &[BigDigit]) -> (Sign, BigUint) {
439
284k
    // Normalize:
440
284k
    if let Some(&0) = a.last() {
441
841k
        a = &a[..a.iter().rposition(|&x| x != 0).map_or(0, |i| i + 1)];
442
253k
    }
443
284k
    if let Some(&0) = b.last() {
444
2.14M
        b = &b[..b.iter().rposition(|&x| x != 0).map_or(0, |i| i + 1)];
445
210k
    }
446
447
284k
    match cmp_slice(a, b) {
448
        Ordering::Greater => {
449
201k
            let mut a = a.to_vec();
450
201k
            sub2(&mut a, b);
451
201k
            (Plus, biguint_from_vec(a))
452
        }
453
        Ordering::Less => {
454
73.3k
            let mut b = b.to_vec();
455
73.3k
            sub2(&mut b, a);
456
73.3k
            (Minus, biguint_from_vec(b))
457
        }
458
9.94k
        Ordering::Equal => (NoSign, BigUint::ZERO),
459
    }
460
284k
}
461
462
macro_rules! impl_mul {
463
    ($(impl Mul<$Other:ty> for $Self:ty;)*) => {$(
464
        impl Mul<$Other> for $Self {
465
            type Output = BigUint;
466
467
            #[inline]
468
158k
            fn mul(self, other: $Other) -> BigUint {
469
158k
                match (&*self.data, &*other.data) {
470
158k
                    // multiply by zero
471
158k
                    (&[], _) | (_, &[]) => BigUint::ZERO,
472
                    // multiply by a scalar
473
29.8k
                    (_, &[digit]) => self * digit,
474
3.64k
                    (&[digit], _) => other * digit,
475
                    // full multiplication
476
100k
                    (x, y) => mul3(x, y),
477
                }
478
158k
            }
_RNvXs5_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mulB9_
Line
Count
Source
468
18.1k
            fn mul(self, other: $Other) -> BigUint {
469
18.1k
                match (&*self.data, &*other.data) {
470
18.1k
                    // multiply by zero
471
18.1k
                    (&[], _) | (_, &[]) => BigUint::ZERO,
472
                    // multiply by a scalar
473
22
                    (_, &[digit]) => self * digit,
474
38
                    (&[digit], _) => other * digit,
475
                    // full multiplication
476
18.0k
                    (x, y) => mul3(x, y),
477
                }
478
18.1k
            }
Unexecuted instantiation: _RNvXs6_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulBY_E3mulB9_
Unexecuted instantiation: _RNvXs7_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRBX_E3mulB9_
_RNvXs8_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mulB9_
Line
Count
Source
468
140k
            fn mul(self, other: $Other) -> BigUint {
469
140k
                match (&*self.data, &*other.data) {
470
140k
                    // multiply by zero
471
140k
                    (&[], _) | (_, &[]) => BigUint::ZERO,
472
                    // multiply by a scalar
473
29.8k
                    (_, &[digit]) => self * digit,
474
3.60k
                    (&[digit], _) => other * digit,
475
                    // full multiplication
476
81.9k
                    (x, y) => mul3(x, y),
477
                }
478
140k
            }
479
        }
480
    )*}
481
}
482
impl_mul! {
483
    impl Mul<BigUint> for BigUint;
484
    impl Mul<BigUint> for &BigUint;
485
    impl Mul<&BigUint> for BigUint;
486
    impl Mul<&BigUint> for &BigUint;
487
}
488
489
macro_rules! impl_mul_assign {
490
    ($(impl MulAssign<$Other:ty> for BigUint;)*) => {$(
491
        impl MulAssign<$Other> for BigUint {
492
            #[inline]
493
57.1k
            fn mul_assign(&mut self, other: $Other) {
494
57.1k
                match (&*self.data, &*other.data) {
495
57.1k
                    // multiply by zero
496
57.1k
                    (&[], _) => {},
497
35.9k
                    (_, &[]) => self.set_zero(),
498
                    // multiply by a scalar
499
9.30k
                    (_, &[digit]) => *self *= digit,
500
3.63k
                    (&[digit], _) => *self = other * digit,
501
                    // full multiplication
502
22.9k
                    (x, y) => *self = mul3(x, y),
503
                }
504
57.1k
            }
_RNvXs9_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssign10mul_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
493
18.6k
            fn mul_assign(&mut self, other: $Other) {
494
18.6k
                match (&*self.data, &*other.data) {
495
18.6k
                    // multiply by zero
496
18.6k
                    (&[], _) => {},
497
9.61k
                    (_, &[]) => self.set_zero(),
498
                    // multiply by a scalar
499
3.12k
                    (_, &[digit]) => *self *= digit,
500
3.30k
                    (&[digit], _) => *self = other * digit,
501
                    // full multiplication
502
3.14k
                    (x, y) => *self = mul3(x, y),
503
                }
504
18.6k
            }
Unexecuted instantiation: _RNvXs9_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssign10mul_assignB9_
_RNvXsa_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignRBX_E10mul_assignB9_
Line
Count
Source
493
38.5k
            fn mul_assign(&mut self, other: $Other) {
494
38.5k
                match (&*self.data, &*other.data) {
495
38.5k
                    // multiply by zero
496
38.5k
                    (&[], _) => {},
497
26.3k
                    (_, &[]) => self.set_zero(),
498
                    // multiply by a scalar
499
6.17k
                    (_, &[digit]) => *self *= digit,
500
335
                    (&[digit], _) => *self = other * digit,
501
                    // full multiplication
502
19.8k
                    (x, y) => *self = mul3(x, y),
503
                }
504
38.5k
            }
505
        }
506
    )*}
507
}
508
impl_mul_assign! {
509
    impl MulAssign<BigUint> for BigUint;
510
    impl MulAssign<&BigUint> for BigUint;
511
}
512
513
promote_unsigned_scalars!(impl Mul for BigUint, mul);
514
promote_unsigned_scalars_assign!(impl MulAssign for BigUint, mul_assign);
515
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<u32> for BigUint, mul);
516
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<u64> for BigUint, mul);
517
forward_all_scalar_binop_to_val_val_commutative!(impl Mul<u128> for BigUint, mul);
518
519
impl Mul<u32> for BigUint {
520
    type Output = BigUint;
521
522
    #[inline]
523
18.1k
    fn mul(mut self, other: u32) -> BigUint {
524
18.1k
        self *= other;
525
18.1k
        self
526
18.1k
    }
527
}
528
impl MulAssign<u32> for BigUint {
529
    #[inline]
530
37.7k
    fn mul_assign(&mut self, other: u32) {
531
37.7k
        scalar_mul(self, other as BigDigit);
532
37.7k
    }
_RNvXs_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB6_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignmE10mul_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
530
19.5k
    fn mul_assign(&mut self, other: u32) {
531
19.5k
        scalar_mul(self, other as BigDigit);
532
19.5k
    }
_RNvXs_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB6_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignmE10mul_assignB8_
Line
Count
Source
530
18.1k
    fn mul_assign(&mut self, other: u32) {
531
18.1k
        scalar_mul(self, other as BigDigit);
532
18.1k
    }
533
}
534
535
impl Mul<u64> for BigUint {
536
    type Output = BigUint;
537
538
    #[inline]
539
37.1k
    fn mul(mut self, other: u64) -> BigUint {
540
37.1k
        self *= other;
541
37.1k
        self
542
37.1k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulyE3mulCs4RkbDk9WRL5_5clvmr
Line
Count
Source
539
3.30k
    fn mul(mut self, other: u64) -> BigUint {
540
3.30k
        self *= other;
541
3.30k
        self
542
3.30k
    }
_RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulyE3mulB9_
Line
Count
Source
539
33.8k
    fn mul(mut self, other: u64) -> BigUint {
540
33.8k
        self *= other;
541
33.8k
        self
542
33.8k
    }
543
}
544
impl MulAssign<u64> for BigUint {
545
    cfg_digit!(
546
        #[inline]
547
        fn mul_assign(&mut self, other: u64) {
548
            if let Some(other) = BigDigit::from_u64(other) {
549
                scalar_mul(self, other);
550
            } else {
551
                let (hi, lo) = big_digit::from_doublebigdigit(other);
552
                *self = mul3(&self.data, &[lo, hi]);
553
            }
554
        }
555
556
        #[inline]
557
46.4k
        fn mul_assign(&mut self, other: u64) {
558
46.4k
            scalar_mul(self, other);
559
46.4k
        }
_RNvXs1_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignyE10mul_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
557
6.43k
        fn mul_assign(&mut self, other: u64) {
558
6.43k
            scalar_mul(self, other);
559
6.43k
        }
_RNvXs1_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignyE10mul_assignB9_
Line
Count
Source
557
40.0k
        fn mul_assign(&mut self, other: u64) {
558
40.0k
            scalar_mul(self, other);
559
40.0k
        }
560
    );
561
}
562
563
impl Mul<u128> for BigUint {
564
    type Output = BigUint;
565
566
    #[inline]
567
0
    fn mul(mut self, other: u128) -> BigUint {
568
0
        self *= other;
569
0
        self
570
0
    }
571
}
572
573
impl MulAssign<u128> for BigUint {
574
    cfg_digit!(
575
        #[inline]
576
        fn mul_assign(&mut self, other: u128) {
577
            if let Some(other) = BigDigit::from_u128(other) {
578
                scalar_mul(self, other);
579
            } else {
580
                *self = match super::u32_from_u128(other) {
581
                    (0, 0, c, d) => mul3(&self.data, &[d, c]),
582
                    (0, b, c, d) => mul3(&self.data, &[d, c, b]),
583
                    (a, b, c, d) => mul3(&self.data, &[d, c, b, a]),
584
                };
585
            }
586
        }
587
588
        #[inline]
589
0
        fn mul_assign(&mut self, other: u128) {
590
0
            if let Some(other) = BigDigit::from_u128(other) {
591
0
                scalar_mul(self, other);
592
0
            } else {
593
0
                let (hi, lo) = big_digit::from_doublebigdigit(other);
594
0
                *self = mul3(&self.data, &[lo, hi]);
595
0
            }
596
0
        }
597
    );
598
}
599
600
impl CheckedMul for BigUint {
601
    #[inline]
602
0
    fn checked_mul(&self, v: &BigUint) -> Option<BigUint> {
603
0
        Some(self.mul(v))
604
0
    }
605
}
606
607
impl_product_iter_type!(BigUint);
608
609
#[test]
610
fn test_sub_sign() {
611
    use crate::BigInt;
612
    use num_traits::Num;
613
614
    fn sub_sign_i(a: &[BigDigit], b: &[BigDigit]) -> BigInt {
615
        let (sign, val) = sub_sign(a, b);
616
        BigInt::from_biguint(sign, val)
617
    }
618
619
    let a = BigUint::from_str_radix("265252859812191058636308480000000", 10).unwrap();
620
    let b = BigUint::from_str_radix("26525285981219105863630848000000", 10).unwrap();
621
    let a_i = BigInt::from(a.clone());
622
    let b_i = BigInt::from(b.clone());
623
624
    assert_eq!(sub_sign_i(&a.data, &b.data), &a_i - &b_i);
625
    assert_eq!(sub_sign_i(&b.data, &a.data), &b_i - &a_i);
626
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint/power.rs
Line
Count
Source
1
use super::monty::monty_modpow;
2
use super::BigUint;
3
4
use crate::big_digit::{self, BigDigit};
5
6
use num_integer::Integer;
7
use num_traits::{One, Pow, ToPrimitive, Zero};
8
9
impl Pow<&BigUint> for BigUint {
10
    type Output = BigUint;
11
12
    #[inline]
13
0
    fn pow(self, exp: &BigUint) -> BigUint {
14
0
        if self.is_one() || exp.is_zero() {
15
0
            BigUint::one()
16
0
        } else if self.is_zero() {
17
0
            Self::ZERO
18
0
        } else if let Some(exp) = exp.to_u64() {
19
0
            self.pow(exp)
20
0
        } else if let Some(exp) = exp.to_u128() {
21
0
            self.pow(exp)
22
        } else {
23
            // At this point, `self >= 2` and `exp >= 2¹²⁸`. The smallest possible result given
24
            // `2.pow(2¹²⁸)` would require far more memory than 64-bit targets can address!
25
0
            panic!("memory overflow")
26
        }
27
0
    }
28
}
29
30
impl Pow<BigUint> for BigUint {
31
    type Output = BigUint;
32
33
    #[inline]
34
0
    fn pow(self, exp: BigUint) -> BigUint {
35
0
        Pow::pow(self, &exp)
36
0
    }
37
}
38
39
impl Pow<&BigUint> for &BigUint {
40
    type Output = BigUint;
41
42
    #[inline]
43
0
    fn pow(self, exp: &BigUint) -> BigUint {
44
0
        if self.is_one() || exp.is_zero() {
45
0
            BigUint::one()
46
0
        } else if self.is_zero() {
47
0
            BigUint::ZERO
48
        } else {
49
0
            self.clone().pow(exp)
50
        }
51
0
    }
52
}
53
54
impl Pow<BigUint> for &BigUint {
55
    type Output = BigUint;
56
57
    #[inline]
58
0
    fn pow(self, exp: BigUint) -> BigUint {
59
0
        Pow::pow(self, &exp)
60
0
    }
61
}
62
63
macro_rules! pow_impl {
64
    ($T:ty) => {
65
        impl Pow<$T> for BigUint {
66
            type Output = BigUint;
67
68
0
            fn pow(self, mut exp: $T) -> BigUint {
69
0
                if exp == 0 {
70
0
                    return BigUint::one();
71
0
                }
72
0
                let mut base = self;
73
74
0
                while exp & 1 == 0 {
75
0
                    base = &base * &base;
76
0
                    exp >>= 1;
77
0
                }
78
79
0
                if exp == 1 {
80
0
                    return base;
81
0
                }
82
0
83
0
                let mut acc = base.clone();
84
0
                while exp > 1 {
85
0
                    exp >>= 1;
86
0
                    base = &base * &base;
87
0
                    if exp & 1 == 1 {
88
0
                        acc *= &base;
89
0
                    }
90
                }
91
0
                acc
92
0
            }
Unexecuted instantiation: _RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowhE3pow
Unexecuted instantiation: _RNvXs6_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowtE3pow
Unexecuted instantiation: _RNvXsa_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowmE3pow
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowyE3pow
Unexecuted instantiation: _RNvXsi_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowjE3pow
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowoE3pow
93
        }
94
95
        impl Pow<&$T> for BigUint {
96
            type Output = BigUint;
97
98
            #[inline]
99
0
            fn pow(self, exp: &$T) -> BigUint {
100
0
                Pow::pow(self, *exp)
101
0
            }
Unexecuted instantiation: _RNvXs3_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRhE3powB9_
Unexecuted instantiation: _RNvXs7_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRtE3powB9_
Unexecuted instantiation: _RNvXsb_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRmE3powB9_
Unexecuted instantiation: _RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRyE3powB9_
Unexecuted instantiation: _RNvXsj_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRjE3powB9_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRoE3powB9_
102
        }
103
104
        impl Pow<$T> for &BigUint {
105
            type Output = BigUint;
106
107
            #[inline]
108
0
            fn pow(self, exp: $T) -> BigUint {
109
0
                if exp == 0 {
110
0
                    return BigUint::one();
111
0
                }
112
0
                Pow::pow(self.clone(), exp)
113
0
            }
Unexecuted instantiation: _RNvXsc_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowmE3powB9_
Unexecuted instantiation: _RNvXs4_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowhE3powB9_
Unexecuted instantiation: _RNvXs8_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowtE3powB9_
Unexecuted instantiation: _RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowyE3powB9_
Unexecuted instantiation: _RNvXsk_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowjE3powB9_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowoE3powB9_
114
        }
115
116
        impl Pow<&$T> for &BigUint {
117
            type Output = BigUint;
118
119
            #[inline]
120
0
            fn pow(self, exp: &$T) -> BigUint {
121
0
                Pow::pow(self, *exp)
122
0
            }
Unexecuted instantiation: _RNvXs5_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRhE3powB9_
Unexecuted instantiation: _RNvXs9_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRtE3powB9_
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRmE3powB9_
Unexecuted instantiation: _RNvXsh_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRyE3powB9_
Unexecuted instantiation: _RNvXsl_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRjE3powB9_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint7biguint5powerRNtB7_7BigUintINtNtCs7cG3k8kmkqw_10num_traits3pow3PowRoE3powB9_
123
        }
124
    };
125
}
126
127
pow_impl!(u8);
128
pow_impl!(u16);
129
pow_impl!(u32);
130
pow_impl!(u64);
131
pow_impl!(usize);
132
pow_impl!(u128);
133
134
5.03k
pub(super) fn modpow(x: &BigUint, exponent: &BigUint, modulus: &BigUint) -> BigUint {
135
5.03k
    assert!(
136
5.03k
        !modulus.is_zero(),
137
0
        "attempt to calculate with zero modulus!"
138
    );
139
140
5.03k
    if modulus.is_odd() {
141
        // For an odd modulus, we can use Montgomery multiplication in base 2^32.
142
2.07k
        monty_modpow(x, exponent, modulus)
143
    } else {
144
        // Otherwise do basically the same as `num::pow`, but with a modulus.
145
2.95k
        plain_modpow(x, &exponent.data, modulus)
146
    }
147
5.03k
}
148
149
2.95k
fn plain_modpow(base: &BigUint, exp_data: &[BigDigit], modulus: &BigUint) -> BigUint {
150
2.95k
    assert!(
151
2.95k
        !modulus.is_zero(),
152
0
        "attempt to calculate with zero modulus!"
153
    );
154
155
2.95k
    let i = match exp_data.iter().position(|&r| r != 0) {
156
710
        None => return BigUint::one(),
157
2.24k
        Some(i) => i,
158
2.24k
    };
159
2.24k
160
2.24k
    let mut base = base % modulus;
161
2.24k
    for _ in 0..i {
162
42.1k
        for _ in 0..big_digit::BITS {
163
41.5k
            base = &base * &base % modulus;
164
41.5k
        }
165
    }
166
167
2.24k
    let mut r = exp_data[i];
168
2.24k
    let mut b = 0u8;
169
9.59k
    while r.is_even() {
170
7.35k
        base = &base * &base % modulus;
171
7.35k
        r >>= 1;
172
7.35k
        b += 1;
173
7.35k
    }
174
175
2.24k
    let mut exp_iter = exp_data[i + 1..].iter();
176
2.24k
    if exp_iter.len() == 0 && r.is_one() {
177
793
        return base;
178
1.45k
    }
179
1.45k
180
1.45k
    let mut acc = base.clone();
181
1.45k
    r >>= 1;
182
1.45k
    b += 1;
183
1.45k
184
1.45k
    {
185
64.1k
        let mut unit = |exp_is_odd| {
186
64.1k
            base = &base * &base % modulus;
187
64.1k
            if exp_is_odd {
188
38.5k
                acc *= &base;
189
38.5k
                acc %= modulus;
190
38.5k
            }
191
64.1k
        };
192
193
1.45k
        if let Some(&last) = exp_iter.next_back() {
194
            // consume exp_data[i]
195
5.01k
            for _ in b..big_digit::BITS {
196
5.01k
                unit(r.is_odd());
197
5.01k
                r >>= 1;
198
5.01k
            }
199
200
            // consume all other digits before the last
201
396
            for &r in exp_iter {
202
299
                let mut r = r;
203
19.4k
                for _ in 0..big_digit::BITS {
204
19.1k
                    unit(r.is_odd());
205
19.1k
                    r >>= 1;
206
19.1k
                }
207
            }
208
97
            r = last;
209
1.35k
        }
210
211
1.45k
        debug_assert_ne!(r, 0);
212
41.4k
        while !r.is_zero() {
213
39.9k
            unit(r.is_odd());
214
39.9k
            r >>= 1;
215
39.9k
        }
216
    }
217
1.45k
    acc
218
2.95k
}
219
220
#[test]
221
fn test_plain_modpow() {
222
    let two = &BigUint::from(2u32);
223
    let modulus = BigUint::from(0x1100u32);
224
225
    let exp = vec![0, 0b1];
226
    assert_eq!(
227
        two.pow(0b1_00000000_u32) % &modulus,
228
        plain_modpow(two, &exp, &modulus)
229
    );
230
    let exp = vec![0, 0b10];
231
    assert_eq!(
232
        two.pow(0b10_00000000_u32) % &modulus,
233
        plain_modpow(two, &exp, &modulus)
234
    );
235
    let exp = vec![0, 0b110010];
236
    assert_eq!(
237
        two.pow(0b110010_00000000_u32) % &modulus,
238
        plain_modpow(two, &exp, &modulus)
239
    );
240
    let exp = vec![0b1, 0b1];
241
    assert_eq!(
242
        two.pow(0b1_00000001_u32) % &modulus,
243
        plain_modpow(two, &exp, &modulus)
244
    );
245
    let exp = vec![0b1100, 0, 0b1];
246
    assert_eq!(
247
        two.pow(0b1_00000000_00001100_u32) % &modulus,
248
        plain_modpow(two, &exp, &modulus)
249
    );
250
}
251
252
#[test]
253
fn test_pow_biguint() {
254
    let base = BigUint::from(5u8);
255
    let exponent = BigUint::from(3u8);
256
257
    assert_eq!(BigUint::from(125u8), base.pow(exponent));
258
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint/shift.rs
Line
Count
Source
1
use super::{biguint_from_vec, BigUint};
2
3
use crate::big_digit;
4
5
use alloc::borrow::Cow;
6
use alloc::vec::Vec;
7
use core::mem;
8
use core::ops::{Shl, ShlAssign, Shr, ShrAssign};
9
use num_traits::{PrimInt, Zero};
10
11
#[inline]
12
215k
fn biguint_shl<T: PrimInt>(n: Cow<'_, BigUint>, shift: T) -> BigUint {
13
215k
    if shift < T::zero() {
14
0
        panic!("attempt to shift left with negative");
15
215k
    }
16
215k
    if n.is_zero() {
17
7.37k
        return n.into_owned();
18
208k
    }
19
208k
    let bits = T::from(big_digit::BITS).unwrap();
20
208k
    let digits = (shift / bits).to_usize().expect("capacity overflow");
21
208k
    let shift = (shift % bits).to_u8().unwrap();
22
208k
    biguint_shl2(n, digits, shift)
23
215k
}
_RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shllECs4RkbDk9WRL5_5clvmr
Line
Count
Source
12
21.5k
fn biguint_shl<T: PrimInt>(n: Cow<'_, BigUint>, shift: T) -> BigUint {
13
21.5k
    if shift < T::zero() {
14
0
        panic!("attempt to shift left with negative");
15
21.5k
    }
16
21.5k
    if n.is_zero() {
17
6.26k
        return n.into_owned();
18
15.2k
    }
19
15.2k
    let bits = T::from(big_digit::BITS).unwrap();
20
15.2k
    let digits = (shift / bits).to_usize().expect("capacity overflow");
21
15.2k
    let shift = (shift % bits).to_u8().unwrap();
22
15.2k
    biguint_shl2(n, digits, shift)
23
21.5k
}
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shlaEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shlhEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shliEB6_
_RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shljEB6_
Line
Count
Source
12
162k
fn biguint_shl<T: PrimInt>(n: Cow<'_, BigUint>, shift: T) -> BigUint {
13
162k
    if shift < T::zero() {
14
0
        panic!("attempt to shift left with negative");
15
162k
    }
16
162k
    if n.is_zero() {
17
0
        return n.into_owned();
18
162k
    }
19
162k
    let bits = T::from(big_digit::BITS).unwrap();
20
162k
    let digits = (shift / bits).to_usize().expect("capacity overflow");
21
162k
    let shift = (shift % bits).to_u8().unwrap();
22
162k
    biguint_shl2(n, digits, shift)
23
162k
}
_RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shllEB6_
Line
Count
Source
12
9.06k
fn biguint_shl<T: PrimInt>(n: Cow<'_, BigUint>, shift: T) -> BigUint {
13
9.06k
    if shift < T::zero() {
14
0
        panic!("attempt to shift left with negative");
15
9.06k
    }
16
9.06k
    if n.is_zero() {
17
811
        return n.into_owned();
18
8.25k
    }
19
8.25k
    let bits = T::from(big_digit::BITS).unwrap();
20
8.25k
    let digits = (shift / bits).to_usize().expect("capacity overflow");
21
8.25k
    let shift = (shift % bits).to_u8().unwrap();
22
8.25k
    biguint_shl2(n, digits, shift)
23
9.06k
}
_RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shlmEB6_
Line
Count
Source
12
20.9k
fn biguint_shl<T: PrimInt>(n: Cow<'_, BigUint>, shift: T) -> BigUint {
13
20.9k
    if shift < T::zero() {
14
0
        panic!("attempt to shift left with negative");
15
20.9k
    }
16
20.9k
    if n.is_zero() {
17
295
        return n.into_owned();
18
20.6k
    }
19
20.6k
    let bits = T::from(big_digit::BITS).unwrap();
20
20.6k
    let digits = (shift / bits).to_usize().expect("capacity overflow");
21
20.6k
    let shift = (shift % bits).to_u8().unwrap();
22
20.6k
    biguint_shl2(n, digits, shift)
23
20.9k
}
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shlnEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shloEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shlsEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shltEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shlxEB6_
_RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shlyEB6_
Line
Count
Source
12
2.07k
fn biguint_shl<T: PrimInt>(n: Cow<'_, BigUint>, shift: T) -> BigUint {
13
2.07k
    if shift < T::zero() {
14
0
        panic!("attempt to shift left with negative");
15
2.07k
    }
16
2.07k
    if n.is_zero() {
17
0
        return n.into_owned();
18
2.07k
    }
19
2.07k
    let bits = T::from(big_digit::BITS).unwrap();
20
2.07k
    let digits = (shift / bits).to_usize().expect("capacity overflow");
21
2.07k
    let shift = (shift % bits).to_u8().unwrap();
22
2.07k
    biguint_shl2(n, digits, shift)
23
2.07k
}
24
25
208k
fn biguint_shl2(n: Cow<'_, BigUint>, digits: usize, shift: u8) -> BigUint {
26
208k
    let mut data = match digits {
27
194k
        0 => n.into_owned().data,
28
        _ => {
29
14.0k
            let len = digits.saturating_add(n.data.len() + 1);
30
14.0k
            let mut data = Vec::with_capacity(len);
31
14.0k
            data.resize(digits, 0);
32
14.0k
            data.extend(n.data.iter());
33
14.0k
            data
34
        }
35
    };
36
37
208k
    if shift > 0 {
38
205k
        let mut carry = 0;
39
205k
        let carry_shift = big_digit::BITS - shift;
40
8.00M
        for elem in data[digits..].iter_mut() {
41
8.00M
            let new_carry = *elem >> carry_shift;
42
8.00M
            *elem = (*elem << shift) | carry;
43
8.00M
            carry = new_carry;
44
8.00M
        }
45
205k
        if carry != 0 {
46
18.5k
            data.push(carry);
47
186k
        }
48
3.22k
    }
49
50
208k
    biguint_from_vec(data)
51
208k
}
52
53
#[inline]
54
101k
fn biguint_shr<T: PrimInt>(n: Cow<'_, BigUint>, shift: T) -> BigUint {
55
101k
    if shift < T::zero() {
56
0
        panic!("attempt to shift right with negative");
57
101k
    }
58
101k
    if n.is_zero() {
59
4.10k
        return n.into_owned();
60
97.2k
    }
61
97.2k
    let bits = T::from(big_digit::BITS).unwrap();
62
97.2k
    let digits = (shift / bits).to_usize().unwrap_or(usize::MAX);
63
97.2k
    let shift = (shift % bits).to_u8().unwrap();
64
97.2k
    biguint_shr2(n, digits, shift)
65
101k
}
_RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shrlECs4RkbDk9WRL5_5clvmr
Line
Count
Source
54
2.24k
fn biguint_shr<T: PrimInt>(n: Cow<'_, BigUint>, shift: T) -> BigUint {
55
2.24k
    if shift < T::zero() {
56
0
        panic!("attempt to shift right with negative");
57
2.24k
    }
58
2.24k
    if n.is_zero() {
59
471
        return n.into_owned();
60
1.77k
    }
61
1.77k
    let bits = T::from(big_digit::BITS).unwrap();
62
1.77k
    let digits = (shift / bits).to_usize().unwrap_or(usize::MAX);
63
1.77k
    let shift = (shift % bits).to_u8().unwrap();
64
1.77k
    biguint_shr2(n, digits, shift)
65
2.24k
}
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shraEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shrhEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shriEB6_
_RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shrjEB6_
Line
Count
Source
54
81.0k
fn biguint_shr<T: PrimInt>(n: Cow<'_, BigUint>, shift: T) -> BigUint {
55
81.0k
    if shift < T::zero() {
56
0
        panic!("attempt to shift right with negative");
57
81.0k
    }
58
81.0k
    if n.is_zero() {
59
7
        return n.into_owned();
60
81.0k
    }
61
81.0k
    let bits = T::from(big_digit::BITS).unwrap();
62
81.0k
    let digits = (shift / bits).to_usize().unwrap_or(usize::MAX);
63
81.0k
    let shift = (shift % bits).to_u8().unwrap();
64
81.0k
    biguint_shr2(n, digits, shift)
65
81.0k
}
_RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shrlEB6_
Line
Count
Source
54
18.1k
fn biguint_shr<T: PrimInt>(n: Cow<'_, BigUint>, shift: T) -> BigUint {
55
18.1k
    if shift < T::zero() {
56
0
        panic!("attempt to shift right with negative");
57
18.1k
    }
58
18.1k
    if n.is_zero() {
59
3.62k
        return n.into_owned();
60
14.5k
    }
61
14.5k
    let bits = T::from(big_digit::BITS).unwrap();
62
14.5k
    let digits = (shift / bits).to_usize().unwrap_or(usize::MAX);
63
14.5k
    let shift = (shift % bits).to_u8().unwrap();
64
14.5k
    biguint_shr2(n, digits, shift)
65
18.1k
}
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shrmEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shrnEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shroEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shrsEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shrtEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shrxEB6_
Unexecuted instantiation: _RINvNtNtCs72ekIXsOXFl_10num_bigint7biguint5shift11biguint_shryEB6_
66
67
97.2k
fn biguint_shr2(n: Cow<'_, BigUint>, digits: usize, shift: u8) -> BigUint {
68
97.2k
    if digits >= n.data.len() {
69
59
        let mut n = n.into_owned();
70
59
        n.set_zero();
71
59
        return n;
72
97.2k
    }
73
97.2k
    let mut data = match n {
74
0
        Cow::Borrowed(n) => n.data[digits..].to_vec(),
75
97.2k
        Cow::Owned(mut n) => {
76
97.2k
            n.data.drain(..digits);
77
97.2k
            n.data
78
        }
79
    };
80
81
97.2k
    if shift > 0 {
82
95.5k
        let mut borrow = 0;
83
95.5k
        let borrow_shift = big_digit::BITS - shift;
84
6.57M
        for elem in data.iter_mut().rev() {
85
6.57M
            let new_borrow = *elem << borrow_shift;
86
6.57M
            *elem = (*elem >> shift) | borrow;
87
6.57M
            borrow = new_borrow;
88
6.57M
        }
89
1.64k
    }
90
91
97.2k
    biguint_from_vec(data)
92
97.2k
}
93
94
macro_rules! impl_shift {
95
    (@ref $Shx:ident :: $shx:ident, $ShxAssign:ident :: $shx_assign:ident, $rhs:ty) => {
96
        impl $Shx<&$rhs> for BigUint {
97
            type Output = BigUint;
98
99
            #[inline]
100
0
            fn $shx(self, rhs: &$rhs) -> BigUint {
101
0
                $Shx::$shx(self, *rhs)
102
0
            }
Unexecuted instantiation: _RNvXsy_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRhE3shlB9_
Unexecuted instantiation: _RNvXsB_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRhE3shrB9_
Unexecuted instantiation: _RNvXsE_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRtE3shlB9_
Unexecuted instantiation: _RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRtE3shrB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRmE3shlB9_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRmE3shrB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRyE3shlB9_
Unexecuted instantiation: _RNvXsT_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRyE3shrB9_
Unexecuted instantiation: _RNvXsW_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRoE3shlB9_
Unexecuted instantiation: _RNvXsZ_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRoE3shrB9_
Unexecuted instantiation: _RNvXs12_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRjE3shlBa_
Unexecuted instantiation: _RNvXs15_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRjE3shrBa_
Unexecuted instantiation: _RNvXs1I_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRaE3shlBa_
Unexecuted instantiation: _RNvXs1L_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRaE3shrBa_
Unexecuted instantiation: _RNvXs1O_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRsE3shlBa_
Unexecuted instantiation: _RNvXs1R_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRsE3shrBa_
Unexecuted instantiation: _RNvXs1U_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRlE3shlBa_
Unexecuted instantiation: _RNvXs1X_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRlE3shrBa_
Unexecuted instantiation: _RNvXs20_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRxE3shlBa_
Unexecuted instantiation: _RNvXs23_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRxE3shrBa_
Unexecuted instantiation: _RNvXs26_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRnE3shlBa_
Unexecuted instantiation: _RNvXs29_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRnE3shrBa_
Unexecuted instantiation: _RNvXs2c_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRiE3shlBa_
Unexecuted instantiation: _RNvXs2f_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRiE3shrBa_
103
        }
104
        impl $Shx<&$rhs> for &BigUint {
105
            type Output = BigUint;
106
107
            #[inline]
108
0
            fn $shx(self, rhs: &$rhs) -> BigUint {
109
0
                $Shx::$shx(self, *rhs)
110
0
            }
Unexecuted instantiation: _RNvXsz_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRhE3shlB9_
Unexecuted instantiation: _RNvXsC_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRhE3shrB9_
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRtE3shlB9_
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRtE3shrB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRmE3shlB9_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRmE3shrB9_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRyE3shlB9_
Unexecuted instantiation: _RNvXsU_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRyE3shrB9_
Unexecuted instantiation: _RNvXsX_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRoE3shlB9_
Unexecuted instantiation: _RNvXs10_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRoE3shrBa_
Unexecuted instantiation: _RNvXs13_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRjE3shlBa_
Unexecuted instantiation: _RNvXs16_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRjE3shrBa_
Unexecuted instantiation: _RNvXs1J_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRaE3shlBa_
Unexecuted instantiation: _RNvXs1M_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRaE3shrBa_
Unexecuted instantiation: _RNvXs1P_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRsE3shlBa_
Unexecuted instantiation: _RNvXs1S_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRsE3shrBa_
Unexecuted instantiation: _RNvXs1V_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRlE3shlBa_
Unexecuted instantiation: _RNvXs1Y_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRlE3shrBa_
Unexecuted instantiation: _RNvXs21_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRxE3shlBa_
Unexecuted instantiation: _RNvXs24_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRxE3shrBa_
Unexecuted instantiation: _RNvXs27_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRnE3shlBa_
Unexecuted instantiation: _RNvXs2a_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRnE3shrBa_
Unexecuted instantiation: _RNvXs2d_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlRiE3shlBa_
Unexecuted instantiation: _RNvXs2g_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrRiE3shrBa_
111
        }
112
        impl $ShxAssign<&$rhs> for BigUint {
113
            #[inline]
114
0
            fn $shx_assign(&mut self, rhs: &$rhs) {
115
0
                $ShxAssign::$shx_assign(self, *rhs);
116
0
            }
Unexecuted instantiation: _RNvXsA_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRhE10shl_assignB9_
Unexecuted instantiation: _RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRhE10shr_assignB9_
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRtE10shl_assignB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRtE10shr_assignB9_
Unexecuted instantiation: _RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRmE10shl_assignB9_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRmE10shr_assignB9_
Unexecuted instantiation: _RNvXsS_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRyE10shl_assignB9_
Unexecuted instantiation: _RNvXsV_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRyE10shr_assignB9_
Unexecuted instantiation: _RNvXsY_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRoE10shl_assignB9_
Unexecuted instantiation: _RNvXs11_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRoE10shr_assignBa_
Unexecuted instantiation: _RNvXs14_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRjE10shl_assignBa_
Unexecuted instantiation: _RNvXs17_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRjE10shr_assignBa_
Unexecuted instantiation: _RNvXs1K_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRaE10shl_assignBa_
Unexecuted instantiation: _RNvXs1N_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRaE10shr_assignBa_
Unexecuted instantiation: _RNvXs1Q_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRsE10shl_assignBa_
Unexecuted instantiation: _RNvXs1T_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRsE10shr_assignBa_
Unexecuted instantiation: _RNvXs1W_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRlE10shl_assignBa_
Unexecuted instantiation: _RNvXs1Z_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRlE10shr_assignBa_
Unexecuted instantiation: _RNvXs22_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRxE10shl_assignBa_
Unexecuted instantiation: _RNvXs25_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRxE10shr_assignBa_
Unexecuted instantiation: _RNvXs28_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRnE10shl_assignBa_
Unexecuted instantiation: _RNvXs2b_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRnE10shr_assignBa_
Unexecuted instantiation: _RNvXs2e_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignRiE10shl_assignBa_
Unexecuted instantiation: _RNvXs2h_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignRiE10shr_assignBa_
117
        }
118
    };
119
    ($($rhs:ty),+) => {$(
120
        impl Shl<$rhs> for BigUint {
121
            type Output = BigUint;
122
123
            #[inline]
124
44.5k
            fn shl(self, rhs: $rhs) -> BigUint {
125
44.5k
                biguint_shl(Cow::Owned(self), rhs)
126
44.5k
            }
_RNvXs1k_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShllE3shlCs4RkbDk9WRL5_5clvmr
Line
Count
Source
124
21.5k
            fn shl(self, rhs: $rhs) -> BigUint {
125
21.5k
                biguint_shl(Cow::Owned(self), rhs)
126
21.5k
            }
Unexecuted instantiation: _RNvXss_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShljE3shlB9_
_RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlyE3shlB9_
Line
Count
Source
124
2.07k
            fn shl(self, rhs: $rhs) -> BigUint {
125
2.07k
                biguint_shl(Cow::Owned(self), rhs)
126
2.07k
            }
Unexecuted instantiation: _RNvXNtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB4_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlhE3shlB6_
Unexecuted instantiation: _RNvXs4_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShltE3shlB9_
_RNvXsa_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlmE3shlB9_
Line
Count
Source
124
20.9k
            fn shl(self, rhs: $rhs) -> BigUint {
125
20.9k
                biguint_shl(Cow::Owned(self), rhs)
126
20.9k
            }
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShloE3shlB9_
Unexecuted instantiation: _RNvXs18_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlaE3shlBa_
Unexecuted instantiation: _RNvXs1e_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlsE3shlBa_
Unexecuted instantiation: _RNvXs1k_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShllE3shlBa_
Unexecuted instantiation: _RNvXs1q_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlxE3shlBa_
Unexecuted instantiation: _RNvXs1w_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlnE3shlBa_
Unexecuted instantiation: _RNvXs1C_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShliE3shlBa_
127
        }
128
        impl Shl<$rhs> for &BigUint {
129
            type Output = BigUint;
130
131
            #[inline]
132
171k
            fn shl(self, rhs: $rhs) -> BigUint {
133
171k
                biguint_shl(Cow::Borrowed(self), rhs)
134
171k
            }
_RNvXst_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShljE3shlB9_
Line
Count
Source
132
162k
            fn shl(self, rhs: $rhs) -> BigUint {
133
162k
                biguint_shl(Cow::Borrowed(self), rhs)
134
162k
            }
_RNvXs1l_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShllE3shlBa_
Line
Count
Source
132
9.06k
            fn shl(self, rhs: $rhs) -> BigUint {
133
9.06k
                biguint_shl(Cow::Borrowed(self), rhs)
134
9.06k
            }
Unexecuted instantiation: _RNvXs_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB6_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlhE3shlB8_
Unexecuted instantiation: _RNvXs5_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShltE3shlB9_
Unexecuted instantiation: _RNvXsb_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlmE3shlB9_
Unexecuted instantiation: _RNvXsh_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlyE3shlB9_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShloE3shlB9_
Unexecuted instantiation: _RNvXs19_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlaE3shlBa_
Unexecuted instantiation: _RNvXs1f_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlsE3shlBa_
Unexecuted instantiation: _RNvXs1r_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlxE3shlBa_
Unexecuted instantiation: _RNvXs1x_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShlnE3shlBa_
Unexecuted instantiation: _RNvXs1D_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShliE3shlBa_
135
        }
136
        impl ShlAssign<$rhs> for BigUint {
137
            #[inline]
138
20.9k
            fn shl_assign(&mut self, rhs: $rhs) {
139
20.9k
                let n = mem::replace(self, Self::ZERO);
140
20.9k
                *self = n << rhs;
141
20.9k
            }
Unexecuted instantiation: _RNvXs0_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignhE10shl_assignB9_
Unexecuted instantiation: _RNvXs6_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssigntE10shl_assignB9_
_RNvXsc_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignmE10shl_assignB9_
Line
Count
Source
138
20.9k
            fn shl_assign(&mut self, rhs: $rhs) {
139
20.9k
                let n = mem::replace(self, Self::ZERO);
140
20.9k
                *self = n << rhs;
141
20.9k
            }
Unexecuted instantiation: _RNvXsi_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignyE10shl_assignB9_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignoE10shl_assignB9_
Unexecuted instantiation: _RNvXsu_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignjE10shl_assignB9_
Unexecuted instantiation: _RNvXs1a_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignaE10shl_assignBa_
Unexecuted instantiation: _RNvXs1g_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignsE10shl_assignBa_
Unexecuted instantiation: _RNvXs1m_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignlE10shl_assignBa_
Unexecuted instantiation: _RNvXs1s_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignxE10shl_assignBa_
Unexecuted instantiation: _RNvXs1y_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssignnE10shl_assignBa_
Unexecuted instantiation: _RNvXs1E_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShlAssigniE10shl_assignBa_
142
        }
143
        impl_shift! { @ref Shl::shl, ShlAssign::shl_assign, $rhs }
144
145
        impl Shr<$rhs> for BigUint {
146
            type Output = BigUint;
147
148
            #[inline]
149
101k
            fn shr(self, rhs: $rhs) -> BigUint {
150
101k
                biguint_shr(Cow::Owned(self), rhs)
151
101k
            }
_RNvXs1n_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrlE3shrCs4RkbDk9WRL5_5clvmr
Line
Count
Source
149
2.24k
            fn shr(self, rhs: $rhs) -> BigUint {
150
2.24k
                biguint_shr(Cow::Owned(self), rhs)
151
2.24k
            }
_RNvXsv_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrjE3shrB9_
Line
Count
Source
149
81.0k
            fn shr(self, rhs: $rhs) -> BigUint {
150
81.0k
                biguint_shr(Cow::Owned(self), rhs)
151
81.0k
            }
_RNvXs1n_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrlE3shrBa_
Line
Count
Source
149
18.1k
            fn shr(self, rhs: $rhs) -> BigUint {
150
18.1k
                biguint_shr(Cow::Owned(self), rhs)
151
18.1k
            }
Unexecuted instantiation: _RNvXs1_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrhE3shrB9_
Unexecuted instantiation: _RNvXs7_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrtE3shrB9_
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrmE3shrB9_
Unexecuted instantiation: _RNvXsj_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShryE3shrB9_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShroE3shrB9_
Unexecuted instantiation: _RNvXs1b_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShraE3shrBa_
Unexecuted instantiation: _RNvXs1h_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrsE3shrBa_
Unexecuted instantiation: _RNvXs1t_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrxE3shrBa_
Unexecuted instantiation: _RNvXs1z_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrnE3shrBa_
Unexecuted instantiation: _RNvXs1F_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShriE3shrBa_
152
        }
153
        impl Shr<$rhs> for &BigUint {
154
            type Output = BigUint;
155
156
            #[inline]
157
0
            fn shr(self, rhs: $rhs) -> BigUint {
158
0
                biguint_shr(Cow::Borrowed(self), rhs)
159
0
            }
Unexecuted instantiation: _RNvXsk_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShryE3shrB9_
Unexecuted instantiation: _RNvXs2_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrhE3shrB9_
Unexecuted instantiation: _RNvXs8_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrtE3shrB9_
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrmE3shrB9_
Unexecuted instantiation: _RNvXsq_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShroE3shrB9_
Unexecuted instantiation: _RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrjE3shrB9_
Unexecuted instantiation: _RNvXs1c_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShraE3shrBa_
Unexecuted instantiation: _RNvXs1i_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrsE3shrBa_
Unexecuted instantiation: _RNvXs1o_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrlE3shrBa_
Unexecuted instantiation: _RNvXs1u_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrxE3shrBa_
Unexecuted instantiation: _RNvXs1A_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShrnE3shrBa_
Unexecuted instantiation: _RNvXs1G_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit3ShriE3shrBa_
160
        }
161
        impl ShrAssign<$rhs> for BigUint {
162
            #[inline]
163
0
            fn shr_assign(&mut self, rhs: $rhs) {
164
0
                let n = mem::replace(self, Self::ZERO);
165
0
                *self = n >> rhs;
166
0
            }
Unexecuted instantiation: _RNvXs3_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignhE10shr_assignB9_
Unexecuted instantiation: _RNvXs9_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssigntE10shr_assignB9_
Unexecuted instantiation: _RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignmE10shr_assignB9_
Unexecuted instantiation: _RNvXsl_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignyE10shr_assignB9_
Unexecuted instantiation: _RNvXsr_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignoE10shr_assignB9_
Unexecuted instantiation: _RNvXsx_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignjE10shr_assignB9_
Unexecuted instantiation: _RNvXs1d_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignaE10shr_assignBa_
Unexecuted instantiation: _RNvXs1j_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignsE10shr_assignBa_
Unexecuted instantiation: _RNvXs1p_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignlE10shr_assignBa_
Unexecuted instantiation: _RNvXs1v_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignxE10shr_assignBa_
Unexecuted instantiation: _RNvXs1B_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssignnE10shr_assignBa_
Unexecuted instantiation: _RNvXs1H_NtNtCs72ekIXsOXFl_10num_bigint7biguint5shiftNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit9ShrAssigniE10shr_assignBa_
167
        }
168
        impl_shift! { @ref Shr::shr, ShrAssign::shr_assign, $rhs }
169
    )*};
170
}
171
172
impl_shift! { u8, u16, u32, u64, u128, usize }
173
impl_shift! { i8, i16, i32, i64, i128, isize }
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/biguint/subtraction.rs
Line
Count
Source
1
use super::BigUint;
2
3
use crate::big_digit::{self, BigDigit};
4
use crate::UsizePromotion;
5
6
use core::cmp::Ordering::{Equal, Greater, Less};
7
use core::ops::{Sub, SubAssign};
8
use num_traits::CheckedSub;
9
10
#[cfg(target_arch = "x86_64")]
11
use core::arch::x86_64 as arch;
12
13
#[cfg(target_arch = "x86")]
14
use core::arch::x86 as arch;
15
16
// Subtract with borrow:
17
#[cfg(target_arch = "x86_64")]
18
cfg_64!(
19
    #[inline]
20
43.6M
    fn sbb(borrow: u8, a: u64, b: u64, out: &mut u64) -> u8 {
21
43.6M
        // Safety: There are absolutely no safety concerns with calling `_subborrow_u64`.
22
43.6M
        // It's just unsafe for API consistency with other intrinsics.
23
43.6M
        unsafe { arch::_subborrow_u64(borrow, a, b, out) }
24
43.6M
    }
25
);
26
27
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
28
cfg_32!(
29
    #[inline]
30
    fn sbb(borrow: u8, a: u32, b: u32, out: &mut u32) -> u8 {
31
        // Safety: There are absolutely no safety concerns with calling `_subborrow_u32`.
32
        // It's just unsafe for API consistency with other intrinsics.
33
        unsafe { arch::_subborrow_u32(borrow, a, b, out) }
34
    }
35
);
36
37
// fallback for environments where we don't have a subborrow intrinsic
38
// (copied from the standard library's `borrowing_sub`)
39
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
40
#[inline]
41
fn sbb(borrow: u8, lhs: BigDigit, rhs: BigDigit, out: &mut BigDigit) -> u8 {
42
    let (a, b) = lhs.overflowing_sub(rhs);
43
    let (c, d) = a.overflowing_sub(borrow as BigDigit);
44
    *out = c;
45
    u8::from(b || d)
46
}
47
48
487k
pub(super) fn sub2(a: &mut [BigDigit], b: &[BigDigit]) {
49
487k
    let mut borrow = 0;
50
487k
51
487k
    let len = Ord::min(a.len(), b.len());
52
487k
    let (a_lo, a_hi) = a.split_at_mut(len);
53
487k
    let (b_lo, b_hi) = b.split_at(len);
54
55
33.6M
    for (a, b) in a_lo.iter_mut().zip(b_lo) {
56
33.6M
        borrow = sbb(borrow, *a, *b, a);
57
33.6M
    }
58
59
487k
    if borrow != 0 {
60
6.98M
        for a in a_hi {
61
6.98M
            borrow = sbb(borrow, *a, 0, a);
62
6.98M
            if borrow == 0 {
63
165k
                break;
64
6.82M
            }
65
        }
66
322k
    }
67
68
    // note: we're _required_ to fail on underflow
69
487k
    assert!(
70
487k
        borrow == 0 && b_hi.iter().all(|x| *x == 0),
71
0
        "Cannot subtract b from a because b is larger than a."
72
    );
73
487k
}
74
75
// Only for the Sub impl. `a` and `b` must have same length.
76
#[inline]
77
43.9k
fn __sub2rev(a: &[BigDigit], b: &mut [BigDigit]) -> u8 {
78
43.9k
    debug_assert!(b.len() == a.len());
79
80
43.9k
    let mut borrow = 0;
81
82
3.07M
    for (ai, bi) in a.iter().zip(b) {
83
3.07M
        borrow = sbb(borrow, *ai, *bi, bi);
84
3.07M
    }
85
86
43.9k
    borrow
87
43.9k
}
88
89
32.4k
fn sub2rev(a: &[BigDigit], b: &mut [BigDigit]) {
90
32.4k
    debug_assert!(b.len() >= a.len());
91
92
32.4k
    let len = Ord::min(a.len(), b.len());
93
32.4k
    let (a_lo, a_hi) = a.split_at(len);
94
32.4k
    let (b_lo, b_hi) = b.split_at_mut(len);
95
32.4k
96
32.4k
    let borrow = __sub2rev(a_lo, b_lo);
97
32.4k
98
32.4k
    assert!(a_hi.is_empty());
99
100
    // note: we're _required_ to fail on underflow
101
32.4k
    assert!(
102
32.4k
        borrow == 0 && b_hi.iter().all(|x| *x == 0),
103
0
        "Cannot subtract b from a because b is larger than a."
104
    );
105
32.4k
}
106
107
forward_val_val_binop!(impl Sub for BigUint, sub);
108
forward_ref_ref_binop!(impl Sub for BigUint, sub);
109
forward_val_assign!(impl SubAssign for BigUint, sub_assign);
110
111
impl Sub<&BigUint> for BigUint {
112
    type Output = BigUint;
113
114
77.7k
    fn sub(mut self, other: &BigUint) -> BigUint {
115
77.7k
        self -= other;
116
77.7k
        self
117
77.7k
    }
118
}
119
impl SubAssign<&BigUint> for BigUint {
120
77.7k
    fn sub_assign(&mut self, other: &BigUint) {
121
77.7k
        sub2(&mut self.data[..], &other.data[..]);
122
77.7k
        self.normalize();
123
77.7k
    }
124
}
125
126
impl Sub<BigUint> for &BigUint {
127
    type Output = BigUint;
128
129
28.4k
    fn sub(self, mut other: BigUint) -> BigUint {
130
28.4k
        let other_len = other.data.len();
131
28.4k
        if other_len < self.data.len() {
132
11.4k
            let lo_borrow = __sub2rev(&self.data[..other_len], &mut other.data);
133
11.4k
            other.data.extend_from_slice(&self.data[other_len..]);
134
11.4k
            if lo_borrow != 0 {
135
7.69k
                sub2(&mut other.data[other_len..], &[1])
136
3.72k
            }
137
17.0k
        } else {
138
17.0k
            sub2rev(&self.data[..], &mut other.data[..]);
139
17.0k
        }
140
28.4k
        other.normalized()
141
28.4k
    }
142
}
143
144
promote_unsigned_scalars!(impl Sub for BigUint, sub);
145
promote_unsigned_scalars_assign!(impl SubAssign for BigUint, sub_assign);
146
forward_all_scalar_binop_to_val_val!(impl Sub<u32> for BigUint, sub);
147
forward_all_scalar_binop_to_val_val!(impl Sub<u64> for BigUint, sub);
148
forward_all_scalar_binop_to_val_val!(impl Sub<u128> for BigUint, sub);
149
150
impl Sub<u32> for BigUint {
151
    type Output = BigUint;
152
153
    #[inline]
154
22.2k
    fn sub(mut self, other: u32) -> BigUint {
155
22.2k
        self -= other;
156
22.2k
        self
157
22.2k
    }
_RNvXs1_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubmE3subCs4RkbDk9WRL5_5clvmr
Line
Count
Source
154
22.2k
    fn sub(mut self, other: u32) -> BigUint {
155
22.2k
        self -= other;
156
22.2k
        self
157
22.2k
    }
Unexecuted instantiation: _RNvXs1_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubmE3subB9_
158
}
159
160
impl SubAssign<u32> for BigUint {
161
22.5k
    fn sub_assign(&mut self, other: u32) {
162
22.5k
        sub2(&mut self.data[..], &[other as BigDigit]);
163
22.5k
        self.normalize();
164
22.5k
    }
165
}
166
167
impl Sub<BigUint> for u32 {
168
    type Output = BigUint;
169
170
    cfg_digit!(
171
        #[inline]
172
        fn sub(self, mut other: BigUint) -> BigUint {
173
            if other.data.len() == 0 {
174
                other.data.push(self);
175
            } else {
176
                sub2rev(&[self], &mut other.data[..]);
177
            }
178
            other.normalized()
179
        }
180
181
        #[inline]
182
15.4k
        fn sub(self, mut other: BigUint) -> BigUint {
183
15.4k
            if other.data.is_empty() {
184
0
                other.data.push(self as BigDigit);
185
15.4k
            } else {
186
15.4k
                sub2rev(&[self as BigDigit], &mut other.data[..]);
187
15.4k
            }
188
15.4k
            other.normalized()
189
15.4k
        }
_RNvXs3_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_7BigUintE3subCs4RkbDk9WRL5_5clvmr
Line
Count
Source
182
15.4k
        fn sub(self, mut other: BigUint) -> BigUint {
183
15.4k
            if other.data.is_empty() {
184
0
                other.data.push(self as BigDigit);
185
15.4k
            } else {
186
15.4k
                sub2rev(&[self as BigDigit], &mut other.data[..]);
187
15.4k
            }
188
15.4k
            other.normalized()
189
15.4k
        }
Unexecuted instantiation: _RNvXs3_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_7BigUintE3subB9_
190
    );
191
}
192
193
impl Sub<u64> for BigUint {
194
    type Output = BigUint;
195
196
    #[inline]
197
0
    fn sub(mut self, other: u64) -> BigUint {
198
0
        self -= other;
199
0
        self
200
0
    }
201
}
202
203
impl SubAssign<u64> for BigUint {
204
    cfg_digit!(
205
        #[inline]
206
        fn sub_assign(&mut self, other: u64) {
207
            let (hi, lo) = big_digit::from_doublebigdigit(other);
208
            sub2(&mut self.data[..], &[lo, hi]);
209
            self.normalize();
210
        }
211
212
        #[inline]
213
0
        fn sub_assign(&mut self, other: u64) {
214
0
            sub2(&mut self.data[..], &[other as BigDigit]);
215
0
            self.normalize();
216
0
        }
217
    );
218
}
219
220
impl Sub<BigUint> for u64 {
221
    type Output = BigUint;
222
223
    cfg_digit!(
224
        #[inline]
225
        fn sub(self, mut other: BigUint) -> BigUint {
226
            while other.data.len() < 2 {
227
                other.data.push(0);
228
            }
229
230
            let (hi, lo) = big_digit::from_doublebigdigit(self);
231
            sub2rev(&[lo, hi], &mut other.data[..]);
232
            other.normalized()
233
        }
234
235
        #[inline]
236
0
        fn sub(self, mut other: BigUint) -> BigUint {
237
0
            if other.data.is_empty() {
238
0
                other.data.push(self);
239
0
            } else {
240
0
                sub2rev(&[self], &mut other.data[..]);
241
0
            }
242
0
            other.normalized()
243
0
        }
244
    );
245
}
246
247
impl Sub<u128> for BigUint {
248
    type Output = BigUint;
249
250
    #[inline]
251
0
    fn sub(mut self, other: u128) -> BigUint {
252
0
        self -= other;
253
0
        self
254
0
    }
255
}
256
257
impl SubAssign<u128> for BigUint {
258
    cfg_digit!(
259
        #[inline]
260
        fn sub_assign(&mut self, other: u128) {
261
            let (a, b, c, d) = super::u32_from_u128(other);
262
            sub2(&mut self.data[..], &[d, c, b, a]);
263
            self.normalize();
264
        }
265
266
        #[inline]
267
0
        fn sub_assign(&mut self, other: u128) {
268
0
            let (hi, lo) = big_digit::from_doublebigdigit(other);
269
0
            sub2(&mut self.data[..], &[lo, hi]);
270
0
            self.normalize();
271
0
        }
272
    );
273
}
274
275
impl Sub<BigUint> for u128 {
276
    type Output = BigUint;
277
278
    cfg_digit!(
279
        #[inline]
280
        fn sub(self, mut other: BigUint) -> BigUint {
281
            while other.data.len() < 4 {
282
                other.data.push(0);
283
            }
284
285
            let (a, b, c, d) = super::u32_from_u128(self);
286
            sub2rev(&[d, c, b, a], &mut other.data[..]);
287
            other.normalized()
288
        }
289
290
        #[inline]
291
0
        fn sub(self, mut other: BigUint) -> BigUint {
292
0
            while other.data.len() < 2 {
293
0
                other.data.push(0);
294
0
            }
295
296
0
            let (hi, lo) = big_digit::from_doublebigdigit(self);
297
0
            sub2rev(&[lo, hi], &mut other.data[..]);
298
0
            other.normalized()
299
0
        }
300
    );
301
}
302
303
impl CheckedSub for BigUint {
304
    #[inline]
305
0
    fn checked_sub(&self, v: &BigUint) -> Option<BigUint> {
306
0
        match self.cmp(v) {
307
0
            Less => None,
308
0
            Equal => Some(Self::ZERO),
309
0
            Greater => Some(self.sub(v)),
310
        }
311
0
    }
312
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/lib.rs
Line
Count
Source
1
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2
// file at the top-level directory of this distribution and at
3
// http://rust-lang.org/COPYRIGHT.
4
//
5
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8
// option. This file may not be copied, modified, or distributed
9
// except according to those terms.
10
11
//! Big Integer Types for Rust
12
//!
13
//! * A [`BigUint`] is unsigned and represented as a vector of digits.
14
//! * A [`BigInt`] is signed and is a combination of [`BigUint`] and [`Sign`].
15
//!
16
//! Common numerical operations are overloaded, so we can treat them
17
//! the same way we treat other numbers.
18
//!
19
//! ## Example
20
//!
21
//! ```rust
22
//! # fn main() {
23
//! use num_bigint::BigUint;
24
//! use num_traits::One;
25
//!
26
//! // Calculate large fibonacci numbers.
27
//! fn fib(n: usize) -> BigUint {
28
//!     let mut f0 = BigUint::ZERO;
29
//!     let mut f1 = BigUint::one();
30
//!     for _ in 0..n {
31
//!         let f2 = f0 + &f1;
32
//!         f0 = f1;
33
//!         f1 = f2;
34
//!     }
35
//!     f0
36
//! }
37
//!
38
//! // This is a very large number.
39
//! println!("fib(1000) = {}", fib(1000));
40
//! # }
41
//! ```
42
//!
43
//! It's easy to generate large random numbers:
44
//!
45
//! ```rust,ignore
46
//! use num_bigint::{ToBigInt, RandBigInt};
47
//!
48
//! let mut rng = rand::thread_rng();
49
//! let a = rng.gen_bigint(1000);
50
//!
51
//! let low = -10000.to_bigint().unwrap();
52
//! let high = 10000.to_bigint().unwrap();
53
//! let b = rng.gen_bigint_range(&low, &high);
54
//!
55
//! // Probably an even larger number.
56
//! println!("{}", a * b);
57
//! ```
58
//!
59
//! See the "Features" section for instructions for enabling random number generation.
60
//!
61
//! ## Features
62
//!
63
//! The `std` crate feature is enabled by default, which enables [`std::error::Error`]
64
//! implementations and some internal use of floating point approximations. This can be disabled by
65
//! depending on `num-bigint` with `default-features = false`. Either way, the `alloc` crate is
66
//! always required for heap allocation of the `BigInt`/`BigUint` digits.
67
//!
68
//! ### Random Generation
69
//!
70
//! `num-bigint` supports the generation of random big integers when the `rand`
71
//! feature is enabled. To enable it include rand as
72
//!
73
//! ```toml
74
//! rand = "0.8"
75
//! num-bigint = { version = "0.4", features = ["rand"] }
76
//! ```
77
//!
78
//! Note that you must use the version of `rand` that `num-bigint` is compatible
79
//! with: `0.8`.
80
//!
81
//! ### Arbitrary Big Integers
82
//!
83
//! `num-bigint` supports `arbitrary` and `quickcheck` features to implement
84
//! [`arbitrary::Arbitrary`] and [`quickcheck::Arbitrary`], respectively, for both `BigInt` and
85
//! `BigUint`. These are useful for fuzzing and other forms of randomized testing.
86
//!
87
//! ### Serialization
88
//!
89
//! The `serde` feature adds implementations of [`Serialize`][serde::Serialize] and
90
//! [`Deserialize`][serde::Deserialize] for both `BigInt` and `BigUint`. Their serialized data is
91
//! generated portably, regardless of platform differences like the internal digit size.
92
//!
93
//!
94
//! ## Compatibility
95
//!
96
//! The `num-bigint` crate is tested for rustc 1.60 and greater.
97
98
#![cfg_attr(docsrs, feature(doc_cfg))]
99
#![doc(html_root_url = "https://docs.rs/num-bigint/0.4")]
100
#![warn(rust_2018_idioms)]
101
#![no_std]
102
103
#[macro_use]
104
extern crate alloc;
105
106
#[cfg(feature = "std")]
107
extern crate std;
108
109
use core::fmt;
110
111
#[macro_use]
112
mod macros;
113
114
mod bigint;
115
mod bigrand;
116
mod biguint;
117
118
#[cfg(target_pointer_width = "32")]
119
type UsizePromotion = u32;
120
#[cfg(target_pointer_width = "64")]
121
type UsizePromotion = u64;
122
123
#[cfg(target_pointer_width = "32")]
124
type IsizePromotion = i32;
125
#[cfg(target_pointer_width = "64")]
126
type IsizePromotion = i64;
127
128
#[derive(Debug, Clone, PartialEq, Eq)]
129
pub struct ParseBigIntError {
130
    kind: BigIntErrorKind,
131
}
132
133
#[derive(Debug, Clone, PartialEq, Eq)]
134
enum BigIntErrorKind {
135
    Empty,
136
    InvalidDigit,
137
}
138
139
impl ParseBigIntError {
140
0
    fn __description(&self) -> &str {
141
        use crate::BigIntErrorKind::*;
142
0
        match self.kind {
143
0
            Empty => "cannot parse integer from empty string",
144
0
            InvalidDigit => "invalid digit found in string",
145
        }
146
0
    }
147
148
0
    fn empty() -> Self {
149
0
        ParseBigIntError {
150
0
            kind: BigIntErrorKind::Empty,
151
0
        }
152
0
    }
153
154
0
    fn invalid() -> Self {
155
0
        ParseBigIntError {
156
0
            kind: BigIntErrorKind::InvalidDigit,
157
0
        }
158
0
    }
159
}
160
161
impl fmt::Display for ParseBigIntError {
162
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163
0
        self.__description().fmt(f)
164
0
    }
165
}
166
167
#[cfg(feature = "std")]
168
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
169
impl std::error::Error for ParseBigIntError {
170
0
    fn description(&self) -> &str {
171
0
        self.__description()
172
0
    }
173
}
174
175
/// The error type returned when a checked conversion regarding big integer fails.
176
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
177
pub struct TryFromBigIntError<T> {
178
    original: T,
179
}
180
181
impl<T> TryFromBigIntError<T> {
182
0
    fn new(original: T) -> Self {
183
0
        TryFromBigIntError { original }
184
0
    }
Unexecuted instantiation: _RNvMs1_Cs72ekIXsOXFl_10num_bigintINtB5_18TryFromBigIntErroruE3newB5_
Unexecuted instantiation: _RNvMs1_Cs72ekIXsOXFl_10num_bigintINtB5_18TryFromBigIntErrorNtNtB5_6bigint6BigIntE3newB5_
Unexecuted instantiation: _RNvMs1_Cs72ekIXsOXFl_10num_bigintINtB5_18TryFromBigIntErrorNtNtB5_7biguint7BigUintE3newB5_
185
186
0
    fn __description(&self) -> &str {
187
0
        "out of range conversion regarding big integer attempted"
188
0
    }
189
190
    /// Extract the original value, if available. The value will be available
191
    /// if the type before conversion was either [`BigInt`] or [`BigUint`].
192
0
    pub fn into_original(self) -> T {
193
0
        self.original
194
0
    }
195
}
196
197
#[cfg(feature = "std")]
198
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
199
impl<T> std::error::Error for TryFromBigIntError<T>
200
where
201
    T: fmt::Debug,
202
{
203
0
    fn description(&self) -> &str {
204
0
        self.__description()
205
0
    }
206
}
207
208
impl<T> fmt::Display for TryFromBigIntError<T> {
209
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210
0
        self.__description().fmt(f)
211
0
    }
212
}
213
214
pub use crate::biguint::BigUint;
215
pub use crate::biguint::ToBigUint;
216
pub use crate::biguint::U32Digits;
217
pub use crate::biguint::U64Digits;
218
219
pub use crate::bigint::BigInt;
220
pub use crate::bigint::Sign;
221
pub use crate::bigint::ToBigInt;
222
223
#[cfg(feature = "rand")]
224
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
225
pub use crate::bigrand::{RandBigInt, RandomBits, UniformBigInt, UniformBigUint};
226
227
mod big_digit {
228
    // A [`BigDigit`] is a [`BigUint`]'s composing element.
229
    cfg_digit!(
230
        pub(crate) type BigDigit = u32;
231
        pub(crate) type BigDigit = u64;
232
    );
233
234
    // A [`DoubleBigDigit`] is the internal type used to do the computations.  Its
235
    // size is the double of the size of [`BigDigit`].
236
    cfg_digit!(
237
        pub(crate) type DoubleBigDigit = u64;
238
        pub(crate) type DoubleBigDigit = u128;
239
    );
240
241
    pub(crate) const BITS: u8 = BigDigit::BITS as u8;
242
    pub(crate) const HALF_BITS: u8 = BITS / 2;
243
    pub(crate) const HALF: BigDigit = (1 << HALF_BITS) - 1;
244
245
    pub(crate) const MAX: BigDigit = BigDigit::MAX;
246
    const LO_MASK: DoubleBigDigit = MAX as DoubleBigDigit;
247
248
    #[inline]
249
7.79M
    fn get_hi(n: DoubleBigDigit) -> BigDigit {
250
7.79M
        (n >> BITS) as BigDigit
251
7.79M
    }
252
    #[inline]
253
7.79M
    fn get_lo(n: DoubleBigDigit) -> BigDigit {
254
7.79M
        (n & LO_MASK) as BigDigit
255
7.79M
    }
256
257
    /// Split one [`DoubleBigDigit`] into two [`BigDigit`]s.
258
    #[inline]
259
7.79M
    pub(crate) fn from_doublebigdigit(n: DoubleBigDigit) -> (BigDigit, BigDigit) {
260
7.79M
        (get_hi(n), get_lo(n))
261
7.79M
    }
262
263
    /// Join two [`BigDigit`]s into one [`DoubleBigDigit`].
264
    #[inline]
265
2.92M
    pub(crate) fn to_doublebigdigit(hi: BigDigit, lo: BigDigit) -> DoubleBigDigit {
266
2.92M
        DoubleBigDigit::from(lo) | (DoubleBigDigit::from(hi) << BITS)
267
2.92M
    }
268
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-bigint-0.4.6/src/macros.rs
Line
Count
Source
1
#![allow(unused_macros)]
2
3
macro_rules! cfg_32 {
4
    ($($any:tt)+) => {
5
        #[cfg(not(target_pointer_width = "64"))] $($any)+
6
    }
7
}
8
9
macro_rules! cfg_32_or_test {
10
    ($($any:tt)+) => {
11
        #[cfg(any(not(target_pointer_width = "64"), test))] $($any)+
12
    }
13
}
14
15
macro_rules! cfg_64 {
16
    ($($any:tt)+) => {
17
        #[cfg(target_pointer_width = "64")] $($any)+
18
    }
19
}
20
21
macro_rules! cfg_digit {
22
    ($item32:item $item64:item) => {
23
        cfg_32!($item32);
24
        cfg_64!($item64);
25
    };
26
}
27
28
macro_rules! cfg_digit_expr {
29
    ($expr32:expr, $expr64:expr) => {
30
        cfg_32!($expr32);
31
        cfg_64!($expr64);
32
    };
33
}
34
35
macro_rules! forward_val_val_binop {
36
    (impl $imp:ident for $res:ty, $method:ident) => {
37
        impl $imp<$res> for $res {
38
            type Output = $res;
39
40
            #[inline]
41
18.4k
            fn $method(self, other: $res) -> $res {
42
18.4k
                // forward to val-ref
43
18.4k
                $imp::$method(self, &other)
44
18.4k
            }
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Div3divB9_
Unexecuted instantiation: _RNvXs2b_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Rem3remBa_
Unexecuted instantiation: _RNvXs6_NtNtCs72ekIXsOXFl_10num_bigint6bigint4bitsNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitAnd6bitandB9_
Unexecuted instantiation: _RNvXs9_NtNtCs72ekIXsOXFl_10num_bigint6bigint4bitsNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops3bit5BitOr5bitorB9_
_RNvXsb_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Sub3subB9_
Line
Count
Source
41
18.4k
            fn $method(self, other: $res) -> $res {
42
18.4k
                // forward to val-ref
43
18.4k
                $imp::$method(self, &other)
44
18.4k
            }
Unexecuted instantiation: _RNvXs5_NtNtCs72ekIXsOXFl_10num_bigint7biguint4bitsNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitAnd6bitandB9_
45
        }
46
    };
47
}
48
49
macro_rules! forward_val_val_binop_commutative {
50
    (impl $imp:ident for $res:ty, $method:ident) => {
51
        impl $imp<$res> for $res {
52
            type Output = $res;
53
54
            #[inline]
55
31.2k
            fn $method(self, other: $res) -> $res {
56
31.2k
                // forward to val-ref, with the larger capacity as val
57
31.2k
                if self.capacity() >= other.capacity() {
58
27.4k
                    $imp::$method(self, &other)
59
                } else {
60
3.76k
                    $imp::$method(other, &self)
61
                }
62
31.2k
            }
Unexecuted instantiation: _RNvXsc_NtNtCs72ekIXsOXFl_10num_bigint6bigint4bitsNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitXor6bitxorB9_
_RNvXs7_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3addB9_
Line
Count
Source
55
31.2k
            fn $method(self, other: $res) -> $res {
56
31.2k
                // forward to val-ref, with the larger capacity as val
57
31.2k
                if self.capacity() >= other.capacity() {
58
27.4k
                    $imp::$method(self, &other)
59
                } else {
60
3.76k
                    $imp::$method(other, &self)
61
                }
62
31.2k
            }
Unexecuted instantiation: _RNvXs8_NtNtCs72ekIXsOXFl_10num_bigint7biguint4bitsNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops3bit5BitOr5bitorB9_
Unexecuted instantiation: _RNvXsc_NtNtCs72ekIXsOXFl_10num_bigint7biguint4bitsNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitXor6bitxorB9_
63
        }
64
    };
65
}
66
67
macro_rules! forward_ref_val_binop {
68
    (impl $imp:ident for $res:ty, $method:ident) => {
69
        impl $imp<$res> for &$res {
70
            type Output = $res;
71
72
            #[inline]
73
0
            fn $method(self, other: $res) -> $res {
74
0
                // forward to ref-ref
75
0
                $imp::$method(self, &other)
76
0
            }
Unexecuted instantiation: _RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivBQ_E3divB9_
Unexecuted instantiation: _RNvXs2d_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemBR_E3remBa_
Unexecuted instantiation: _RNvXs7_NtNtCs72ekIXsOXFl_10num_bigint6bigint4bitsRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitAndBM_E6bitandB9_
Unexecuted instantiation: _RNvXsa_NtNtCs72ekIXsOXFl_10num_bigint6bigint4bitsRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit5BitOrBM_E5bitorB9_
Unexecuted instantiation: _RNvXsq_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivBR_E3divB9_
Unexecuted instantiation: _RNvXs1c_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemBS_E3remBa_
Unexecuted instantiation: _RNvXs6_NtNtCs72ekIXsOXFl_10num_bigint7biguint4bitsRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitAndBN_E6bitandB9_
77
        }
78
    };
79
}
80
81
macro_rules! forward_ref_val_binop_commutative {
82
    (impl $imp:ident for $res:ty, $method:ident) => {
83
        impl $imp<$res> for &$res {
84
            type Output = $res;
85
86
            #[inline]
87
1.22k
            fn $method(self, other: $res) -> $res {
88
1.22k
                // reverse, forward to val-ref
89
1.22k
                $imp::$method(other, self)
90
1.22k
            }
Unexecuted instantiation: _RNvXs8_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddBR_E3addCs4RkbDk9WRL5_5clvmr
_RNvXs8_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddBR_E3addB9_
Line
Count
Source
87
1.22k
            fn $method(self, other: $res) -> $res {
88
1.22k
                // reverse, forward to val-ref
89
1.22k
                $imp::$method(other, self)
90
1.22k
            }
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint6bigint4bitsRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitXorBM_E6bitxorB9_
Unexecuted instantiation: _RNvXs9_NtNtCs72ekIXsOXFl_10num_bigint7biguint4bitsRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit5BitOrBN_E5bitorB9_
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint7biguint4bitsRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitXorBN_E6bitxorB9_
91
        }
92
    };
93
}
94
95
macro_rules! forward_val_ref_binop {
96
    (impl $imp:ident for $res:ty, $method:ident) => {
97
        impl $imp<&$res> for $res {
98
            type Output = $res;
99
100
            #[inline]
101
115k
            fn $method(self, other: &$res) -> $res {
102
115k
                // forward to ref-ref
103
115k
                $imp::$method(&self, other)
104
115k
            }
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRBP_E3divB9_
Unexecuted instantiation: _RNvXs2c_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRBQ_E3remBa_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRBQ_E3divB9_
_RNvXs1b_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRBR_E3remBa_
Line
Count
Source
101
115k
            fn $method(self, other: &$res) -> $res {
102
115k
                // forward to ref-ref
103
115k
                $imp::$method(&self, other)
104
115k
            }
105
        }
106
    };
107
}
108
109
macro_rules! forward_ref_ref_binop {
110
    (impl $imp:ident for $res:ty, $method:ident) => {
111
        impl $imp<&$res> for &$res {
112
            type Output = $res;
113
114
            #[inline]
115
14.3k
            fn $method(self, other: &$res) -> $res {
116
14.3k
                // forward to val-ref
117
14.3k
                $imp::$method(self.clone(), other)
118
14.3k
            }
119
        }
120
    };
121
}
122
123
macro_rules! forward_ref_ref_binop_commutative {
124
    (impl $imp:ident for $res:ty, $method:ident) => {
125
        impl $imp<&$res> for &$res {
126
            type Output = $res;
127
128
            #[inline]
129
17.2k
            fn $method(self, other: &$res) -> $res {
130
17.2k
                // forward to val-ref, choosing the larger to clone
131
17.2k
                if self.len() >= other.len() {
132
6.04k
                    $imp::$method(self.clone(), other)
133
                } else {
134
11.2k
                    $imp::$method(other.clone(), self)
135
                }
136
17.2k
            }
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint6bigint4bitsRNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitXor6bitxorB9_
_RNvXs9_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3addB9_
Line
Count
Source
129
17.2k
            fn $method(self, other: &$res) -> $res {
130
17.2k
                // forward to val-ref, choosing the larger to clone
131
17.2k
                if self.len() >= other.len() {
132
6.04k
                    $imp::$method(self.clone(), other)
133
                } else {
134
11.2k
                    $imp::$method(other.clone(), self)
135
                }
136
17.2k
            }
Unexecuted instantiation: _RNvXsa_NtNtCs72ekIXsOXFl_10num_bigint7biguint4bitsRNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops3bit5BitOr5bitorB9_
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint7biguint4bitsRNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitXor6bitxorB9_
137
        }
138
    };
139
}
140
141
macro_rules! forward_val_assign {
142
    (impl $imp:ident for $res:ty, $method:ident) => {
143
        impl $imp<$res> for $res {
144
            #[inline]
145
102k
            fn $method(&mut self, other: $res) {
146
102k
                self.$method(&other);
147
102k
            }
_RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssign10add_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
145
78.7k
            fn $method(&mut self, other: $res) {
146
78.7k
                self.$method(&other);
147
78.7k
            }
_RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssign10sub_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
145
14.7k
            fn $method(&mut self, other: $res) {
146
14.7k
                self.$method(&other);
147
14.7k
            }
_RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssign10add_assignB9_
Line
Count
Source
145
9.06k
            fn $method(&mut self, other: $res) {
146
9.06k
                self.$method(&other);
147
9.06k
            }
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9DivAssign10div_assignB9_
Unexecuted instantiation: _RNvXs2e_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssign10rem_assignBa_
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssign10sub_assignB9_
Unexecuted instantiation: _RNvXs8_NtNtCs72ekIXsOXFl_10num_bigint6bigint4bitsNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops3bit12BitAndAssign13bitand_assignB9_
Unexecuted instantiation: _RNvXsb_NtNtCs72ekIXsOXFl_10num_bigint6bigint4bitsNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops3bit11BitOrAssign12bitor_assignB9_
Unexecuted instantiation: _RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint6bigint4bitsNtB7_6BigIntNtNtNtCsbQ8arDwx5Xq_4core3ops3bit12BitXorAssign13bitxor_assignB9_
Unexecuted instantiation: _RNvXsa_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssign10add_assignB9_
Unexecuted instantiation: _RNvXsr_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9DivAssign10div_assignB9_
Unexecuted instantiation: _RNvXs1d_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssign10rem_assignBa_
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssign10sub_assignB9_
Unexecuted instantiation: _RNvXs7_NtNtCs72ekIXsOXFl_10num_bigint7biguint4bitsNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops3bit12BitAndAssign13bitand_assignB9_
Unexecuted instantiation: _RNvXsb_NtNtCs72ekIXsOXFl_10num_bigint7biguint4bitsNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops3bit11BitOrAssign12bitor_assignB9_
Unexecuted instantiation: _RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint7biguint4bitsNtB7_7BigUintNtNtNtCsbQ8arDwx5Xq_4core3ops3bit12BitXorAssign13bitxor_assignB9_
148
        }
149
    };
150
}
151
152
macro_rules! forward_val_assign_scalar {
153
    (impl $imp:ident for $res:ty, $scalar:ty, $method:ident) => {
154
        impl $imp<$res> for $scalar {
155
            #[inline]
156
0
            fn $method(&mut self, other: $res) {
157
0
                self.$method(&other);
158
0
            }
Unexecuted instantiation: _RNvXs1Y_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs20_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs22_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs24_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs26_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs28_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs2a_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs2c_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisioniINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs2e_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs2g_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs2i_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
Unexecuted instantiation: _RNvXs2k_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignNtB8_7BigUintE10rem_assignBa_
159
        }
160
    };
161
}
162
163
/// use this if val_val_binop is already implemented and the reversed order is required
164
macro_rules! forward_scalar_val_val_binop_commutative {
165
    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
166
        impl $imp<$res> for $scalar {
167
            type Output = $res;
168
169
            #[inline]
170
0
            fn $method(self, other: $res) -> $res {
171
0
                $imp::$method(other, self)
172
0
            }
Unexecuted instantiation: _RNvXsC_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXs19_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1g_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1u_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1B_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1n_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1I_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1a_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1h_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1v_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1C_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1o_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1J_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXsC_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
173
        }
174
    };
175
}
176
177
// Forward scalar to ref-val, when reusing storage is not helpful
178
macro_rules! forward_scalar_val_val_binop_to_ref_val {
179
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
180
        impl $imp<$scalar> for $res {
181
            type Output = $res;
182
183
            #[inline]
184
0
            fn $method(self, other: $scalar) -> $res {
185
0
                $imp::$method(&self, other)
186
0
            }
187
        }
188
189
        impl $imp<$res> for $scalar {
190
            type Output = $res;
191
192
            #[inline]
193
0
            fn $method(self, other: $res) -> $res {
194
0
                $imp::$method(self, &other)
195
0
            }
196
        }
197
    };
198
}
199
200
macro_rules! forward_scalar_ref_ref_binop_to_ref_val {
201
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
202
        impl $imp<&$scalar> for &$res {
203
            type Output = $res;
204
205
            #[inline]
206
0
            fn $method(self, other: &$scalar) -> $res {
207
0
                $imp::$method(self, *other)
208
0
            }
209
        }
210
211
        impl $imp<&$res> for &$scalar {
212
            type Output = $res;
213
214
            #[inline]
215
0
            fn $method(self, other: &$res) -> $res {
216
0
                $imp::$method(*self, other)
217
0
            }
218
        }
219
    };
220
}
221
222
macro_rules! forward_scalar_val_ref_binop_to_ref_val {
223
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
224
        impl $imp<&$scalar> for $res {
225
            type Output = $res;
226
227
            #[inline]
228
0
            fn $method(self, other: &$scalar) -> $res {
229
0
                $imp::$method(&self, *other)
230
0
            }
231
        }
232
233
        impl $imp<$res> for &$scalar {
234
            type Output = $res;
235
236
            #[inline]
237
0
            fn $method(self, other: $res) -> $res {
238
0
                $imp::$method(*self, &other)
239
0
            }
240
        }
241
    };
242
}
243
244
macro_rules! forward_scalar_val_ref_binop_to_val_val {
245
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
246
        impl $imp<&$scalar> for $res {
247
            type Output = $res;
248
249
            #[inline]
250
0
            fn $method(self, other: &$scalar) -> $res {
251
0
                $imp::$method(self, *other)
252
0
            }
Unexecuted instantiation: _RNvXsl_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRhE3addB9_
Unexecuted instantiation: _RNvXsr_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRtE3addB9_
Unexecuted instantiation: _RNvXsz_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRjE3addB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRaE3addB9_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRsE3addB9_
Unexecuted instantiation: _RNvXsX_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRiE3addB9_
Unexecuted instantiation: _RNvXs1a_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRmE3addBa_
Unexecuted instantiation: _RNvXs1h_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRyE3addBa_
Unexecuted instantiation: _RNvXs1o_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRoE3addBa_
Unexecuted instantiation: _RNvXs1v_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRlE3addBa_
Unexecuted instantiation: _RNvXs1C_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRxE3addBa_
Unexecuted instantiation: _RNvXs1J_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRnE3addBa_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRhE3divB9_
Unexecuted instantiation: _RNvXsT_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRtE3divB9_
Unexecuted instantiation: _RNvXs11_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRjE3divBa_
Unexecuted instantiation: _RNvXs1b_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRaE3divBa_
Unexecuted instantiation: _RNvXs1h_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRsE3divBa_
Unexecuted instantiation: _RNvXs1p_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRiE3divBa_
Unexecuted instantiation: _RNvXs1B_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRmE3divBa_
Unexecuted instantiation: _RNvXs1H_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRyE3divBa_
Unexecuted instantiation: _RNvXs1N_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRoE3divBa_
Unexecuted instantiation: _RNvXs1T_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRlE3divBa_
Unexecuted instantiation: _RNvXs1Z_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRxE3divBa_
Unexecuted instantiation: _RNvXs25_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRnE3divBa_
Unexecuted instantiation: _RNvXs2j_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRhE3remBa_
Unexecuted instantiation: _RNvXs2p_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRtE3remBa_
Unexecuted instantiation: _RNvXs2x_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRjE3remBa_
Unexecuted instantiation: _RNvXs2H_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRaE3remBa_
Unexecuted instantiation: _RNvXs2N_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRsE3remBa_
Unexecuted instantiation: _RNvXs2V_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRiE3remBa_
Unexecuted instantiation: _RNvXs37_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRmE3remBa_
Unexecuted instantiation: _RNvXs3d_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRyE3remBa_
Unexecuted instantiation: _RNvXs3j_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRoE3remBa_
Unexecuted instantiation: _RNvXs3p_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRlE3remBa_
Unexecuted instantiation: _RNvXs3v_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRxE3remBa_
Unexecuted instantiation: _RNvXs3B_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRnE3remBa_
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRhE3mulB9_
Unexecuted instantiation: _RNvXss_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRtE3mulB9_
Unexecuted instantiation: _RNvXsA_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRjE3mulB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRaE3mulB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRsE3mulB9_
Unexecuted instantiation: _RNvXsY_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRiE3mulB9_
Unexecuted instantiation: _RNvXs1b_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRmE3mulBa_
Unexecuted instantiation: _RNvXs1i_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRyE3mulBa_
Unexecuted instantiation: _RNvXs1p_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRoE3mulBa_
Unexecuted instantiation: _RNvXs1w_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRlE3mulBa_
Unexecuted instantiation: _RNvXs1D_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRxE3mulBa_
Unexecuted instantiation: _RNvXs1K_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRnE3mulBa_
Unexecuted instantiation: _RNvXsr_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRhE3subB9_
Unexecuted instantiation: _RNvXsx_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRtE3subB9_
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRjE3subB9_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRaE3subB9_
Unexecuted instantiation: _RNvXsV_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRsE3subB9_
Unexecuted instantiation: _RNvXs13_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRiE3subBa_
Unexecuted instantiation: _RNvXs1f_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRmE3subBa_
Unexecuted instantiation: _RNvXs1l_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRyE3subBa_
Unexecuted instantiation: _RNvXs1r_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRoE3subBa_
Unexecuted instantiation: _RNvXs1x_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRlE3subBa_
Unexecuted instantiation: _RNvXs1D_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRxE3subBa_
Unexecuted instantiation: _RNvXs1J_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRnE3subBa_
Unexecuted instantiation: _RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRhE3addB9_
Unexecuted instantiation: _RNvXsl_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRtE3addB9_
Unexecuted instantiation: _RNvXst_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRjE3addB9_
Unexecuted instantiation: _RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRmE3addB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRyE3addB9_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRoE3addB9_
Unexecuted instantiation: _RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRhE3divB9_
Unexecuted instantiation: _RNvXsC_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRtE3divB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRjE3divB9_
Unexecuted instantiation: _RNvXsT_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRmE3divB9_
Unexecuted instantiation: _RNvXsZ_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRyE3divB9_
Unexecuted instantiation: _RNvXs15_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRoE3divBa_
Unexecuted instantiation: _RNvXs1i_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRhE3remBa_
Unexecuted instantiation: _RNvXs1o_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRtE3remBa_
Unexecuted instantiation: _RNvXs1w_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRjE3remBa_
Unexecuted instantiation: _RNvXs1L_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRyE3remBa_
Unexecuted instantiation: _RNvXs1R_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRoE3remBa_
Unexecuted instantiation: _RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRhE3mulB9_
Unexecuted instantiation: _RNvXsl_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRtE3mulB9_
Unexecuted instantiation: _RNvXst_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRjE3mulB9_
Unexecuted instantiation: _RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRmE3mulB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRyE3mulB9_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRoE3mulB9_
Unexecuted instantiation: _RNvXsi_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRhE3subB9_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRtE3subB9_
Unexecuted instantiation: _RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRjE3subB9_
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRmE3subB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRyE3subB9_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRoE3subB9_
253
        }
254
255
        impl $imp<$res> for &$scalar {
256
            type Output = $res;
257
258
            #[inline]
259
0
            fn $method(self, other: $res) -> $res {
260
0
                $imp::$method(*self, other)
261
0
            }
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXss_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsA_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsY_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXs1b_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1i_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1p_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1w_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1D_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1K_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB7_6BigIntE3divB9_
Unexecuted instantiation: _RNvXsU_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB7_6BigIntE3divB9_
Unexecuted instantiation: _RNvXs12_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1c_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1i_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1q_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1C_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1I_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1O_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1U_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs20_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs26_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs2k_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2q_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2y_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2I_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2O_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2W_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs38_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3e_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3k_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3q_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3w_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3C_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXst_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsB_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsZ_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXs1c_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1j_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1q_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1x_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1E_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1L_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXss_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsy_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsW_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXs14_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1g_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1m_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1s_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1y_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1E_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1K_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsu_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsE_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsS_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsx_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXsU_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXs10_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_7BigUintE3divBa_
Unexecuted instantiation: _RNvXs16_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_7BigUintE3divBa_
Unexecuted instantiation: _RNvXs1j_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1p_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1x_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1M_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1S_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsu_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsE_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsS_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsj_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsx_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsS_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_7BigUintE3subB9_
262
        }
263
    };
264
}
265
266
macro_rules! forward_scalar_ref_val_binop_to_val_val {
267
    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
268
        impl $imp<$scalar> for &$res {
269
            type Output = $res;
270
271
            #[inline]
272
33.7k
            fn $method(self, other: $scalar) -> $res {
273
33.7k
                $imp::$method(self.clone(), other)
274
33.7k
            }
Unexecuted instantiation: _RNvXs39_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemmE3remBa_
Unexecuted instantiation: _RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubmE3subB9_
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddmE3addB9_
Unexecuted instantiation: _RNvXsV_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivmE3divB9_
Unexecuted instantiation: _RNvXs17_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivoE3divBa_
Unexecuted instantiation: _RNvXs1N_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemyE3remBa_
Unexecuted instantiation: _RNvXs1T_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemoE3remBa_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddhE3addB9_
Unexecuted instantiation: _RNvXst_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddtE3addB9_
Unexecuted instantiation: _RNvXsB_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddjE3addB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddaE3addB9_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddsE3addB9_
Unexecuted instantiation: _RNvXsZ_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddiE3addB9_
Unexecuted instantiation: _RNvXs1c_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddmE3addBa_
Unexecuted instantiation: _RNvXs1j_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddyE3addBa_
Unexecuted instantiation: _RNvXs1q_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddoE3addBa_
Unexecuted instantiation: _RNvXs1x_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddlE3addBa_
Unexecuted instantiation: _RNvXs1E_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddxE3addBa_
Unexecuted instantiation: _RNvXs1L_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddnE3addBa_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivhE3divB9_
Unexecuted instantiation: _RNvXsV_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivtE3divB9_
Unexecuted instantiation: _RNvXs13_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivjE3divBa_
Unexecuted instantiation: _RNvXs1d_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivaE3divBa_
Unexecuted instantiation: _RNvXs1j_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivsE3divBa_
Unexecuted instantiation: _RNvXs1r_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DiviE3divBa_
Unexecuted instantiation: _RNvXs1D_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivmE3divBa_
Unexecuted instantiation: _RNvXs1J_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivyE3divBa_
Unexecuted instantiation: _RNvXs1P_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivoE3divBa_
Unexecuted instantiation: _RNvXs1V_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivlE3divBa_
Unexecuted instantiation: _RNvXs21_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivxE3divBa_
Unexecuted instantiation: _RNvXs27_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivnE3divBa_
Unexecuted instantiation: _RNvXs2l_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemhE3remBa_
Unexecuted instantiation: _RNvXs2r_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemtE3remBa_
Unexecuted instantiation: _RNvXs2z_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemjE3remBa_
Unexecuted instantiation: _RNvXs2J_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemaE3remBa_
Unexecuted instantiation: _RNvXs2P_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemsE3remBa_
Unexecuted instantiation: _RNvXs2X_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemiE3remBa_
Unexecuted instantiation: _RNvXs3f_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemyE3remBa_
Unexecuted instantiation: _RNvXs3l_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemoE3remBa_
Unexecuted instantiation: _RNvXs3r_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemlE3remBa_
Unexecuted instantiation: _RNvXs3x_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemxE3remBa_
Unexecuted instantiation: _RNvXs3D_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemnE3remBa_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulhE3mulB9_
Unexecuted instantiation: _RNvXsu_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MultE3mulB9_
Unexecuted instantiation: _RNvXsC_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MuljE3mulB9_
Unexecuted instantiation: _RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulaE3mulB9_
Unexecuted instantiation: _RNvXsS_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulsE3mulB9_
Unexecuted instantiation: _RNvXs10_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MuliE3mulBa_
Unexecuted instantiation: _RNvXs1d_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulmE3mulBa_
Unexecuted instantiation: _RNvXs1k_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulyE3mulBa_
Unexecuted instantiation: _RNvXs1r_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MuloE3mulBa_
Unexecuted instantiation: _RNvXs1y_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MullE3mulBa_
Unexecuted instantiation: _RNvXs1F_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulxE3mulBa_
Unexecuted instantiation: _RNvXs1M_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulnE3mulBa_
Unexecuted instantiation: _RNvXst_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubhE3subB9_
Unexecuted instantiation: _RNvXsz_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubtE3subB9_
Unexecuted instantiation: _RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubjE3subB9_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubaE3subB9_
Unexecuted instantiation: _RNvXsX_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubsE3subB9_
Unexecuted instantiation: _RNvXs15_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubiE3subBa_
Unexecuted instantiation: _RNvXs1h_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubmE3subBa_
Unexecuted instantiation: _RNvXs1n_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubyE3subBa_
Unexecuted instantiation: _RNvXs1t_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SuboE3subBa_
Unexecuted instantiation: _RNvXs1z_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SublE3subBa_
Unexecuted instantiation: _RNvXs1F_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubxE3subBa_
Unexecuted instantiation: _RNvXs1L_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubnE3subBa_
Unexecuted instantiation: _RNvXsh_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddhE3addB9_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddtE3addB9_
Unexecuted instantiation: _RNvXsv_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddjE3addB9_
Unexecuted instantiation: _RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddyE3addB9_
Unexecuted instantiation: _RNvXsT_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddoE3addB9_
Unexecuted instantiation: _RNvXsy_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivhE3divB9_
Unexecuted instantiation: _RNvXsE_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivtE3divB9_
Unexecuted instantiation: _RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivjE3divB9_
Unexecuted instantiation: _RNvXs11_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivyE3divBa_
Unexecuted instantiation: _RNvXs1k_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemhE3remBa_
Unexecuted instantiation: _RNvXs1q_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemtE3remBa_
Unexecuted instantiation: _RNvXs1y_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemjE3remBa_
_RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulyE3mulB9_
Line
Count
Source
272
33.7k
            fn $method(self, other: $scalar) -> $res {
273
33.7k
                $imp::$method(self.clone(), other)
274
33.7k
            }
Unexecuted instantiation: _RNvXsh_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulhE3mulB9_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MultE3mulB9_
Unexecuted instantiation: _RNvXsv_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MuljE3mulB9_
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulmE3mulB9_
Unexecuted instantiation: _RNvXsT_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MuloE3mulB9_
Unexecuted instantiation: _RNvXsk_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubhE3subB9_
Unexecuted instantiation: _RNvXsq_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubtE3subB9_
Unexecuted instantiation: _RNvXsy_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubjE3subB9_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubyE3subB9_
Unexecuted instantiation: _RNvXsT_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SuboE3subB9_
275
        }
276
277
        impl $imp<&$res> for $scalar {
278
            type Output = $res;
279
280
            #[inline]
281
0
            fn $method(self, other: &$res) -> $res {
282
0
                $imp::$method(self, other.clone())
283
0
            }
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsu_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsC_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsS_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXs10_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additioniINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1d_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1k_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1r_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1y_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1F_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1M_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_6BigIntE3divB9_
Unexecuted instantiation: _RNvXsW_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_6BigIntE3divB9_
Unexecuted instantiation: _RNvXs14_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1e_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1k_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1s_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisioniINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1E_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1K_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1Q_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1W_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs22_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs28_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs2m_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2s_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2A_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2K_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2Q_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2Y_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisioniINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3a_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3g_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3m_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3s_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3y_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3E_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsv_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsT_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXs11_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1e_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1l_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1s_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1z_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1G_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1N_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXsu_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsA_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsS_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsY_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXs16_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractioniINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1i_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1o_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1u_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1A_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1G_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1M_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXsi_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsU_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsz_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXsW_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXs12_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_7BigUintE3divBa_
Unexecuted instantiation: _RNvXs18_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_7BigUintE3divBa_
Unexecuted instantiation: _RNvXs1l_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1r_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1z_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1O_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1U_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXsi_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsU_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsl_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsr_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsz_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsU_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
284
        }
285
    };
286
}
287
288
macro_rules! forward_scalar_ref_ref_binop_to_val_val {
289
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
290
        impl $imp<&$scalar> for &$res {
291
            type Output = $res;
292
293
            #[inline]
294
0
            fn $method(self, other: &$scalar) -> $res {
295
0
                $imp::$method(self.clone(), *other)
296
0
            }
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRhE3addB9_
Unexecuted instantiation: _RNvXsv_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRtE3addB9_
Unexecuted instantiation: _RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRjE3addB9_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRaE3addB9_
Unexecuted instantiation: _RNvXsT_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRsE3addB9_
Unexecuted instantiation: _RNvXs11_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRiE3addBa_
Unexecuted instantiation: _RNvXs1e_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRmE3addBa_
Unexecuted instantiation: _RNvXs1l_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRyE3addBa_
Unexecuted instantiation: _RNvXs1s_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRoE3addBa_
Unexecuted instantiation: _RNvXs1z_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRlE3addBa_
Unexecuted instantiation: _RNvXs1G_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRxE3addBa_
Unexecuted instantiation: _RNvXs1N_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRnE3addBa_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRhE3divB9_
Unexecuted instantiation: _RNvXsX_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRtE3divB9_
Unexecuted instantiation: _RNvXs15_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRjE3divBa_
Unexecuted instantiation: _RNvXs1f_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRaE3divBa_
Unexecuted instantiation: _RNvXs1l_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRsE3divBa_
Unexecuted instantiation: _RNvXs1t_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRiE3divBa_
Unexecuted instantiation: _RNvXs1F_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRmE3divBa_
Unexecuted instantiation: _RNvXs1L_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRyE3divBa_
Unexecuted instantiation: _RNvXs1R_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRoE3divBa_
Unexecuted instantiation: _RNvXs1X_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRlE3divBa_
Unexecuted instantiation: _RNvXs23_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRxE3divBa_
Unexecuted instantiation: _RNvXs29_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRnE3divBa_
Unexecuted instantiation: _RNvXs2n_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRhE3remBa_
Unexecuted instantiation: _RNvXs2t_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRtE3remBa_
Unexecuted instantiation: _RNvXs2B_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRjE3remBa_
Unexecuted instantiation: _RNvXs2L_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRaE3remBa_
Unexecuted instantiation: _RNvXs2R_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRsE3remBa_
Unexecuted instantiation: _RNvXs2Z_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRiE3remBa_
Unexecuted instantiation: _RNvXs3b_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRmE3remBa_
Unexecuted instantiation: _RNvXs3h_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRyE3remBa_
Unexecuted instantiation: _RNvXs3n_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRoE3remBa_
Unexecuted instantiation: _RNvXs3t_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRlE3remBa_
Unexecuted instantiation: _RNvXs3z_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRxE3remBa_
Unexecuted instantiation: _RNvXs3F_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRnE3remBa_
Unexecuted instantiation: _RNvXsq_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRhE3mulB9_
Unexecuted instantiation: _RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRtE3mulB9_
Unexecuted instantiation: _RNvXsE_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRjE3mulB9_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRaE3mulB9_
Unexecuted instantiation: _RNvXsU_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRsE3mulB9_
Unexecuted instantiation: _RNvXs12_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRiE3mulBa_
Unexecuted instantiation: _RNvXs1f_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRmE3mulBa_
Unexecuted instantiation: _RNvXs1m_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRyE3mulBa_
Unexecuted instantiation: _RNvXs1t_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRoE3mulBa_
Unexecuted instantiation: _RNvXs1A_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRlE3mulBa_
Unexecuted instantiation: _RNvXs1H_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRxE3mulBa_
Unexecuted instantiation: _RNvXs1O_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRnE3mulBa_
Unexecuted instantiation: _RNvXsv_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRhE3subB9_
Unexecuted instantiation: _RNvXsB_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRtE3subB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRjE3subB9_
Unexecuted instantiation: _RNvXsT_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRaE3subB9_
Unexecuted instantiation: _RNvXsZ_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRsE3subB9_
Unexecuted instantiation: _RNvXs17_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRiE3subBa_
Unexecuted instantiation: _RNvXs1j_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRmE3subBa_
Unexecuted instantiation: _RNvXs1p_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRyE3subBa_
Unexecuted instantiation: _RNvXs1v_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRoE3subBa_
Unexecuted instantiation: _RNvXs1B_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRlE3subBa_
Unexecuted instantiation: _RNvXs1H_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRxE3subBa_
Unexecuted instantiation: _RNvXs1N_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRnE3subBa_
Unexecuted instantiation: _RNvXsj_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRhE3addB9_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRtE3addB9_
Unexecuted instantiation: _RNvXsx_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRjE3addB9_
Unexecuted instantiation: _RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRmE3addB9_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRyE3addB9_
Unexecuted instantiation: _RNvXsV_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRoE3addB9_
Unexecuted instantiation: _RNvXsA_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRhE3divB9_
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRtE3divB9_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRjE3divB9_
Unexecuted instantiation: _RNvXsX_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRmE3divB9_
Unexecuted instantiation: _RNvXs13_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRyE3divBa_
Unexecuted instantiation: _RNvXs19_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRoE3divBa_
Unexecuted instantiation: _RNvXs1m_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRhE3remBa_
Unexecuted instantiation: _RNvXs1s_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRtE3remBa_
Unexecuted instantiation: _RNvXs1A_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRjE3remBa_
Unexecuted instantiation: _RNvXs1P_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRyE3remBa_
Unexecuted instantiation: _RNvXs1V_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRoE3remBa_
Unexecuted instantiation: _RNvXsj_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRhE3mulB9_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRtE3mulB9_
Unexecuted instantiation: _RNvXsx_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRjE3mulB9_
Unexecuted instantiation: _RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRmE3mulB9_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRyE3mulB9_
Unexecuted instantiation: _RNvXsV_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRoE3mulB9_
Unexecuted instantiation: _RNvXsm_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRhE3subB9_
Unexecuted instantiation: _RNvXss_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRtE3subB9_
Unexecuted instantiation: _RNvXsA_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRjE3subB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRmE3subB9_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRyE3subB9_
Unexecuted instantiation: _RNvXsV_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRoE3subB9_
297
        }
298
299
        impl $imp<&$res> for &$scalar {
300
            type Output = $res;
301
302
            #[inline]
303
0
            fn $method(self, other: &$res) -> $res {
304
0
                $imp::$method(*self, other.clone())
305
0
            }
Unexecuted instantiation: _RNvXsq_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsE_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsU_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXs12_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1f_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1m_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1t_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1A_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1H_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXs1O_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionRnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB8_6BigIntE3addBa_
Unexecuted instantiation: _RNvXsS_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_6BigIntE3divB9_
Unexecuted instantiation: _RNvXsY_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_6BigIntE3divB9_
Unexecuted instantiation: _RNvXs16_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1g_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1m_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1u_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1G_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1M_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1S_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1Y_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs24_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs2a_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs2o_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2u_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2C_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2M_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2S_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs30_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3c_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3i_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3o_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3u_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3A_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs3G_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionRnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXsr_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsx_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsV_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXs13_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1g_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1n_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1u_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1B_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1I_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXs1P_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationRnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB8_6BigIntE3mulBa_
Unexecuted instantiation: _RNvXsw_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsC_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsU_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXs10_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs18_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1k_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1q_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1w_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1C_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRlINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1I_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRxINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXs1O_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionRnINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXsk_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsq_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsy_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsW_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXsB_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXsY_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXs14_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_7BigUintE3divBa_
Unexecuted instantiation: _RNvXs1a_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivRNtB8_7BigUintE3divBa_
Unexecuted instantiation: _RNvXs1n_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1t_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1B_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1Q_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1W_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemRNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXsk_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsq_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsy_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsP_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsW_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXst_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsB_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRmINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRyINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsW_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionRoINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRNtB7_7BigUintE3subB9_
306
        }
307
    };
308
}
309
310
macro_rules! promote_scalars {
311
    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
312
        $(
313
            forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
314
315
            impl $imp<$scalar> for $res {
316
                type Output = $res;
317
318
                #[allow(clippy::cast_lossless)]
319
                #[inline]
320
48
                fn $method(self, other: $scalar) -> $res {
321
48
                    $imp::$method(self, other as $promo)
322
48
                }
_RNvXsb_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddhE3addCs4RkbDk9WRL5_5clvmr
Line
Count
Source
320
48
                fn $method(self, other: $scalar) -> $res {
321
48
                    $imp::$method(self, other as $promo)
322
48
                }
Unexecuted instantiation: _RNvXsh_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddhE3addB9_
Unexecuted instantiation: _RNvXsj_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddtE3addB9_
Unexecuted instantiation: _RNvXsx_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddjE3addB9_
Unexecuted instantiation: _RNvXsF_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddaE3addB9_
Unexecuted instantiation: _RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddsE3addB9_
Unexecuted instantiation: _RNvXsV_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddiE3addB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivhE3divB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivtE3divB9_
Unexecuted instantiation: _RNvXsZ_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivjE3divB9_
Unexecuted instantiation: _RNvXs17_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivaE3divBa_
Unexecuted instantiation: _RNvXs19_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivsE3divBa_
Unexecuted instantiation: _RNvXs1n_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DiviE3divBa_
Unexecuted instantiation: _RNvXs2f_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemhE3remBa_
Unexecuted instantiation: _RNvXs2h_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemtE3remBa_
Unexecuted instantiation: _RNvXs2v_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemjE3remBa_
Unexecuted instantiation: _RNvXs2D_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemaE3remBa_
Unexecuted instantiation: _RNvXs2F_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemsE3remBa_
Unexecuted instantiation: _RNvXs2T_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemiE3remBa_
Unexecuted instantiation: _RNvXsi_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulhE3mulB9_
Unexecuted instantiation: _RNvXsk_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MultE3mulB9_
Unexecuted instantiation: _RNvXsy_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MuljE3mulB9_
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulaE3mulB9_
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulsE3mulB9_
Unexecuted instantiation: _RNvXsW_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MuliE3mulB9_
Unexecuted instantiation: _RNvXsn_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubhE3subB9_
Unexecuted instantiation: _RNvXsp_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubtE3subB9_
Unexecuted instantiation: _RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubjE3subB9_
Unexecuted instantiation: _RNvXsL_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubaE3subB9_
Unexecuted instantiation: _RNvXsN_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB7_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubsE3subB9_
Unexecuted instantiation: _RNvXs11_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubiE3subBa_
Unexecuted instantiation: _RNvXsb_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddhE3addB9_
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddtE3addB9_
Unexecuted instantiation: _RNvXsr_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddjE3addB9_
Unexecuted instantiation: _RNvXss_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivhE3divB9_
Unexecuted instantiation: _RNvXsu_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivtE3divB9_
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivjE3divB9_
Unexecuted instantiation: _RNvXs1e_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemhE3remBa_
Unexecuted instantiation: _RNvXs1g_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemtE3remBa_
Unexecuted instantiation: _RNvXs1u_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemjE3remBa_
Unexecuted instantiation: _RNvXsb_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulhE3mulB9_
Unexecuted instantiation: _RNvXsd_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MultE3mulB9_
Unexecuted instantiation: _RNvXsr_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MuljE3mulB9_
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubhE3subB9_
Unexecuted instantiation: _RNvXsg_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubtE3subB9_
Unexecuted instantiation: _RNvXsu_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubjE3subB9_
323
            }
324
325
            impl $imp<$res> for $scalar {
326
                type Output = $res;
327
328
                #[allow(clippy::cast_lossless)]
329
                #[inline]
330
0
                fn $method(self, other: $res) -> $res {
331
0
                    $imp::$method(self as $promo, other)
332
0
                }
Unexecuted instantiation: _RNvXsi_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsk_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsy_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsG_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsI_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsW_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additioniINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_6BigIntE3addB9_
Unexecuted instantiation: _RNvXsK_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB7_6BigIntE3divB9_
Unexecuted instantiation: _RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB7_6BigIntE3divB9_
Unexecuted instantiation: _RNvXs10_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs18_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1a_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs1o_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisioniINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB8_6BigIntE3divBa_
Unexecuted instantiation: _RNvXs2g_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2i_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2w_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2E_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2G_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXs2U_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisioniINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_6BigIntE3remBa_
Unexecuted instantiation: _RNvXsj_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsl_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsz_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsH_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXsX_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationiINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_6BigIntE3mulB9_
Unexecuted instantiation: _RNvXso_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsq_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsE_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsM_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionaINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXsO_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionsINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_6BigIntE3subB9_
Unexecuted instantiation: _RNvXs12_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractioniINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB8_6BigIntE3subBa_
Unexecuted instantiation: _RNvXsc_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXss_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddNtB7_7BigUintE3addB9_
Unexecuted instantiation: _RNvXst_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXsv_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivNtB7_7BigUintE3divB9_
Unexecuted instantiation: _RNvXs1f_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1h_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXs1v_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemNtB8_7BigUintE3remBa_
Unexecuted instantiation: _RNvXsc_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXse_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationtINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXss_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulNtB7_7BigUintE3mulB9_
Unexecuted instantiation: _RNvXsf_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionhINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsh_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractiontINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_7BigUintE3subB9_
Unexecuted instantiation: _RNvXsv_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionjINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubNtB7_7BigUintE3subB9_
333
            }
334
        )*
335
    }
336
}
337
macro_rules! promote_scalars_assign {
338
    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
339
        $(
340
            impl $imp<$scalar> for $res {
341
                #[allow(clippy::cast_lossless)]
342
                #[inline]
343
0
                fn $method(&mut self, other: $scalar) {
344
0
                    self.$method(other as $promo);
345
0
                }
Unexecuted instantiation: _RNvXs13_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignhE10add_assignBa_
Unexecuted instantiation: _RNvXs14_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssigntE10add_assignBa_
Unexecuted instantiation: _RNvXs15_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignjE10add_assignBa_
Unexecuted instantiation: _RNvXs16_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignaE10add_assignBa_
Unexecuted instantiation: _RNvXs17_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignsE10add_assignBa_
Unexecuted instantiation: _RNvXs18_NtNtCs72ekIXsOXFl_10num_bigint6bigint8additionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssigniE10add_assignBa_
Unexecuted instantiation: _RNvXs1v_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9DivAssignhE10div_assignBa_
Unexecuted instantiation: _RNvXs1w_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9DivAssigntE10div_assignBa_
Unexecuted instantiation: _RNvXs1x_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9DivAssignjE10div_assignBa_
Unexecuted instantiation: _RNvXs1y_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9DivAssignaE10div_assignBa_
Unexecuted instantiation: _RNvXs1z_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9DivAssignsE10div_assignBa_
Unexecuted instantiation: _RNvXs1A_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9DivAssigniE10div_assignBa_
Unexecuted instantiation: _RNvXs31_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignhE10rem_assignBa_
Unexecuted instantiation: _RNvXs32_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssigntE10rem_assignBa_
Unexecuted instantiation: _RNvXs33_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignjE10rem_assignBa_
Unexecuted instantiation: _RNvXs34_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignaE10rem_assignBa_
Unexecuted instantiation: _RNvXs35_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignsE10rem_assignBa_
Unexecuted instantiation: _RNvXs36_NtNtCs72ekIXsOXFl_10num_bigint6bigint8divisionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssigniE10rem_assignBa_
Unexecuted instantiation: _RNvXs14_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignhE10mul_assignBa_
Unexecuted instantiation: _RNvXs15_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssigntE10mul_assignBa_
Unexecuted instantiation: _RNvXs16_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignjE10mul_assignBa_
Unexecuted instantiation: _RNvXs17_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignaE10mul_assignBa_
Unexecuted instantiation: _RNvXs18_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignsE10mul_assignBa_
Unexecuted instantiation: _RNvXs19_NtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplicationNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssigniE10mul_assignBa_
Unexecuted instantiation: _RNvXs19_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssignhE10sub_assignBa_
Unexecuted instantiation: _RNvXs1a_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssigntE10sub_assignBa_
Unexecuted instantiation: _RNvXs1b_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssignjE10sub_assignBa_
Unexecuted instantiation: _RNvXs1c_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssignaE10sub_assignBa_
Unexecuted instantiation: _RNvXs1d_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssignsE10sub_assignBa_
Unexecuted instantiation: _RNvXs1e_NtNtCs72ekIXsOXFl_10num_bigint6bigint11subtractionNtB8_6BigIntINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssigniE10sub_assignBa_
Unexecuted instantiation: _RNvXsz_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignhE10add_assignB9_
Unexecuted instantiation: _RNvXsA_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssigntE10add_assignB9_
Unexecuted instantiation: _RNvXsB_NtNtCs72ekIXsOXFl_10num_bigint7biguint8additionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9AddAssignjE10add_assignB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9DivAssignhE10div_assignB9_
Unexecuted instantiation: _RNvXsR_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9DivAssigntE10div_assignB9_
Unexecuted instantiation: _RNvXsS_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9DivAssignjE10div_assignB9_
Unexecuted instantiation: _RNvXs1C_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignhE10rem_assignBa_
Unexecuted instantiation: _RNvXs1D_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssigntE10rem_assignBa_
Unexecuted instantiation: _RNvXs1E_NtNtCs72ekIXsOXFl_10num_bigint7biguint8divisionNtB8_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9RemAssignjE10rem_assignBa_
Unexecuted instantiation: _RNvXsz_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignhE10mul_assignB9_
Unexecuted instantiation: _RNvXsA_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssigntE10mul_assignB9_
Unexecuted instantiation: _RNvXsB_NtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9MulAssignjE10mul_assignB9_
Unexecuted instantiation: _RNvXsC_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssignhE10sub_assignB9_
Unexecuted instantiation: _RNvXsD_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssigntE10sub_assignB9_
Unexecuted instantiation: _RNvXsE_NtNtCs72ekIXsOXFl_10num_bigint7biguint11subtractionNtB7_7BigUintINtNtNtCsbQ8arDwx5Xq_4core3ops5arith9SubAssignjE10sub_assignB9_
346
            }
347
        )*
348
    }
349
}
350
351
macro_rules! promote_unsigned_scalars {
352
    (impl $imp:ident for $res:ty, $method:ident) => {
353
        promote_scalars!(impl $imp<u32> for $res, $method, u8, u16);
354
        promote_scalars!(impl $imp<UsizePromotion> for $res, $method, usize);
355
    }
356
}
357
358
macro_rules! promote_unsigned_scalars_assign {
359
    (impl $imp:ident for $res:ty, $method:ident) => {
360
        promote_scalars_assign!(impl $imp<u32> for $res, $method, u8, u16);
361
        promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, usize);
362
    }
363
}
364
365
macro_rules! promote_signed_scalars {
366
    (impl $imp:ident for $res:ty, $method:ident) => {
367
        promote_scalars!(impl $imp<i32> for $res, $method, i8, i16);
368
        promote_scalars!(impl $imp<IsizePromotion> for $res, $method, isize);
369
    }
370
}
371
372
macro_rules! promote_signed_scalars_assign {
373
    (impl $imp:ident for $res:ty, $method:ident) => {
374
        promote_scalars_assign!(impl $imp<i32> for $res, $method, i8, i16);
375
        promote_scalars_assign!(impl $imp<IsizePromotion> for $res, $method, isize);
376
    }
377
}
378
379
// Forward everything to ref-ref, when reusing storage is not helpful
380
macro_rules! forward_all_binop_to_ref_ref {
381
    (impl $imp:ident for $res:ty, $method:ident) => {
382
        forward_val_val_binop!(impl $imp for $res, $method);
383
        forward_val_ref_binop!(impl $imp for $res, $method);
384
        forward_ref_val_binop!(impl $imp for $res, $method);
385
    };
386
}
387
388
// Forward everything to val-ref, so LHS storage can be reused
389
macro_rules! forward_all_binop_to_val_ref {
390
    (impl $imp:ident for $res:ty, $method:ident) => {
391
        forward_val_val_binop!(impl $imp for $res, $method);
392
        forward_ref_val_binop!(impl $imp for $res, $method);
393
        forward_ref_ref_binop!(impl $imp for $res, $method);
394
    };
395
}
396
397
// Forward everything to val-ref, commutatively, so either LHS or RHS storage can be reused
398
macro_rules! forward_all_binop_to_val_ref_commutative {
399
    (impl $imp:ident for $res:ty, $method:ident) => {
400
        forward_val_val_binop_commutative!(impl $imp for $res, $method);
401
        forward_ref_val_binop_commutative!(impl $imp for $res, $method);
402
        forward_ref_ref_binop_commutative!(impl $imp for $res, $method);
403
    };
404
}
405
406
macro_rules! forward_all_scalar_binop_to_ref_val {
407
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
408
        forward_scalar_val_val_binop_to_ref_val!(impl $imp<$scalar> for $res, $method);
409
        forward_scalar_val_ref_binop_to_ref_val!(impl $imp<$scalar> for $res, $method);
410
        forward_scalar_ref_ref_binop_to_ref_val!(impl $imp<$scalar> for $res, $method);
411
    }
412
}
413
414
macro_rules! forward_all_scalar_binop_to_val_val {
415
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
416
        forward_scalar_val_ref_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
417
        forward_scalar_ref_val_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
418
        forward_scalar_ref_ref_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
419
    }
420
}
421
422
macro_rules! forward_all_scalar_binop_to_val_val_commutative {
423
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
424
        forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method);
425
        forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
426
    }
427
}
428
429
macro_rules! promote_all_scalars {
430
    (impl $imp:ident for $res:ty, $method:ident) => {
431
        promote_unsigned_scalars!(impl $imp for $res, $method);
432
        promote_signed_scalars!(impl $imp for $res, $method);
433
    }
434
}
435
436
macro_rules! promote_all_scalars_assign {
437
    (impl $imp:ident for $res:ty, $method:ident) => {
438
        promote_unsigned_scalars_assign!(impl $imp for $res, $method);
439
        promote_signed_scalars_assign!(impl $imp for $res, $method);
440
    }
441
}
442
443
macro_rules! impl_sum_iter_type {
444
    ($res:ty) => {
445
        impl<T> Sum<T> for $res
446
        where
447
            $res: Add<T, Output = $res>,
448
        {
449
0
            fn sum<I>(iter: I) -> Self
450
0
            where
451
0
                I: Iterator<Item = T>,
452
0
            {
453
0
                iter.fold(Self::ZERO, <$res>::add)
454
0
            }
Unexecuted instantiation: _RINvXININtNtCs72ekIXsOXFl_10num_bigint6bigint8additions1P_0pENtB8_6BigIntINtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits5accum3SumpE3sumpEBa_
Unexecuted instantiation: _RINvXININtNtCs72ekIXsOXFl_10num_bigint7biguint8additionsX_0pENtB8_7BigUintINtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits5accum3SumpE3sumpEBa_
455
        }
456
    };
457
}
458
459
macro_rules! impl_product_iter_type {
460
    ($res:ty) => {
461
        impl<T> Product<T> for $res
462
        where
463
            $res: Mul<T, Output = $res>,
464
        {
465
0
            fn product<I>(iter: I) -> Self
466
0
            where
467
0
                I: Iterator<Item = T>,
468
0
            {
469
0
                iter.fold(One::one(), <$res>::mul)
470
0
            }
Unexecuted instantiation: _RINvXININtNtCs72ekIXsOXFl_10num_bigint6bigint14multiplications1Q_0pENtB8_6BigIntINtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits5accum7ProductpE7productpEBa_
Unexecuted instantiation: _RINvXININtNtCs72ekIXsOXFl_10num_bigint7biguint14multiplicationsX_0pENtB8_7BigUintINtNtNtNtCsbQ8arDwx5Xq_4core4iter6traits5accum7ProductpE7productpEBa_
471
        }
472
    };
473
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-integer-0.1.46/src/average.rs
Line
Count
Source
1
use crate::Integer;
2
use core::ops::{BitAnd, BitOr, BitXor, Shr};
3
4
/// Provides methods to compute the average of two integers, without overflows.
5
pub trait Average: Integer {
6
    /// Returns the ceiling value of the average of `self` and `other`.
7
    /// -- `⌈(self + other)/2⌉`
8
    ///
9
    /// # Examples
10
    ///
11
    /// ```
12
    /// use num_integer::Average;
13
    ///
14
    /// assert_eq!(( 3).average_ceil(&10),  7);
15
    /// assert_eq!((-2).average_ceil(&-5), -3);
16
    /// assert_eq!(( 4).average_ceil(& 4),  4);
17
    ///
18
    /// assert_eq!(u8::max_value().average_ceil(&2), 129);
19
    /// assert_eq!(i8::min_value().average_ceil(&-1), -64);
20
    /// assert_eq!(i8::min_value().average_ceil(&i8::max_value()), 0);
21
    /// ```
22
    ///
23
    fn average_ceil(&self, other: &Self) -> Self;
24
25
    /// Returns the floor value of the average of `self` and `other`.
26
    /// -- `⌊(self + other)/2⌋`
27
    ///
28
    /// # Examples
29
    ///
30
    /// ```
31
    /// use num_integer::Average;
32
    ///
33
    /// assert_eq!(( 3).average_floor(&10),  6);
34
    /// assert_eq!((-2).average_floor(&-5), -4);
35
    /// assert_eq!(( 4).average_floor(& 4),  4);
36
    ///
37
    /// assert_eq!(u8::max_value().average_floor(&2), 128);
38
    /// assert_eq!(i8::min_value().average_floor(&-1), -65);
39
    /// assert_eq!(i8::min_value().average_floor(&i8::max_value()), -1);
40
    /// ```
41
    ///
42
    fn average_floor(&self, other: &Self) -> Self;
43
}
44
45
impl<I> Average for I
46
where
47
    I: Integer + Shr<usize, Output = I>,
48
    for<'a, 'b> &'a I:
49
        BitAnd<&'b I, Output = I> + BitOr<&'b I, Output = I> + BitXor<&'b I, Output = I>,
50
{
51
    // The Henry Gordon Dietz implementation as shown in the Hacker's Delight,
52
    // see http://aggregate.org/MAGIC/#Average%20of%20Integers
53
54
    /// Returns the floor value of the average of `self` and `other`.
55
    #[inline]
56
0
    fn average_floor(&self, other: &I) -> I {
57
0
        (self & other) + ((self ^ other) >> 1)
58
0
    }
59
60
    /// Returns the ceil value of the average of `self` and `other`.
61
    #[inline]
62
0
    fn average_ceil(&self, other: &I) -> I {
63
0
        (self | other) - ((self ^ other) >> 1)
64
0
    }
65
}
66
67
/// Returns the floor value of the average of `x` and `y` --
68
/// see [Average::average_floor](trait.Average.html#tymethod.average_floor).
69
#[inline]
70
0
pub fn average_floor<T: Average>(x: T, y: T) -> T {
71
0
    x.average_floor(&y)
72
0
}
73
/// Returns the ceiling value of the average of `x` and `y` --
74
/// see [Average::average_ceil](trait.Average.html#tymethod.average_ceil).
75
#[inline]
76
0
pub fn average_ceil<T: Average>(x: T, y: T) -> T {
77
0
    x.average_ceil(&y)
78
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-integer-0.1.46/src/lib.rs
Line
Count
Source
1
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2
// file at the top-level directory of this distribution and at
3
// http://rust-lang.org/COPYRIGHT.
4
//
5
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8
// option. This file may not be copied, modified, or distributed
9
// except according to those terms.
10
11
//! Integer trait and functions.
12
//!
13
//! ## Compatibility
14
//!
15
//! The `num-integer` crate is tested for rustc 1.31 and greater.
16
17
#![doc(html_root_url = "https://docs.rs/num-integer/0.1")]
18
#![no_std]
19
20
use core::mem;
21
use core::ops::Add;
22
23
use num_traits::{Num, Signed, Zero};
24
25
mod roots;
26
pub use crate::roots::Roots;
27
pub use crate::roots::{cbrt, nth_root, sqrt};
28
29
mod average;
30
pub use crate::average::Average;
31
pub use crate::average::{average_ceil, average_floor};
32
33
pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
34
    /// Floored integer division.
35
    ///
36
    /// # Examples
37
    ///
38
    /// ~~~
39
    /// # use num_integer::Integer;
40
    /// assert!(( 8).div_floor(& 3) ==  2);
41
    /// assert!(( 8).div_floor(&-3) == -3);
42
    /// assert!((-8).div_floor(& 3) == -3);
43
    /// assert!((-8).div_floor(&-3) ==  2);
44
    ///
45
    /// assert!(( 1).div_floor(& 2) ==  0);
46
    /// assert!(( 1).div_floor(&-2) == -1);
47
    /// assert!((-1).div_floor(& 2) == -1);
48
    /// assert!((-1).div_floor(&-2) ==  0);
49
    /// ~~~
50
    fn div_floor(&self, other: &Self) -> Self;
51
52
    /// Floored integer modulo, satisfying:
53
    ///
54
    /// ~~~
55
    /// # use num_integer::Integer;
56
    /// # let n = 1; let d = 1;
57
    /// assert!(n.div_floor(&d) * d + n.mod_floor(&d) == n)
58
    /// ~~~
59
    ///
60
    /// # Examples
61
    ///
62
    /// ~~~
63
    /// # use num_integer::Integer;
64
    /// assert!(( 8).mod_floor(& 3) ==  2);
65
    /// assert!(( 8).mod_floor(&-3) == -1);
66
    /// assert!((-8).mod_floor(& 3) ==  1);
67
    /// assert!((-8).mod_floor(&-3) == -2);
68
    ///
69
    /// assert!(( 1).mod_floor(& 2) ==  1);
70
    /// assert!(( 1).mod_floor(&-2) == -1);
71
    /// assert!((-1).mod_floor(& 2) ==  1);
72
    /// assert!((-1).mod_floor(&-2) == -1);
73
    /// ~~~
74
    fn mod_floor(&self, other: &Self) -> Self;
75
76
    /// Ceiled integer division.
77
    ///
78
    /// # Examples
79
    ///
80
    /// ~~~
81
    /// # use num_integer::Integer;
82
    /// assert_eq!(( 8).div_ceil( &3),  3);
83
    /// assert_eq!(( 8).div_ceil(&-3), -2);
84
    /// assert_eq!((-8).div_ceil( &3), -2);
85
    /// assert_eq!((-8).div_ceil(&-3),  3);
86
    ///
87
    /// assert_eq!(( 1).div_ceil( &2), 1);
88
    /// assert_eq!(( 1).div_ceil(&-2), 0);
89
    /// assert_eq!((-1).div_ceil( &2), 0);
90
    /// assert_eq!((-1).div_ceil(&-2), 1);
91
    /// ~~~
92
0
    fn div_ceil(&self, other: &Self) -> Self {
93
0
        let (q, r) = self.div_mod_floor(other);
94
0
        if r.is_zero() {
95
0
            q
96
        } else {
97
0
            q + Self::one()
98
        }
99
0
    }
100
101
    /// Greatest Common Divisor (GCD).
102
    ///
103
    /// # Examples
104
    ///
105
    /// ~~~
106
    /// # use num_integer::Integer;
107
    /// assert_eq!(6.gcd(&8), 2);
108
    /// assert_eq!(7.gcd(&3), 1);
109
    /// ~~~
110
    fn gcd(&self, other: &Self) -> Self;
111
112
    /// Lowest Common Multiple (LCM).
113
    ///
114
    /// # Examples
115
    ///
116
    /// ~~~
117
    /// # use num_integer::Integer;
118
    /// assert_eq!(7.lcm(&3), 21);
119
    /// assert_eq!(2.lcm(&4), 4);
120
    /// assert_eq!(0.lcm(&0), 0);
121
    /// ~~~
122
    fn lcm(&self, other: &Self) -> Self;
123
124
    /// Greatest Common Divisor (GCD) and
125
    /// Lowest Common Multiple (LCM) together.
126
    ///
127
    /// Potentially more efficient than calling `gcd` and `lcm`
128
    /// individually for identical inputs.
129
    ///
130
    /// # Examples
131
    ///
132
    /// ~~~
133
    /// # use num_integer::Integer;
134
    /// assert_eq!(10.gcd_lcm(&4), (2, 20));
135
    /// assert_eq!(8.gcd_lcm(&9), (1, 72));
136
    /// ~~~
137
    #[inline]
138
0
    fn gcd_lcm(&self, other: &Self) -> (Self, Self) {
139
0
        (self.gcd(other), self.lcm(other))
140
0
    }
141
142
    /// Greatest common divisor and Bézout coefficients.
143
    ///
144
    /// # Examples
145
    ///
146
    /// ~~~
147
    /// # fn main() {
148
    /// # use num_integer::{ExtendedGcd, Integer};
149
    /// # use num_traits::NumAssign;
150
    /// fn check<A: Copy + Integer + NumAssign>(a: A, b: A) -> bool {
151
    ///     let ExtendedGcd { gcd, x, y, .. } = a.extended_gcd(&b);
152
    ///     gcd == x * a + y * b
153
    /// }
154
    /// assert!(check(10isize, 4isize));
155
    /// assert!(check(8isize,  9isize));
156
    /// # }
157
    /// ~~~
158
    #[inline]
159
0
    fn extended_gcd(&self, other: &Self) -> ExtendedGcd<Self>
160
0
    where
161
0
        Self: Clone,
162
0
    {
163
0
        let mut s = (Self::zero(), Self::one());
164
0
        let mut t = (Self::one(), Self::zero());
165
0
        let mut r = (other.clone(), self.clone());
166
167
0
        while !r.0.is_zero() {
168
0
            let q = r.1.clone() / r.0.clone();
169
0
            let f = |mut r: (Self, Self)| {
170
0
                mem::swap(&mut r.0, &mut r.1);
171
0
                r.0 = r.0 - q.clone() * r.1.clone();
172
0
                r
173
0
            };
Unexecuted instantiation: _RNCNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B8_
Unexecuted instantiation: _RNCNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B8_
Unexecuted instantiation: _RNCNvYaNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
Unexecuted instantiation: _RNCNvYhNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
Unexecuted instantiation: _RNCNvYiNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
Unexecuted instantiation: _RNCNvYjNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
Unexecuted instantiation: _RNCNvYlNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
Unexecuted instantiation: _RNCNvYmNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
Unexecuted instantiation: _RNCNvYnNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
Unexecuted instantiation: _RNCNvYoNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
Unexecuted instantiation: _RNCNvYsNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
Unexecuted instantiation: _RNCNvYtNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
Unexecuted instantiation: _RNCNvYxNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
Unexecuted instantiation: _RNCNvYyNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcd0B7_
174
0
            r = f(r);
175
0
            s = f(s);
176
0
            t = f(t);
177
        }
178
179
0
        if r.1 >= Self::zero() {
180
0
            ExtendedGcd {
181
0
                gcd: r.1,
182
0
                x: s.1,
183
0
                y: t.1,
184
0
            }
185
        } else {
186
0
            ExtendedGcd {
187
0
                gcd: Self::zero() - r.1,
188
0
                x: Self::zero() - s.1,
189
0
                y: Self::zero() - t.1,
190
0
            }
191
        }
192
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB6_
Unexecuted instantiation: _RNvYaNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
Unexecuted instantiation: _RNvYhNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
Unexecuted instantiation: _RNvYiNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
Unexecuted instantiation: _RNvYjNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
Unexecuted instantiation: _RNvYlNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
Unexecuted instantiation: _RNvYmNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
Unexecuted instantiation: _RNvYnNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
Unexecuted instantiation: _RNvYoNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
Unexecuted instantiation: _RNvYsNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
Unexecuted instantiation: _RNvYtNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
Unexecuted instantiation: _RNvYxNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
Unexecuted instantiation: _RNvYyNtCsd1gRxjdwU23_11num_integer7Integer12extended_gcdB5_
193
194
    /// Greatest common divisor, least common multiple, and Bézout coefficients.
195
    #[inline]
196
0
    fn extended_gcd_lcm(&self, other: &Self) -> (ExtendedGcd<Self>, Self)
197
0
    where
198
0
        Self: Clone + Signed,
199
0
    {
200
0
        (self.extended_gcd(other), self.lcm(other))
201
0
    }
202
203
    /// Deprecated, use `is_multiple_of` instead.
204
    #[deprecated(note = "Please use is_multiple_of instead")]
205
    #[inline]
206
0
    fn divides(&self, other: &Self) -> bool {
207
0
        self.is_multiple_of(other)
208
0
    }
Unexecuted instantiation: _RNvYaNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
Unexecuted instantiation: _RNvYhNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
Unexecuted instantiation: _RNvYiNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
Unexecuted instantiation: _RNvYjNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
Unexecuted instantiation: _RNvYlNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
Unexecuted instantiation: _RNvYmNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
Unexecuted instantiation: _RNvYnNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
Unexecuted instantiation: _RNvYoNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
Unexecuted instantiation: _RNvYsNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
Unexecuted instantiation: _RNvYtNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
Unexecuted instantiation: _RNvYxNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
Unexecuted instantiation: _RNvYyNtCsd1gRxjdwU23_11num_integer7Integer7dividesB5_
209
210
    /// Returns `true` if `self` is a multiple of `other`.
211
    ///
212
    /// # Examples
213
    ///
214
    /// ~~~
215
    /// # use num_integer::Integer;
216
    /// assert_eq!(9.is_multiple_of(&3), true);
217
    /// assert_eq!(3.is_multiple_of(&9), false);
218
    /// ~~~
219
    fn is_multiple_of(&self, other: &Self) -> bool;
220
221
    /// Returns `true` if the number is even.
222
    ///
223
    /// # Examples
224
    ///
225
    /// ~~~
226
    /// # use num_integer::Integer;
227
    /// assert_eq!(3.is_even(), false);
228
    /// assert_eq!(4.is_even(), true);
229
    /// ~~~
230
    fn is_even(&self) -> bool;
231
232
    /// Returns `true` if the number is odd.
233
    ///
234
    /// # Examples
235
    ///
236
    /// ~~~
237
    /// # use num_integer::Integer;
238
    /// assert_eq!(3.is_odd(), true);
239
    /// assert_eq!(4.is_odd(), false);
240
    /// ~~~
241
    fn is_odd(&self) -> bool;
242
243
    /// Simultaneous truncated integer division and modulus.
244
    /// Returns `(quotient, remainder)`.
245
    ///
246
    /// # Examples
247
    ///
248
    /// ~~~
249
    /// # use num_integer::Integer;
250
    /// assert_eq!(( 8).div_rem( &3), ( 2,  2));
251
    /// assert_eq!(( 8).div_rem(&-3), (-2,  2));
252
    /// assert_eq!((-8).div_rem( &3), (-2, -2));
253
    /// assert_eq!((-8).div_rem(&-3), ( 2, -2));
254
    ///
255
    /// assert_eq!(( 1).div_rem( &2), ( 0,  1));
256
    /// assert_eq!(( 1).div_rem(&-2), ( 0,  1));
257
    /// assert_eq!((-1).div_rem( &2), ( 0, -1));
258
    /// assert_eq!((-1).div_rem(&-2), ( 0, -1));
259
    /// ~~~
260
    fn div_rem(&self, other: &Self) -> (Self, Self);
261
262
    /// Simultaneous floored integer division and modulus.
263
    /// Returns `(quotient, remainder)`.
264
    ///
265
    /// # Examples
266
    ///
267
    /// ~~~
268
    /// # use num_integer::Integer;
269
    /// assert_eq!(( 8).div_mod_floor( &3), ( 2,  2));
270
    /// assert_eq!(( 8).div_mod_floor(&-3), (-3, -1));
271
    /// assert_eq!((-8).div_mod_floor( &3), (-3,  1));
272
    /// assert_eq!((-8).div_mod_floor(&-3), ( 2, -2));
273
    ///
274
    /// assert_eq!(( 1).div_mod_floor( &2), ( 0,  1));
275
    /// assert_eq!(( 1).div_mod_floor(&-2), (-1, -1));
276
    /// assert_eq!((-1).div_mod_floor( &2), (-1,  1));
277
    /// assert_eq!((-1).div_mod_floor(&-2), ( 0, -1));
278
    /// ~~~
279
0
    fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
280
0
        (self.div_floor(other), self.mod_floor(other))
281
0
    }
Unexecuted instantiation: _RNvYhNtCsd1gRxjdwU23_11num_integer7Integer13div_mod_floorB5_
Unexecuted instantiation: _RNvYjNtCsd1gRxjdwU23_11num_integer7Integer13div_mod_floorB5_
Unexecuted instantiation: _RNvYmNtCsd1gRxjdwU23_11num_integer7Integer13div_mod_floorB5_
Unexecuted instantiation: _RNvYoNtCsd1gRxjdwU23_11num_integer7Integer13div_mod_floorB5_
Unexecuted instantiation: _RNvYtNtCsd1gRxjdwU23_11num_integer7Integer13div_mod_floorB5_
Unexecuted instantiation: _RNvYyNtCsd1gRxjdwU23_11num_integer7Integer13div_mod_floorB5_
282
283
    /// Rounds up to nearest multiple of argument.
284
    ///
285
    /// # Notes
286
    ///
287
    /// For signed types, `a.next_multiple_of(b) = a.prev_multiple_of(b.neg())`.
288
    ///
289
    /// # Examples
290
    ///
291
    /// ~~~
292
    /// # use num_integer::Integer;
293
    /// assert_eq!(( 16).next_multiple_of(& 8),  16);
294
    /// assert_eq!(( 23).next_multiple_of(& 8),  24);
295
    /// assert_eq!(( 16).next_multiple_of(&-8),  16);
296
    /// assert_eq!(( 23).next_multiple_of(&-8),  16);
297
    /// assert_eq!((-16).next_multiple_of(& 8), -16);
298
    /// assert_eq!((-23).next_multiple_of(& 8), -16);
299
    /// assert_eq!((-16).next_multiple_of(&-8), -16);
300
    /// assert_eq!((-23).next_multiple_of(&-8), -24);
301
    /// ~~~
302
    #[inline]
303
0
    fn next_multiple_of(&self, other: &Self) -> Self
304
0
    where
305
0
        Self: Clone,
306
0
    {
307
0
        let m = self.mod_floor(other);
308
0
        self.clone()
309
0
            + if m.is_zero() {
310
0
                Self::zero()
311
            } else {
312
0
                other.clone() - m
313
            }
314
0
    }
Unexecuted instantiation: _RNvYhNtCsd1gRxjdwU23_11num_integer7Integer16next_multiple_ofB5_
Unexecuted instantiation: _RNvYjNtCsd1gRxjdwU23_11num_integer7Integer16next_multiple_ofB5_
Unexecuted instantiation: _RNvYmNtCsd1gRxjdwU23_11num_integer7Integer16next_multiple_ofB5_
Unexecuted instantiation: _RNvYoNtCsd1gRxjdwU23_11num_integer7Integer16next_multiple_ofB5_
Unexecuted instantiation: _RNvYtNtCsd1gRxjdwU23_11num_integer7Integer16next_multiple_ofB5_
Unexecuted instantiation: _RNvYyNtCsd1gRxjdwU23_11num_integer7Integer16next_multiple_ofB5_
315
316
    /// Rounds down to nearest multiple of argument.
317
    ///
318
    /// # Notes
319
    ///
320
    /// For signed types, `a.prev_multiple_of(b) = a.next_multiple_of(b.neg())`.
321
    ///
322
    /// # Examples
323
    ///
324
    /// ~~~
325
    /// # use num_integer::Integer;
326
    /// assert_eq!(( 16).prev_multiple_of(& 8),  16);
327
    /// assert_eq!(( 23).prev_multiple_of(& 8),  16);
328
    /// assert_eq!(( 16).prev_multiple_of(&-8),  16);
329
    /// assert_eq!(( 23).prev_multiple_of(&-8),  24);
330
    /// assert_eq!((-16).prev_multiple_of(& 8), -16);
331
    /// assert_eq!((-23).prev_multiple_of(& 8), -24);
332
    /// assert_eq!((-16).prev_multiple_of(&-8), -16);
333
    /// assert_eq!((-23).prev_multiple_of(&-8), -16);
334
    /// ~~~
335
    #[inline]
336
0
    fn prev_multiple_of(&self, other: &Self) -> Self
337
0
    where
338
0
        Self: Clone,
339
0
    {
340
0
        self.clone() - self.mod_floor(other)
341
0
    }
Unexecuted instantiation: _RNvYhNtCsd1gRxjdwU23_11num_integer7Integer16prev_multiple_ofB5_
Unexecuted instantiation: _RNvYjNtCsd1gRxjdwU23_11num_integer7Integer16prev_multiple_ofB5_
Unexecuted instantiation: _RNvYmNtCsd1gRxjdwU23_11num_integer7Integer16prev_multiple_ofB5_
Unexecuted instantiation: _RNvYoNtCsd1gRxjdwU23_11num_integer7Integer16prev_multiple_ofB5_
Unexecuted instantiation: _RNvYtNtCsd1gRxjdwU23_11num_integer7Integer16prev_multiple_ofB5_
Unexecuted instantiation: _RNvYyNtCsd1gRxjdwU23_11num_integer7Integer16prev_multiple_ofB5_
342
343
    /// Decrements self by one.
344
    ///
345
    /// # Examples
346
    ///
347
    /// ~~~
348
    /// # use num_integer::Integer;
349
    /// let mut x: i32 = 43;
350
    /// x.dec();
351
    /// assert_eq!(x, 42);
352
    /// ~~~
353
0
    fn dec(&mut self)
354
0
    where
355
0
        Self: Clone,
356
0
    {
357
0
        *self = self.clone() - Self::one()
358
0
    }
Unexecuted instantiation: _RNvYaNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
Unexecuted instantiation: _RNvYhNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
Unexecuted instantiation: _RNvYiNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
Unexecuted instantiation: _RNvYjNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
Unexecuted instantiation: _RNvYlNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
Unexecuted instantiation: _RNvYmNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
Unexecuted instantiation: _RNvYnNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
Unexecuted instantiation: _RNvYoNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
Unexecuted instantiation: _RNvYsNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
Unexecuted instantiation: _RNvYtNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
Unexecuted instantiation: _RNvYxNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
Unexecuted instantiation: _RNvYyNtCsd1gRxjdwU23_11num_integer7Integer3decB5_
359
360
    /// Increments self by one.
361
    ///
362
    /// # Examples
363
    ///
364
    /// ~~~
365
    /// # use num_integer::Integer;
366
    /// let mut x: i32 = 41;
367
    /// x.inc();
368
    /// assert_eq!(x, 42);
369
    /// ~~~
370
0
    fn inc(&mut self)
371
0
    where
372
0
        Self: Clone,
373
0
    {
374
0
        *self = self.clone() + Self::one()
375
0
    }
Unexecuted instantiation: _RNvYaNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
Unexecuted instantiation: _RNvYhNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
Unexecuted instantiation: _RNvYiNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
Unexecuted instantiation: _RNvYjNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
Unexecuted instantiation: _RNvYlNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
Unexecuted instantiation: _RNvYmNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
Unexecuted instantiation: _RNvYnNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
Unexecuted instantiation: _RNvYoNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
Unexecuted instantiation: _RNvYsNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
Unexecuted instantiation: _RNvYtNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
Unexecuted instantiation: _RNvYxNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
Unexecuted instantiation: _RNvYyNtCsd1gRxjdwU23_11num_integer7Integer3incB5_
376
}
377
378
/// Greatest common divisor and Bézout coefficients
379
///
380
/// ```no_build
381
/// let e = isize::extended_gcd(a, b);
382
/// assert_eq!(e.gcd, e.x*a + e.y*b);
383
/// ```
384
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
385
pub struct ExtendedGcd<A> {
386
    pub gcd: A,
387
    pub x: A,
388
    pub y: A,
389
}
390
391
/// Simultaneous integer division and modulus
392
#[inline]
393
0
pub fn div_rem<T: Integer>(x: T, y: T) -> (T, T) {
394
0
    x.div_rem(&y)
395
0
}
396
/// Floored integer division
397
#[inline]
398
0
pub fn div_floor<T: Integer>(x: T, y: T) -> T {
399
0
    x.div_floor(&y)
400
0
}
401
/// Floored integer modulus
402
#[inline]
403
0
pub fn mod_floor<T: Integer>(x: T, y: T) -> T {
404
0
    x.mod_floor(&y)
405
0
}
406
/// Simultaneous floored integer division and modulus
407
#[inline]
408
0
pub fn div_mod_floor<T: Integer>(x: T, y: T) -> (T, T) {
409
0
    x.div_mod_floor(&y)
410
0
}
411
/// Ceiled integer division
412
#[inline]
413
0
pub fn div_ceil<T: Integer>(x: T, y: T) -> T {
414
0
    x.div_ceil(&y)
415
0
}
416
417
/// Calculates the Greatest Common Divisor (GCD) of the number and `other`. The
418
/// result is always non-negative.
419
#[inline(always)]
420
0
pub fn gcd<T: Integer>(x: T, y: T) -> T {
421
0
    x.gcd(&y)
422
0
}
423
/// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
424
#[inline(always)]
425
0
pub fn lcm<T: Integer>(x: T, y: T) -> T {
426
0
    x.lcm(&y)
427
0
}
428
429
/// Calculates the Greatest Common Divisor (GCD) and
430
/// Lowest Common Multiple (LCM) of the number and `other`.
431
#[inline(always)]
432
0
pub fn gcd_lcm<T: Integer>(x: T, y: T) -> (T, T) {
433
0
    x.gcd_lcm(&y)
434
0
}
435
436
macro_rules! impl_integer_for_isize {
437
    ($T:ty, $test_mod:ident) => {
438
        impl Integer for $T {
439
            /// Floored integer division
440
            #[inline]
441
0
            fn div_floor(&self, other: &Self) -> Self {
442
0
                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
443
0
                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
444
0
                let (d, r) = self.div_rem(other);
445
0
                if (r > 0 && *other < 0) || (r < 0 && *other > 0) {
446
0
                    d - 1
447
                } else {
448
0
                    d
449
                }
450
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer9div_floorB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer9div_floorB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer9div_floorB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer9div_floorB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer9div_floorB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer9div_floorB5_
451
452
            /// Floored integer modulo
453
            #[inline]
454
0
            fn mod_floor(&self, other: &Self) -> Self {
455
0
                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
456
0
                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
457
0
                let r = *self % *other;
458
0
                if (r > 0 && *other < 0) || (r < 0 && *other > 0) {
459
0
                    r + *other
460
                } else {
461
0
                    r
462
                }
463
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer9mod_floorB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer9mod_floorB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer9mod_floorB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer9mod_floorB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer9mod_floorB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer9mod_floorB5_
464
465
            /// Calculates `div_floor` and `mod_floor` simultaneously
466
            #[inline]
467
0
            fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
468
0
                // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
469
0
                // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
470
0
                let (d, r) = self.div_rem(other);
471
0
                if (r > 0 && *other < 0) || (r < 0 && *other > 0) {
472
0
                    (d - 1, r + *other)
473
                } else {
474
0
                    (d, r)
475
                }
476
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer13div_mod_floorB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer13div_mod_floorB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer13div_mod_floorB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer13div_mod_floorB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer13div_mod_floorB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer13div_mod_floorB5_
477
478
            #[inline]
479
0
            fn div_ceil(&self, other: &Self) -> Self {
480
0
                let (d, r) = self.div_rem(other);
481
0
                if (r > 0 && *other > 0) || (r < 0 && *other < 0) {
482
0
                    d + 1
483
                } else {
484
0
                    d
485
                }
486
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer8div_ceilB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer8div_ceilB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer8div_ceilB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer8div_ceilB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer8div_ceilB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer8div_ceilB5_
487
488
            /// Calculates the Greatest Common Divisor (GCD) of the number and
489
            /// `other`. The result is always non-negative.
490
            #[inline]
491
0
            fn gcd(&self, other: &Self) -> Self {
492
0
                // Use Stein's algorithm
493
0
                let mut m = *self;
494
0
                let mut n = *other;
495
0
                if m == 0 || n == 0 {
496
0
                    return (m | n).abs();
497
0
                }
498
0
499
0
                // find common factors of 2
500
0
                let shift = (m | n).trailing_zeros();
501
0
502
0
                // The algorithm needs positive numbers, but the minimum value
503
0
                // can't be represented as a positive one.
504
0
                // It's also a power of two, so the gcd can be
505
0
                // calculated by bitshifting in that case
506
0
507
0
                // Assuming two's complement, the number created by the shift
508
0
                // is positive for all numbers except gcd = abs(min value)
509
0
                // The call to .abs() causes a panic in debug mode
510
0
                if m == Self::min_value() || n == Self::min_value() {
511
0
                    return (1 << shift).abs();
512
0
                }
513
0
514
0
                // guaranteed to be positive now, rest like unsigned algorithm
515
0
                m = m.abs();
516
0
                n = n.abs();
517
0
518
0
                // divide n and m by 2 until odd
519
0
                m >>= m.trailing_zeros();
520
0
                n >>= n.trailing_zeros();
521
522
0
                while m != n {
523
0
                    if m > n {
524
0
                        m -= n;
525
0
                        m >>= m.trailing_zeros();
526
0
                    } else {
527
0
                        n -= m;
528
0
                        n >>= n.trailing_zeros();
529
0
                    }
530
                }
531
0
                m << shift
532
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer3gcdB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer3gcdB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer3gcdB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer3gcdB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer3gcdB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer3gcdB5_
533
534
            #[inline]
535
0
            fn extended_gcd_lcm(&self, other: &Self) -> (ExtendedGcd<Self>, Self) {
536
0
                let egcd = self.extended_gcd(other);
537
                // should not have to recalculate abs
538
0
                let lcm = if egcd.gcd.is_zero() {
539
0
                    Self::zero()
540
                } else {
541
0
                    (*self * (*other / egcd.gcd)).abs()
542
                };
543
0
                (egcd, lcm)
544
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer16extended_gcd_lcmB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer16extended_gcd_lcmB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer16extended_gcd_lcmB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer16extended_gcd_lcmB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer16extended_gcd_lcmB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer16extended_gcd_lcmB5_
545
546
            /// Calculates the Lowest Common Multiple (LCM) of the number and
547
            /// `other`.
548
            #[inline]
549
0
            fn lcm(&self, other: &Self) -> Self {
550
0
                self.gcd_lcm(other).1
551
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer3lcmB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer3lcmB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer3lcmB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer3lcmB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer3lcmB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer3lcmB5_
552
553
            /// Calculates the Greatest Common Divisor (GCD) and
554
            /// Lowest Common Multiple (LCM) of the number and `other`.
555
            #[inline]
556
0
            fn gcd_lcm(&self, other: &Self) -> (Self, Self) {
557
0
                if self.is_zero() && other.is_zero() {
558
0
                    return (Self::zero(), Self::zero());
559
0
                }
560
0
                let gcd = self.gcd(other);
561
0
                // should not have to recalculate abs
562
0
                let lcm = (*self * (*other / gcd)).abs();
563
0
                (gcd, lcm)
564
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer7gcd_lcmB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer7gcd_lcmB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer7gcd_lcmB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer7gcd_lcmB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer7gcd_lcmB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer7gcd_lcmB5_
565
566
            /// Returns `true` if the number is a multiple of `other`.
567
            #[inline]
568
0
            fn is_multiple_of(&self, other: &Self) -> bool {
569
0
                if other.is_zero() {
570
0
                    return self.is_zero();
571
0
                }
572
0
                *self % *other == 0
573
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer14is_multiple_ofB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer14is_multiple_ofB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer14is_multiple_ofB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer14is_multiple_ofB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer14is_multiple_ofB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer14is_multiple_ofB5_
574
575
            /// Returns `true` if the number is divisible by `2`
576
            #[inline]
577
0
            fn is_even(&self) -> bool {
578
0
                (*self) & 1 == 0
579
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer7is_evenB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer7is_evenB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer7is_evenB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer7is_evenB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer7is_evenB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer7is_evenB5_
580
581
            /// Returns `true` if the number is not divisible by `2`
582
            #[inline]
583
0
            fn is_odd(&self) -> bool {
584
0
                !self.is_even()
585
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer6is_oddB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer6is_oddB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer6is_oddB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer6is_oddB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer6is_oddB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer6is_oddB5_
586
587
            /// Simultaneous truncated integer division and modulus.
588
            #[inline]
589
0
            fn div_rem(&self, other: &Self) -> (Self, Self) {
590
0
                (*self / *other, *self % *other)
591
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer7div_remB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer7div_remB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer7div_remB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer7div_remB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer7div_remB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer7div_remB5_
592
593
            /// Rounds up to nearest multiple of argument.
594
            #[inline]
595
0
            fn next_multiple_of(&self, other: &Self) -> Self {
596
0
                // Avoid the overflow of `MIN % -1`
597
0
                if *other == -1 {
598
0
                    return *self;
599
0
                }
600
0
601
0
                let m = Integer::mod_floor(self, other);
602
0
                *self + if m == 0 { 0 } else { other - m }
603
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer16next_multiple_ofB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer16next_multiple_ofB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer16next_multiple_ofB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer16next_multiple_ofB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer16next_multiple_ofB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer16next_multiple_ofB5_
604
605
            /// Rounds down to nearest multiple of argument.
606
            #[inline]
607
0
            fn prev_multiple_of(&self, other: &Self) -> Self {
608
0
                // Avoid the overflow of `MIN % -1`
609
0
                if *other == -1 {
610
0
                    return *self;
611
0
                }
612
0
613
0
                *self - Integer::mod_floor(self, other)
614
0
            }
Unexecuted instantiation: _RNvXs6_Csd1gRxjdwU23_11num_integeraNtB5_7Integer16prev_multiple_ofB5_
Unexecuted instantiation: _RNvXs7_Csd1gRxjdwU23_11num_integersNtB5_7Integer16prev_multiple_ofB5_
Unexecuted instantiation: _RNvXs8_Csd1gRxjdwU23_11num_integerlNtB5_7Integer16prev_multiple_ofB5_
Unexecuted instantiation: _RNvXs9_Csd1gRxjdwU23_11num_integerxNtB5_7Integer16prev_multiple_ofB5_
Unexecuted instantiation: _RNvXsa_Csd1gRxjdwU23_11num_integernNtB5_7Integer16prev_multiple_ofB5_
Unexecuted instantiation: _RNvXsb_Csd1gRxjdwU23_11num_integeriNtB5_7Integer16prev_multiple_ofB5_
615
        }
616
617
        #[cfg(test)]
618
        mod $test_mod {
619
            use crate::Integer;
620
            use core::mem;
621
622
            /// Checks that the division rule holds for:
623
            ///
624
            /// - `n`: numerator (dividend)
625
            /// - `d`: denominator (divisor)
626
            /// - `qr`: quotient and remainder
627
            #[cfg(test)]
628
            fn test_division_rule((n, d): ($T, $T), (q, r): ($T, $T)) {
629
                assert_eq!(d * q + r, n);
630
            }
631
632
            #[test]
633
            fn test_div_rem() {
634
                fn test_nd_dr(nd: ($T, $T), qr: ($T, $T)) {
635
                    let (n, d) = nd;
636
                    let separate_div_rem = (n / d, n % d);
637
                    let combined_div_rem = n.div_rem(&d);
638
639
                    test_division_rule(nd, qr);
640
641
                    assert_eq!(separate_div_rem, qr);
642
                    assert_eq!(combined_div_rem, qr);
643
                }
644
645
                test_nd_dr((8, 3), (2, 2));
646
                test_nd_dr((8, -3), (-2, 2));
647
                test_nd_dr((-8, 3), (-2, -2));
648
                test_nd_dr((-8, -3), (2, -2));
649
650
                test_nd_dr((1, 2), (0, 1));
651
                test_nd_dr((1, -2), (0, 1));
652
                test_nd_dr((-1, 2), (0, -1));
653
                test_nd_dr((-1, -2), (0, -1));
654
            }
655
656
            #[test]
657
            fn test_div_mod_floor() {
658
                fn test_nd_dm(nd: ($T, $T), dm: ($T, $T)) {
659
                    let (n, d) = nd;
660
                    let separate_div_mod_floor =
661
                        (Integer::div_floor(&n, &d), Integer::mod_floor(&n, &d));
662
                    let combined_div_mod_floor = Integer::div_mod_floor(&n, &d);
663
664
                    test_division_rule(nd, dm);
665
666
                    assert_eq!(separate_div_mod_floor, dm);
667
                    assert_eq!(combined_div_mod_floor, dm);
668
                }
669
670
                test_nd_dm((8, 3), (2, 2));
671
                test_nd_dm((8, -3), (-3, -1));
672
                test_nd_dm((-8, 3), (-3, 1));
673
                test_nd_dm((-8, -3), (2, -2));
674
675
                test_nd_dm((1, 2), (0, 1));
676
                test_nd_dm((1, -2), (-1, -1));
677
                test_nd_dm((-1, 2), (-1, 1));
678
                test_nd_dm((-1, -2), (0, -1));
679
            }
680
681
            #[test]
682
            fn test_gcd() {
683
                assert_eq!((10 as $T).gcd(&2), 2 as $T);
684
                assert_eq!((10 as $T).gcd(&3), 1 as $T);
685
                assert_eq!((0 as $T).gcd(&3), 3 as $T);
686
                assert_eq!((3 as $T).gcd(&3), 3 as $T);
687
                assert_eq!((56 as $T).gcd(&42), 14 as $T);
688
                assert_eq!((3 as $T).gcd(&-3), 3 as $T);
689
                assert_eq!((-6 as $T).gcd(&3), 3 as $T);
690
                assert_eq!((-4 as $T).gcd(&-2), 2 as $T);
691
            }
692
693
            #[test]
694
            fn test_gcd_cmp_with_euclidean() {
695
                fn euclidean_gcd(mut m: $T, mut n: $T) -> $T {
696
                    while m != 0 {
697
                        mem::swap(&mut m, &mut n);
698
                        m %= n;
699
                    }
700
701
                    n.abs()
702
                }
703
704
                // gcd(-128, b) = 128 is not representable as positive value
705
                // for i8
706
                for i in -127..=127 {
707
                    for j in -127..=127 {
708
                        assert_eq!(euclidean_gcd(i, j), i.gcd(&j));
709
                    }
710
                }
711
            }
712
713
            #[test]
714
            fn test_gcd_min_val() {
715
                let min = <$T>::min_value();
716
                let max = <$T>::max_value();
717
                let max_pow2 = max / 2 + 1;
718
                assert_eq!(min.gcd(&max), 1 as $T);
719
                assert_eq!(max.gcd(&min), 1 as $T);
720
                assert_eq!(min.gcd(&max_pow2), max_pow2);
721
                assert_eq!(max_pow2.gcd(&min), max_pow2);
722
                assert_eq!(min.gcd(&42), 2 as $T);
723
                assert_eq!((42 as $T).gcd(&min), 2 as $T);
724
            }
725
726
            #[test]
727
            #[should_panic]
728
            fn test_gcd_min_val_min_val() {
729
                let min = <$T>::min_value();
730
                assert!(min.gcd(&min) >= 0);
731
            }
732
733
            #[test]
734
            #[should_panic]
735
            fn test_gcd_min_val_0() {
736
                let min = <$T>::min_value();
737
                assert!(min.gcd(&0) >= 0);
738
            }
739
740
            #[test]
741
            #[should_panic]
742
            fn test_gcd_0_min_val() {
743
                let min = <$T>::min_value();
744
                assert!((0 as $T).gcd(&min) >= 0);
745
            }
746
747
            #[test]
748
            fn test_lcm() {
749
                assert_eq!((1 as $T).lcm(&0), 0 as $T);
750
                assert_eq!((0 as $T).lcm(&1), 0 as $T);
751
                assert_eq!((1 as $T).lcm(&1), 1 as $T);
752
                assert_eq!((-1 as $T).lcm(&1), 1 as $T);
753
                assert_eq!((1 as $T).lcm(&-1), 1 as $T);
754
                assert_eq!((-1 as $T).lcm(&-1), 1 as $T);
755
                assert_eq!((8 as $T).lcm(&9), 72 as $T);
756
                assert_eq!((11 as $T).lcm(&5), 55 as $T);
757
            }
758
759
            #[test]
760
            fn test_gcd_lcm() {
761
                use core::iter::once;
762
                for i in once(0)
763
                    .chain((1..).take(127).flat_map(|a| once(a).chain(once(-a))))
764
                    .chain(once(-128))
765
                {
766
                    for j in once(0)
767
                        .chain((1..).take(127).flat_map(|a| once(a).chain(once(-a))))
768
                        .chain(once(-128))
769
                    {
770
                        assert_eq!(i.gcd_lcm(&j), (i.gcd(&j), i.lcm(&j)));
771
                    }
772
                }
773
            }
774
775
            #[test]
776
            fn test_extended_gcd_lcm() {
777
                use crate::ExtendedGcd;
778
                use core::fmt::Debug;
779
                use num_traits::NumAssign;
780
781
                fn check<A: Copy + Debug + Integer + NumAssign>(a: A, b: A) {
782
                    let ExtendedGcd { gcd, x, y, .. } = a.extended_gcd(&b);
783
                    assert_eq!(gcd, x * a + y * b);
784
                }
785
786
                use core::iter::once;
787
                for i in once(0)
788
                    .chain((1..).take(127).flat_map(|a| once(a).chain(once(-a))))
789
                    .chain(once(-128))
790
                {
791
                    for j in once(0)
792
                        .chain((1..).take(127).flat_map(|a| once(a).chain(once(-a))))
793
                        .chain(once(-128))
794
                    {
795
                        check(i, j);
796
                        let (ExtendedGcd { gcd, .. }, lcm) = i.extended_gcd_lcm(&j);
797
                        assert_eq!((gcd, lcm), (i.gcd(&j), i.lcm(&j)));
798
                    }
799
                }
800
            }
801
802
            #[test]
803
            fn test_even() {
804
                assert_eq!((-4 as $T).is_even(), true);
805
                assert_eq!((-3 as $T).is_even(), false);
806
                assert_eq!((-2 as $T).is_even(), true);
807
                assert_eq!((-1 as $T).is_even(), false);
808
                assert_eq!((0 as $T).is_even(), true);
809
                assert_eq!((1 as $T).is_even(), false);
810
                assert_eq!((2 as $T).is_even(), true);
811
                assert_eq!((3 as $T).is_even(), false);
812
                assert_eq!((4 as $T).is_even(), true);
813
            }
814
815
            #[test]
816
            fn test_odd() {
817
                assert_eq!((-4 as $T).is_odd(), false);
818
                assert_eq!((-3 as $T).is_odd(), true);
819
                assert_eq!((-2 as $T).is_odd(), false);
820
                assert_eq!((-1 as $T).is_odd(), true);
821
                assert_eq!((0 as $T).is_odd(), false);
822
                assert_eq!((1 as $T).is_odd(), true);
823
                assert_eq!((2 as $T).is_odd(), false);
824
                assert_eq!((3 as $T).is_odd(), true);
825
                assert_eq!((4 as $T).is_odd(), false);
826
            }
827
828
            #[test]
829
            fn test_multiple_of_one_limits() {
830
                for x in &[<$T>::min_value(), <$T>::max_value()] {
831
                    for one in &[1, -1] {
832
                        assert_eq!(Integer::next_multiple_of(x, one), *x);
833
                        assert_eq!(Integer::prev_multiple_of(x, one), *x);
834
                    }
835
                }
836
            }
837
        }
838
    };
839
}
840
841
impl_integer_for_isize!(i8, test_integer_i8);
842
impl_integer_for_isize!(i16, test_integer_i16);
843
impl_integer_for_isize!(i32, test_integer_i32);
844
impl_integer_for_isize!(i64, test_integer_i64);
845
impl_integer_for_isize!(i128, test_integer_i128);
846
impl_integer_for_isize!(isize, test_integer_isize);
847
848
macro_rules! impl_integer_for_usize {
849
    ($T:ty, $test_mod:ident) => {
850
        impl Integer for $T {
851
            /// Unsigned integer division. Returns the same result as `div` (`/`).
852
            #[inline]
853
0
            fn div_floor(&self, other: &Self) -> Self {
854
0
                *self / *other
855
0
            }
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer9div_floorB5_
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer9div_floorB5_
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer9div_floorB5_
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer9div_floorB5_
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer9div_floorB5_
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer9div_floorB5_
856
857
            /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
858
            #[inline]
859
0
            fn mod_floor(&self, other: &Self) -> Self {
860
0
                *self % *other
861
0
            }
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer9mod_floorB5_
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer9mod_floorB5_
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer9mod_floorB5_
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer9mod_floorB5_
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer9mod_floorB5_
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer9mod_floorB5_
862
863
            #[inline]
864
140k
            fn div_ceil(&self, other: &Self) -> Self {
865
140k
                *self / *other + (0 != *self % *other) as Self
866
140k
            }
_RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer8div_ceilCs72ekIXsOXFl_10num_bigint
Line
Count
Source
864
140k
            fn div_ceil(&self, other: &Self) -> Self {
865
140k
                *self / *other + (0 != *self % *other) as Self
866
140k
            }
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer8div_ceilB5_
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer8div_ceilB5_
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer8div_ceilB5_
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer8div_ceilB5_
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer8div_ceilB5_
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer8div_ceilB5_
867
868
            /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
869
            #[inline]
870
0
            fn gcd(&self, other: &Self) -> Self {
871
0
                // Use Stein's algorithm
872
0
                let mut m = *self;
873
0
                let mut n = *other;
874
0
                if m == 0 || n == 0 {
875
0
                    return m | n;
876
0
                }
877
0
878
0
                // find common factors of 2
879
0
                let shift = (m | n).trailing_zeros();
880
0
881
0
                // divide n and m by 2 until odd
882
0
                m >>= m.trailing_zeros();
883
0
                n >>= n.trailing_zeros();
884
885
0
                while m != n {
886
0
                    if m > n {
887
0
                        m -= n;
888
0
                        m >>= m.trailing_zeros();
889
0
                    } else {
890
0
                        n -= m;
891
0
                        n >>= n.trailing_zeros();
892
0
                    }
893
                }
894
0
                m << shift
895
0
            }
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer3gcdB5_
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer3gcdB5_
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer3gcdB5_
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer3gcdB5_
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer3gcdB5_
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer3gcdB5_
896
897
            #[inline]
898
0
            fn extended_gcd_lcm(&self, other: &Self) -> (ExtendedGcd<Self>, Self) {
899
0
                let egcd = self.extended_gcd(other);
900
                // should not have to recalculate abs
901
0
                let lcm = if egcd.gcd.is_zero() {
902
0
                    Self::zero()
903
                } else {
904
0
                    *self * (*other / egcd.gcd)
905
                };
906
0
                (egcd, lcm)
907
0
            }
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer16extended_gcd_lcmB5_
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer16extended_gcd_lcmB5_
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer16extended_gcd_lcmB5_
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer16extended_gcd_lcmB5_
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer16extended_gcd_lcmB5_
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer16extended_gcd_lcmB5_
908
909
            /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
910
            #[inline]
911
0
            fn lcm(&self, other: &Self) -> Self {
912
0
                self.gcd_lcm(other).1
913
0
            }
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer3lcmB5_
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer3lcmB5_
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer3lcmB5_
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer3lcmB5_
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer3lcmB5_
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer3lcmB5_
914
915
            /// Calculates the Greatest Common Divisor (GCD) and
916
            /// Lowest Common Multiple (LCM) of the number and `other`.
917
            #[inline]
918
0
            fn gcd_lcm(&self, other: &Self) -> (Self, Self) {
919
0
                if self.is_zero() && other.is_zero() {
920
0
                    return (Self::zero(), Self::zero());
921
0
                }
922
0
                let gcd = self.gcd(other);
923
0
                let lcm = *self * (*other / gcd);
924
0
                (gcd, lcm)
925
0
            }
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer7gcd_lcmB5_
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer7gcd_lcmB5_
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer7gcd_lcmB5_
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer7gcd_lcmB5_
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer7gcd_lcmB5_
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer7gcd_lcmB5_
926
927
            /// Returns `true` if the number is a multiple of `other`.
928
            #[inline]
929
0
            fn is_multiple_of(&self, other: &Self) -> bool {
930
0
                if other.is_zero() {
931
0
                    return self.is_zero();
932
0
                }
933
0
                *self % *other == 0
934
0
            }
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer14is_multiple_ofB5_
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer14is_multiple_ofB5_
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer14is_multiple_ofB5_
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer14is_multiple_ofB5_
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer14is_multiple_ofB5_
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer14is_multiple_ofB5_
935
936
            /// Returns `true` if the number is divisible by `2`.
937
            #[inline]
938
79.7k
            fn is_even(&self) -> bool {
939
79.7k
                *self % 2 == 0
940
79.7k
            }
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer7is_evenCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer7is_evenCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer7is_evenCs72ekIXsOXFl_10num_bigint
_RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer7is_evenCs72ekIXsOXFl_10num_bigint
Line
Count
Source
938
79.7k
            fn is_even(&self) -> bool {
939
79.7k
                *self % 2 == 0
940
79.7k
            }
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer7is_evenCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer7is_evenCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer7is_evenB5_
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer7is_evenB5_
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer7is_evenB5_
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer7is_evenB5_
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer7is_evenB5_
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer7is_evenB5_
941
942
            /// Returns `true` if the number is not divisible by `2`.
943
            #[inline]
944
64.1k
            fn is_odd(&self) -> bool {
945
64.1k
                !self.is_even()
946
64.1k
            }
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer6is_oddCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer6is_oddCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer6is_oddCs72ekIXsOXFl_10num_bigint
_RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer6is_oddCs72ekIXsOXFl_10num_bigint
Line
Count
Source
944
64.1k
            fn is_odd(&self) -> bool {
945
64.1k
                !self.is_even()
946
64.1k
            }
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer6is_oddCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer6is_oddCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer6is_oddB5_
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer6is_oddB5_
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer6is_oddB5_
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer6is_oddB5_
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer6is_oddB5_
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer6is_oddB5_
947
948
            /// Simultaneous truncated integer division and modulus.
949
            #[inline]
950
0
            fn div_rem(&self, other: &Self) -> (Self, Self) {
951
0
                (*self / *other, *self % *other)
952
0
            }
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer7div_remCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsc_Csd1gRxjdwU23_11num_integerhNtB5_7Integer7div_remB5_
Unexecuted instantiation: _RNvXsd_Csd1gRxjdwU23_11num_integertNtB5_7Integer7div_remB5_
Unexecuted instantiation: _RNvXse_Csd1gRxjdwU23_11num_integermNtB5_7Integer7div_remB5_
Unexecuted instantiation: _RNvXsf_Csd1gRxjdwU23_11num_integeryNtB5_7Integer7div_remB5_
Unexecuted instantiation: _RNvXsg_Csd1gRxjdwU23_11num_integeroNtB5_7Integer7div_remB5_
Unexecuted instantiation: _RNvXsh_Csd1gRxjdwU23_11num_integerjNtB5_7Integer7div_remB5_
953
        }
954
955
        #[cfg(test)]
956
        mod $test_mod {
957
            use crate::Integer;
958
            use core::mem;
959
960
            #[test]
961
            fn test_div_mod_floor() {
962
                assert_eq!(<$T as Integer>::div_floor(&10, &3), 3 as $T);
963
                assert_eq!(<$T as Integer>::mod_floor(&10, &3), 1 as $T);
964
                assert_eq!(<$T as Integer>::div_mod_floor(&10, &3), (3 as $T, 1 as $T));
965
                assert_eq!(<$T as Integer>::div_floor(&5, &5), 1 as $T);
966
                assert_eq!(<$T as Integer>::mod_floor(&5, &5), 0 as $T);
967
                assert_eq!(<$T as Integer>::div_mod_floor(&5, &5), (1 as $T, 0 as $T));
968
                assert_eq!(<$T as Integer>::div_floor(&3, &7), 0 as $T);
969
                assert_eq!(<$T as Integer>::div_floor(&3, &7), 0 as $T);
970
                assert_eq!(<$T as Integer>::mod_floor(&3, &7), 3 as $T);
971
                assert_eq!(<$T as Integer>::div_mod_floor(&3, &7), (0 as $T, 3 as $T));
972
            }
973
974
            #[test]
975
            fn test_gcd() {
976
                assert_eq!((10 as $T).gcd(&2), 2 as $T);
977
                assert_eq!((10 as $T).gcd(&3), 1 as $T);
978
                assert_eq!((0 as $T).gcd(&3), 3 as $T);
979
                assert_eq!((3 as $T).gcd(&3), 3 as $T);
980
                assert_eq!((56 as $T).gcd(&42), 14 as $T);
981
            }
982
983
            #[test]
984
            fn test_gcd_cmp_with_euclidean() {
985
                fn euclidean_gcd(mut m: $T, mut n: $T) -> $T {
986
                    while m != 0 {
987
                        mem::swap(&mut m, &mut n);
988
                        m %= n;
989
                    }
990
                    n
991
                }
992
993
                for i in 0..=255 {
994
                    for j in 0..=255 {
995
                        assert_eq!(euclidean_gcd(i, j), i.gcd(&j));
996
                    }
997
                }
998
            }
999
1000
            #[test]
1001
            fn test_lcm() {
1002
                assert_eq!((1 as $T).lcm(&0), 0 as $T);
1003
                assert_eq!((0 as $T).lcm(&1), 0 as $T);
1004
                assert_eq!((1 as $T).lcm(&1), 1 as $T);
1005
                assert_eq!((8 as $T).lcm(&9), 72 as $T);
1006
                assert_eq!((11 as $T).lcm(&5), 55 as $T);
1007
                assert_eq!((15 as $T).lcm(&17), 255 as $T);
1008
            }
1009
1010
            #[test]
1011
            fn test_gcd_lcm() {
1012
                for i in (0..).take(256) {
1013
                    for j in (0..).take(256) {
1014
                        assert_eq!(i.gcd_lcm(&j), (i.gcd(&j), i.lcm(&j)));
1015
                    }
1016
                }
1017
            }
1018
1019
            #[test]
1020
            fn test_is_multiple_of() {
1021
                assert!((0 as $T).is_multiple_of(&(0 as $T)));
1022
                assert!((6 as $T).is_multiple_of(&(6 as $T)));
1023
                assert!((6 as $T).is_multiple_of(&(3 as $T)));
1024
                assert!((6 as $T).is_multiple_of(&(1 as $T)));
1025
1026
                assert!(!(42 as $T).is_multiple_of(&(5 as $T)));
1027
                assert!(!(5 as $T).is_multiple_of(&(3 as $T)));
1028
                assert!(!(42 as $T).is_multiple_of(&(0 as $T)));
1029
            }
1030
1031
            #[test]
1032
            fn test_even() {
1033
                assert_eq!((0 as $T).is_even(), true);
1034
                assert_eq!((1 as $T).is_even(), false);
1035
                assert_eq!((2 as $T).is_even(), true);
1036
                assert_eq!((3 as $T).is_even(), false);
1037
                assert_eq!((4 as $T).is_even(), true);
1038
            }
1039
1040
            #[test]
1041
            fn test_odd() {
1042
                assert_eq!((0 as $T).is_odd(), false);
1043
                assert_eq!((1 as $T).is_odd(), true);
1044
                assert_eq!((2 as $T).is_odd(), false);
1045
                assert_eq!((3 as $T).is_odd(), true);
1046
                assert_eq!((4 as $T).is_odd(), false);
1047
            }
1048
        }
1049
    };
1050
}
1051
1052
impl_integer_for_usize!(u8, test_integer_u8);
1053
impl_integer_for_usize!(u16, test_integer_u16);
1054
impl_integer_for_usize!(u32, test_integer_u32);
1055
impl_integer_for_usize!(u64, test_integer_u64);
1056
impl_integer_for_usize!(u128, test_integer_u128);
1057
impl_integer_for_usize!(usize, test_integer_usize);
1058
1059
/// An iterator over binomial coefficients.
1060
pub struct IterBinomial<T> {
1061
    a: T,
1062
    n: T,
1063
    k: T,
1064
}
1065
1066
impl<T> IterBinomial<T>
1067
where
1068
    T: Integer,
1069
{
1070
    /// For a given n, iterate over all binomial coefficients binomial(n, k), for k=0...n.
1071
    ///
1072
    /// Note that this might overflow, depending on `T`. For the primitive
1073
    /// integer types, the following n are the largest ones for which there will
1074
    /// be no overflow:
1075
    ///
1076
    /// type | n
1077
    /// -----|---
1078
    /// u8   | 10
1079
    /// i8   |  9
1080
    /// u16  | 18
1081
    /// i16  | 17
1082
    /// u32  | 34
1083
    /// i32  | 33
1084
    /// u64  | 67
1085
    /// i64  | 66
1086
    ///
1087
    /// For larger n, `T` should be a bigint type.
1088
0
    pub fn new(n: T) -> IterBinomial<T> {
1089
0
        IterBinomial {
1090
0
            k: T::zero(),
1091
0
            a: T::one(),
1092
0
            n,
1093
0
        }
1094
0
    }
1095
}
1096
1097
impl<T> Iterator for IterBinomial<T>
1098
where
1099
    T: Integer + Clone,
1100
{
1101
    type Item = T;
1102
1103
0
    fn next(&mut self) -> Option<T> {
1104
0
        if self.k > self.n {
1105
0
            return None;
1106
0
        }
1107
0
        self.a = if !self.k.is_zero() {
1108
0
            multiply_and_divide(
1109
0
                self.a.clone(),
1110
0
                self.n.clone() - self.k.clone() + T::one(),
1111
0
                self.k.clone(),
1112
0
            )
1113
        } else {
1114
0
            T::one()
1115
        };
1116
0
        self.k = self.k.clone() + T::one();
1117
0
        Some(self.a.clone())
1118
0
    }
1119
}
1120
1121
/// Calculate r * a / b, avoiding overflows and fractions.
1122
///
1123
/// Assumes that b divides r * a evenly.
1124
0
fn multiply_and_divide<T: Integer + Clone>(r: T, a: T, b: T) -> T {
1125
0
    // See http://blog.plover.com/math/choose-2.html for the idea.
1126
0
    let g = gcd(r.clone(), b.clone());
1127
0
    r / g.clone() * (a / (b / g))
1128
0
}
1129
1130
/// Calculate the binomial coefficient.
1131
///
1132
/// Note that this might overflow, depending on `T`. For the primitive integer
1133
/// types, the following n are the largest ones possible such that there will
1134
/// be no overflow for any k:
1135
///
1136
/// type | n
1137
/// -----|---
1138
/// u8   | 10
1139
/// i8   |  9
1140
/// u16  | 18
1141
/// i16  | 17
1142
/// u32  | 34
1143
/// i32  | 33
1144
/// u64  | 67
1145
/// i64  | 66
1146
///
1147
/// For larger n, consider using a bigint type for `T`.
1148
0
pub fn binomial<T: Integer + Clone>(mut n: T, k: T) -> T {
1149
0
    // See http://blog.plover.com/math/choose.html for the idea.
1150
0
    if k > n {
1151
0
        return T::zero();
1152
0
    }
1153
0
    if k > n.clone() - k.clone() {
1154
0
        return binomial(n.clone(), n - k);
1155
0
    }
1156
0
    let mut r = T::one();
1157
0
    let mut d = T::one();
1158
    loop {
1159
0
        if d > k {
1160
0
            break;
1161
0
        }
1162
0
        r = multiply_and_divide(r, n.clone(), d.clone());
1163
0
        n = n - T::one();
1164
0
        d = d + T::one();
1165
    }
1166
0
    r
1167
0
}
1168
1169
/// Calculate the multinomial coefficient.
1170
0
pub fn multinomial<T: Integer + Clone>(k: &[T]) -> T
1171
0
where
1172
0
    for<'a> T: Add<&'a T, Output = T>,
1173
0
{
1174
0
    let mut r = T::one();
1175
0
    let mut p = T::zero();
1176
0
    for i in k {
1177
0
        p = p + i;
1178
0
        r = r * binomial(p.clone(), i.clone());
1179
0
    }
1180
0
    r
1181
0
}
1182
1183
#[test]
1184
fn test_lcm_overflow() {
1185
    macro_rules! check {
1186
        ($t:ty, $x:expr, $y:expr, $r:expr) => {{
1187
            let x: $t = $x;
1188
            let y: $t = $y;
1189
            let o = x.checked_mul(y);
1190
            assert!(
1191
                o.is_none(),
1192
                "sanity checking that {} input {} * {} overflows",
1193
                stringify!($t),
1194
                x,
1195
                y
1196
            );
1197
            assert_eq!(x.lcm(&y), $r);
1198
            assert_eq!(y.lcm(&x), $r);
1199
        }};
1200
    }
1201
1202
    // Original bug (Issue #166)
1203
    check!(i64, 46656000000000000, 600, 46656000000000000);
1204
1205
    check!(i8, 0x40, 0x04, 0x40);
1206
    check!(u8, 0x80, 0x02, 0x80);
1207
    check!(i16, 0x40_00, 0x04, 0x40_00);
1208
    check!(u16, 0x80_00, 0x02, 0x80_00);
1209
    check!(i32, 0x4000_0000, 0x04, 0x4000_0000);
1210
    check!(u32, 0x8000_0000, 0x02, 0x8000_0000);
1211
    check!(i64, 0x4000_0000_0000_0000, 0x04, 0x4000_0000_0000_0000);
1212
    check!(u64, 0x8000_0000_0000_0000, 0x02, 0x8000_0000_0000_0000);
1213
}
1214
1215
#[test]
1216
fn test_iter_binomial() {
1217
    macro_rules! check_simple {
1218
        ($t:ty) => {{
1219
            let n: $t = 3;
1220
            let expected = [1, 3, 3, 1];
1221
            for (b, &e) in IterBinomial::new(n).zip(&expected) {
1222
                assert_eq!(b, e);
1223
            }
1224
        }};
1225
    }
1226
1227
    check_simple!(u8);
1228
    check_simple!(i8);
1229
    check_simple!(u16);
1230
    check_simple!(i16);
1231
    check_simple!(u32);
1232
    check_simple!(i32);
1233
    check_simple!(u64);
1234
    check_simple!(i64);
1235
1236
    macro_rules! check_binomial {
1237
        ($t:ty, $n:expr) => {{
1238
            let n: $t = $n;
1239
            let mut k: $t = 0;
1240
            for b in IterBinomial::new(n) {
1241
                assert_eq!(b, binomial(n, k));
1242
                k += 1;
1243
            }
1244
        }};
1245
    }
1246
1247
    // Check the largest n for which there is no overflow.
1248
    check_binomial!(u8, 10);
1249
    check_binomial!(i8, 9);
1250
    check_binomial!(u16, 18);
1251
    check_binomial!(i16, 17);
1252
    check_binomial!(u32, 34);
1253
    check_binomial!(i32, 33);
1254
    check_binomial!(u64, 67);
1255
    check_binomial!(i64, 66);
1256
}
1257
1258
#[test]
1259
fn test_binomial() {
1260
    macro_rules! check {
1261
        ($t:ty, $x:expr, $y:expr, $r:expr) => {{
1262
            let x: $t = $x;
1263
            let y: $t = $y;
1264
            let expected: $t = $r;
1265
            assert_eq!(binomial(x, y), expected);
1266
            if y <= x {
1267
                assert_eq!(binomial(x, x - y), expected);
1268
            }
1269
        }};
1270
    }
1271
    check!(u8, 9, 4, 126);
1272
    check!(u8, 0, 0, 1);
1273
    check!(u8, 2, 3, 0);
1274
1275
    check!(i8, 9, 4, 126);
1276
    check!(i8, 0, 0, 1);
1277
    check!(i8, 2, 3, 0);
1278
1279
    check!(u16, 100, 2, 4950);
1280
    check!(u16, 14, 4, 1001);
1281
    check!(u16, 0, 0, 1);
1282
    check!(u16, 2, 3, 0);
1283
1284
    check!(i16, 100, 2, 4950);
1285
    check!(i16, 14, 4, 1001);
1286
    check!(i16, 0, 0, 1);
1287
    check!(i16, 2, 3, 0);
1288
1289
    check!(u32, 100, 2, 4950);
1290
    check!(u32, 35, 11, 417225900);
1291
    check!(u32, 14, 4, 1001);
1292
    check!(u32, 0, 0, 1);
1293
    check!(u32, 2, 3, 0);
1294
1295
    check!(i32, 100, 2, 4950);
1296
    check!(i32, 35, 11, 417225900);
1297
    check!(i32, 14, 4, 1001);
1298
    check!(i32, 0, 0, 1);
1299
    check!(i32, 2, 3, 0);
1300
1301
    check!(u64, 100, 2, 4950);
1302
    check!(u64, 35, 11, 417225900);
1303
    check!(u64, 14, 4, 1001);
1304
    check!(u64, 0, 0, 1);
1305
    check!(u64, 2, 3, 0);
1306
1307
    check!(i64, 100, 2, 4950);
1308
    check!(i64, 35, 11, 417225900);
1309
    check!(i64, 14, 4, 1001);
1310
    check!(i64, 0, 0, 1);
1311
    check!(i64, 2, 3, 0);
1312
}
1313
1314
#[test]
1315
fn test_multinomial() {
1316
    macro_rules! check_binomial {
1317
        ($t:ty, $k:expr) => {{
1318
            let n: $t = $k.iter().fold(0, |acc, &x| acc + x);
1319
            let k: &[$t] = $k;
1320
            assert_eq!(k.len(), 2);
1321
            assert_eq!(multinomial(k), binomial(n, k[0]));
1322
        }};
1323
    }
1324
1325
    check_binomial!(u8, &[4, 5]);
1326
1327
    check_binomial!(i8, &[4, 5]);
1328
1329
    check_binomial!(u16, &[2, 98]);
1330
    check_binomial!(u16, &[4, 10]);
1331
1332
    check_binomial!(i16, &[2, 98]);
1333
    check_binomial!(i16, &[4, 10]);
1334
1335
    check_binomial!(u32, &[2, 98]);
1336
    check_binomial!(u32, &[11, 24]);
1337
    check_binomial!(u32, &[4, 10]);
1338
1339
    check_binomial!(i32, &[2, 98]);
1340
    check_binomial!(i32, &[11, 24]);
1341
    check_binomial!(i32, &[4, 10]);
1342
1343
    check_binomial!(u64, &[2, 98]);
1344
    check_binomial!(u64, &[11, 24]);
1345
    check_binomial!(u64, &[4, 10]);
1346
1347
    check_binomial!(i64, &[2, 98]);
1348
    check_binomial!(i64, &[11, 24]);
1349
    check_binomial!(i64, &[4, 10]);
1350
1351
    macro_rules! check_multinomial {
1352
        ($t:ty, $k:expr, $r:expr) => {{
1353
            let k: &[$t] = $k;
1354
            let expected: $t = $r;
1355
            assert_eq!(multinomial(k), expected);
1356
        }};
1357
    }
1358
1359
    check_multinomial!(u8, &[2, 1, 2], 30);
1360
    check_multinomial!(u8, &[2, 3, 0], 10);
1361
1362
    check_multinomial!(i8, &[2, 1, 2], 30);
1363
    check_multinomial!(i8, &[2, 3, 0], 10);
1364
1365
    check_multinomial!(u16, &[2, 1, 2], 30);
1366
    check_multinomial!(u16, &[2, 3, 0], 10);
1367
1368
    check_multinomial!(i16, &[2, 1, 2], 30);
1369
    check_multinomial!(i16, &[2, 3, 0], 10);
1370
1371
    check_multinomial!(u32, &[2, 1, 2], 30);
1372
    check_multinomial!(u32, &[2, 3, 0], 10);
1373
1374
    check_multinomial!(i32, &[2, 1, 2], 30);
1375
    check_multinomial!(i32, &[2, 3, 0], 10);
1376
1377
    check_multinomial!(u64, &[2, 1, 2], 30);
1378
    check_multinomial!(u64, &[2, 3, 0], 10);
1379
1380
    check_multinomial!(i64, &[2, 1, 2], 30);
1381
    check_multinomial!(i64, &[2, 3, 0], 10);
1382
1383
    check_multinomial!(u64, &[], 1);
1384
    check_multinomial!(u64, &[0], 1);
1385
    check_multinomial!(u64, &[12345], 1);
1386
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-integer-0.1.46/src/roots.rs
Line
Count
Source
1
use crate::Integer;
2
use core::mem;
3
use num_traits::{checked_pow, PrimInt};
4
5
/// Provides methods to compute an integer's square root, cube root,
6
/// and arbitrary `n`th root.
7
pub trait Roots: Integer {
8
    /// Returns the truncated principal `n`th root of an integer
9
    /// -- `if x >= 0 { ⌊ⁿ√x⌋ } else { ⌈ⁿ√x⌉ }`
10
    ///
11
    /// This is solving for `r` in `rⁿ = x`, rounding toward zero.
12
    /// If `x` is positive, the result will satisfy `rⁿ ≤ x < (r+1)ⁿ`.
13
    /// If `x` is negative and `n` is odd, then `(r-1)ⁿ < x ≤ rⁿ`.
14
    ///
15
    /// # Panics
16
    ///
17
    /// Panics if `n` is zero:
18
    ///
19
    /// ```should_panic
20
    /// # use num_integer::Roots;
21
    /// println!("can't compute ⁰√x : {}", 123.nth_root(0));
22
    /// ```
23
    ///
24
    /// or if `n` is even and `self` is negative:
25
    ///
26
    /// ```should_panic
27
    /// # use num_integer::Roots;
28
    /// println!("no imaginary numbers... {}", (-1).nth_root(10));
29
    /// ```
30
    ///
31
    /// # Examples
32
    ///
33
    /// ```
34
    /// use num_integer::Roots;
35
    ///
36
    /// let x: i32 = 12345;
37
    /// assert_eq!(x.nth_root(1), x);
38
    /// assert_eq!(x.nth_root(2), x.sqrt());
39
    /// assert_eq!(x.nth_root(3), x.cbrt());
40
    /// assert_eq!(x.nth_root(4), 10);
41
    /// assert_eq!(x.nth_root(13), 2);
42
    /// assert_eq!(x.nth_root(14), 1);
43
    /// assert_eq!(x.nth_root(std::u32::MAX), 1);
44
    ///
45
    /// assert_eq!(std::i32::MAX.nth_root(30), 2);
46
    /// assert_eq!(std::i32::MAX.nth_root(31), 1);
47
    /// assert_eq!(std::i32::MIN.nth_root(31), -2);
48
    /// assert_eq!((std::i32::MIN + 1).nth_root(31), -1);
49
    ///
50
    /// assert_eq!(std::u32::MAX.nth_root(31), 2);
51
    /// assert_eq!(std::u32::MAX.nth_root(32), 1);
52
    /// ```
53
    fn nth_root(&self, n: u32) -> Self;
54
55
    /// Returns the truncated principal square root of an integer -- `⌊√x⌋`
56
    ///
57
    /// This is solving for `r` in `r² = x`, rounding toward zero.
58
    /// The result will satisfy `r² ≤ x < (r+1)²`.
59
    ///
60
    /// # Panics
61
    ///
62
    /// Panics if `self` is less than zero:
63
    ///
64
    /// ```should_panic
65
    /// # use num_integer::Roots;
66
    /// println!("no imaginary numbers... {}", (-1).sqrt());
67
    /// ```
68
    ///
69
    /// # Examples
70
    ///
71
    /// ```
72
    /// use num_integer::Roots;
73
    ///
74
    /// let x: i32 = 12345;
75
    /// assert_eq!((x * x).sqrt(), x);
76
    /// assert_eq!((x * x + 1).sqrt(), x);
77
    /// assert_eq!((x * x - 1).sqrt(), x - 1);
78
    /// ```
79
    #[inline]
80
0
    fn sqrt(&self) -> Self {
81
0
        self.nth_root(2)
82
0
    }
83
84
    /// Returns the truncated principal cube root of an integer --
85
    /// `if x >= 0 { ⌊∛x⌋ } else { ⌈∛x⌉ }`
86
    ///
87
    /// This is solving for `r` in `r³ = x`, rounding toward zero.
88
    /// If `x` is positive, the result will satisfy `r³ ≤ x < (r+1)³`.
89
    /// If `x` is negative, then `(r-1)³ < x ≤ r³`.
90
    ///
91
    /// # Examples
92
    ///
93
    /// ```
94
    /// use num_integer::Roots;
95
    ///
96
    /// let x: i32 = 1234;
97
    /// assert_eq!((x * x * x).cbrt(), x);
98
    /// assert_eq!((x * x * x + 1).cbrt(), x);
99
    /// assert_eq!((x * x * x - 1).cbrt(), x - 1);
100
    ///
101
    /// assert_eq!((-(x * x * x)).cbrt(), -x);
102
    /// assert_eq!((-(x * x * x + 1)).cbrt(), -x);
103
    /// assert_eq!((-(x * x * x - 1)).cbrt(), -(x - 1));
104
    /// ```
105
    #[inline]
106
0
    fn cbrt(&self) -> Self {
107
0
        self.nth_root(3)
108
0
    }
109
}
110
111
/// Returns the truncated principal square root of an integer --
112
/// see [Roots::sqrt](trait.Roots.html#method.sqrt).
113
#[inline]
114
0
pub fn sqrt<T: Roots>(x: T) -> T {
115
0
    x.sqrt()
116
0
}
117
118
/// Returns the truncated principal cube root of an integer --
119
/// see [Roots::cbrt](trait.Roots.html#method.cbrt).
120
#[inline]
121
0
pub fn cbrt<T: Roots>(x: T) -> T {
122
0
    x.cbrt()
123
0
}
124
125
/// Returns the truncated principal `n`th root of an integer --
126
/// see [Roots::nth_root](trait.Roots.html#tymethod.nth_root).
127
#[inline]
128
0
pub fn nth_root<T: Roots>(x: T, n: u32) -> T {
129
0
    x.nth_root(n)
130
0
}
131
132
macro_rules! signed_roots {
133
    ($T:ty, $U:ty) => {
134
        impl Roots for $T {
135
            #[inline]
136
0
            fn nth_root(&self, n: u32) -> Self {
137
0
                if *self >= 0 {
138
0
                    (*self as $U).nth_root(n) as Self
139
                } else {
140
0
                    assert!(n.is_odd(), "even roots of a negative are imaginary");
141
0
                    -((self.wrapping_neg() as $U).nth_root(n) as Self)
142
                }
143
0
            }
Unexecuted instantiation: _RNvXNtCsd1gRxjdwU23_11num_integer5rootsaNtB2_5Roots8nth_rootB4_
Unexecuted instantiation: _RNvXs_NtCsd1gRxjdwU23_11num_integer5rootssNtB4_5Roots8nth_rootB6_
Unexecuted instantiation: _RNvXs0_NtCsd1gRxjdwU23_11num_integer5rootslNtB5_5Roots8nth_rootB7_
Unexecuted instantiation: _RNvXs1_NtCsd1gRxjdwU23_11num_integer5rootsxNtB5_5Roots8nth_rootB7_
Unexecuted instantiation: _RNvXs2_NtCsd1gRxjdwU23_11num_integer5rootsnNtB5_5Roots8nth_rootB7_
Unexecuted instantiation: _RNvXs3_NtCsd1gRxjdwU23_11num_integer5rootsiNtB5_5Roots8nth_rootB7_
144
145
            #[inline]
146
0
            fn sqrt(&self) -> Self {
147
0
                assert!(*self >= 0, "the square root of a negative is imaginary");
148
0
                (*self as $U).sqrt() as Self
149
0
            }
Unexecuted instantiation: _RNvXNtCsd1gRxjdwU23_11num_integer5rootsaNtB2_5Roots4sqrtB4_
Unexecuted instantiation: _RNvXs_NtCsd1gRxjdwU23_11num_integer5rootssNtB4_5Roots4sqrtB6_
Unexecuted instantiation: _RNvXs0_NtCsd1gRxjdwU23_11num_integer5rootslNtB5_5Roots4sqrtB7_
Unexecuted instantiation: _RNvXs1_NtCsd1gRxjdwU23_11num_integer5rootsxNtB5_5Roots4sqrtB7_
Unexecuted instantiation: _RNvXs2_NtCsd1gRxjdwU23_11num_integer5rootsnNtB5_5Roots4sqrtB7_
Unexecuted instantiation: _RNvXs3_NtCsd1gRxjdwU23_11num_integer5rootsiNtB5_5Roots4sqrtB7_
150
151
            #[inline]
152
0
            fn cbrt(&self) -> Self {
153
0
                if *self >= 0 {
154
0
                    (*self as $U).cbrt() as Self
155
                } else {
156
0
                    -((self.wrapping_neg() as $U).cbrt() as Self)
157
                }
158
0
            }
Unexecuted instantiation: _RNvXNtCsd1gRxjdwU23_11num_integer5rootsaNtB2_5Roots4cbrtB4_
Unexecuted instantiation: _RNvXs_NtCsd1gRxjdwU23_11num_integer5rootssNtB4_5Roots4cbrtB6_
Unexecuted instantiation: _RNvXs0_NtCsd1gRxjdwU23_11num_integer5rootslNtB5_5Roots4cbrtB7_
Unexecuted instantiation: _RNvXs1_NtCsd1gRxjdwU23_11num_integer5rootsxNtB5_5Roots4cbrtB7_
Unexecuted instantiation: _RNvXs2_NtCsd1gRxjdwU23_11num_integer5rootsnNtB5_5Roots4cbrtB7_
Unexecuted instantiation: _RNvXs3_NtCsd1gRxjdwU23_11num_integer5rootsiNtB5_5Roots4cbrtB7_
159
        }
160
    };
161
}
162
163
signed_roots!(i8, u8);
164
signed_roots!(i16, u16);
165
signed_roots!(i32, u32);
166
signed_roots!(i64, u64);
167
signed_roots!(i128, u128);
168
signed_roots!(isize, usize);
169
170
#[inline]
171
0
fn fixpoint<T, F>(mut x: T, f: F) -> T
172
0
where
173
0
    T: Integer + Copy,
174
0
    F: Fn(T) -> T,
175
0
{
176
0
    let mut xn = f(x);
177
0
    while x < xn {
178
0
        x = xn;
179
0
        xn = f(x);
180
0
    }
181
0
    while x > xn {
182
0
        x = xn;
183
0
        xn = f(x);
184
0
    }
185
0
    x
186
0
}
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointhNCNvNvXs4_B2_hNtB2_5Roots4sqrt2go0EB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointhNCNvNvXs4_B2_hNtB2_5Roots8nth_root2go0EB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointjNCNvNvXs9_B2_jNtB2_5Roots4cbrt2go0EB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointjNCNvNvXs9_B2_jNtB2_5Roots4sqrt2go0EB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointjNCNvNvXs9_B2_jNtB2_5Roots8nth_root2go0EB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointmNCNvNvXs6_B2_mNtB2_5Roots4sqrt2go0EB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointmNCNvNvXs6_B2_mNtB2_5Roots8nth_root2go0EB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointtNCNvNvXs5_B2_tNtB2_5Roots4sqrt2go0EB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointtNCNvNvXs5_B2_tNtB2_5Roots8nth_root2go0EB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointyNCNvNvXs7_B2_yNtB2_5Roots4cbrt2go0EB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointyNCNvNvXs7_B2_yNtB2_5Roots4sqrt2go0EB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots8fixpointyNCNvNvXs7_B2_yNtB2_5Roots8nth_root2go0EB4_
187
188
#[inline]
189
0
fn bits<T>() -> u32 {
190
0
    8 * mem::size_of::<T>() as u32
191
0
}
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4bitshEB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4bitsjEB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4bitsmEB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4bitsoEB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4bitstEB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4bitsyEB4_
192
193
#[inline]
194
0
fn log2<T: PrimInt>(x: T) -> u32 {
195
0
    debug_assert!(x > T::zero());
196
0
    bits::<T>() - 1 - x.leading_zeros()
197
0
}
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4log2hEB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4log2jEB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4log2mEB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4log2oEB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4log2tEB4_
Unexecuted instantiation: _RINvNtCsd1gRxjdwU23_11num_integer5roots4log2yEB4_
198
199
macro_rules! unsigned_roots {
200
    ($T:ident) => {
201
        impl Roots for $T {
202
            #[inline]
203
0
            fn nth_root(&self, n: u32) -> Self {
204
0
                fn go(a: $T, n: u32) -> $T {
205
0
                    // Specialize small roots
206
0
                    match n {
207
0
                        0 => panic!("can't find a root of degree 0!"),
208
0
                        1 => return a,
209
0
                        2 => return a.sqrt(),
210
0
                        3 => return a.cbrt(),
211
0
                        _ => (),
212
0
                    }
213
0
214
0
                    // The root of values less than 2ⁿ can only be 0 or 1.
215
0
                    if bits::<$T>() <= n || a < (1 << n) {
216
0
                        return (a > 0) as $T;
217
0
                    }
218
0
219
0
                    if bits::<$T>() > 64 {
220
                        // 128-bit division is slow, so do a bitwise `nth_root` until it's small enough.
221
0
                        return if a <= core::u64::MAX as $T {
222
0
                            (a as u64).nth_root(n) as $T
223
                        } else {
224
0
                            let lo = (a >> n).nth_root(n) << 1;
225
0
                            let hi = lo + 1;
226
0
                            // 128-bit `checked_mul` also involves division, but we can't always
227
0
                            // compute `hiⁿ` without risking overflow.  Try to avoid it though...
228
0
                            if hi.next_power_of_two().trailing_zeros() * n >= bits::<$T>() {
229
0
                                match checked_pow(hi, n as usize) {
230
0
                                    Some(x) if x <= a => hi,
231
0
                                    _ => lo,
232
                                }
233
                            } else {
234
0
                                if hi.pow(n) <= a {
235
0
                                    hi
236
                                } else {
237
0
                                    lo
238
                                }
239
                            }
240
                        };
241
0
                    }
242
243
                    #[cfg(feature = "std")]
244
                    #[inline]
245
0
                    fn guess(x: $T, n: u32) -> $T {
246
0
                        // for smaller inputs, `f64` doesn't justify its cost.
247
0
                        if bits::<$T>() <= 32 || x <= core::u32::MAX as $T {
248
0
                            1 << ((log2(x) + n - 1) / n)
249
                        } else {
250
0
                            ((x as f64).ln() / f64::from(n)).exp() as $T
251
                        }
252
0
                    }
Unexecuted instantiation: _RNvNvNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB9_5Roots8nth_root2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB9_5Roots8nth_root2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB9_5Roots8nth_root2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB9_5Roots8nth_root2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB9_5Roots8nth_root2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB9_5Roots8nth_root2go5guessBb_
253
254
                    #[cfg(not(feature = "std"))]
255
                    #[inline]
256
                    fn guess(x: $T, n: u32) -> $T {
257
                        1 << ((log2(x) + n - 1) / n)
258
                    }
259
260
                    // https://en.wikipedia.org/wiki/Nth_root_algorithm
261
0
                    let n1 = n - 1;
262
0
                    let next = |x: $T| {
263
0
                        let y = match checked_pow(x, n1 as usize) {
264
0
                            Some(ax) => a / ax,
265
0
                            None => 0,
266
                        };
267
0
                        (y + x * n1 as $T) / n as $T
268
0
                    };
Unexecuted instantiation: _RNCNvNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB9_5Roots8nth_root2go0Bb_
Unexecuted instantiation: _RNCNvNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB9_5Roots8nth_root2go0Bb_
Unexecuted instantiation: _RNCNvNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB9_5Roots8nth_root2go0Bb_
Unexecuted instantiation: _RNCNvNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB9_5Roots8nth_root2go0Bb_
Unexecuted instantiation: _RNCNvNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB9_5Roots8nth_root2go0Bb_
Unexecuted instantiation: _RNCNvNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB9_5Roots8nth_root2go0Bb_
269
0
                    fixpoint(guess(a, n), next)
270
0
                }
Unexecuted instantiation: _RNvNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB7_5Roots8nth_root2go
Unexecuted instantiation: _RNvNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB7_5Roots8nth_root2go
Unexecuted instantiation: _RNvNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB7_5Roots8nth_root2go
Unexecuted instantiation: _RNvNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB7_5Roots8nth_root2go
Unexecuted instantiation: _RNvNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB7_5Roots8nth_root2go
Unexecuted instantiation: _RNvNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB7_5Roots8nth_root2go
271
0
                go(*self, n)
272
0
            }
Unexecuted instantiation: _RNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB5_5Roots8nth_rootCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB5_5Roots8nth_rootB7_
Unexecuted instantiation: _RNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB5_5Roots8nth_rootB7_
Unexecuted instantiation: _RNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB5_5Roots8nth_rootB7_
Unexecuted instantiation: _RNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB5_5Roots8nth_rootB7_
Unexecuted instantiation: _RNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB5_5Roots8nth_rootB7_
Unexecuted instantiation: _RNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB5_5Roots8nth_rootB7_
273
274
            #[inline]
275
0
            fn sqrt(&self) -> Self {
276
0
                fn go(a: $T) -> $T {
277
0
                    if bits::<$T>() > 64 {
278
                        // 128-bit division is slow, so do a bitwise `sqrt` until it's small enough.
279
0
                        return if a <= core::u64::MAX as $T {
280
0
                            (a as u64).sqrt() as $T
281
                        } else {
282
0
                            let lo = (a >> 2u32).sqrt() << 1;
283
0
                            let hi = lo + 1;
284
0
                            if hi * hi <= a {
285
0
                                hi
286
                            } else {
287
0
                                lo
288
                            }
289
                        };
290
0
                    }
291
0
292
0
                    if a < 4 {
293
0
                        return (a > 0) as $T;
294
0
                    }
295
296
                    #[cfg(feature = "std")]
297
                    #[inline]
298
0
                    fn guess(x: $T) -> $T {
299
0
                        (x as f64).sqrt() as $T
300
0
                    }
Unexecuted instantiation: _RNvNvNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB9_5Roots4sqrt2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB9_5Roots4sqrt2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB9_5Roots4sqrt2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB9_5Roots4sqrt2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB9_5Roots4sqrt2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB9_5Roots4sqrt2go5guessBb_
301
302
                    #[cfg(not(feature = "std"))]
303
                    #[inline]
304
                    fn guess(x: $T) -> $T {
305
                        1 << ((log2(x) + 1) / 2)
306
                    }
307
308
                    // https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
309
0
                    let next = |x: $T| (a / x + x) >> 1;
Unexecuted instantiation: _RNCNvNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB9_5Roots4sqrt2go0Bb_
Unexecuted instantiation: _RNCNvNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB9_5Roots4sqrt2go0Bb_
Unexecuted instantiation: _RNCNvNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB9_5Roots4sqrt2go0Bb_
Unexecuted instantiation: _RNCNvNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB9_5Roots4sqrt2go0Bb_
Unexecuted instantiation: _RNCNvNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB9_5Roots4sqrt2go0Bb_
Unexecuted instantiation: _RNCNvNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB9_5Roots4sqrt2go0Bb_
310
0
                    fixpoint(guess(a), next)
311
0
                }
Unexecuted instantiation: _RNvNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB7_5Roots4sqrt2go
Unexecuted instantiation: _RNvNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB7_5Roots4sqrt2go
Unexecuted instantiation: _RNvNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB7_5Roots4sqrt2go
Unexecuted instantiation: _RNvNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB7_5Roots4sqrt2go
Unexecuted instantiation: _RNvNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB7_5Roots4sqrt2go
Unexecuted instantiation: _RNvNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB7_5Roots4sqrt2go
312
0
                go(*self)
313
0
            }
Unexecuted instantiation: _RNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB5_5Roots4sqrtCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB5_5Roots4sqrtCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB5_5Roots4sqrtB7_
Unexecuted instantiation: _RNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB5_5Roots4sqrtB7_
Unexecuted instantiation: _RNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB5_5Roots4sqrtB7_
Unexecuted instantiation: _RNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB5_5Roots4sqrtB7_
Unexecuted instantiation: _RNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB5_5Roots4sqrtB7_
Unexecuted instantiation: _RNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB5_5Roots4sqrtB7_
314
315
            #[inline]
316
0
            fn cbrt(&self) -> Self {
317
0
                fn go(a: $T) -> $T {
318
0
                    if bits::<$T>() > 64 {
319
                        // 128-bit division is slow, so do a bitwise `cbrt` until it's small enough.
320
0
                        return if a <= core::u64::MAX as $T {
321
0
                            (a as u64).cbrt() as $T
322
                        } else {
323
0
                            let lo = (a >> 3u32).cbrt() << 1;
324
0
                            let hi = lo + 1;
325
0
                            if hi * hi * hi <= a {
326
0
                                hi
327
                            } else {
328
0
                                lo
329
                            }
330
                        };
331
0
                    }
332
0
333
0
                    if bits::<$T>() <= 32 {
334
                        // Implementation based on Hacker's Delight `icbrt2`
335
0
                        let mut x = a;
336
0
                        let mut y2 = 0;
337
0
                        let mut y = 0;
338
0
                        let smax = bits::<$T>() / 3;
339
0
                        for s in (0..smax + 1).rev() {
340
0
                            let s = s * 3;
341
0
                            y2 *= 4;
342
0
                            y *= 2;
343
0
                            let b = 3 * (y2 + y) + 1;
344
0
                            if x >> s >= b {
345
0
                                x -= b << s;
346
0
                                y2 += 2 * y + 1;
347
0
                                y += 1;
348
0
                            }
349
                        }
350
0
                        return y;
351
0
                    }
352
0
353
0
                    if a < 8 {
354
0
                        return (a > 0) as $T;
355
0
                    }
356
0
                    if a <= core::u32::MAX as $T {
357
0
                        return (a as u32).cbrt() as $T;
358
0
                    }
359
360
                    #[cfg(feature = "std")]
361
                    #[inline]
362
0
                    fn guess(x: $T) -> $T {
363
0
                        (x as f64).cbrt() as $T
364
0
                    }
Unexecuted instantiation: _RNvNvNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB9_5Roots4cbrt2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB9_5Roots4cbrt2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB9_5Roots4cbrt2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB9_5Roots4cbrt2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB9_5Roots4cbrt2go5guessBb_
Unexecuted instantiation: _RNvNvNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB9_5Roots4cbrt2go5guessBb_
365
366
                    #[cfg(not(feature = "std"))]
367
                    #[inline]
368
                    fn guess(x: $T) -> $T {
369
                        1 << ((log2(x) + 2) / 3)
370
                    }
371
372
                    // https://en.wikipedia.org/wiki/Cube_root#Numerical_methods
373
0
                    let next = |x: $T| (a / (x * x) + x * 2) / 3;
Unexecuted instantiation: _RNCNvNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB9_5Roots4cbrt2go0Bb_
Unexecuted instantiation: _RNCNvNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB9_5Roots4cbrt2go0Bb_
Unexecuted instantiation: _RNCNvNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB9_5Roots4cbrt2go0Bb_
Unexecuted instantiation: _RNCNvNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB9_5Roots4cbrt2go0Bb_
Unexecuted instantiation: _RNCNvNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB9_5Roots4cbrt2go0Bb_
Unexecuted instantiation: _RNCNvNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB9_5Roots4cbrt2go0Bb_
374
0
                    fixpoint(guess(a), next)
375
0
                }
Unexecuted instantiation: _RNvNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB7_5Roots4cbrt2go
Unexecuted instantiation: _RNvNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB7_5Roots4cbrt2go
Unexecuted instantiation: _RNvNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB7_5Roots4cbrt2go
Unexecuted instantiation: _RNvNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB7_5Roots4cbrt2go
Unexecuted instantiation: _RNvNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB7_5Roots4cbrt2go
Unexecuted instantiation: _RNvNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB7_5Roots4cbrt2go
376
0
                go(*self)
377
0
            }
Unexecuted instantiation: _RNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB5_5Roots4cbrtCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs4_NtCsd1gRxjdwU23_11num_integer5rootshNtB5_5Roots4cbrtB7_
Unexecuted instantiation: _RNvXs5_NtCsd1gRxjdwU23_11num_integer5rootstNtB5_5Roots4cbrtB7_
Unexecuted instantiation: _RNvXs6_NtCsd1gRxjdwU23_11num_integer5rootsmNtB5_5Roots4cbrtB7_
Unexecuted instantiation: _RNvXs7_NtCsd1gRxjdwU23_11num_integer5rootsyNtB5_5Roots4cbrtB7_
Unexecuted instantiation: _RNvXs8_NtCsd1gRxjdwU23_11num_integer5rootsoNtB5_5Roots4cbrtB7_
Unexecuted instantiation: _RNvXs9_NtCsd1gRxjdwU23_11num_integer5rootsjNtB5_5Roots4cbrtB7_
378
        }
379
    };
380
}
381
382
unsigned_roots!(u8);
383
unsigned_roots!(u16);
384
unsigned_roots!(u32);
385
unsigned_roots!(u64);
386
unsigned_roots!(u128);
387
unsigned_roots!(usize);
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/bounds.rs
Line
Count
Source
1
use core::num::Wrapping;
2
use core::{f32, f64};
3
use core::{i128, i16, i32, i64, i8, isize};
4
use core::{u128, u16, u32, u64, u8, usize};
5
6
/// Numbers which have upper and lower bounds
7
pub trait Bounded {
8
    // FIXME (#5527): These should be associated constants
9
    /// Returns the smallest finite number this type can represent
10
    fn min_value() -> Self;
11
    /// Returns the largest finite number this type can represent
12
    fn max_value() -> Self;
13
}
14
15
/// Numbers which have lower bounds
16
pub trait LowerBounded {
17
    /// Returns the smallest finite number this type can represent
18
    fn min_value() -> Self;
19
}
20
21
// FIXME: With a major version bump, this should be a supertrait instead
22
impl<T: Bounded> LowerBounded for T {
23
0
    fn min_value() -> T {
24
0
        Bounded::min_value()
25
0
    }
26
}
27
28
/// Numbers which have upper bounds
29
pub trait UpperBounded {
30
    /// Returns the largest finite number this type can represent
31
    fn max_value() -> Self;
32
}
33
34
// FIXME: With a major version bump, this should be a supertrait instead
35
impl<T: Bounded> UpperBounded for T {
36
0
    fn max_value() -> T {
37
0
        Bounded::max_value()
38
0
    }
39
}
40
41
macro_rules! bounded_impl {
42
    ($t:ty, $min:expr, $max:expr) => {
43
        impl Bounded for $t {
44
            #[inline]
45
0
            fn min_value() -> $t {
46
0
                $min
47
0
            }
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits6boundsjNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits6boundshNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits6boundstNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits6boundsmNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits6boundsyNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits6boundsoNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits6boundsiNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits6boundsaNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits6boundssNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits6boundslNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits6boundsxNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits6boundsnNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits6boundsfNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXsz_NtCs7cG3k8kmkqw_10num_traits6boundsdNtB5_7Bounded9min_valueB7_
48
49
            #[inline]
50
0
            fn max_value() -> $t {
51
0
                $max
52
0
            }
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits6boundsjNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits6boundshNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits6boundstNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits6boundsmNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits6boundsyNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits6boundsoNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits6boundsiNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits6boundsaNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits6boundssNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits6boundslNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits6boundsxNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits6boundsnNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits6boundsfNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXsz_NtCs7cG3k8kmkqw_10num_traits6boundsdNtB5_7Bounded9max_valueB7_
53
        }
54
    };
55
}
56
57
bounded_impl!(usize, usize::MIN, usize::MAX);
58
bounded_impl!(u8, u8::MIN, u8::MAX);
59
bounded_impl!(u16, u16::MIN, u16::MAX);
60
bounded_impl!(u32, u32::MIN, u32::MAX);
61
bounded_impl!(u64, u64::MIN, u64::MAX);
62
bounded_impl!(u128, u128::MIN, u128::MAX);
63
64
bounded_impl!(isize, isize::MIN, isize::MAX);
65
bounded_impl!(i8, i8::MIN, i8::MAX);
66
bounded_impl!(i16, i16::MIN, i16::MAX);
67
bounded_impl!(i32, i32::MIN, i32::MAX);
68
bounded_impl!(i64, i64::MIN, i64::MAX);
69
bounded_impl!(i128, i128::MIN, i128::MAX);
70
71
impl<T: Bounded> Bounded for Wrapping<T> {
72
0
    fn min_value() -> Self {
73
0
        Wrapping(T::min_value())
74
0
    }
75
0
    fn max_value() -> Self {
76
0
        Wrapping(T::max_value())
77
0
    }
78
}
79
80
bounded_impl!(f32, f32::MIN, f32::MAX);
81
82
macro_rules! for_each_tuple_ {
83
    ( $m:ident !! ) => (
84
        $m! { }
85
    );
86
    ( $m:ident !! $h:ident, $($t:ident,)* ) => (
87
        $m! { $h $($t)* }
88
        for_each_tuple_! { $m !! $($t,)* }
89
    );
90
}
91
macro_rules! for_each_tuple {
92
    ($m:ident) => {
93
        for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, }
94
    };
95
}
96
97
macro_rules! bounded_tuple {
98
    ( $($name:ident)* ) => (
99
        impl<$($name: Bounded,)*> Bounded for ($($name,)*) {
100
            #[inline]
101
0
            fn min_value() -> Self {
102
0
                ($($name::min_value(),)*)
103
0
            }
Unexecuted instantiation: _RNvXsy_NtCs7cG3k8kmkqw_10num_traits6boundsuNtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundsse_0ppppppppppppppppppppETppppppppppppppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssf_0pppppppppppppppppppETpppppppppppppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssg_0ppppppppppppppppppETppppppppppppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssh_0pppppppppppppppppETpppppppppppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssi_0ppppppppppppppppETppppppppppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssj_0pppppppppppppppETpppppppppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssk_0ppppppppppppppETppppppppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssl_0pppppppppppppETpppppppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssm_0ppppppppppppETppppppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssn_0pppppppppppETpppppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundsso_0ppppppppppETppppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssp_0pppppppppETpppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssq_0ppppppppETppppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssr_0pppppppETpppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundsss_0ppppppETppppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundsst_0pppppETpppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssu_0ppppETppppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssv_0pppETpppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssw_0ppETppENtB5_7Bounded9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssx_0pETpENtB5_7Bounded9min_valueB7_
104
            #[inline]
105
0
            fn max_value() -> Self {
106
0
                ($($name::max_value(),)*)
107
0
            }
Unexecuted instantiation: _RNvXsy_NtCs7cG3k8kmkqw_10num_traits6boundsuNtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundsse_0ppppppppppppppppppppETppppppppppppppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssf_0pppppppppppppppppppETpppppppppppppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssg_0ppppppppppppppppppETppppppppppppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssh_0pppppppppppppppppETpppppppppppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssi_0ppppppppppppppppETppppppppppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssj_0pppppppppppppppETpppppppppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssk_0ppppppppppppppETppppppppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssl_0pppppppppppppETpppppppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssm_0ppppppppppppETppppppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssn_0pppppppppppETpppppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundsso_0ppppppppppETppppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssp_0pppppppppETpppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssq_0ppppppppETppppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssr_0pppppppETpppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundsss_0ppppppETppppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundsst_0pppppETpppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssu_0ppppETppppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssv_0pppETpppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssw_0ppETppENtB5_7Bounded9max_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits6boundssx_0pETpENtB5_7Bounded9max_valueB7_
108
        }
109
    );
110
}
111
112
for_each_tuple!(bounded_tuple);
113
bounded_impl!(f64, f64::MIN, f64::MAX);
114
115
#[test]
116
fn wrapping_bounded() {
117
    macro_rules! test_wrapping_bounded {
118
        ($($t:ty)+) => {
119
            $(
120
                assert_eq!(<Wrapping<$t> as Bounded>::min_value().0, <$t>::min_value());
121
                assert_eq!(<Wrapping<$t> as Bounded>::max_value().0, <$t>::max_value());
122
            )+
123
        };
124
    }
125
126
    test_wrapping_bounded!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
127
}
128
129
#[test]
130
fn wrapping_bounded_i128() {
131
    macro_rules! test_wrapping_bounded {
132
        ($($t:ty)+) => {
133
            $(
134
                assert_eq!(<Wrapping<$t> as Bounded>::min_value().0, <$t>::min_value());
135
                assert_eq!(<Wrapping<$t> as Bounded>::max_value().0, <$t>::max_value());
136
            )+
137
        };
138
    }
139
140
    test_wrapping_bounded!(u128 i128);
141
}
142
143
#[test]
144
fn wrapping_is_bounded() {
145
    fn require_bounded<T: Bounded>(_: &T) {}
146
    require_bounded(&Wrapping(42_u32));
147
    require_bounded(&Wrapping(-42));
148
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/cast.rs
Line
Count
Source
1
use core::mem::size_of;
2
use core::num::Wrapping;
3
use core::{f32, f64};
4
use core::{i128, i16, i32, i64, i8, isize};
5
use core::{u128, u16, u32, u64, u8, usize};
6
7
/// A generic trait for converting a value to a number.
8
///
9
/// A value can be represented by the target type when it lies within
10
/// the range of scalars supported by the target type.
11
/// For example, a negative integer cannot be represented by an unsigned
12
/// integer type, and an `i64` with a very high magnitude might not be
13
/// convertible to an `i32`.
14
/// On the other hand, conversions with possible precision loss or truncation
15
/// are admitted, like an `f32` with a decimal part to an integer type, or
16
/// even a large `f64` saturating to `f32` infinity.
17
pub trait ToPrimitive {
18
    /// Converts the value of `self` to an `isize`. If the value cannot be
19
    /// represented by an `isize`, then `None` is returned.
20
    #[inline]
21
0
    fn to_isize(&self) -> Option<isize> {
22
0
        self.to_i64().as_ref().and_then(ToPrimitive::to_isize)
23
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive8to_isizeB6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive8to_isizeB6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive8to_isizeB7_
24
25
    /// Converts the value of `self` to an `i8`. If the value cannot be
26
    /// represented by an `i8`, then `None` is returned.
27
    #[inline]
28
0
    fn to_i8(&self) -> Option<i8> {
29
0
        self.to_i64().as_ref().and_then(ToPrimitive::to_i8)
30
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive5to_i8B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive5to_i8B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive5to_i8B7_
31
32
    /// Converts the value of `self` to an `i16`. If the value cannot be
33
    /// represented by an `i16`, then `None` is returned.
34
    #[inline]
35
0
    fn to_i16(&self) -> Option<i16> {
36
0
        self.to_i64().as_ref().and_then(ToPrimitive::to_i16)
37
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_i16B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_i16B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_i16B7_
38
39
    /// Converts the value of `self` to an `i32`. If the value cannot be
40
    /// represented by an `i32`, then `None` is returned.
41
    #[inline]
42
0
    fn to_i32(&self) -> Option<i32> {
43
0
        self.to_i64().as_ref().and_then(ToPrimitive::to_i32)
44
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_i32B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_i32B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_i32B7_
45
46
    /// Converts the value of `self` to an `i64`. If the value cannot be
47
    /// represented by an `i64`, then `None` is returned.
48
    fn to_i64(&self) -> Option<i64>;
49
50
    /// Converts the value of `self` to an `i128`. If the value cannot be
51
    /// represented by an `i128` (`i64` under the default implementation), then
52
    /// `None` is returned.
53
    ///
54
    /// The default implementation converts through `to_i64()`. Types implementing
55
    /// this trait should override this method if they can represent a greater range.
56
    #[inline]
57
0
    fn to_i128(&self) -> Option<i128> {
58
0
        self.to_i64().map(From::from)
59
0
    }
60
61
    /// Converts the value of `self` to a `usize`. If the value cannot be
62
    /// represented by a `usize`, then `None` is returned.
63
    #[inline]
64
0
    fn to_usize(&self) -> Option<usize> {
65
0
        self.to_u64().as_ref().and_then(ToPrimitive::to_usize)
66
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive8to_usizeB6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive8to_usizeB6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive8to_usizeB7_
67
68
    /// Converts the value of `self` to a `u8`. If the value cannot be
69
    /// represented by a `u8`, then `None` is returned.
70
    #[inline]
71
0
    fn to_u8(&self) -> Option<u8> {
72
0
        self.to_u64().as_ref().and_then(ToPrimitive::to_u8)
73
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive5to_u8B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive5to_u8B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive5to_u8B7_
74
75
    /// Converts the value of `self` to a `u16`. If the value cannot be
76
    /// represented by a `u16`, then `None` is returned.
77
    #[inline]
78
0
    fn to_u16(&self) -> Option<u16> {
79
0
        self.to_u64().as_ref().and_then(ToPrimitive::to_u16)
80
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_u16B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_u16B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_u16B7_
81
82
    /// Converts the value of `self` to a `u32`. If the value cannot be
83
    /// represented by a `u32`, then `None` is returned.
84
    #[inline]
85
509k
    fn to_u32(&self) -> Option<u32> {
86
509k
        self.to_u64().as_ref().and_then(ToPrimitive::to_u32)
87
509k
    }
_RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_u32Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
85
353k
    fn to_u32(&self) -> Option<u32> {
86
353k
        self.to_u64().as_ref().and_then(ToPrimitive::to_u32)
87
353k
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_u32B6_
_RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_u32B6_
Line
Count
Source
85
155k
    fn to_u32(&self) -> Option<u32> {
86
155k
        self.to_u64().as_ref().and_then(ToPrimitive::to_u32)
87
155k
    }
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast11ToPrimitive6to_u32B7_
88
89
    /// Converts the value of `self` to a `u64`. If the value cannot be
90
    /// represented by a `u64`, then `None` is returned.
91
    fn to_u64(&self) -> Option<u64>;
92
93
    /// Converts the value of `self` to a `u128`. If the value cannot be
94
    /// represented by a `u128` (`u64` under the default implementation), then
95
    /// `None` is returned.
96
    ///
97
    /// The default implementation converts through `to_u64()`. Types implementing
98
    /// this trait should override this method if they can represent a greater range.
99
    #[inline]
100
0
    fn to_u128(&self) -> Option<u128> {
101
0
        self.to_u64().map(From::from)
102
0
    }
103
104
    /// Converts the value of `self` to an `f32`. Overflows may map to positive
105
    /// or negative inifinity, otherwise `None` is returned if the value cannot
106
    /// be represented by an `f32`.
107
    #[inline]
108
0
    fn to_f32(&self) -> Option<f32> {
109
0
        self.to_f64().as_ref().and_then(ToPrimitive::to_f32)
110
0
    }
111
112
    /// Converts the value of `self` to an `f64`. Overflows may map to positive
113
    /// or negative inifinity, otherwise `None` is returned if the value cannot
114
    /// be represented by an `f64`.
115
    ///
116
    /// The default implementation tries to convert through `to_i64()`, and
117
    /// failing that through `to_u64()`. Types implementing this trait should
118
    /// override this method if they can represent a greater range.
119
    #[inline]
120
0
    fn to_f64(&self) -> Option<f64> {
121
0
        match self.to_i64() {
122
0
            Some(i) => i.to_f64(),
123
0
            None => self.to_u64().as_ref().and_then(ToPrimitive::to_f64),
124
        }
125
0
    }
126
}
127
128
macro_rules! impl_to_primitive_int_to_int {
129
    ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
130
        #[inline]
131
        $(#[$cfg])*
132
0
        fn $method(&self) -> Option<$DstT> {
133
0
            let min = $DstT::MIN as $SrcT;
134
0
            let max = $DstT::MAX as $SrcT;
135
0
            if size_of::<$SrcT>() <= size_of::<$DstT>() || (min <= *self && *self <= max) {
136
0
                Some(*self as $DstT)
137
            } else {
138
0
                None
139
            }
140
0
        }
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive5to_i8Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive6to_i16Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive6to_i32Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive8to_isizeCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive6to_i64Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive7to_i128B7_
141
    )*}
142
}
143
144
macro_rules! impl_to_primitive_int_to_uint {
145
    ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
146
        #[inline]
147
        $(#[$cfg])*
148
83.8k
        fn $method(&self) -> Option<$DstT> {
149
83.8k
            let max = $DstT::MAX as $SrcT;
150
83.8k
            if 0 <= *self && (size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max) {
151
83.8k
                Some(*self as $DstT)
152
            } else {
153
0
                None
154
            }
155
83.8k
        }
_RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive5to_u8Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
148
17.0k
        fn $method(&self) -> Option<$DstT> {
149
17.0k
            let max = $DstT::MAX as $SrcT;
150
17.0k
            if 0 <= *self && (size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max) {
151
17.0k
                Some(*self as $DstT)
152
            } else {
153
0
                None
154
            }
155
17.0k
        }
_RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive6to_u64Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
148
86
        fn $method(&self) -> Option<$DstT> {
149
86
            let max = $DstT::MAX as $SrcT;
150
86
            if 0 <= *self && (size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max) {
151
86
                Some(*self as $DstT)
152
            } else {
153
0
                None
154
            }
155
86
        }
_RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive8to_usizeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
148
17.0k
        fn $method(&self) -> Option<$DstT> {
149
17.0k
            let max = $DstT::MAX as $SrcT;
150
17.0k
            if 0 <= *self && (size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max) {
151
17.0k
                Some(*self as $DstT)
152
            } else {
153
0
                None
154
            }
155
17.0k
        }
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
_RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Line
Count
Source
148
22.7k
        fn $method(&self) -> Option<$DstT> {
149
22.7k
            let max = $DstT::MAX as $SrcT;
150
22.7k
            if 0 <= *self && (size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max) {
151
22.7k
                Some(*self as $DstT)
152
            } else {
153
0
                None
154
            }
155
22.7k
        }
_RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
Line
Count
Source
148
4.12k
        fn $method(&self) -> Option<$DstT> {
149
4.12k
            let max = $DstT::MAX as $SrcT;
150
4.12k
            if 0 <= *self && (size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max) {
151
4.12k
                Some(*self as $DstT)
152
            } else {
153
0
                None
154
            }
155
4.12k
        }
_RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
Line
Count
Source
148
22.7k
        fn $method(&self) -> Option<$DstT> {
149
22.7k
            let max = $DstT::MAX as $SrcT;
150
22.7k
            if 0 <= *self && (size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max) {
151
22.7k
                Some(*self as $DstT)
152
            } else {
153
0
                None
154
            }
155
22.7k
        }
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive7to_u128B7_
156
    )*}
157
}
158
159
macro_rules! impl_to_primitive_int {
160
    ($T:ident) => {
161
        impl ToPrimitive for $T {
162
            impl_to_primitive_int_to_int! { $T:
163
                fn to_isize -> isize;
164
                fn to_i8 -> i8;
165
                fn to_i16 -> i16;
166
                fn to_i32 -> i32;
167
                fn to_i64 -> i64;
168
                fn to_i128 -> i128;
169
            }
170
171
            impl_to_primitive_int_to_uint! { $T:
172
                fn to_usize -> usize;
173
                fn to_u8 -> u8;
174
                fn to_u16 -> u16;
175
                fn to_u32 -> u32;
176
                fn to_u64 -> u64;
177
                fn to_u128 -> u128;
178
            }
179
180
            #[inline]
181
0
            fn to_f32(&self) -> Option<f32> {
182
0
                Some(*self as f32)
183
0
            }
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive6to_f32B7_
184
            #[inline]
185
0
            fn to_f64(&self) -> Option<f64> {
186
0
                Some(*self as f64)
187
0
            }
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_11ToPrimitive6to_f64B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_11ToPrimitive6to_f64B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_11ToPrimitive6to_f64B7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_11ToPrimitive6to_f64B7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_11ToPrimitive6to_f64B7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_11ToPrimitive6to_f64B7_
188
        }
189
    };
190
}
191
192
impl_to_primitive_int!(isize);
193
impl_to_primitive_int!(i8);
194
impl_to_primitive_int!(i16);
195
impl_to_primitive_int!(i32);
196
impl_to_primitive_int!(i64);
197
impl_to_primitive_int!(i128);
198
199
macro_rules! impl_to_primitive_uint_to_int {
200
    ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
201
        #[inline]
202
        $(#[$cfg])*
203
39.8k
        fn $method(&self) -> Option<$DstT> {
204
39.8k
            let max = $DstT::MAX as $SrcT;
205
39.8k
            if size_of::<$SrcT>() < size_of::<$DstT>() || *self <= max {
206
39.8k
                Some(*self as $DstT)
207
            } else {
208
0
                None
209
            }
210
39.8k
        }
_RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_i32Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
203
17.0k
        fn $method(&self) -> Option<$DstT> {
204
17.0k
            let max = $DstT::MAX as $SrcT;
205
17.0k
            if size_of::<$SrcT>() < size_of::<$DstT>() || *self <= max {
206
17.0k
                Some(*self as $DstT)
207
            } else {
208
0
                None
209
            }
210
17.0k
        }
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive5to_i8Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_i16Cs72ekIXsOXFl_10num_bigint
_RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_i32Cs72ekIXsOXFl_10num_bigint
Line
Count
Source
203
22.7k
        fn $method(&self) -> Option<$DstT> {
204
22.7k
            let max = $DstT::MAX as $SrcT;
205
22.7k
            if size_of::<$SrcT>() < size_of::<$DstT>() || *self <= max {
206
22.7k
                Some(*self as $DstT)
207
            } else {
208
0
                None
209
            }
210
22.7k
        }
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_i64Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive7to_i128Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive8to_isizeCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_i64Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive7to_i128Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive7to_i128B7_
211
    )*}
212
}
213
214
macro_rules! impl_to_primitive_uint_to_uint {
215
    ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
216
        #[inline]
217
        $(#[$cfg])*
218
1.22M
        fn $method(&self) -> Option<$DstT> {
219
1.22M
            let max = $DstT::MAX as $SrcT;
220
1.22M
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
1.19M
                Some(*self as $DstT)
222
            } else {
223
30.3k
                None
224
            }
225
1.22M
        }
_RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_u32Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
218
243k
        fn $method(&self) -> Option<$DstT> {
219
243k
            let max = $DstT::MAX as $SrcT;
220
243k
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
224k
                Some(*self as $DstT)
222
            } else {
223
18.9k
                None
224
            }
225
243k
        }
_RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Line
Count
Source
218
243k
        fn $method(&self) -> Option<$DstT> {
219
243k
            let max = $DstT::MAX as $SrcT;
220
243k
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
243k
                Some(*self as $DstT)
222
            } else {
223
0
                None
224
            }
225
243k
        }
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
_RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
Line
Count
Source
218
243k
        fn $method(&self) -> Option<$DstT> {
219
243k
            let max = $DstT::MAX as $SrcT;
220
243k
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
243k
                Some(*self as $DstT)
222
            } else {
223
0
                None
224
            }
225
243k
        }
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_u16Cs72ekIXsOXFl_10num_bigint
_RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_u32Cs72ekIXsOXFl_10num_bigint
Line
Count
Source
218
20.6k
        fn $method(&self) -> Option<$DstT> {
219
20.6k
            let max = $DstT::MAX as $SrcT;
220
20.6k
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
20.6k
                Some(*self as $DstT)
222
            } else {
223
0
                None
224
            }
225
20.6k
        }
_RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
Line
Count
Source
218
2.07k
        fn $method(&self) -> Option<$DstT> {
219
2.07k
            let max = $DstT::MAX as $SrcT;
220
2.07k
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
2.07k
                Some(*self as $DstT)
222
            } else {
223
0
                None
224
            }
225
2.07k
        }
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive7to_u128Cs72ekIXsOXFl_10num_bigint
_RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
Line
Count
Source
218
243k
        fn $method(&self) -> Option<$DstT> {
219
243k
            let max = $DstT::MAX as $SrcT;
220
243k
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
243k
                Some(*self as $DstT)
222
            } else {
223
0
                None
224
            }
225
243k
        }
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
_RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Line
Count
Source
218
20.6k
        fn $method(&self) -> Option<$DstT> {
219
20.6k
            let max = $DstT::MAX as $SrcT;
220
20.6k
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
20.6k
                Some(*self as $DstT)
222
            } else {
223
0
                None
224
            }
225
20.6k
        }
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
_RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
Line
Count
Source
218
20.6k
        fn $method(&self) -> Option<$DstT> {
219
20.6k
            let max = $DstT::MAX as $SrcT;
220
20.6k
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
20.6k
                Some(*self as $DstT)
222
            } else {
223
0
                None
224
            }
225
20.6k
        }
_RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Line
Count
Source
218
2.07k
        fn $method(&self) -> Option<$DstT> {
219
2.07k
            let max = $DstT::MAX as $SrcT;
220
2.07k
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
2.07k
                Some(*self as $DstT)
222
            } else {
223
0
                None
224
            }
225
2.07k
        }
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_u16Cs72ekIXsOXFl_10num_bigint
_RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_u32Cs72ekIXsOXFl_10num_bigint
Line
Count
Source
218
45.6k
        fn $method(&self) -> Option<$DstT> {
219
45.6k
            let max = $DstT::MAX as $SrcT;
220
45.6k
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
34.2k
                Some(*self as $DstT)
222
            } else {
223
11.3k
                None
224
            }
225
45.6k
        }
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
_RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
Line
Count
Source
218
142k
        fn $method(&self) -> Option<$DstT> {
219
142k
            let max = $DstT::MAX as $SrcT;
220
142k
            if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
221
142k
                Some(*self as $DstT)
222
            } else {
223
0
                None
224
            }
225
142k
        }
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive5to_u8Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive6to_u64Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive7to_u128B7_
226
    )*}
227
}
228
229
macro_rules! impl_to_primitive_uint {
230
    ($T:ident) => {
231
        impl ToPrimitive for $T {
232
            impl_to_primitive_uint_to_int! { $T:
233
                fn to_isize -> isize;
234
                fn to_i8 -> i8;
235
                fn to_i16 -> i16;
236
                fn to_i32 -> i32;
237
                fn to_i64 -> i64;
238
                fn to_i128 -> i128;
239
            }
240
241
            impl_to_primitive_uint_to_uint! { $T:
242
                fn to_usize -> usize;
243
                fn to_u8 -> u8;
244
                fn to_u16 -> u16;
245
                fn to_u32 -> u32;
246
                fn to_u64 -> u64;
247
                fn to_u128 -> u128;
248
            }
249
250
            #[inline]
251
0
            fn to_f32(&self) -> Option<f32> {
252
0
                Some(*self as f32)
253
0
            }
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive6to_f32B7_
254
            #[inline]
255
0
            fn to_f64(&self) -> Option<f64> {
256
0
                Some(*self as f64)
257
0
            }
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_11ToPrimitive6to_f64B7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_11ToPrimitive6to_f64B7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_11ToPrimitive6to_f64B7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_11ToPrimitive6to_f64B7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_11ToPrimitive6to_f64B7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_11ToPrimitive6to_f64B7_
258
        }
259
    };
260
}
261
262
impl_to_primitive_uint!(usize);
263
impl_to_primitive_uint!(u8);
264
impl_to_primitive_uint!(u16);
265
impl_to_primitive_uint!(u32);
266
impl_to_primitive_uint!(u64);
267
impl_to_primitive_uint!(u128);
268
269
macro_rules! impl_to_primitive_float_to_float {
270
    ($SrcT:ident : $( fn $method:ident -> $DstT:ident ; )*) => {$(
271
        #[inline]
272
0
        fn $method(&self) -> Option<$DstT> {
273
0
            // We can safely cast all values, whether NaN, +-inf, or finite.
274
0
            // Finite values that are reducing size may saturate to +-inf.
275
0
            Some(*self as $DstT)
276
0
        }
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive6to_f64B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive6to_f64B7_
277
    )*}
278
}
279
280
macro_rules! float_to_int_unchecked {
281
    // SAFETY: Must not be NaN or infinite; must be representable as the integer after truncating.
282
    // We already checked that the float is in the exclusive range `(MIN-1, MAX+1)`.
283
    ($float:expr => $int:ty) => {
284
        unsafe { $float.to_int_unchecked::<$int>() }
285
    };
286
}
287
288
macro_rules! impl_to_primitive_float_to_signed_int {
289
    ($f:ident : $( $(#[$cfg:meta])* fn $method:ident -> $i:ident ; )*) => {$(
290
        #[inline]
291
        $(#[$cfg])*
292
0
        fn $method(&self) -> Option<$i> {
293
0
            // Float as int truncates toward zero, so we want to allow values
294
0
            // in the exclusive range `(MIN-1, MAX+1)`.
295
0
            if size_of::<$f>() > size_of::<$i>() {
296
                // With a larger size, we can represent the range exactly.
297
                const MIN_M1: $f = $i::MIN as $f - 1.0;
298
                const MAX_P1: $f = $i::MAX as $f + 1.0;
299
0
                if *self > MIN_M1 && *self < MAX_P1 {
300
0
                    return Some(float_to_int_unchecked!(*self => $i));
301
0
                }
302
            } else {
303
                // We can't represent `MIN-1` exactly, but there's no fractional part
304
                // at this magnitude, so we can just use a `MIN` inclusive boundary.
305
                const MIN: $f = $i::MIN as $f;
306
                // We can't represent `MAX` exactly, but it will round up to exactly
307
                // `MAX+1` (a power of two) when we cast it.
308
                const MAX_P1: $f = $i::MAX as $f;
309
0
                if *self >= MIN && *self < MAX_P1 {
310
0
                    return Some(float_to_int_unchecked!(*self => $i));
311
0
                }
312
            }
313
0
            None
314
0
        }
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive7to_i128B7_
315
    )*}
316
}
317
318
macro_rules! impl_to_primitive_float_to_unsigned_int {
319
    ($f:ident : $( $(#[$cfg:meta])* fn $method:ident -> $u:ident ; )*) => {$(
320
        #[inline]
321
        $(#[$cfg])*
322
0
        fn $method(&self) -> Option<$u> {
323
0
            // Float as int truncates toward zero, so we want to allow values
324
0
            // in the exclusive range `(-1, MAX+1)`.
325
0
            if size_of::<$f>() > size_of::<$u>() {
326
                // With a larger size, we can represent the range exactly.
327
                const MAX_P1: $f = $u::MAX as $f + 1.0;
328
0
                if *self > -1.0 && *self < MAX_P1 {
329
0
                    return Some(float_to_int_unchecked!(*self => $u));
330
0
                }
331
            } else {
332
                // We can't represent `MAX` exactly, but it will round up to exactly
333
                // `MAX+1` (a power of two) when we cast it.
334
                // (`u128::MAX as f32` is infinity, but this is still ok.)
335
                const MAX_P1: $f = $u::MAX as $f;
336
0
                if *self > -1.0 && *self < MAX_P1 {
337
0
                    return Some(float_to_int_unchecked!(*self => $u));
338
0
                }
339
            }
340
0
            None
341
0
        }
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive8to_usizeCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_11ToPrimitive7to_u128B7_
342
    )*}
343
}
344
345
macro_rules! impl_to_primitive_float {
346
    ($T:ident) => {
347
        impl ToPrimitive for $T {
348
            impl_to_primitive_float_to_signed_int! { $T:
349
                fn to_isize -> isize;
350
                fn to_i8 -> i8;
351
                fn to_i16 -> i16;
352
                fn to_i32 -> i32;
353
                fn to_i64 -> i64;
354
                fn to_i128 -> i128;
355
            }
356
357
            impl_to_primitive_float_to_unsigned_int! { $T:
358
                fn to_usize -> usize;
359
                fn to_u8 -> u8;
360
                fn to_u16 -> u16;
361
                fn to_u32 -> u32;
362
                fn to_u64 -> u64;
363
                fn to_u128 -> u128;
364
            }
365
366
            impl_to_primitive_float_to_float! { $T:
367
                fn to_f32 -> f32;
368
                fn to_f64 -> f64;
369
            }
370
        }
371
    };
372
}
373
374
impl_to_primitive_float!(f32);
375
impl_to_primitive_float!(f64);
376
377
/// A generic trait for converting a number to a value.
378
///
379
/// A value can be represented by the target type when it lies within
380
/// the range of scalars supported by the target type.
381
/// For example, a negative integer cannot be represented by an unsigned
382
/// integer type, and an `i64` with a very high magnitude might not be
383
/// convertible to an `i32`.
384
/// On the other hand, conversions with possible precision loss or truncation
385
/// are admitted, like an `f32` with a decimal part to an integer type, or
386
/// even a large `f64` saturating to `f32` infinity.
387
pub trait FromPrimitive: Sized {
388
    /// Converts an `isize` to return an optional value of this type. If the
389
    /// value cannot be represented by this type, then `None` is returned.
390
    #[inline]
391
0
    fn from_isize(n: isize) -> Option<Self> {
392
0
        n.to_i64().and_then(FromPrimitive::from_i64)
393
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive10from_isizeB6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive10from_isizeB6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive10from_isizeB7_
394
395
    /// Converts an `i8` to return an optional value of this type. If the
396
    /// value cannot be represented by this type, then `None` is returned.
397
    #[inline]
398
0
    fn from_i8(n: i8) -> Option<Self> {
399
0
        FromPrimitive::from_i64(From::from(n))
400
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive7from_i8B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive7from_i8B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive7from_i8B7_
401
402
    /// Converts an `i16` to return an optional value of this type. If the
403
    /// value cannot be represented by this type, then `None` is returned.
404
    #[inline]
405
0
    fn from_i16(n: i16) -> Option<Self> {
406
0
        FromPrimitive::from_i64(From::from(n))
407
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_i16B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_i16B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_i16B7_
408
409
    /// Converts an `i32` to return an optional value of this type. If the
410
    /// value cannot be represented by this type, then `None` is returned.
411
    #[inline]
412
0
    fn from_i32(n: i32) -> Option<Self> {
413
0
        FromPrimitive::from_i64(From::from(n))
414
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_i32B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_i32B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_i32B7_
415
416
    /// Converts an `i64` to return an optional value of this type. If the
417
    /// value cannot be represented by this type, then `None` is returned.
418
    fn from_i64(n: i64) -> Option<Self>;
419
420
    /// Converts an `i128` to return an optional value of this type. If the
421
    /// value cannot be represented by this type, then `None` is returned.
422
    ///
423
    /// The default implementation converts through `from_i64()`. Types implementing
424
    /// this trait should override this method if they can represent a greater range.
425
    #[inline]
426
0
    fn from_i128(n: i128) -> Option<Self> {
427
0
        n.to_i64().and_then(FromPrimitive::from_i64)
428
0
    }
429
430
    /// Converts a `usize` to return an optional value of this type. If the
431
    /// value cannot be represented by this type, then `None` is returned.
432
    #[inline]
433
0
    fn from_usize(n: usize) -> Option<Self> {
434
0
        n.to_u64().and_then(FromPrimitive::from_u64)
435
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive10from_usizeB6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive10from_usizeB6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive10from_usizeB7_
436
437
    /// Converts an `u8` to return an optional value of this type. If the
438
    /// value cannot be represented by this type, then `None` is returned.
439
    #[inline]
440
0
    fn from_u8(n: u8) -> Option<Self> {
441
0
        FromPrimitive::from_u64(From::from(n))
442
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive7from_u8B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive7from_u8B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive7from_u8B7_
443
444
    /// Converts an `u16` to return an optional value of this type. If the
445
    /// value cannot be represented by this type, then `None` is returned.
446
    #[inline]
447
0
    fn from_u16(n: u16) -> Option<Self> {
448
0
        FromPrimitive::from_u64(From::from(n))
449
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_u16B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_u16B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_u16B7_
450
451
    /// Converts an `u32` to return an optional value of this type. If the
452
    /// value cannot be represented by this type, then `None` is returned.
453
    #[inline]
454
0
    fn from_u32(n: u32) -> Option<Self> {
455
0
        FromPrimitive::from_u64(From::from(n))
456
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_u32B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_u32B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_u32B7_
457
458
    /// Converts an `u64` to return an optional value of this type. If the
459
    /// value cannot be represented by this type, then `None` is returned.
460
    fn from_u64(n: u64) -> Option<Self>;
461
462
    /// Converts an `u128` to return an optional value of this type. If the
463
    /// value cannot be represented by this type, then `None` is returned.
464
    ///
465
    /// The default implementation converts through `from_u64()`. Types implementing
466
    /// this trait should override this method if they can represent a greater range.
467
    #[inline]
468
0
    fn from_u128(n: u128) -> Option<Self> {
469
0
        n.to_u64().and_then(FromPrimitive::from_u64)
470
0
    }
471
472
    /// Converts a `f32` to return an optional value of this type. If the
473
    /// value cannot be represented by this type, then `None` is returned.
474
    #[inline]
475
0
    fn from_f32(n: f32) -> Option<Self> {
476
0
        FromPrimitive::from_f64(From::from(n))
477
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_f32B6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_f32B6_
Unexecuted instantiation: _RNvYpNtNtCs7cG3k8kmkqw_10num_traits4cast13FromPrimitive8from_f32B7_
478
479
    /// Converts a `f64` to return an optional value of this type. If the
480
    /// value cannot be represented by this type, then `None` is returned.
481
    ///
482
    /// The default implementation tries to convert through `from_i64()`, and
483
    /// failing that through `from_u64()`. Types implementing this trait should
484
    /// override this method if they can represent a greater range.
485
    #[inline]
486
0
    fn from_f64(n: f64) -> Option<Self> {
487
0
        match n.to_i64() {
488
0
            Some(i) => FromPrimitive::from_i64(i),
489
0
            None => n.to_u64().and_then(FromPrimitive::from_u64),
490
        }
491
0
    }
492
}
493
494
macro_rules! impl_from_primitive {
495
    ($T:ty, $to_ty:ident) => {
496
        #[allow(deprecated)]
497
        impl FromPrimitive for $T {
498
            #[inline]
499
0
            fn from_isize(n: isize) -> Option<$T> {
500
0
                n.$to_ty()
501
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive10from_isizeB7_
502
            #[inline]
503
0
            fn from_i8(n: i8) -> Option<$T> {
504
0
                n.$to_ty()
505
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive7from_i8B7_
506
            #[inline]
507
0
            fn from_i16(n: i16) -> Option<$T> {
508
0
                n.$to_ty()
509
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive8from_i16B7_
510
            #[inline]
511
0
            fn from_i32(n: i32) -> Option<$T> {
512
0
                n.$to_ty()
513
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive8from_i32B7_
514
            #[inline]
515
0
            fn from_i64(n: i64) -> Option<$T> {
516
0
                n.$to_ty()
517
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive8from_i64B7_
518
            #[inline]
519
0
            fn from_i128(n: i128) -> Option<$T> {
520
0
                n.$to_ty()
521
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive9from_i128B7_
522
523
            #[inline]
524
0
            fn from_usize(n: usize) -> Option<$T> {
525
0
                n.$to_ty()
526
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive10from_usizeB7_
527
            #[inline]
528
0
            fn from_u8(n: u8) -> Option<$T> {
529
0
                n.$to_ty()
530
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive7from_u8B7_
531
            #[inline]
532
0
            fn from_u16(n: u16) -> Option<$T> {
533
0
                n.$to_ty()
534
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive8from_u16B7_
535
            #[inline]
536
0
            fn from_u32(n: u32) -> Option<$T> {
537
0
                n.$to_ty()
538
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive8from_u32B7_
539
            #[inline]
540
0
            fn from_u64(n: u64) -> Option<$T> {
541
0
                n.$to_ty()
542
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive8from_u64B7_
543
            #[inline]
544
0
            fn from_u128(n: u128) -> Option<$T> {
545
0
                n.$to_ty()
546
0
            }
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive9from_u128Cs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive9from_u128B7_
547
548
            #[inline]
549
0
            fn from_f32(n: f32) -> Option<$T> {
550
0
                n.$to_ty()
551
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive8from_f32B7_
552
            #[inline]
553
0
            fn from_f64(n: f64) -> Option<$T> {
554
0
                n.$to_ty()
555
0
            }
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits4castiNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits4castaNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits4castsNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits4castlNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits4castxNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits4castnNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits4castjNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits4casthNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits4casttNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits4castmNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits4castyNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits4castoNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits4castfNtB5_13FromPrimitive8from_f64B7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits4castdNtB5_13FromPrimitive8from_f64B7_
556
        }
557
    };
558
}
559
560
impl_from_primitive!(isize, to_isize);
561
impl_from_primitive!(i8, to_i8);
562
impl_from_primitive!(i16, to_i16);
563
impl_from_primitive!(i32, to_i32);
564
impl_from_primitive!(i64, to_i64);
565
impl_from_primitive!(i128, to_i128);
566
impl_from_primitive!(usize, to_usize);
567
impl_from_primitive!(u8, to_u8);
568
impl_from_primitive!(u16, to_u16);
569
impl_from_primitive!(u32, to_u32);
570
impl_from_primitive!(u64, to_u64);
571
impl_from_primitive!(u128, to_u128);
572
impl_from_primitive!(f32, to_f32);
573
impl_from_primitive!(f64, to_f64);
574
575
macro_rules! impl_to_primitive_wrapping {
576
    ($( $(#[$cfg:meta])* fn $method:ident -> $i:ident ; )*) => {$(
577
        #[inline]
578
        $(#[$cfg])*
579
0
        fn $method(&self) -> Option<$i> {
580
0
            (self.0).$method()
581
0
        }
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive8to_isizeB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive5to_i8B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive6to_i16B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive6to_i32B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive6to_i64B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive7to_i128B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive8to_usizeB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive5to_u8B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive6to_u16B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive6to_u32B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive6to_u64B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive7to_u128B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive6to_f32B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4cast0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_11ToPrimitive6to_f64B7_
582
    )*}
583
}
584
585
impl<T: ToPrimitive> ToPrimitive for Wrapping<T> {
586
    impl_to_primitive_wrapping! {
587
        fn to_isize -> isize;
588
        fn to_i8 -> i8;
589
        fn to_i16 -> i16;
590
        fn to_i32 -> i32;
591
        fn to_i64 -> i64;
592
        fn to_i128 -> i128;
593
594
        fn to_usize -> usize;
595
        fn to_u8 -> u8;
596
        fn to_u16 -> u16;
597
        fn to_u32 -> u32;
598
        fn to_u64 -> u64;
599
        fn to_u128 -> u128;
600
601
        fn to_f32 -> f32;
602
        fn to_f64 -> f64;
603
    }
604
}
605
606
macro_rules! impl_from_primitive_wrapping {
607
    ($( $(#[$cfg:meta])* fn $method:ident ( $i:ident ); )*) => {$(
608
        #[inline]
609
        $(#[$cfg])*
610
0
        fn $method(n: $i) -> Option<Self> {
611
0
            T::$method(n).map(Wrapping)
612
0
        }
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive10from_isizeB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive7from_i8B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive8from_i16B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive8from_i32B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive8from_i64B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive9from_i128B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive10from_usizeB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive7from_u8B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive8from_u16B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive8from_u32B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive8from_u64B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive9from_u128B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive8from_f32B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4casts_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB5_13FromPrimitive8from_f64B7_
613
    )*}
614
}
615
616
impl<T: FromPrimitive> FromPrimitive for Wrapping<T> {
617
    impl_from_primitive_wrapping! {
618
        fn from_isize(isize);
619
        fn from_i8(i8);
620
        fn from_i16(i16);
621
        fn from_i32(i32);
622
        fn from_i64(i64);
623
        fn from_i128(i128);
624
625
        fn from_usize(usize);
626
        fn from_u8(u8);
627
        fn from_u16(u16);
628
        fn from_u32(u32);
629
        fn from_u64(u64);
630
        fn from_u128(u128);
631
632
        fn from_f32(f32);
633
        fn from_f64(f64);
634
    }
635
}
636
637
/// Cast from one machine scalar to another.
638
///
639
/// # Examples
640
///
641
/// ```
642
/// # use num_traits as num;
643
/// let twenty: f32 = num::cast(0x14).unwrap();
644
/// assert_eq!(twenty, 20f32);
645
/// ```
646
///
647
#[inline]
648
0
pub fn cast<T: NumCast, U: NumCast>(n: T) -> Option<U> {
649
0
    NumCast::from(n)
650
0
}
651
652
/// An interface for casting between machine scalars.
653
pub trait NumCast: Sized + ToPrimitive {
654
    /// Creates a number from another value that can be converted into
655
    /// a primitive via the `ToPrimitive` trait. If the source value cannot be
656
    /// represented by the target type, then `None` is returned.
657
    ///
658
    /// A value can be represented by the target type when it lies within
659
    /// the range of scalars supported by the target type.
660
    /// For example, a negative integer cannot be represented by an unsigned
661
    /// integer type, and an `i64` with a very high magnitude might not be
662
    /// convertible to an `i32`.
663
    /// On the other hand, conversions with possible precision loss or truncation
664
    /// are admitted, like an `f32` with a decimal part to an integer type, or
665
    /// even a large `f64` saturating to `f32` infinity.
666
    fn from<T: ToPrimitive>(n: T) -> Option<Self>;
667
}
668
669
macro_rules! impl_num_cast {
670
    ($T:ty, $conv:ident) => {
671
        impl NumCast for $T {
672
            #[inline]
673
            #[allow(deprecated)]
674
305k
            fn from<N: ToPrimitive>(n: N) -> Option<$T> {
675
305k
                // `$conv` could be generated using `concat_idents!`, but that
676
305k
                // macro seems to be broken at the moment
677
305k
                n.$conv()
678
305k
            }
_RINvXsB_NtCs7cG3k8kmkqw_10num_traits4castlNtB6_7NumCast4fromhECs4RkbDk9WRL5_5clvmr
Line
Count
Source
674
17.0k
            fn from<N: ToPrimitive>(n: N) -> Option<$T> {
675
17.0k
                // `$conv` could be generated using `concat_idents!`, but that
676
17.0k
                // macro seems to be broken at the moment
677
17.0k
                n.$conv()
678
17.0k
            }
Unexecuted instantiation: _RINvXsA_NtCs7cG3k8kmkqw_10num_traits4castsNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
_RINvXsB_NtCs7cG3k8kmkqw_10num_traits4castlNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
Line
Count
Source
674
22.7k
            fn from<N: ToPrimitive>(n: N) -> Option<$T> {
675
22.7k
                // `$conv` could be generated using `concat_idents!`, but that
676
22.7k
                // macro seems to be broken at the moment
677
22.7k
                n.$conv()
678
22.7k
            }
Unexecuted instantiation: _RINvXsC_NtCs7cG3k8kmkqw_10num_traits4castxNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RINvXsD_NtCs7cG3k8kmkqw_10num_traits4castnNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RINvXsE_NtCs7cG3k8kmkqw_10num_traits4castiNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RINvXst_NtCs7cG3k8kmkqw_10num_traits4casthNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RINvXsu_NtCs7cG3k8kmkqw_10num_traits4casttNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
_RINvXsv_NtCs7cG3k8kmkqw_10num_traits4castmNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
Line
Count
Source
674
20.6k
            fn from<N: ToPrimitive>(n: N) -> Option<$T> {
675
20.6k
                // `$conv` could be generated using `concat_idents!`, but that
676
20.6k
                // macro seems to be broken at the moment
677
20.6k
                n.$conv()
678
20.6k
            }
_RINvXsw_NtCs7cG3k8kmkqw_10num_traits4castyNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
Line
Count
Source
674
2.07k
            fn from<N: ToPrimitive>(n: N) -> Option<$T> {
675
2.07k
                // `$conv` could be generated using `concat_idents!`, but that
676
2.07k
                // macro seems to be broken at the moment
677
2.07k
                n.$conv()
678
2.07k
            }
Unexecuted instantiation: _RINvXsx_NtCs7cG3k8kmkqw_10num_traits4castoNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
_RINvXsy_NtCs7cG3k8kmkqw_10num_traits4castjNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
Line
Count
Source
674
243k
            fn from<N: ToPrimitive>(n: N) -> Option<$T> {
675
243k
                // `$conv` could be generated using `concat_idents!`, but that
676
243k
                // macro seems to be broken at the moment
677
243k
                n.$conv()
678
243k
            }
Unexecuted instantiation: _RINvXsz_NtCs7cG3k8kmkqw_10num_traits4castaNtB6_7NumCast4fromhECs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RINvXst_NtCs7cG3k8kmkqw_10num_traits4casthNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsu_NtCs7cG3k8kmkqw_10num_traits4casttNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsv_NtCs7cG3k8kmkqw_10num_traits4castmNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsw_NtCs7cG3k8kmkqw_10num_traits4castyNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsx_NtCs7cG3k8kmkqw_10num_traits4castoNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsy_NtCs7cG3k8kmkqw_10num_traits4castjNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsz_NtCs7cG3k8kmkqw_10num_traits4castaNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsA_NtCs7cG3k8kmkqw_10num_traits4castsNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsB_NtCs7cG3k8kmkqw_10num_traits4castlNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsC_NtCs7cG3k8kmkqw_10num_traits4castxNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsD_NtCs7cG3k8kmkqw_10num_traits4castnNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsE_NtCs7cG3k8kmkqw_10num_traits4castiNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsF_NtCs7cG3k8kmkqw_10num_traits4castfNtB6_7NumCast4frompEB8_
Unexecuted instantiation: _RINvXsG_NtCs7cG3k8kmkqw_10num_traits4castdNtB6_7NumCast4frompEB8_
679
        }
680
    };
681
}
682
683
impl_num_cast!(u8, to_u8);
684
impl_num_cast!(u16, to_u16);
685
impl_num_cast!(u32, to_u32);
686
impl_num_cast!(u64, to_u64);
687
impl_num_cast!(u128, to_u128);
688
impl_num_cast!(usize, to_usize);
689
impl_num_cast!(i8, to_i8);
690
impl_num_cast!(i16, to_i16);
691
impl_num_cast!(i32, to_i32);
692
impl_num_cast!(i64, to_i64);
693
impl_num_cast!(i128, to_i128);
694
impl_num_cast!(isize, to_isize);
695
impl_num_cast!(f32, to_f32);
696
impl_num_cast!(f64, to_f64);
697
698
impl<T: NumCast> NumCast for Wrapping<T> {
699
0
    fn from<U: ToPrimitive>(n: U) -> Option<Self> {
700
0
        T::from(n).map(Wrapping)
701
0
    }
702
}
703
704
/// A generic interface for casting between machine scalars with the
705
/// `as` operator, which admits narrowing and precision loss.
706
/// Implementers of this trait `AsPrimitive` should behave like a primitive
707
/// numeric type (e.g. a newtype around another primitive), and the
708
/// intended conversion must never fail.
709
///
710
/// # Examples
711
///
712
/// ```
713
/// # use num_traits::AsPrimitive;
714
/// let three: i32 = (3.14159265f32).as_();
715
/// assert_eq!(three, 3);
716
/// ```
717
///
718
/// # Safety
719
///
720
/// **In Rust versions before 1.45.0**, some uses of the `as` operator were not entirely safe.
721
/// In particular, it was undefined behavior if
722
/// a truncated floating point value could not fit in the target integer
723
/// type ([#10184](https://github.com/rust-lang/rust/issues/10184)).
724
///
725
/// ```ignore
726
/// # use num_traits::AsPrimitive;
727
/// let x: u8 = (1.04E+17).as_(); // UB
728
/// ```
729
///
730
pub trait AsPrimitive<T>: 'static + Copy
731
where
732
    T: 'static + Copy,
733
{
734
    /// Convert a value to another, using the `as` operator.
735
    fn as_(self) -> T;
736
}
737
738
macro_rules! impl_as_primitive {
739
    (@ $T: ty => $(#[$cfg:meta])* impl $U: ty ) => {
740
        $(#[$cfg])*
741
        impl AsPrimitive<$U> for $T {
742
0
            #[inline] fn as_(self) -> $U { self as $U }
Unexecuted instantiation: _RNvXsH_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitivecE3as_B7_
Unexecuted instantiation: _RNvXsI_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitivefE3as_B7_
Unexecuted instantiation: _RNvXsJ_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitivedE3as_B7_
Unexecuted instantiation: _RNvXsK_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitivehE3as_B7_
Unexecuted instantiation: _RNvXsL_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitivetE3as_B7_
Unexecuted instantiation: _RNvXsM_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitivemE3as_B7_
Unexecuted instantiation: _RNvXsN_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitiveyE3as_B7_
Unexecuted instantiation: _RNvXsO_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitiveoE3as_B7_
Unexecuted instantiation: _RNvXsP_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitivejE3as_B7_
Unexecuted instantiation: _RNvXsQ_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitiveaE3as_B7_
Unexecuted instantiation: _RNvXsR_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitivesE3as_B7_
Unexecuted instantiation: _RNvXsS_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitivelE3as_B7_
Unexecuted instantiation: _RNvXsT_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitivexE3as_B7_
Unexecuted instantiation: _RNvXsU_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitivenE3as_B7_
Unexecuted instantiation: _RNvXsV_NtCs7cG3k8kmkqw_10num_traits4casthINtB5_11AsPrimitiveiE3as_B7_
Unexecuted instantiation: _RNvXsW_NtCs7cG3k8kmkqw_10num_traits4castaINtB5_11AsPrimitivefE3as_B7_
Unexecuted instantiation: _RNvXsX_NtCs7cG3k8kmkqw_10num_traits4castaINtB5_11AsPrimitivedE3as_B7_
Unexecuted instantiation: _RNvXsY_NtCs7cG3k8kmkqw_10num_traits4castaINtB5_11AsPrimitivehE3as_B7_
Unexecuted instantiation: _RNvXsZ_NtCs7cG3k8kmkqw_10num_traits4castaINtB5_11AsPrimitivetE3as_B7_
Unexecuted instantiation: _RNvXs10_NtCs7cG3k8kmkqw_10num_traits4castaINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs11_NtCs7cG3k8kmkqw_10num_traits4castaINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs12_NtCs7cG3k8kmkqw_10num_traits4castaINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs13_NtCs7cG3k8kmkqw_10num_traits4castaINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs14_NtCs7cG3k8kmkqw_10num_traits4castaINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs15_NtCs7cG3k8kmkqw_10num_traits4castaINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs16_NtCs7cG3k8kmkqw_10num_traits4castaINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs17_NtCs7cG3k8kmkqw_10num_traits4castaINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs18_NtCs7cG3k8kmkqw_10num_traits4castaINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs19_NtCs7cG3k8kmkqw_10num_traits4castaINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs1a_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs1b_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs1c_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs1d_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs1e_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs1f_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs1g_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs1h_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs1i_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs1j_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs1k_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs1l_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs1m_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs1n_NtCs7cG3k8kmkqw_10num_traits4casttINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs1o_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs1p_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs1q_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs1r_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs1s_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs1t_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs1u_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs1v_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs1w_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs1x_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs1y_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs1z_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs1A_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs1B_NtCs7cG3k8kmkqw_10num_traits4castsINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs1C_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs1D_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs1E_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs1F_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs1G_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs1H_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs1I_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs1J_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs1K_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs1L_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs1M_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs1N_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs1O_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs1P_NtCs7cG3k8kmkqw_10num_traits4castmINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs1Q_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs1R_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs1S_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs1T_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs1U_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs1V_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs1W_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs1X_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs1Y_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs1Z_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs20_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs21_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs22_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs23_NtCs7cG3k8kmkqw_10num_traits4castlINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs24_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs25_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs26_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs27_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs28_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs29_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs2a_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs2b_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs2c_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs2d_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs2e_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs2f_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs2g_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs2h_NtCs7cG3k8kmkqw_10num_traits4castyINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs2i_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs2j_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs2k_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs2l_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs2m_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs2n_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs2o_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs2p_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs2q_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs2r_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs2s_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs2t_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs2u_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs2v_NtCs7cG3k8kmkqw_10num_traits4castxINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs2w_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs2x_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs2y_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs2z_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs2A_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs2B_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs2C_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs2D_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs2E_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs2F_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs2G_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs2H_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs2I_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs2J_NtCs7cG3k8kmkqw_10num_traits4castoINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs2K_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs2L_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs2M_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs2N_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs2O_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs2P_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs2Q_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs2R_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs2S_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs2T_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs2U_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs2V_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs2W_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs2X_NtCs7cG3k8kmkqw_10num_traits4castnINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs2Y_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs2Z_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs30_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs31_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs32_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs33_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs34_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs35_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs36_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs37_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs38_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs39_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs3a_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs3b_NtCs7cG3k8kmkqw_10num_traits4castjINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs3c_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs3d_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs3e_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs3f_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs3g_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs3h_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs3i_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs3j_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs3k_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs3l_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs3m_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs3n_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs3o_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs3p_NtCs7cG3k8kmkqw_10num_traits4castiINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs3q_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs3r_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs3s_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs3t_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs3u_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs3v_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs3w_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs3x_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs3y_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs3z_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs3A_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs3B_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs3C_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs3D_NtCs7cG3k8kmkqw_10num_traits4castfINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs3E_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitivefE3as_B8_
Unexecuted instantiation: _RNvXs3F_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitivedE3as_B8_
Unexecuted instantiation: _RNvXs3G_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs3H_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs3I_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs3J_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs3K_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs3L_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs3M_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs3N_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs3O_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs3P_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs3Q_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs3R_NtCs7cG3k8kmkqw_10num_traits4castdINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs3S_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitivecE3as_B8_
Unexecuted instantiation: _RNvXs3T_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs3U_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs3V_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs3W_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs3X_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs3Y_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs3Z_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs40_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs41_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs42_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs43_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs44_NtCs7cG3k8kmkqw_10num_traits4castcINtB6_11AsPrimitiveiE3as_B8_
Unexecuted instantiation: _RNvXs45_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitivehE3as_B8_
Unexecuted instantiation: _RNvXs46_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitivetE3as_B8_
Unexecuted instantiation: _RNvXs47_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitivemE3as_B8_
Unexecuted instantiation: _RNvXs48_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitiveyE3as_B8_
Unexecuted instantiation: _RNvXs49_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitiveoE3as_B8_
Unexecuted instantiation: _RNvXs4a_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitivejE3as_B8_
Unexecuted instantiation: _RNvXs4b_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitiveaE3as_B8_
Unexecuted instantiation: _RNvXs4c_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitivesE3as_B8_
Unexecuted instantiation: _RNvXs4d_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitivelE3as_B8_
Unexecuted instantiation: _RNvXs4e_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitivexE3as_B8_
Unexecuted instantiation: _RNvXs4f_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitivenE3as_B8_
Unexecuted instantiation: _RNvXs4g_NtCs7cG3k8kmkqw_10num_traits4castbINtB6_11AsPrimitiveiE3as_B8_
743
        }
744
    };
745
    (@ $T: ty => { $( $U: ty ),* } ) => {$(
746
        impl_as_primitive!(@ $T => impl $U);
747
    )*};
748
    ($T: ty => { $( $U: ty ),* } ) => {
749
        impl_as_primitive!(@ $T => { $( $U ),* });
750
        impl_as_primitive!(@ $T => { u8, u16, u32, u64, u128, usize });
751
        impl_as_primitive!(@ $T => { i8, i16, i32, i64, i128, isize });
752
    };
753
}
754
755
impl_as_primitive!(u8 => { char, f32, f64 });
756
impl_as_primitive!(i8 => { f32, f64 });
757
impl_as_primitive!(u16 => { f32, f64 });
758
impl_as_primitive!(i16 => { f32, f64 });
759
impl_as_primitive!(u32 => { f32, f64 });
760
impl_as_primitive!(i32 => { f32, f64 });
761
impl_as_primitive!(u64 => { f32, f64 });
762
impl_as_primitive!(i64 => { f32, f64 });
763
impl_as_primitive!(u128 => { f32, f64 });
764
impl_as_primitive!(i128 => { f32, f64 });
765
impl_as_primitive!(usize => { f32, f64 });
766
impl_as_primitive!(isize => { f32, f64 });
767
impl_as_primitive!(f32 => { f32, f64 });
768
impl_as_primitive!(f64 => { f32, f64 });
769
impl_as_primitive!(char => { char });
770
impl_as_primitive!(bool => {});
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/float.rs
Line
Count
Source
1
use core::cmp::Ordering;
2
use core::num::FpCategory;
3
use core::ops::{Add, Div, Neg};
4
5
use core::f32;
6
use core::f64;
7
8
use crate::{Num, NumCast, ToPrimitive};
9
10
/// Generic trait for floating point numbers that works with `no_std`.
11
///
12
/// This trait implements a subset of the `Float` trait.
13
pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
14
    /// Returns positive infinity.
15
    ///
16
    /// # Examples
17
    ///
18
    /// ```
19
    /// use num_traits::float::FloatCore;
20
    /// use std::{f32, f64};
21
    ///
22
    /// fn check<T: FloatCore>(x: T) {
23
    ///     assert!(T::infinity() == x);
24
    /// }
25
    ///
26
    /// check(f32::INFINITY);
27
    /// check(f64::INFINITY);
28
    /// ```
29
    fn infinity() -> Self;
30
31
    /// Returns negative infinity.
32
    ///
33
    /// # Examples
34
    ///
35
    /// ```
36
    /// use num_traits::float::FloatCore;
37
    /// use std::{f32, f64};
38
    ///
39
    /// fn check<T: FloatCore>(x: T) {
40
    ///     assert!(T::neg_infinity() == x);
41
    /// }
42
    ///
43
    /// check(f32::NEG_INFINITY);
44
    /// check(f64::NEG_INFINITY);
45
    /// ```
46
    fn neg_infinity() -> Self;
47
48
    /// Returns NaN.
49
    ///
50
    /// # Examples
51
    ///
52
    /// ```
53
    /// use num_traits::float::FloatCore;
54
    ///
55
    /// fn check<T: FloatCore>() {
56
    ///     let n = T::nan();
57
    ///     assert!(n != n);
58
    /// }
59
    ///
60
    /// check::<f32>();
61
    /// check::<f64>();
62
    /// ```
63
    fn nan() -> Self;
64
65
    /// Returns `-0.0`.
66
    ///
67
    /// # Examples
68
    ///
69
    /// ```
70
    /// use num_traits::float::FloatCore;
71
    /// use std::{f32, f64};
72
    ///
73
    /// fn check<T: FloatCore>(n: T) {
74
    ///     let z = T::neg_zero();
75
    ///     assert!(z.is_zero());
76
    ///     assert!(T::one() / z == n);
77
    /// }
78
    ///
79
    /// check(f32::NEG_INFINITY);
80
    /// check(f64::NEG_INFINITY);
81
    /// ```
82
    fn neg_zero() -> Self;
83
84
    /// Returns the smallest finite value that this type can represent.
85
    ///
86
    /// # Examples
87
    ///
88
    /// ```
89
    /// use num_traits::float::FloatCore;
90
    /// use std::{f32, f64};
91
    ///
92
    /// fn check<T: FloatCore>(x: T) {
93
    ///     assert!(T::min_value() == x);
94
    /// }
95
    ///
96
    /// check(f32::MIN);
97
    /// check(f64::MIN);
98
    /// ```
99
    fn min_value() -> Self;
100
101
    /// Returns the smallest positive, normalized value that this type can represent.
102
    ///
103
    /// # Examples
104
    ///
105
    /// ```
106
    /// use num_traits::float::FloatCore;
107
    /// use std::{f32, f64};
108
    ///
109
    /// fn check<T: FloatCore>(x: T) {
110
    ///     assert!(T::min_positive_value() == x);
111
    /// }
112
    ///
113
    /// check(f32::MIN_POSITIVE);
114
    /// check(f64::MIN_POSITIVE);
115
    /// ```
116
    fn min_positive_value() -> Self;
117
118
    /// Returns epsilon, a small positive value.
119
    ///
120
    /// # Examples
121
    ///
122
    /// ```
123
    /// use num_traits::float::FloatCore;
124
    /// use std::{f32, f64};
125
    ///
126
    /// fn check<T: FloatCore>(x: T) {
127
    ///     assert!(T::epsilon() == x);
128
    /// }
129
    ///
130
    /// check(f32::EPSILON);
131
    /// check(f64::EPSILON);
132
    /// ```
133
    fn epsilon() -> Self;
134
135
    /// Returns the largest finite value that this type can represent.
136
    ///
137
    /// # Examples
138
    ///
139
    /// ```
140
    /// use num_traits::float::FloatCore;
141
    /// use std::{f32, f64};
142
    ///
143
    /// fn check<T: FloatCore>(x: T) {
144
    ///     assert!(T::max_value() == x);
145
    /// }
146
    ///
147
    /// check(f32::MAX);
148
    /// check(f64::MAX);
149
    /// ```
150
    fn max_value() -> Self;
151
152
    /// Returns `true` if the number is NaN.
153
    ///
154
    /// # Examples
155
    ///
156
    /// ```
157
    /// use num_traits::float::FloatCore;
158
    /// use std::{f32, f64};
159
    ///
160
    /// fn check<T: FloatCore>(x: T, p: bool) {
161
    ///     assert!(x.is_nan() == p);
162
    /// }
163
    ///
164
    /// check(f32::NAN, true);
165
    /// check(f32::INFINITY, false);
166
    /// check(f64::NAN, true);
167
    /// check(0.0f64, false);
168
    /// ```
169
    #[inline]
170
    #[allow(clippy::eq_op)]
171
0
    fn is_nan(self) -> bool {
172
0
        self != self
173
0
    }
174
175
    /// Returns `true` if the number is infinite.
176
    ///
177
    /// # Examples
178
    ///
179
    /// ```
180
    /// use num_traits::float::FloatCore;
181
    /// use std::{f32, f64};
182
    ///
183
    /// fn check<T: FloatCore>(x: T, p: bool) {
184
    ///     assert!(x.is_infinite() == p);
185
    /// }
186
    ///
187
    /// check(f32::INFINITY, true);
188
    /// check(f32::NEG_INFINITY, true);
189
    /// check(f32::NAN, false);
190
    /// check(f64::INFINITY, true);
191
    /// check(f64::NEG_INFINITY, true);
192
    /// check(0.0f64, false);
193
    /// ```
194
    #[inline]
195
0
    fn is_infinite(self) -> bool {
196
0
        self == Self::infinity() || self == Self::neg_infinity()
197
0
    }
198
199
    /// Returns `true` if the number is neither infinite or NaN.
200
    ///
201
    /// # Examples
202
    ///
203
    /// ```
204
    /// use num_traits::float::FloatCore;
205
    /// use std::{f32, f64};
206
    ///
207
    /// fn check<T: FloatCore>(x: T, p: bool) {
208
    ///     assert!(x.is_finite() == p);
209
    /// }
210
    ///
211
    /// check(f32::INFINITY, false);
212
    /// check(f32::MAX, true);
213
    /// check(f64::NEG_INFINITY, false);
214
    /// check(f64::MIN_POSITIVE, true);
215
    /// check(f64::NAN, false);
216
    /// ```
217
    #[inline]
218
0
    fn is_finite(self) -> bool {
219
0
        !(self.is_nan() || self.is_infinite())
220
0
    }
221
222
    /// Returns `true` if the number is neither zero, infinite, subnormal or NaN.
223
    ///
224
    /// # Examples
225
    ///
226
    /// ```
227
    /// use num_traits::float::FloatCore;
228
    /// use std::{f32, f64};
229
    ///
230
    /// fn check<T: FloatCore>(x: T, p: bool) {
231
    ///     assert!(x.is_normal() == p);
232
    /// }
233
    ///
234
    /// check(f32::INFINITY, false);
235
    /// check(f32::MAX, true);
236
    /// check(f64::NEG_INFINITY, false);
237
    /// check(f64::MIN_POSITIVE, true);
238
    /// check(0.0f64, false);
239
    /// ```
240
    #[inline]
241
0
    fn is_normal(self) -> bool {
242
0
        self.classify() == FpCategory::Normal
243
0
    }
244
245
    /// Returns `true` if the number is [subnormal].
246
    ///
247
    /// ```
248
    /// use num_traits::float::FloatCore;
249
    /// use std::f64;
250
    ///
251
    /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64
252
    /// let max = f64::MAX;
253
    /// let lower_than_min = 1.0e-308_f64;
254
    /// let zero = 0.0_f64;
255
    ///
256
    /// assert!(!min.is_subnormal());
257
    /// assert!(!max.is_subnormal());
258
    ///
259
    /// assert!(!zero.is_subnormal());
260
    /// assert!(!f64::NAN.is_subnormal());
261
    /// assert!(!f64::INFINITY.is_subnormal());
262
    /// // Values between `0` and `min` are Subnormal.
263
    /// assert!(lower_than_min.is_subnormal());
264
    /// ```
265
    /// [subnormal]: https://en.wikipedia.org/wiki/Subnormal_number
266
    #[inline]
267
0
    fn is_subnormal(self) -> bool {
268
0
        self.classify() == FpCategory::Subnormal
269
0
    }
270
271
    /// Returns the floating point category of the number. If only one property
272
    /// is going to be tested, it is generally faster to use the specific
273
    /// predicate instead.
274
    ///
275
    /// # Examples
276
    ///
277
    /// ```
278
    /// use num_traits::float::FloatCore;
279
    /// use std::{f32, f64};
280
    /// use std::num::FpCategory;
281
    ///
282
    /// fn check<T: FloatCore>(x: T, c: FpCategory) {
283
    ///     assert!(x.classify() == c);
284
    /// }
285
    ///
286
    /// check(f32::INFINITY, FpCategory::Infinite);
287
    /// check(f32::MAX, FpCategory::Normal);
288
    /// check(f64::NAN, FpCategory::Nan);
289
    /// check(f64::MIN_POSITIVE, FpCategory::Normal);
290
    /// check(f64::MIN_POSITIVE / 2.0, FpCategory::Subnormal);
291
    /// check(0.0f64, FpCategory::Zero);
292
    /// ```
293
    fn classify(self) -> FpCategory;
294
295
    /// Returns the largest integer less than or equal to a number.
296
    ///
297
    /// # Examples
298
    ///
299
    /// ```
300
    /// use num_traits::float::FloatCore;
301
    /// use std::{f32, f64};
302
    ///
303
    /// fn check<T: FloatCore>(x: T, y: T) {
304
    ///     assert!(x.floor() == y);
305
    /// }
306
    ///
307
    /// check(f32::INFINITY, f32::INFINITY);
308
    /// check(0.9f32, 0.0);
309
    /// check(1.0f32, 1.0);
310
    /// check(1.1f32, 1.0);
311
    /// check(-0.0f64, 0.0);
312
    /// check(-0.9f64, -1.0);
313
    /// check(-1.0f64, -1.0);
314
    /// check(-1.1f64, -2.0);
315
    /// check(f64::MIN, f64::MIN);
316
    /// ```
317
    #[inline]
318
0
    fn floor(self) -> Self {
319
0
        let f = self.fract();
320
0
        if f.is_nan() || f.is_zero() {
321
0
            self
322
0
        } else if self < Self::zero() {
323
0
            self - f - Self::one()
324
        } else {
325
0
            self - f
326
        }
327
0
    }
328
329
    /// Returns the smallest integer greater than or equal to a number.
330
    ///
331
    /// # Examples
332
    ///
333
    /// ```
334
    /// use num_traits::float::FloatCore;
335
    /// use std::{f32, f64};
336
    ///
337
    /// fn check<T: FloatCore>(x: T, y: T) {
338
    ///     assert!(x.ceil() == y);
339
    /// }
340
    ///
341
    /// check(f32::INFINITY, f32::INFINITY);
342
    /// check(0.9f32, 1.0);
343
    /// check(1.0f32, 1.0);
344
    /// check(1.1f32, 2.0);
345
    /// check(-0.0f64, 0.0);
346
    /// check(-0.9f64, -0.0);
347
    /// check(-1.0f64, -1.0);
348
    /// check(-1.1f64, -1.0);
349
    /// check(f64::MIN, f64::MIN);
350
    /// ```
351
    #[inline]
352
0
    fn ceil(self) -> Self {
353
0
        let f = self.fract();
354
0
        if f.is_nan() || f.is_zero() {
355
0
            self
356
0
        } else if self > Self::zero() {
357
0
            self - f + Self::one()
358
        } else {
359
0
            self - f
360
        }
361
0
    }
362
363
    /// Returns the nearest integer to a number. Round half-way cases away from `0.0`.
364
    ///
365
    /// # Examples
366
    ///
367
    /// ```
368
    /// use num_traits::float::FloatCore;
369
    /// use std::{f32, f64};
370
    ///
371
    /// fn check<T: FloatCore>(x: T, y: T) {
372
    ///     assert!(x.round() == y);
373
    /// }
374
    ///
375
    /// check(f32::INFINITY, f32::INFINITY);
376
    /// check(0.4f32, 0.0);
377
    /// check(0.5f32, 1.0);
378
    /// check(0.6f32, 1.0);
379
    /// check(-0.4f64, 0.0);
380
    /// check(-0.5f64, -1.0);
381
    /// check(-0.6f64, -1.0);
382
    /// check(f64::MIN, f64::MIN);
383
    /// ```
384
    #[inline]
385
0
    fn round(self) -> Self {
386
0
        let one = Self::one();
387
0
        let h = Self::from(0.5).expect("Unable to cast from 0.5");
388
0
        let f = self.fract();
389
0
        if f.is_nan() || f.is_zero() {
390
0
            self
391
0
        } else if self > Self::zero() {
392
0
            if f < h {
393
0
                self - f
394
            } else {
395
0
                self - f + one
396
            }
397
0
        } else if -f < h {
398
0
            self - f
399
        } else {
400
0
            self - f - one
401
        }
402
0
    }
403
404
    /// Return the integer part of a number.
405
    ///
406
    /// # Examples
407
    ///
408
    /// ```
409
    /// use num_traits::float::FloatCore;
410
    /// use std::{f32, f64};
411
    ///
412
    /// fn check<T: FloatCore>(x: T, y: T) {
413
    ///     assert!(x.trunc() == y);
414
    /// }
415
    ///
416
    /// check(f32::INFINITY, f32::INFINITY);
417
    /// check(0.9f32, 0.0);
418
    /// check(1.0f32, 1.0);
419
    /// check(1.1f32, 1.0);
420
    /// check(-0.0f64, 0.0);
421
    /// check(-0.9f64, -0.0);
422
    /// check(-1.0f64, -1.0);
423
    /// check(-1.1f64, -1.0);
424
    /// check(f64::MIN, f64::MIN);
425
    /// ```
426
    #[inline]
427
0
    fn trunc(self) -> Self {
428
0
        let f = self.fract();
429
0
        if f.is_nan() {
430
0
            self
431
        } else {
432
0
            self - f
433
        }
434
0
    }
435
436
    /// Returns the fractional part of a number.
437
    ///
438
    /// # Examples
439
    ///
440
    /// ```
441
    /// use num_traits::float::FloatCore;
442
    /// use std::{f32, f64};
443
    ///
444
    /// fn check<T: FloatCore>(x: T, y: T) {
445
    ///     assert!(x.fract() == y);
446
    /// }
447
    ///
448
    /// check(f32::MAX, 0.0);
449
    /// check(0.75f32, 0.75);
450
    /// check(1.0f32, 0.0);
451
    /// check(1.25f32, 0.25);
452
    /// check(-0.0f64, 0.0);
453
    /// check(-0.75f64, -0.75);
454
    /// check(-1.0f64, 0.0);
455
    /// check(-1.25f64, -0.25);
456
    /// check(f64::MIN, 0.0);
457
    /// ```
458
    #[inline]
459
0
    fn fract(self) -> Self {
460
0
        if self.is_zero() {
461
0
            Self::zero()
462
        } else {
463
0
            self % Self::one()
464
        }
465
0
    }
466
467
    /// Computes the absolute value of `self`. Returns `FloatCore::nan()` if the
468
    /// number is `FloatCore::nan()`.
469
    ///
470
    /// # Examples
471
    ///
472
    /// ```
473
    /// use num_traits::float::FloatCore;
474
    /// use std::{f32, f64};
475
    ///
476
    /// fn check<T: FloatCore>(x: T, y: T) {
477
    ///     assert!(x.abs() == y);
478
    /// }
479
    ///
480
    /// check(f32::INFINITY, f32::INFINITY);
481
    /// check(1.0f32, 1.0);
482
    /// check(0.0f64, 0.0);
483
    /// check(-0.0f64, 0.0);
484
    /// check(-1.0f64, 1.0);
485
    /// check(f64::MIN, f64::MAX);
486
    /// ```
487
    #[inline]
488
0
    fn abs(self) -> Self {
489
0
        if self.is_sign_positive() {
490
0
            return self;
491
0
        }
492
0
        if self.is_sign_negative() {
493
0
            return -self;
494
0
        }
495
0
        Self::nan()
496
0
    }
497
498
    /// Returns a number that represents the sign of `self`.
499
    ///
500
    /// - `1.0` if the number is positive, `+0.0` or `FloatCore::infinity()`
501
    /// - `-1.0` if the number is negative, `-0.0` or `FloatCore::neg_infinity()`
502
    /// - `FloatCore::nan()` if the number is `FloatCore::nan()`
503
    ///
504
    /// # Examples
505
    ///
506
    /// ```
507
    /// use num_traits::float::FloatCore;
508
    /// use std::{f32, f64};
509
    ///
510
    /// fn check<T: FloatCore>(x: T, y: T) {
511
    ///     assert!(x.signum() == y);
512
    /// }
513
    ///
514
    /// check(f32::INFINITY, 1.0);
515
    /// check(3.0f32, 1.0);
516
    /// check(0.0f32, 1.0);
517
    /// check(-0.0f64, -1.0);
518
    /// check(-3.0f64, -1.0);
519
    /// check(f64::MIN, -1.0);
520
    /// ```
521
    #[inline]
522
0
    fn signum(self) -> Self {
523
0
        if self.is_nan() {
524
0
            Self::nan()
525
0
        } else if self.is_sign_negative() {
526
0
            -Self::one()
527
        } else {
528
0
            Self::one()
529
        }
530
0
    }
531
532
    /// Returns `true` if `self` is positive, including `+0.0` and
533
    /// `FloatCore::infinity()`, and `FloatCore::nan()`.
534
    ///
535
    /// # Examples
536
    ///
537
    /// ```
538
    /// use num_traits::float::FloatCore;
539
    /// use std::{f32, f64};
540
    ///
541
    /// fn check<T: FloatCore>(x: T, p: bool) {
542
    ///     assert!(x.is_sign_positive() == p);
543
    /// }
544
    ///
545
    /// check(f32::INFINITY, true);
546
    /// check(f32::MAX, true);
547
    /// check(0.0f32, true);
548
    /// check(-0.0f64, false);
549
    /// check(f64::NEG_INFINITY, false);
550
    /// check(f64::MIN_POSITIVE, true);
551
    /// check(f64::NAN, true);
552
    /// check(-f64::NAN, false);
553
    /// ```
554
    #[inline]
555
0
    fn is_sign_positive(self) -> bool {
556
0
        !self.is_sign_negative()
557
0
    }
558
559
    /// Returns `true` if `self` is negative, including `-0.0` and
560
    /// `FloatCore::neg_infinity()`, and `-FloatCore::nan()`.
561
    ///
562
    /// # Examples
563
    ///
564
    /// ```
565
    /// use num_traits::float::FloatCore;
566
    /// use std::{f32, f64};
567
    ///
568
    /// fn check<T: FloatCore>(x: T, p: bool) {
569
    ///     assert!(x.is_sign_negative() == p);
570
    /// }
571
    ///
572
    /// check(f32::INFINITY, false);
573
    /// check(f32::MAX, false);
574
    /// check(0.0f32, false);
575
    /// check(-0.0f64, true);
576
    /// check(f64::NEG_INFINITY, true);
577
    /// check(f64::MIN_POSITIVE, false);
578
    /// check(f64::NAN, false);
579
    /// check(-f64::NAN, true);
580
    /// ```
581
    #[inline]
582
0
    fn is_sign_negative(self) -> bool {
583
0
        let (_, _, sign) = self.integer_decode();
584
0
        sign < 0
585
0
    }
586
587
    /// Returns the minimum of the two numbers.
588
    ///
589
    /// If one of the arguments is NaN, then the other argument is returned.
590
    ///
591
    /// # Examples
592
    ///
593
    /// ```
594
    /// use num_traits::float::FloatCore;
595
    /// use std::{f32, f64};
596
    ///
597
    /// fn check<T: FloatCore>(x: T, y: T, min: T) {
598
    ///     assert!(x.min(y) == min);
599
    /// }
600
    ///
601
    /// check(1.0f32, 2.0, 1.0);
602
    /// check(f32::NAN, 2.0, 2.0);
603
    /// check(1.0f64, -2.0, -2.0);
604
    /// check(1.0f64, f64::NAN, 1.0);
605
    /// ```
606
    #[inline]
607
0
    fn min(self, other: Self) -> Self {
608
0
        if self.is_nan() {
609
0
            return other;
610
0
        }
611
0
        if other.is_nan() {
612
0
            return self;
613
0
        }
614
0
        if self < other {
615
0
            self
616
        } else {
617
0
            other
618
        }
619
0
    }
620
621
    /// Returns the maximum of the two numbers.
622
    ///
623
    /// If one of the arguments is NaN, then the other argument is returned.
624
    ///
625
    /// # Examples
626
    ///
627
    /// ```
628
    /// use num_traits::float::FloatCore;
629
    /// use std::{f32, f64};
630
    ///
631
    /// fn check<T: FloatCore>(x: T, y: T, max: T) {
632
    ///     assert!(x.max(y) == max);
633
    /// }
634
    ///
635
    /// check(1.0f32, 2.0, 2.0);
636
    /// check(1.0f32, f32::NAN, 1.0);
637
    /// check(-1.0f64, 2.0, 2.0);
638
    /// check(-1.0f64, f64::NAN, -1.0);
639
    /// ```
640
    #[inline]
641
0
    fn max(self, other: Self) -> Self {
642
0
        if self.is_nan() {
643
0
            return other;
644
0
        }
645
0
        if other.is_nan() {
646
0
            return self;
647
0
        }
648
0
        if self > other {
649
0
            self
650
        } else {
651
0
            other
652
        }
653
0
    }
654
655
    /// A value bounded by a minimum and a maximum
656
    ///
657
    ///  If input is less than min then this returns min.
658
    ///  If input is greater than max then this returns max.
659
    ///  Otherwise this returns input.
660
    ///
661
    /// **Panics** in debug mode if `!(min <= max)`.
662
    ///
663
    /// # Examples
664
    ///
665
    /// ```
666
    /// use num_traits::float::FloatCore;
667
    ///
668
    /// fn check<T: FloatCore>(val: T, min: T, max: T, expected: T) {
669
    ///     assert!(val.clamp(min, max) == expected);
670
    /// }
671
    ///
672
    ///
673
    /// check(1.0f32, 0.0, 2.0, 1.0);
674
    /// check(1.0f32, 2.0, 3.0, 2.0);
675
    /// check(3.0f32, 0.0, 2.0, 2.0);
676
    ///
677
    /// check(1.0f64, 0.0, 2.0, 1.0);
678
    /// check(1.0f64, 2.0, 3.0, 2.0);
679
    /// check(3.0f64, 0.0, 2.0, 2.0);
680
    /// ```
681
0
    fn clamp(self, min: Self, max: Self) -> Self {
682
0
        crate::clamp(self, min, max)
683
0
    }
684
685
    /// Returns the reciprocal (multiplicative inverse) of the number.
686
    ///
687
    /// # Examples
688
    ///
689
    /// ```
690
    /// use num_traits::float::FloatCore;
691
    /// use std::{f32, f64};
692
    ///
693
    /// fn check<T: FloatCore>(x: T, y: T) {
694
    ///     assert!(x.recip() == y);
695
    ///     assert!(y.recip() == x);
696
    /// }
697
    ///
698
    /// check(f32::INFINITY, 0.0);
699
    /// check(2.0f32, 0.5);
700
    /// check(-0.25f64, -4.0);
701
    /// check(-0.0f64, f64::NEG_INFINITY);
702
    /// ```
703
    #[inline]
704
0
    fn recip(self) -> Self {
705
0
        Self::one() / self
706
0
    }
707
708
    /// Raise a number to an integer power.
709
    ///
710
    /// Using this function is generally faster than using `powf`
711
    ///
712
    /// # Examples
713
    ///
714
    /// ```
715
    /// use num_traits::float::FloatCore;
716
    ///
717
    /// fn check<T: FloatCore>(x: T, exp: i32, powi: T) {
718
    ///     assert!(x.powi(exp) == powi);
719
    /// }
720
    ///
721
    /// check(9.0f32, 2, 81.0);
722
    /// check(1.0f32, -2, 1.0);
723
    /// check(10.0f64, 20, 1e20);
724
    /// check(4.0f64, -2, 0.0625);
725
    /// check(-1.0f64, std::i32::MIN, 1.0);
726
    /// ```
727
    #[inline]
728
0
    fn powi(mut self, mut exp: i32) -> Self {
729
0
        if exp < 0 {
730
0
            exp = exp.wrapping_neg();
731
0
            self = self.recip();
732
0
        }
733
        // It should always be possible to convert a positive `i32` to a `usize`.
734
        // Note, `i32::MIN` will wrap and still be negative, so we need to convert
735
        // to `u32` without sign-extension before growing to `usize`.
736
0
        super::pow(self, (exp as u32).to_usize().unwrap())
737
0
    }
738
739
    /// Converts to degrees, assuming the number is in radians.
740
    ///
741
    /// # Examples
742
    ///
743
    /// ```
744
    /// use num_traits::float::FloatCore;
745
    /// use std::{f32, f64};
746
    ///
747
    /// fn check<T: FloatCore>(rad: T, deg: T) {
748
    ///     assert!(rad.to_degrees() == deg);
749
    /// }
750
    ///
751
    /// check(0.0f32, 0.0);
752
    /// check(f32::consts::PI, 180.0);
753
    /// check(f64::consts::FRAC_PI_4, 45.0);
754
    /// check(f64::INFINITY, f64::INFINITY);
755
    /// ```
756
    fn to_degrees(self) -> Self;
757
758
    /// Converts to radians, assuming the number is in degrees.
759
    ///
760
    /// # Examples
761
    ///
762
    /// ```
763
    /// use num_traits::float::FloatCore;
764
    /// use std::{f32, f64};
765
    ///
766
    /// fn check<T: FloatCore>(deg: T, rad: T) {
767
    ///     assert!(deg.to_radians() == rad);
768
    /// }
769
    ///
770
    /// check(0.0f32, 0.0);
771
    /// check(180.0, f32::consts::PI);
772
    /// check(45.0, f64::consts::FRAC_PI_4);
773
    /// check(f64::INFINITY, f64::INFINITY);
774
    /// ```
775
    fn to_radians(self) -> Self;
776
777
    /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
778
    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
779
    ///
780
    /// # Examples
781
    ///
782
    /// ```
783
    /// use num_traits::float::FloatCore;
784
    /// use std::{f32, f64};
785
    ///
786
    /// fn check<T: FloatCore>(x: T, m: u64, e: i16, s:i8) {
787
    ///     let (mantissa, exponent, sign) = x.integer_decode();
788
    ///     assert_eq!(mantissa, m);
789
    ///     assert_eq!(exponent, e);
790
    ///     assert_eq!(sign, s);
791
    /// }
792
    ///
793
    /// check(2.0f32, 1 << 23, -22, 1);
794
    /// check(-2.0f32, 1 << 23, -22, -1);
795
    /// check(f32::INFINITY, 1 << 23, 105, 1);
796
    /// check(f64::NEG_INFINITY, 1 << 52, 972, -1);
797
    /// ```
798
    fn integer_decode(self) -> (u64, i16, i8);
799
}
800
801
impl FloatCore for f32 {
802
    constant! {
803
        infinity() -> f32::INFINITY;
804
        neg_infinity() -> f32::NEG_INFINITY;
805
        nan() -> f32::NAN;
806
        neg_zero() -> -0.0;
807
        min_value() -> f32::MIN;
808
        min_positive_value() -> f32::MIN_POSITIVE;
809
        epsilon() -> f32::EPSILON;
810
        max_value() -> f32::MAX;
811
    }
812
813
    #[inline]
814
0
    fn integer_decode(self) -> (u64, i16, i8) {
815
0
        integer_decode_f32(self)
816
0
    }
817
818
    forward! {
819
        Self::is_nan(self) -> bool;
820
        Self::is_infinite(self) -> bool;
821
        Self::is_finite(self) -> bool;
822
        Self::is_normal(self) -> bool;
823
        Self::is_subnormal(self) -> bool;
824
        Self::clamp(self, min: Self, max: Self) -> Self;
825
        Self::classify(self) -> FpCategory;
826
        Self::is_sign_positive(self) -> bool;
827
        Self::is_sign_negative(self) -> bool;
828
        Self::min(self, other: Self) -> Self;
829
        Self::max(self, other: Self) -> Self;
830
        Self::recip(self) -> Self;
831
        Self::to_degrees(self) -> Self;
832
        Self::to_radians(self) -> Self;
833
    }
834
835
    #[cfg(feature = "std")]
836
    forward! {
837
        Self::floor(self) -> Self;
838
        Self::ceil(self) -> Self;
839
        Self::round(self) -> Self;
840
        Self::trunc(self) -> Self;
841
        Self::fract(self) -> Self;
842
        Self::abs(self) -> Self;
843
        Self::signum(self) -> Self;
844
        Self::powi(self, n: i32) -> Self;
845
    }
846
847
    #[cfg(all(not(feature = "std"), feature = "libm"))]
848
    forward! {
849
        libm::floorf as floor(self) -> Self;
850
        libm::ceilf as ceil(self) -> Self;
851
        libm::roundf as round(self) -> Self;
852
        libm::truncf as trunc(self) -> Self;
853
        libm::fabsf as abs(self) -> Self;
854
    }
855
856
    #[cfg(all(not(feature = "std"), feature = "libm"))]
857
    #[inline]
858
    fn fract(self) -> Self {
859
        self - libm::truncf(self)
860
    }
861
}
862
863
impl FloatCore for f64 {
864
    constant! {
865
        infinity() -> f64::INFINITY;
866
        neg_infinity() -> f64::NEG_INFINITY;
867
        nan() -> f64::NAN;
868
        neg_zero() -> -0.0;
869
        min_value() -> f64::MIN;
870
        min_positive_value() -> f64::MIN_POSITIVE;
871
        epsilon() -> f64::EPSILON;
872
        max_value() -> f64::MAX;
873
    }
874
875
    #[inline]
876
0
    fn integer_decode(self) -> (u64, i16, i8) {
877
0
        integer_decode_f64(self)
878
0
    }
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore14integer_decodeCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore14integer_decodeB6_
879
880
    forward! {
881
        Self::is_nan(self) -> bool;
882
        Self::is_infinite(self) -> bool;
883
        Self::is_finite(self) -> bool;
884
        Self::is_normal(self) -> bool;
885
        Self::is_subnormal(self) -> bool;
886
        Self::clamp(self, min: Self, max: Self) -> Self;
887
        Self::classify(self) -> FpCategory;
888
        Self::is_sign_positive(self) -> bool;
889
        Self::is_sign_negative(self) -> bool;
890
        Self::min(self, other: Self) -> Self;
891
        Self::max(self, other: Self) -> Self;
892
        Self::recip(self) -> Self;
893
        Self::to_degrees(self) -> Self;
894
        Self::to_radians(self) -> Self;
895
    }
896
897
    #[cfg(feature = "std")]
898
    forward! {
899
        Self::floor(self) -> Self;
900
        Self::ceil(self) -> Self;
901
        Self::round(self) -> Self;
902
        Self::trunc(self) -> Self;
903
        Self::fract(self) -> Self;
904
        Self::abs(self) -> Self;
905
        Self::signum(self) -> Self;
906
        Self::powi(self, n: i32) -> Self;
907
    }
908
909
    #[cfg(all(not(feature = "std"), feature = "libm"))]
910
    forward! {
911
        libm::floor as floor(self) -> Self;
912
        libm::ceil as ceil(self) -> Self;
913
        libm::round as round(self) -> Self;
914
        libm::trunc as trunc(self) -> Self;
915
        libm::fabs as abs(self) -> Self;
916
    }
917
918
    #[cfg(all(not(feature = "std"), feature = "libm"))]
919
    #[inline]
920
    fn fract(self) -> Self {
921
        self - libm::trunc(self)
922
    }
923
}
924
925
// FIXME: these doctests aren't actually helpful, because they're using and
926
// testing the inherent methods directly, not going through `Float`.
927
928
/// Generic trait for floating point numbers
929
///
930
/// This trait is only available with the `std` feature, or with the `libm` feature otherwise.
931
#[cfg(any(feature = "std", feature = "libm"))]
932
pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
933
    /// Returns the `NaN` value.
934
    ///
935
    /// ```
936
    /// use num_traits::Float;
937
    ///
938
    /// let nan: f32 = Float::nan();
939
    ///
940
    /// assert!(nan.is_nan());
941
    /// ```
942
    fn nan() -> Self;
943
    /// Returns the infinite value.
944
    ///
945
    /// ```
946
    /// use num_traits::Float;
947
    /// use std::f32;
948
    ///
949
    /// let infinity: f32 = Float::infinity();
950
    ///
951
    /// assert!(infinity.is_infinite());
952
    /// assert!(!infinity.is_finite());
953
    /// assert!(infinity > f32::MAX);
954
    /// ```
955
    fn infinity() -> Self;
956
    /// Returns the negative infinite value.
957
    ///
958
    /// ```
959
    /// use num_traits::Float;
960
    /// use std::f32;
961
    ///
962
    /// let neg_infinity: f32 = Float::neg_infinity();
963
    ///
964
    /// assert!(neg_infinity.is_infinite());
965
    /// assert!(!neg_infinity.is_finite());
966
    /// assert!(neg_infinity < f32::MIN);
967
    /// ```
968
    fn neg_infinity() -> Self;
969
    /// Returns `-0.0`.
970
    ///
971
    /// ```
972
    /// use num_traits::{Zero, Float};
973
    ///
974
    /// let inf: f32 = Float::infinity();
975
    /// let zero: f32 = Zero::zero();
976
    /// let neg_zero: f32 = Float::neg_zero();
977
    ///
978
    /// assert_eq!(zero, neg_zero);
979
    /// assert_eq!(7.0f32/inf, zero);
980
    /// assert_eq!(zero * 10.0, zero);
981
    /// ```
982
    fn neg_zero() -> Self;
983
984
    /// Returns the smallest finite value that this type can represent.
985
    ///
986
    /// ```
987
    /// use num_traits::Float;
988
    /// use std::f64;
989
    ///
990
    /// let x: f64 = Float::min_value();
991
    ///
992
    /// assert_eq!(x, f64::MIN);
993
    /// ```
994
    fn min_value() -> Self;
995
996
    /// Returns the smallest positive, normalized value that this type can represent.
997
    ///
998
    /// ```
999
    /// use num_traits::Float;
1000
    /// use std::f64;
1001
    ///
1002
    /// let x: f64 = Float::min_positive_value();
1003
    ///
1004
    /// assert_eq!(x, f64::MIN_POSITIVE);
1005
    /// ```
1006
    fn min_positive_value() -> Self;
1007
1008
    /// Returns epsilon, a small positive value.
1009
    ///
1010
    /// ```
1011
    /// use num_traits::Float;
1012
    /// use std::f64;
1013
    ///
1014
    /// let x: f64 = Float::epsilon();
1015
    ///
1016
    /// assert_eq!(x, f64::EPSILON);
1017
    /// ```
1018
    ///
1019
    /// # Panics
1020
    ///
1021
    /// The default implementation will panic if `f32::EPSILON` cannot
1022
    /// be cast to `Self`.
1023
0
    fn epsilon() -> Self {
1024
0
        Self::from(f32::EPSILON).expect("Unable to cast from f32::EPSILON")
1025
0
    }
1026
1027
    /// Returns the largest finite value that this type can represent.
1028
    ///
1029
    /// ```
1030
    /// use num_traits::Float;
1031
    /// use std::f64;
1032
    ///
1033
    /// let x: f64 = Float::max_value();
1034
    /// assert_eq!(x, f64::MAX);
1035
    /// ```
1036
    fn max_value() -> Self;
1037
1038
    /// Returns `true` if this value is `NaN` and false otherwise.
1039
    ///
1040
    /// ```
1041
    /// use num_traits::Float;
1042
    /// use std::f64;
1043
    ///
1044
    /// let nan = f64::NAN;
1045
    /// let f = 7.0;
1046
    ///
1047
    /// assert!(nan.is_nan());
1048
    /// assert!(!f.is_nan());
1049
    /// ```
1050
    fn is_nan(self) -> bool;
1051
1052
    /// Returns `true` if this value is positive infinity or negative infinity and
1053
    /// false otherwise.
1054
    ///
1055
    /// ```
1056
    /// use num_traits::Float;
1057
    /// use std::f32;
1058
    ///
1059
    /// let f = 7.0f32;
1060
    /// let inf: f32 = Float::infinity();
1061
    /// let neg_inf: f32 = Float::neg_infinity();
1062
    /// let nan: f32 = f32::NAN;
1063
    ///
1064
    /// assert!(!f.is_infinite());
1065
    /// assert!(!nan.is_infinite());
1066
    ///
1067
    /// assert!(inf.is_infinite());
1068
    /// assert!(neg_inf.is_infinite());
1069
    /// ```
1070
    fn is_infinite(self) -> bool;
1071
1072
    /// Returns `true` if this number is neither infinite nor `NaN`.
1073
    ///
1074
    /// ```
1075
    /// use num_traits::Float;
1076
    /// use std::f32;
1077
    ///
1078
    /// let f = 7.0f32;
1079
    /// let inf: f32 = Float::infinity();
1080
    /// let neg_inf: f32 = Float::neg_infinity();
1081
    /// let nan: f32 = f32::NAN;
1082
    ///
1083
    /// assert!(f.is_finite());
1084
    ///
1085
    /// assert!(!nan.is_finite());
1086
    /// assert!(!inf.is_finite());
1087
    /// assert!(!neg_inf.is_finite());
1088
    /// ```
1089
    fn is_finite(self) -> bool;
1090
1091
    /// Returns `true` if the number is neither zero, infinite,
1092
    /// [subnormal][subnormal], or `NaN`.
1093
    ///
1094
    /// ```
1095
    /// use num_traits::Float;
1096
    /// use std::f32;
1097
    ///
1098
    /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
1099
    /// let max = f32::MAX;
1100
    /// let lower_than_min = 1.0e-40_f32;
1101
    /// let zero = 0.0f32;
1102
    ///
1103
    /// assert!(min.is_normal());
1104
    /// assert!(max.is_normal());
1105
    ///
1106
    /// assert!(!zero.is_normal());
1107
    /// assert!(!f32::NAN.is_normal());
1108
    /// assert!(!f32::INFINITY.is_normal());
1109
    /// // Values between `0` and `min` are Subnormal.
1110
    /// assert!(!lower_than_min.is_normal());
1111
    /// ```
1112
    /// [subnormal]: http://en.wikipedia.org/wiki/Subnormal_number
1113
    fn is_normal(self) -> bool;
1114
1115
    /// Returns `true` if the number is [subnormal].
1116
    ///
1117
    /// ```
1118
    /// use num_traits::Float;
1119
    /// use std::f64;
1120
    ///
1121
    /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64
1122
    /// let max = f64::MAX;
1123
    /// let lower_than_min = 1.0e-308_f64;
1124
    /// let zero = 0.0_f64;
1125
    ///
1126
    /// assert!(!min.is_subnormal());
1127
    /// assert!(!max.is_subnormal());
1128
    ///
1129
    /// assert!(!zero.is_subnormal());
1130
    /// assert!(!f64::NAN.is_subnormal());
1131
    /// assert!(!f64::INFINITY.is_subnormal());
1132
    /// // Values between `0` and `min` are Subnormal.
1133
    /// assert!(lower_than_min.is_subnormal());
1134
    /// ```
1135
    /// [subnormal]: https://en.wikipedia.org/wiki/Subnormal_number
1136
    #[inline]
1137
0
    fn is_subnormal(self) -> bool {
1138
0
        self.classify() == FpCategory::Subnormal
1139
0
    }
1140
1141
    /// Returns the floating point category of the number. If only one property
1142
    /// is going to be tested, it is generally faster to use the specific
1143
    /// predicate instead.
1144
    ///
1145
    /// ```
1146
    /// use num_traits::Float;
1147
    /// use std::num::FpCategory;
1148
    /// use std::f32;
1149
    ///
1150
    /// let num = 12.4f32;
1151
    /// let inf = f32::INFINITY;
1152
    ///
1153
    /// assert_eq!(num.classify(), FpCategory::Normal);
1154
    /// assert_eq!(inf.classify(), FpCategory::Infinite);
1155
    /// ```
1156
    fn classify(self) -> FpCategory;
1157
1158
    /// Returns the largest integer less than or equal to a number.
1159
    ///
1160
    /// ```
1161
    /// use num_traits::Float;
1162
    ///
1163
    /// let f = 3.99;
1164
    /// let g = 3.0;
1165
    ///
1166
    /// assert_eq!(f.floor(), 3.0);
1167
    /// assert_eq!(g.floor(), 3.0);
1168
    /// ```
1169
    fn floor(self) -> Self;
1170
1171
    /// Returns the smallest integer greater than or equal to a number.
1172
    ///
1173
    /// ```
1174
    /// use num_traits::Float;
1175
    ///
1176
    /// let f = 3.01;
1177
    /// let g = 4.0;
1178
    ///
1179
    /// assert_eq!(f.ceil(), 4.0);
1180
    /// assert_eq!(g.ceil(), 4.0);
1181
    /// ```
1182
    fn ceil(self) -> Self;
1183
1184
    /// Returns the nearest integer to a number. Round half-way cases away from
1185
    /// `0.0`.
1186
    ///
1187
    /// ```
1188
    /// use num_traits::Float;
1189
    ///
1190
    /// let f = 3.3;
1191
    /// let g = -3.3;
1192
    ///
1193
    /// assert_eq!(f.round(), 3.0);
1194
    /// assert_eq!(g.round(), -3.0);
1195
    /// ```
1196
    fn round(self) -> Self;
1197
1198
    /// Return the integer part of a number.
1199
    ///
1200
    /// ```
1201
    /// use num_traits::Float;
1202
    ///
1203
    /// let f = 3.3;
1204
    /// let g = -3.7;
1205
    ///
1206
    /// assert_eq!(f.trunc(), 3.0);
1207
    /// assert_eq!(g.trunc(), -3.0);
1208
    /// ```
1209
    fn trunc(self) -> Self;
1210
1211
    /// Returns the fractional part of a number.
1212
    ///
1213
    /// ```
1214
    /// use num_traits::Float;
1215
    ///
1216
    /// let x = 3.5;
1217
    /// let y = -3.5;
1218
    /// let abs_difference_x = (x.fract() - 0.5).abs();
1219
    /// let abs_difference_y = (y.fract() - (-0.5)).abs();
1220
    ///
1221
    /// assert!(abs_difference_x < 1e-10);
1222
    /// assert!(abs_difference_y < 1e-10);
1223
    /// ```
1224
    fn fract(self) -> Self;
1225
1226
    /// Computes the absolute value of `self`. Returns `Float::nan()` if the
1227
    /// number is `Float::nan()`.
1228
    ///
1229
    /// ```
1230
    /// use num_traits::Float;
1231
    /// use std::f64;
1232
    ///
1233
    /// let x = 3.5;
1234
    /// let y = -3.5;
1235
    ///
1236
    /// let abs_difference_x = (x.abs() - x).abs();
1237
    /// let abs_difference_y = (y.abs() - (-y)).abs();
1238
    ///
1239
    /// assert!(abs_difference_x < 1e-10);
1240
    /// assert!(abs_difference_y < 1e-10);
1241
    ///
1242
    /// assert!(f64::NAN.abs().is_nan());
1243
    /// ```
1244
    fn abs(self) -> Self;
1245
1246
    /// Returns a number that represents the sign of `self`.
1247
    ///
1248
    /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
1249
    /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
1250
    /// - `Float::nan()` if the number is `Float::nan()`
1251
    ///
1252
    /// ```
1253
    /// use num_traits::Float;
1254
    /// use std::f64;
1255
    ///
1256
    /// let f = 3.5;
1257
    ///
1258
    /// assert_eq!(f.signum(), 1.0);
1259
    /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
1260
    ///
1261
    /// assert!(f64::NAN.signum().is_nan());
1262
    /// ```
1263
    fn signum(self) -> Self;
1264
1265
    /// Returns `true` if `self` is positive, including `+0.0`,
1266
    /// `Float::infinity()`, and `Float::nan()`.
1267
    ///
1268
    /// ```
1269
    /// use num_traits::Float;
1270
    /// use std::f64;
1271
    ///
1272
    /// let nan: f64 = f64::NAN;
1273
    /// let neg_nan: f64 = -f64::NAN;
1274
    ///
1275
    /// let f = 7.0;
1276
    /// let g = -7.0;
1277
    ///
1278
    /// assert!(f.is_sign_positive());
1279
    /// assert!(!g.is_sign_positive());
1280
    /// assert!(nan.is_sign_positive());
1281
    /// assert!(!neg_nan.is_sign_positive());
1282
    /// ```
1283
    fn is_sign_positive(self) -> bool;
1284
1285
    /// Returns `true` if `self` is negative, including `-0.0`,
1286
    /// `Float::neg_infinity()`, and `-Float::nan()`.
1287
    ///
1288
    /// ```
1289
    /// use num_traits::Float;
1290
    /// use std::f64;
1291
    ///
1292
    /// let nan: f64 = f64::NAN;
1293
    /// let neg_nan: f64 = -f64::NAN;
1294
    ///
1295
    /// let f = 7.0;
1296
    /// let g = -7.0;
1297
    ///
1298
    /// assert!(!f.is_sign_negative());
1299
    /// assert!(g.is_sign_negative());
1300
    /// assert!(!nan.is_sign_negative());
1301
    /// assert!(neg_nan.is_sign_negative());
1302
    /// ```
1303
    fn is_sign_negative(self) -> bool;
1304
1305
    /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
1306
    /// error, yielding a more accurate result than an unfused multiply-add.
1307
    ///
1308
    /// Using `mul_add` can be more performant than an unfused multiply-add if
1309
    /// the target architecture has a dedicated `fma` CPU instruction.
1310
    ///
1311
    /// ```
1312
    /// use num_traits::Float;
1313
    ///
1314
    /// let m = 10.0;
1315
    /// let x = 4.0;
1316
    /// let b = 60.0;
1317
    ///
1318
    /// // 100.0
1319
    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
1320
    ///
1321
    /// assert!(abs_difference < 1e-10);
1322
    /// ```
1323
    fn mul_add(self, a: Self, b: Self) -> Self;
1324
    /// Take the reciprocal (inverse) of a number, `1/x`.
1325
    ///
1326
    /// ```
1327
    /// use num_traits::Float;
1328
    ///
1329
    /// let x = 2.0;
1330
    /// let abs_difference = (x.recip() - (1.0/x)).abs();
1331
    ///
1332
    /// assert!(abs_difference < 1e-10);
1333
    /// ```
1334
    fn recip(self) -> Self;
1335
1336
    /// Raise a number to an integer power.
1337
    ///
1338
    /// Using this function is generally faster than using `powf`
1339
    ///
1340
    /// ```
1341
    /// use num_traits::Float;
1342
    ///
1343
    /// let x = 2.0;
1344
    /// let abs_difference = (x.powi(2) - x*x).abs();
1345
    ///
1346
    /// assert!(abs_difference < 1e-10);
1347
    /// ```
1348
    fn powi(self, n: i32) -> Self;
1349
1350
    /// Raise a number to a floating point power.
1351
    ///
1352
    /// ```
1353
    /// use num_traits::Float;
1354
    ///
1355
    /// let x = 2.0;
1356
    /// let abs_difference = (x.powf(2.0) - x*x).abs();
1357
    ///
1358
    /// assert!(abs_difference < 1e-10);
1359
    /// ```
1360
    fn powf(self, n: Self) -> Self;
1361
1362
    /// Take the square root of a number.
1363
    ///
1364
    /// Returns NaN if `self` is a negative number.
1365
    ///
1366
    /// ```
1367
    /// use num_traits::Float;
1368
    ///
1369
    /// let positive = 4.0;
1370
    /// let negative = -4.0;
1371
    ///
1372
    /// let abs_difference = (positive.sqrt() - 2.0).abs();
1373
    ///
1374
    /// assert!(abs_difference < 1e-10);
1375
    /// assert!(negative.sqrt().is_nan());
1376
    /// ```
1377
    fn sqrt(self) -> Self;
1378
1379
    /// Returns `e^(self)`, (the exponential function).
1380
    ///
1381
    /// ```
1382
    /// use num_traits::Float;
1383
    ///
1384
    /// let one = 1.0;
1385
    /// // e^1
1386
    /// let e = one.exp();
1387
    ///
1388
    /// // ln(e) - 1 == 0
1389
    /// let abs_difference = (e.ln() - 1.0).abs();
1390
    ///
1391
    /// assert!(abs_difference < 1e-10);
1392
    /// ```
1393
    fn exp(self) -> Self;
1394
1395
    /// Returns `2^(self)`.
1396
    ///
1397
    /// ```
1398
    /// use num_traits::Float;
1399
    ///
1400
    /// let f = 2.0;
1401
    ///
1402
    /// // 2^2 - 4 == 0
1403
    /// let abs_difference = (f.exp2() - 4.0).abs();
1404
    ///
1405
    /// assert!(abs_difference < 1e-10);
1406
    /// ```
1407
    fn exp2(self) -> Self;
1408
1409
    /// Returns the natural logarithm of the number.
1410
    ///
1411
    /// ```
1412
    /// use num_traits::Float;
1413
    ///
1414
    /// let one = 1.0;
1415
    /// // e^1
1416
    /// let e = one.exp();
1417
    ///
1418
    /// // ln(e) - 1 == 0
1419
    /// let abs_difference = (e.ln() - 1.0).abs();
1420
    ///
1421
    /// assert!(abs_difference < 1e-10);
1422
    /// ```
1423
    fn ln(self) -> Self;
1424
1425
    /// Returns the logarithm of the number with respect to an arbitrary base.
1426
    ///
1427
    /// ```
1428
    /// use num_traits::Float;
1429
    ///
1430
    /// let ten = 10.0;
1431
    /// let two = 2.0;
1432
    ///
1433
    /// // log10(10) - 1 == 0
1434
    /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs();
1435
    ///
1436
    /// // log2(2) - 1 == 0
1437
    /// let abs_difference_2 = (two.log(2.0) - 1.0).abs();
1438
    ///
1439
    /// assert!(abs_difference_10 < 1e-10);
1440
    /// assert!(abs_difference_2 < 1e-10);
1441
    /// ```
1442
    fn log(self, base: Self) -> Self;
1443
1444
    /// Returns the base 2 logarithm of the number.
1445
    ///
1446
    /// ```
1447
    /// use num_traits::Float;
1448
    ///
1449
    /// let two = 2.0;
1450
    ///
1451
    /// // log2(2) - 1 == 0
1452
    /// let abs_difference = (two.log2() - 1.0).abs();
1453
    ///
1454
    /// assert!(abs_difference < 1e-10);
1455
    /// ```
1456
    fn log2(self) -> Self;
1457
1458
    /// Returns the base 10 logarithm of the number.
1459
    ///
1460
    /// ```
1461
    /// use num_traits::Float;
1462
    ///
1463
    /// let ten = 10.0;
1464
    ///
1465
    /// // log10(10) - 1 == 0
1466
    /// let abs_difference = (ten.log10() - 1.0).abs();
1467
    ///
1468
    /// assert!(abs_difference < 1e-10);
1469
    /// ```
1470
    fn log10(self) -> Self;
1471
1472
    /// Converts radians to degrees.
1473
    ///
1474
    /// ```
1475
    /// use std::f64::consts;
1476
    ///
1477
    /// let angle = consts::PI;
1478
    ///
1479
    /// let abs_difference = (angle.to_degrees() - 180.0).abs();
1480
    ///
1481
    /// assert!(abs_difference < 1e-10);
1482
    /// ```
1483
    #[inline]
1484
0
    fn to_degrees(self) -> Self {
1485
0
        let halfpi = Self::zero().acos();
1486
0
        let ninety = Self::from(90u8).unwrap();
1487
0
        self * ninety / halfpi
1488
0
    }
1489
1490
    /// Converts degrees to radians.
1491
    ///
1492
    /// ```
1493
    /// use std::f64::consts;
1494
    ///
1495
    /// let angle = 180.0_f64;
1496
    ///
1497
    /// let abs_difference = (angle.to_radians() - consts::PI).abs();
1498
    ///
1499
    /// assert!(abs_difference < 1e-10);
1500
    /// ```
1501
    #[inline]
1502
0
    fn to_radians(self) -> Self {
1503
0
        let halfpi = Self::zero().acos();
1504
0
        let ninety = Self::from(90u8).unwrap();
1505
0
        self * halfpi / ninety
1506
0
    }
1507
1508
    /// Returns the maximum of the two numbers.
1509
    ///
1510
    /// ```
1511
    /// use num_traits::Float;
1512
    ///
1513
    /// let x = 1.0;
1514
    /// let y = 2.0;
1515
    ///
1516
    /// assert_eq!(x.max(y), y);
1517
    /// ```
1518
    fn max(self, other: Self) -> Self;
1519
1520
    /// Returns the minimum of the two numbers.
1521
    ///
1522
    /// ```
1523
    /// use num_traits::Float;
1524
    ///
1525
    /// let x = 1.0;
1526
    /// let y = 2.0;
1527
    ///
1528
    /// assert_eq!(x.min(y), x);
1529
    /// ```
1530
    fn min(self, other: Self) -> Self;
1531
1532
    /// Clamps a value between a min and max.
1533
    ///
1534
    /// **Panics** in debug mode if `!(min <= max)`.
1535
    ///
1536
    /// ```
1537
    /// use num_traits::Float;
1538
    ///
1539
    /// let x = 1.0;
1540
    /// let y = 2.0;
1541
    /// let z = 3.0;
1542
    ///
1543
    /// assert_eq!(x.clamp(y, z), 2.0);
1544
    /// ```
1545
0
    fn clamp(self, min: Self, max: Self) -> Self {
1546
0
        crate::clamp(self, min, max)
1547
0
    }
1548
1549
    /// The positive difference of two numbers.
1550
    ///
1551
    /// * If `self <= other`: `0:0`
1552
    /// * Else: `self - other`
1553
    ///
1554
    /// ```
1555
    /// use num_traits::Float;
1556
    ///
1557
    /// let x = 3.0;
1558
    /// let y = -3.0;
1559
    ///
1560
    /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
1561
    /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
1562
    ///
1563
    /// assert!(abs_difference_x < 1e-10);
1564
    /// assert!(abs_difference_y < 1e-10);
1565
    /// ```
1566
    fn abs_sub(self, other: Self) -> Self;
1567
1568
    /// Take the cubic root of a number.
1569
    ///
1570
    /// ```
1571
    /// use num_traits::Float;
1572
    ///
1573
    /// let x = 8.0;
1574
    ///
1575
    /// // x^(1/3) - 2 == 0
1576
    /// let abs_difference = (x.cbrt() - 2.0).abs();
1577
    ///
1578
    /// assert!(abs_difference < 1e-10);
1579
    /// ```
1580
    fn cbrt(self) -> Self;
1581
1582
    /// Calculate the length of the hypotenuse of a right-angle triangle given
1583
    /// legs of length `x` and `y`.
1584
    ///
1585
    /// ```
1586
    /// use num_traits::Float;
1587
    ///
1588
    /// let x = 2.0;
1589
    /// let y = 3.0;
1590
    ///
1591
    /// // sqrt(x^2 + y^2)
1592
    /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
1593
    ///
1594
    /// assert!(abs_difference < 1e-10);
1595
    /// ```
1596
    fn hypot(self, other: Self) -> Self;
1597
1598
    /// Computes the sine of a number (in radians).
1599
    ///
1600
    /// ```
1601
    /// use num_traits::Float;
1602
    /// use std::f64;
1603
    ///
1604
    /// let x = f64::consts::PI/2.0;
1605
    ///
1606
    /// let abs_difference = (x.sin() - 1.0).abs();
1607
    ///
1608
    /// assert!(abs_difference < 1e-10);
1609
    /// ```
1610
    fn sin(self) -> Self;
1611
1612
    /// Computes the cosine of a number (in radians).
1613
    ///
1614
    /// ```
1615
    /// use num_traits::Float;
1616
    /// use std::f64;
1617
    ///
1618
    /// let x = 2.0*f64::consts::PI;
1619
    ///
1620
    /// let abs_difference = (x.cos() - 1.0).abs();
1621
    ///
1622
    /// assert!(abs_difference < 1e-10);
1623
    /// ```
1624
    fn cos(self) -> Self;
1625
1626
    /// Computes the tangent of a number (in radians).
1627
    ///
1628
    /// ```
1629
    /// use num_traits::Float;
1630
    /// use std::f64;
1631
    ///
1632
    /// let x = f64::consts::PI/4.0;
1633
    /// let abs_difference = (x.tan() - 1.0).abs();
1634
    ///
1635
    /// assert!(abs_difference < 1e-14);
1636
    /// ```
1637
    fn tan(self) -> Self;
1638
1639
    /// Computes the arcsine of a number. Return value is in radians in
1640
    /// the range [-pi/2, pi/2] or NaN if the number is outside the range
1641
    /// [-1, 1].
1642
    ///
1643
    /// ```
1644
    /// use num_traits::Float;
1645
    /// use std::f64;
1646
    ///
1647
    /// let f = f64::consts::PI / 2.0;
1648
    ///
1649
    /// // asin(sin(pi/2))
1650
    /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
1651
    ///
1652
    /// assert!(abs_difference < 1e-10);
1653
    /// ```
1654
    fn asin(self) -> Self;
1655
1656
    /// Computes the arccosine of a number. Return value is in radians in
1657
    /// the range [0, pi] or NaN if the number is outside the range
1658
    /// [-1, 1].
1659
    ///
1660
    /// ```
1661
    /// use num_traits::Float;
1662
    /// use std::f64;
1663
    ///
1664
    /// let f = f64::consts::PI / 4.0;
1665
    ///
1666
    /// // acos(cos(pi/4))
1667
    /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
1668
    ///
1669
    /// assert!(abs_difference < 1e-10);
1670
    /// ```
1671
    fn acos(self) -> Self;
1672
1673
    /// Computes the arctangent of a number. Return value is in radians in the
1674
    /// range [-pi/2, pi/2];
1675
    ///
1676
    /// ```
1677
    /// use num_traits::Float;
1678
    ///
1679
    /// let f = 1.0;
1680
    ///
1681
    /// // atan(tan(1))
1682
    /// let abs_difference = (f.tan().atan() - 1.0).abs();
1683
    ///
1684
    /// assert!(abs_difference < 1e-10);
1685
    /// ```
1686
    fn atan(self) -> Self;
1687
1688
    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
1689
    ///
1690
    /// * `x = 0`, `y = 0`: `0`
1691
    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
1692
    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
1693
    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
1694
    ///
1695
    /// ```
1696
    /// use num_traits::Float;
1697
    /// use std::f64;
1698
    ///
1699
    /// let pi = f64::consts::PI;
1700
    /// // All angles from horizontal right (+x)
1701
    /// // 45 deg counter-clockwise
1702
    /// let x1 = 3.0;
1703
    /// let y1 = -3.0;
1704
    ///
1705
    /// // 135 deg clockwise
1706
    /// let x2 = -3.0;
1707
    /// let y2 = 3.0;
1708
    ///
1709
    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
1710
    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
1711
    ///
1712
    /// assert!(abs_difference_1 < 1e-10);
1713
    /// assert!(abs_difference_2 < 1e-10);
1714
    /// ```
1715
    fn atan2(self, other: Self) -> Self;
1716
1717
    /// Simultaneously computes the sine and cosine of the number, `x`. Returns
1718
    /// `(sin(x), cos(x))`.
1719
    ///
1720
    /// ```
1721
    /// use num_traits::Float;
1722
    /// use std::f64;
1723
    ///
1724
    /// let x = f64::consts::PI/4.0;
1725
    /// let f = x.sin_cos();
1726
    ///
1727
    /// let abs_difference_0 = (f.0 - x.sin()).abs();
1728
    /// let abs_difference_1 = (f.1 - x.cos()).abs();
1729
    ///
1730
    /// assert!(abs_difference_0 < 1e-10);
1731
    /// assert!(abs_difference_0 < 1e-10);
1732
    /// ```
1733
    fn sin_cos(self) -> (Self, Self);
1734
1735
    /// Returns `e^(self) - 1` in a way that is accurate even if the
1736
    /// number is close to zero.
1737
    ///
1738
    /// ```
1739
    /// use num_traits::Float;
1740
    ///
1741
    /// let x = 7.0;
1742
    ///
1743
    /// // e^(ln(7)) - 1
1744
    /// let abs_difference = (x.ln().exp_m1() - 6.0).abs();
1745
    ///
1746
    /// assert!(abs_difference < 1e-10);
1747
    /// ```
1748
    fn exp_m1(self) -> Self;
1749
1750
    /// Returns `ln(1+n)` (natural logarithm) more accurately than if
1751
    /// the operations were performed separately.
1752
    ///
1753
    /// ```
1754
    /// use num_traits::Float;
1755
    /// use std::f64;
1756
    ///
1757
    /// let x = f64::consts::E - 1.0;
1758
    ///
1759
    /// // ln(1 + (e - 1)) == ln(e) == 1
1760
    /// let abs_difference = (x.ln_1p() - 1.0).abs();
1761
    ///
1762
    /// assert!(abs_difference < 1e-10);
1763
    /// ```
1764
    fn ln_1p(self) -> Self;
1765
1766
    /// Hyperbolic sine function.
1767
    ///
1768
    /// ```
1769
    /// use num_traits::Float;
1770
    /// use std::f64;
1771
    ///
1772
    /// let e = f64::consts::E;
1773
    /// let x = 1.0;
1774
    ///
1775
    /// let f = x.sinh();
1776
    /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
1777
    /// let g = (e*e - 1.0)/(2.0*e);
1778
    /// let abs_difference = (f - g).abs();
1779
    ///
1780
    /// assert!(abs_difference < 1e-10);
1781
    /// ```
1782
    fn sinh(self) -> Self;
1783
1784
    /// Hyperbolic cosine function.
1785
    ///
1786
    /// ```
1787
    /// use num_traits::Float;
1788
    /// use std::f64;
1789
    ///
1790
    /// let e = f64::consts::E;
1791
    /// let x = 1.0;
1792
    /// let f = x.cosh();
1793
    /// // Solving cosh() at 1 gives this result
1794
    /// let g = (e*e + 1.0)/(2.0*e);
1795
    /// let abs_difference = (f - g).abs();
1796
    ///
1797
    /// // Same result
1798
    /// assert!(abs_difference < 1.0e-10);
1799
    /// ```
1800
    fn cosh(self) -> Self;
1801
1802
    /// Hyperbolic tangent function.
1803
    ///
1804
    /// ```
1805
    /// use num_traits::Float;
1806
    /// use std::f64;
1807
    ///
1808
    /// let e = f64::consts::E;
1809
    /// let x = 1.0;
1810
    ///
1811
    /// let f = x.tanh();
1812
    /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
1813
    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
1814
    /// let abs_difference = (f - g).abs();
1815
    ///
1816
    /// assert!(abs_difference < 1.0e-10);
1817
    /// ```
1818
    fn tanh(self) -> Self;
1819
1820
    /// Inverse hyperbolic sine function.
1821
    ///
1822
    /// ```
1823
    /// use num_traits::Float;
1824
    ///
1825
    /// let x = 1.0;
1826
    /// let f = x.sinh().asinh();
1827
    ///
1828
    /// let abs_difference = (f - x).abs();
1829
    ///
1830
    /// assert!(abs_difference < 1.0e-10);
1831
    /// ```
1832
    fn asinh(self) -> Self;
1833
1834
    /// Inverse hyperbolic cosine function.
1835
    ///
1836
    /// ```
1837
    /// use num_traits::Float;
1838
    ///
1839
    /// let x = 1.0;
1840
    /// let f = x.cosh().acosh();
1841
    ///
1842
    /// let abs_difference = (f - x).abs();
1843
    ///
1844
    /// assert!(abs_difference < 1.0e-10);
1845
    /// ```
1846
    fn acosh(self) -> Self;
1847
1848
    /// Inverse hyperbolic tangent function.
1849
    ///
1850
    /// ```
1851
    /// use num_traits::Float;
1852
    /// use std::f64;
1853
    ///
1854
    /// let e = f64::consts::E;
1855
    /// let f = e.tanh().atanh();
1856
    ///
1857
    /// let abs_difference = (f - e).abs();
1858
    ///
1859
    /// assert!(abs_difference < 1.0e-10);
1860
    /// ```
1861
    fn atanh(self) -> Self;
1862
1863
    /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
1864
    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
1865
    ///
1866
    /// ```
1867
    /// use num_traits::Float;
1868
    ///
1869
    /// let num = 2.0f32;
1870
    ///
1871
    /// // (8388608, -22, 1)
1872
    /// let (mantissa, exponent, sign) = Float::integer_decode(num);
1873
    /// let sign_f = sign as f32;
1874
    /// let mantissa_f = mantissa as f32;
1875
    /// let exponent_f = num.powf(exponent as f32);
1876
    ///
1877
    /// // 1 * 8388608 * 2^(-22) == 2
1878
    /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
1879
    ///
1880
    /// assert!(abs_difference < 1e-10);
1881
    /// ```
1882
    fn integer_decode(self) -> (u64, i16, i8);
1883
1884
    /// Returns a number composed of the magnitude of `self` and the sign of
1885
    /// `sign`.
1886
    ///
1887
    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise
1888
    /// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of
1889
    /// `sign` is returned.
1890
    ///
1891
    /// # Examples
1892
    ///
1893
    /// ```
1894
    /// use num_traits::Float;
1895
    ///
1896
    /// let f = 3.5_f32;
1897
    ///
1898
    /// assert_eq!(f.copysign(0.42), 3.5_f32);
1899
    /// assert_eq!(f.copysign(-0.42), -3.5_f32);
1900
    /// assert_eq!((-f).copysign(0.42), 3.5_f32);
1901
    /// assert_eq!((-f).copysign(-0.42), -3.5_f32);
1902
    ///
1903
    /// assert!(f32::nan().copysign(1.0).is_nan());
1904
    /// ```
1905
0
    fn copysign(self, sign: Self) -> Self {
1906
0
        if self.is_sign_negative() == sign.is_sign_negative() {
1907
0
            self
1908
        } else {
1909
0
            self.neg()
1910
        }
1911
0
    }
1912
}
1913
1914
#[cfg(feature = "std")]
1915
macro_rules! float_impl_std {
1916
    ($T:ident $decode:ident) => {
1917
        impl Float for $T {
1918
            constant! {
1919
                nan() -> $T::NAN;
1920
                infinity() -> $T::INFINITY;
1921
                neg_infinity() -> $T::NEG_INFINITY;
1922
                neg_zero() -> -0.0;
1923
                min_value() -> $T::MIN;
1924
                min_positive_value() -> $T::MIN_POSITIVE;
1925
                epsilon() -> $T::EPSILON;
1926
                max_value() -> $T::MAX;
1927
            }
1928
1929
            #[inline]
1930
            #[allow(deprecated)]
1931
0
            fn abs_sub(self, other: Self) -> Self {
1932
0
                <$T>::abs_sub(self, other)
1933
0
            }
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float7abs_subB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float7abs_subB7_
1934
1935
            #[inline]
1936
0
            fn integer_decode(self) -> (u64, i16, i8) {
1937
0
                $decode(self)
1938
0
            }
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float14integer_decodeB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float14integer_decodeB7_
1939
1940
            forward! {
1941
                Self::is_nan(self) -> bool;
1942
                Self::is_infinite(self) -> bool;
1943
                Self::is_finite(self) -> bool;
1944
                Self::is_normal(self) -> bool;
1945
                Self::is_subnormal(self) -> bool;
1946
                Self::classify(self) -> FpCategory;
1947
                Self::clamp(self, min: Self, max: Self) -> Self;
1948
                Self::floor(self) -> Self;
1949
                Self::ceil(self) -> Self;
1950
                Self::round(self) -> Self;
1951
                Self::trunc(self) -> Self;
1952
                Self::fract(self) -> Self;
1953
                Self::abs(self) -> Self;
1954
                Self::signum(self) -> Self;
1955
                Self::is_sign_positive(self) -> bool;
1956
                Self::is_sign_negative(self) -> bool;
1957
                Self::mul_add(self, a: Self, b: Self) -> Self;
1958
                Self::recip(self) -> Self;
1959
                Self::powi(self, n: i32) -> Self;
1960
                Self::powf(self, n: Self) -> Self;
1961
                Self::sqrt(self) -> Self;
1962
                Self::exp(self) -> Self;
1963
                Self::exp2(self) -> Self;
1964
                Self::ln(self) -> Self;
1965
                Self::log(self, base: Self) -> Self;
1966
                Self::log2(self) -> Self;
1967
                Self::log10(self) -> Self;
1968
                Self::to_degrees(self) -> Self;
1969
                Self::to_radians(self) -> Self;
1970
                Self::max(self, other: Self) -> Self;
1971
                Self::min(self, other: Self) -> Self;
1972
                Self::cbrt(self) -> Self;
1973
                Self::hypot(self, other: Self) -> Self;
1974
                Self::sin(self) -> Self;
1975
                Self::cos(self) -> Self;
1976
                Self::tan(self) -> Self;
1977
                Self::asin(self) -> Self;
1978
                Self::acos(self) -> Self;
1979
                Self::atan(self) -> Self;
1980
                Self::atan2(self, other: Self) -> Self;
1981
                Self::sin_cos(self) -> (Self, Self);
1982
                Self::exp_m1(self) -> Self;
1983
                Self::ln_1p(self) -> Self;
1984
                Self::sinh(self) -> Self;
1985
                Self::cosh(self) -> Self;
1986
                Self::tanh(self) -> Self;
1987
                Self::asinh(self) -> Self;
1988
                Self::acosh(self) -> Self;
1989
                Self::atanh(self) -> Self;
1990
                Self::copysign(self, sign: Self) -> Self;
1991
            }
1992
        }
1993
    };
1994
}
1995
1996
#[cfg(all(not(feature = "std"), feature = "libm"))]
1997
macro_rules! float_impl_libm {
1998
    ($T:ident $decode:ident) => {
1999
        constant! {
2000
            nan() -> $T::NAN;
2001
            infinity() -> $T::INFINITY;
2002
            neg_infinity() -> $T::NEG_INFINITY;
2003
            neg_zero() -> -0.0;
2004
            min_value() -> $T::MIN;
2005
            min_positive_value() -> $T::MIN_POSITIVE;
2006
            epsilon() -> $T::EPSILON;
2007
            max_value() -> $T::MAX;
2008
        }
2009
2010
        #[inline]
2011
        fn integer_decode(self) -> (u64, i16, i8) {
2012
            $decode(self)
2013
        }
2014
2015
        #[inline]
2016
        fn fract(self) -> Self {
2017
            self - Float::trunc(self)
2018
        }
2019
2020
        #[inline]
2021
        fn log(self, base: Self) -> Self {
2022
            self.ln() / base.ln()
2023
        }
2024
2025
        forward! {
2026
            Self::is_nan(self) -> bool;
2027
            Self::is_infinite(self) -> bool;
2028
            Self::is_finite(self) -> bool;
2029
            Self::is_normal(self) -> bool;
2030
            Self::is_subnormal(self) -> bool;
2031
            Self::clamp(self, min: Self, max: Self) -> Self;
2032
            Self::classify(self) -> FpCategory;
2033
            Self::is_sign_positive(self) -> bool;
2034
            Self::is_sign_negative(self) -> bool;
2035
            Self::min(self, other: Self) -> Self;
2036
            Self::max(self, other: Self) -> Self;
2037
            Self::recip(self) -> Self;
2038
            Self::to_degrees(self) -> Self;
2039
            Self::to_radians(self) -> Self;
2040
        }
2041
2042
        forward! {
2043
            FloatCore::signum(self) -> Self;
2044
            FloatCore::powi(self, n: i32) -> Self;
2045
        }
2046
    };
2047
}
2048
2049
0
fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
2050
0
    let bits: u32 = f.to_bits();
2051
0
    let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
2052
0
    let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
2053
0
    let mantissa = if exponent == 0 {
2054
0
        (bits & 0x7fffff) << 1
2055
    } else {
2056
0
        (bits & 0x7fffff) | 0x800000
2057
    };
2058
    // Exponent bias + mantissa shift
2059
0
    exponent -= 127 + 23;
2060
0
    (mantissa as u64, exponent, sign)
2061
0
}
2062
2063
0
fn integer_decode_f64(f: f64) -> (u64, i16, i8) {
2064
0
    let bits: u64 = f.to_bits();
2065
0
    let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
2066
0
    let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
2067
0
    let mantissa = if exponent == 0 {
2068
0
        (bits & 0xfffffffffffff) << 1
2069
    } else {
2070
0
        (bits & 0xfffffffffffff) | 0x10000000000000
2071
    };
2072
    // Exponent bias + mantissa shift
2073
0
    exponent -= 1023 + 52;
2074
0
    (mantissa, exponent, sign)
2075
0
}
2076
2077
#[cfg(feature = "std")]
2078
float_impl_std!(f32 integer_decode_f32);
2079
#[cfg(feature = "std")]
2080
float_impl_std!(f64 integer_decode_f64);
2081
2082
#[cfg(all(not(feature = "std"), feature = "libm"))]
2083
impl Float for f32 {
2084
    float_impl_libm!(f32 integer_decode_f32);
2085
2086
    #[inline]
2087
    #[allow(deprecated)]
2088
    fn abs_sub(self, other: Self) -> Self {
2089
        libm::fdimf(self, other)
2090
    }
2091
2092
    forward! {
2093
        libm::floorf as floor(self) -> Self;
2094
        libm::ceilf as ceil(self) -> Self;
2095
        libm::roundf as round(self) -> Self;
2096
        libm::truncf as trunc(self) -> Self;
2097
        libm::fabsf as abs(self) -> Self;
2098
        libm::fmaf as mul_add(self, a: Self, b: Self) -> Self;
2099
        libm::powf as powf(self, n: Self) -> Self;
2100
        libm::sqrtf as sqrt(self) -> Self;
2101
        libm::expf as exp(self) -> Self;
2102
        libm::exp2f as exp2(self) -> Self;
2103
        libm::logf as ln(self) -> Self;
2104
        libm::log2f as log2(self) -> Self;
2105
        libm::log10f as log10(self) -> Self;
2106
        libm::cbrtf as cbrt(self) -> Self;
2107
        libm::hypotf as hypot(self, other: Self) -> Self;
2108
        libm::sinf as sin(self) -> Self;
2109
        libm::cosf as cos(self) -> Self;
2110
        libm::tanf as tan(self) -> Self;
2111
        libm::asinf as asin(self) -> Self;
2112
        libm::acosf as acos(self) -> Self;
2113
        libm::atanf as atan(self) -> Self;
2114
        libm::atan2f as atan2(self, other: Self) -> Self;
2115
        libm::sincosf as sin_cos(self) -> (Self, Self);
2116
        libm::expm1f as exp_m1(self) -> Self;
2117
        libm::log1pf as ln_1p(self) -> Self;
2118
        libm::sinhf as sinh(self) -> Self;
2119
        libm::coshf as cosh(self) -> Self;
2120
        libm::tanhf as tanh(self) -> Self;
2121
        libm::asinhf as asinh(self) -> Self;
2122
        libm::acoshf as acosh(self) -> Self;
2123
        libm::atanhf as atanh(self) -> Self;
2124
        libm::copysignf as copysign(self, other: Self) -> Self;
2125
    }
2126
}
2127
2128
#[cfg(all(not(feature = "std"), feature = "libm"))]
2129
impl Float for f64 {
2130
    float_impl_libm!(f64 integer_decode_f64);
2131
2132
    #[inline]
2133
    #[allow(deprecated)]
2134
    fn abs_sub(self, other: Self) -> Self {
2135
        libm::fdim(self, other)
2136
    }
2137
2138
    forward! {
2139
        libm::floor as floor(self) -> Self;
2140
        libm::ceil as ceil(self) -> Self;
2141
        libm::round as round(self) -> Self;
2142
        libm::trunc as trunc(self) -> Self;
2143
        libm::fabs as abs(self) -> Self;
2144
        libm::fma as mul_add(self, a: Self, b: Self) -> Self;
2145
        libm::pow as powf(self, n: Self) -> Self;
2146
        libm::sqrt as sqrt(self) -> Self;
2147
        libm::exp as exp(self) -> Self;
2148
        libm::exp2 as exp2(self) -> Self;
2149
        libm::log as ln(self) -> Self;
2150
        libm::log2 as log2(self) -> Self;
2151
        libm::log10 as log10(self) -> Self;
2152
        libm::cbrt as cbrt(self) -> Self;
2153
        libm::hypot as hypot(self, other: Self) -> Self;
2154
        libm::sin as sin(self) -> Self;
2155
        libm::cos as cos(self) -> Self;
2156
        libm::tan as tan(self) -> Self;
2157
        libm::asin as asin(self) -> Self;
2158
        libm::acos as acos(self) -> Self;
2159
        libm::atan as atan(self) -> Self;
2160
        libm::atan2 as atan2(self, other: Self) -> Self;
2161
        libm::sincos as sin_cos(self) -> (Self, Self);
2162
        libm::expm1 as exp_m1(self) -> Self;
2163
        libm::log1p as ln_1p(self) -> Self;
2164
        libm::sinh as sinh(self) -> Self;
2165
        libm::cosh as cosh(self) -> Self;
2166
        libm::tanh as tanh(self) -> Self;
2167
        libm::asinh as asinh(self) -> Self;
2168
        libm::acosh as acosh(self) -> Self;
2169
        libm::atanh as atanh(self) -> Self;
2170
        libm::copysign as copysign(self, sign: Self) -> Self;
2171
    }
2172
}
2173
2174
macro_rules! float_const_impl {
2175
    ($(#[$doc:meta] $constant:ident,)+) => (
2176
        #[allow(non_snake_case)]
2177
        pub trait FloatConst {
2178
            $(#[$doc] fn $constant() -> Self;)+
2179
            #[doc = "Return the full circle constant `τ`."]
2180
            #[inline]
2181
0
            fn TAU() -> Self where Self: Sized + Add<Self, Output = Self> {
2182
0
                Self::PI() + Self::PI()
2183
0
            }
2184
            #[doc = "Return `log10(2.0)`."]
2185
            #[inline]
2186
0
            fn LOG10_2() -> Self where Self: Sized + Div<Self, Output = Self> {
2187
0
                Self::LN_2() / Self::LN_10()
2188
0
            }
2189
            #[doc = "Return `log2(10.0)`."]
2190
            #[inline]
2191
0
            fn LOG2_10() -> Self where Self: Sized + Div<Self, Output = Self> {
2192
0
                Self::LN_10() / Self::LN_2()
2193
0
            }
2194
        }
2195
        float_const_impl! { @float f32, $($constant,)+ }
2196
        float_const_impl! { @float f64, $($constant,)+ }
2197
    );
2198
    (@float $T:ident, $($constant:ident,)+) => (
2199
        impl FloatConst for $T {
2200
            constant! {
2201
                $( $constant() -> $T::consts::$constant; )+
2202
                TAU() -> 6.28318530717958647692528676655900577;
2203
                LOG10_2() -> 0.301029995663981195213738894724493027;
2204
                LOG2_10() -> 3.32192809488736234787031942948939018;
2205
            }
2206
        }
2207
    );
2208
}
2209
2210
float_const_impl! {
2211
    #[doc = "Return Euler’s number."]
2212
    E,
2213
    #[doc = "Return `1.0 / π`."]
2214
    FRAC_1_PI,
2215
    #[doc = "Return `1.0 / sqrt(2.0)`."]
2216
    FRAC_1_SQRT_2,
2217
    #[doc = "Return `2.0 / π`."]
2218
    FRAC_2_PI,
2219
    #[doc = "Return `2.0 / sqrt(π)`."]
2220
    FRAC_2_SQRT_PI,
2221
    #[doc = "Return `π / 2.0`."]
2222
    FRAC_PI_2,
2223
    #[doc = "Return `π / 3.0`."]
2224
    FRAC_PI_3,
2225
    #[doc = "Return `π / 4.0`."]
2226
    FRAC_PI_4,
2227
    #[doc = "Return `π / 6.0`."]
2228
    FRAC_PI_6,
2229
    #[doc = "Return `π / 8.0`."]
2230
    FRAC_PI_8,
2231
    #[doc = "Return `ln(10.0)`."]
2232
    LN_10,
2233
    #[doc = "Return `ln(2.0)`."]
2234
    LN_2,
2235
    #[doc = "Return `log10(e)`."]
2236
    LOG10_E,
2237
    #[doc = "Return `log2(e)`."]
2238
    LOG2_E,
2239
    #[doc = "Return Archimedes’ constant `π`."]
2240
    PI,
2241
    #[doc = "Return `sqrt(2.0)`."]
2242
    SQRT_2,
2243
}
2244
2245
/// Trait for floating point numbers that provide an implementation
2246
/// of the `totalOrder` predicate as defined in the IEEE 754 (2008 revision)
2247
/// floating point standard.
2248
pub trait TotalOrder {
2249
    /// Return the ordering between `self` and `other`.
2250
    ///
2251
    /// Unlike the standard partial comparison between floating point numbers,
2252
    /// this comparison always produces an ordering in accordance to
2253
    /// the `totalOrder` predicate as defined in the IEEE 754 (2008 revision)
2254
    /// floating point standard. The values are ordered in the following sequence:
2255
    ///
2256
    /// - negative quiet NaN
2257
    /// - negative signaling NaN
2258
    /// - negative infinity
2259
    /// - negative numbers
2260
    /// - negative subnormal numbers
2261
    /// - negative zero
2262
    /// - positive zero
2263
    /// - positive subnormal numbers
2264
    /// - positive numbers
2265
    /// - positive infinity
2266
    /// - positive signaling NaN
2267
    /// - positive quiet NaN.
2268
    ///
2269
    /// The ordering established by this function does not always agree with the
2270
    /// [`PartialOrd`] and [`PartialEq`] implementations. For example,
2271
    /// they consider negative and positive zero equal, while `total_cmp`
2272
    /// doesn't.
2273
    ///
2274
    /// The interpretation of the signaling NaN bit follows the definition in
2275
    /// the IEEE 754 standard, which may not match the interpretation by some of
2276
    /// the older, non-conformant (e.g. MIPS) hardware implementations.
2277
    ///
2278
    /// # Examples
2279
    /// ```
2280
    /// use num_traits::float::TotalOrder;
2281
    /// use std::cmp::Ordering;
2282
    /// use std::{f32, f64};
2283
    ///
2284
    /// fn check_eq<T: TotalOrder>(x: T, y: T) {
2285
    ///     assert_eq!(x.total_cmp(&y), Ordering::Equal);
2286
    /// }
2287
    ///
2288
    /// check_eq(f64::NAN, f64::NAN);
2289
    /// check_eq(f32::NAN, f32::NAN);
2290
    ///
2291
    /// fn check_lt<T: TotalOrder>(x: T, y: T) {
2292
    ///     assert_eq!(x.total_cmp(&y), Ordering::Less);
2293
    /// }
2294
    ///
2295
    /// check_lt(-f64::NAN, f64::NAN);
2296
    /// check_lt(f64::INFINITY, f64::NAN);
2297
    /// check_lt(-0.0_f64, 0.0_f64);
2298
    /// ```
2299
    fn total_cmp(&self, other: &Self) -> Ordering;
2300
}
2301
macro_rules! totalorder_impl {
2302
    ($T:ident, $I:ident, $U:ident, $bits:expr) => {
2303
        impl TotalOrder for $T {
2304
            #[inline]
2305
            #[cfg(has_total_cmp)]
2306
0
            fn total_cmp(&self, other: &Self) -> Ordering {
2307
0
                // Forward to the core implementation
2308
0
                Self::total_cmp(&self, other)
2309
0
            }
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10TotalOrder9total_cmpB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10TotalOrder9total_cmpB7_
2310
            #[inline]
2311
            #[cfg(not(has_total_cmp))]
2312
            fn total_cmp(&self, other: &Self) -> Ordering {
2313
                // Backport the core implementation (since 1.62)
2314
                let mut left = self.to_bits() as $I;
2315
                let mut right = other.to_bits() as $I;
2316
2317
                left ^= (((left >> ($bits - 1)) as $U) >> 1) as $I;
2318
                right ^= (((right >> ($bits - 1)) as $U) >> 1) as $I;
2319
2320
                left.cmp(&right)
2321
            }
2322
        }
2323
    };
2324
}
2325
totalorder_impl!(f64, i64, u64, 64);
2326
totalorder_impl!(f32, i32, u32, 32);
2327
2328
#[cfg(test)]
2329
mod tests {
2330
    use core::f64::consts;
2331
2332
    const DEG_RAD_PAIRS: [(f64, f64); 7] = [
2333
        (0.0, 0.),
2334
        (22.5, consts::FRAC_PI_8),
2335
        (30.0, consts::FRAC_PI_6),
2336
        (45.0, consts::FRAC_PI_4),
2337
        (60.0, consts::FRAC_PI_3),
2338
        (90.0, consts::FRAC_PI_2),
2339
        (180.0, consts::PI),
2340
    ];
2341
2342
    #[test]
2343
    fn convert_deg_rad() {
2344
        use crate::float::FloatCore;
2345
2346
        for &(deg, rad) in &DEG_RAD_PAIRS {
2347
            assert!((FloatCore::to_degrees(rad) - deg).abs() < 1e-6);
2348
            assert!((FloatCore::to_radians(deg) - rad).abs() < 1e-6);
2349
2350
            let (deg, rad) = (deg as f32, rad as f32);
2351
            assert!((FloatCore::to_degrees(rad) - deg).abs() < 1e-5);
2352
            assert!((FloatCore::to_radians(deg) - rad).abs() < 1e-5);
2353
        }
2354
    }
2355
2356
    #[cfg(any(feature = "std", feature = "libm"))]
2357
    #[test]
2358
    fn convert_deg_rad_std() {
2359
        for &(deg, rad) in &DEG_RAD_PAIRS {
2360
            use crate::Float;
2361
2362
            assert!((Float::to_degrees(rad) - deg).abs() < 1e-6);
2363
            assert!((Float::to_radians(deg) - rad).abs() < 1e-6);
2364
2365
            let (deg, rad) = (deg as f32, rad as f32);
2366
            assert!((Float::to_degrees(rad) - deg).abs() < 1e-5);
2367
            assert!((Float::to_radians(deg) - rad).abs() < 1e-5);
2368
        }
2369
    }
2370
2371
    #[test]
2372
    fn to_degrees_rounding() {
2373
        use crate::float::FloatCore;
2374
2375
        assert_eq!(
2376
            FloatCore::to_degrees(1_f32),
2377
            57.2957795130823208767981548141051703
2378
        );
2379
    }
2380
2381
    #[test]
2382
    #[cfg(any(feature = "std", feature = "libm"))]
2383
    fn extra_logs() {
2384
        use crate::float::{Float, FloatConst};
2385
2386
        fn check<F: Float + FloatConst>(diff: F) {
2387
            let _2 = F::from(2.0).unwrap();
2388
            assert!((F::LOG10_2() - F::log10(_2)).abs() < diff);
2389
            assert!((F::LOG10_2() - F::LN_2() / F::LN_10()).abs() < diff);
2390
2391
            let _10 = F::from(10.0).unwrap();
2392
            assert!((F::LOG2_10() - F::log2(_10)).abs() < diff);
2393
            assert!((F::LOG2_10() - F::LN_10() / F::LN_2()).abs() < diff);
2394
        }
2395
2396
        check::<f32>(1e-6);
2397
        check::<f64>(1e-12);
2398
    }
2399
2400
    #[test]
2401
    #[cfg(any(feature = "std", feature = "libm"))]
2402
    fn copysign() {
2403
        use crate::float::Float;
2404
        test_copysign_generic(2.0_f32, -2.0_f32, f32::nan());
2405
        test_copysign_generic(2.0_f64, -2.0_f64, f64::nan());
2406
        test_copysignf(2.0_f32, -2.0_f32, f32::nan());
2407
    }
2408
2409
    #[cfg(any(feature = "std", feature = "libm"))]
2410
    fn test_copysignf(p: f32, n: f32, nan: f32) {
2411
        use crate::float::Float;
2412
        use core::ops::Neg;
2413
2414
        assert!(p.is_sign_positive());
2415
        assert!(n.is_sign_negative());
2416
        assert!(nan.is_nan());
2417
2418
        assert_eq!(p, Float::copysign(p, p));
2419
        assert_eq!(p.neg(), Float::copysign(p, n));
2420
2421
        assert_eq!(n, Float::copysign(n, n));
2422
        assert_eq!(n.neg(), Float::copysign(n, p));
2423
2424
        assert!(Float::copysign(nan, p).is_sign_positive());
2425
        assert!(Float::copysign(nan, n).is_sign_negative());
2426
    }
2427
2428
    #[cfg(any(feature = "std", feature = "libm"))]
2429
    fn test_copysign_generic<F: crate::float::Float + ::core::fmt::Debug>(p: F, n: F, nan: F) {
2430
        assert!(p.is_sign_positive());
2431
        assert!(n.is_sign_negative());
2432
        assert!(nan.is_nan());
2433
        assert!(!nan.is_subnormal());
2434
2435
        assert_eq!(p, p.copysign(p));
2436
        assert_eq!(p.neg(), p.copysign(n));
2437
2438
        assert_eq!(n, n.copysign(n));
2439
        assert_eq!(n.neg(), n.copysign(p));
2440
2441
        assert!(nan.copysign(p).is_sign_positive());
2442
        assert!(nan.copysign(n).is_sign_negative());
2443
    }
2444
2445
    #[cfg(any(feature = "std", feature = "libm"))]
2446
    fn test_subnormal<F: crate::float::Float + ::core::fmt::Debug>() {
2447
        let min_positive = F::min_positive_value();
2448
        let lower_than_min = min_positive / F::from(2.0f32).unwrap();
2449
        assert!(!min_positive.is_subnormal());
2450
        assert!(lower_than_min.is_subnormal());
2451
    }
2452
2453
    #[test]
2454
    #[cfg(any(feature = "std", feature = "libm"))]
2455
    fn subnormal() {
2456
        test_subnormal::<f64>();
2457
        test_subnormal::<f32>();
2458
    }
2459
2460
    #[test]
2461
    fn total_cmp() {
2462
        use crate::float::TotalOrder;
2463
        use core::cmp::Ordering;
2464
        use core::{f32, f64};
2465
2466
        fn check_eq<T: TotalOrder>(x: T, y: T) {
2467
            assert_eq!(x.total_cmp(&y), Ordering::Equal);
2468
        }
2469
        fn check_lt<T: TotalOrder>(x: T, y: T) {
2470
            assert_eq!(x.total_cmp(&y), Ordering::Less);
2471
        }
2472
        fn check_gt<T: TotalOrder>(x: T, y: T) {
2473
            assert_eq!(x.total_cmp(&y), Ordering::Greater);
2474
        }
2475
2476
        check_eq(f64::NAN, f64::NAN);
2477
        check_eq(f32::NAN, f32::NAN);
2478
2479
        check_lt(-0.0_f64, 0.0_f64);
2480
        check_lt(-0.0_f32, 0.0_f32);
2481
2482
        // x87 registers don't preserve the exact value of signaling NaN:
2483
        // https://github.com/rust-lang/rust/issues/115567
2484
        #[cfg(not(target_arch = "x86"))]
2485
        {
2486
            let s_nan = f64::from_bits(0x7ff4000000000000);
2487
            let q_nan = f64::from_bits(0x7ff8000000000000);
2488
            check_lt(s_nan, q_nan);
2489
2490
            let neg_s_nan = f64::from_bits(0xfff4000000000000);
2491
            let neg_q_nan = f64::from_bits(0xfff8000000000000);
2492
            check_lt(neg_q_nan, neg_s_nan);
2493
2494
            let s_nan = f32::from_bits(0x7fa00000);
2495
            let q_nan = f32::from_bits(0x7fc00000);
2496
            check_lt(s_nan, q_nan);
2497
2498
            let neg_s_nan = f32::from_bits(0xffa00000);
2499
            let neg_q_nan = f32::from_bits(0xffc00000);
2500
            check_lt(neg_q_nan, neg_s_nan);
2501
        }
2502
2503
        check_lt(-f64::NAN, f64::NEG_INFINITY);
2504
        check_gt(1.0_f64, -f64::NAN);
2505
        check_lt(f64::INFINITY, f64::NAN);
2506
        check_gt(f64::NAN, 1.0_f64);
2507
2508
        check_lt(-f32::NAN, f32::NEG_INFINITY);
2509
        check_gt(1.0_f32, -f32::NAN);
2510
        check_lt(f32::INFINITY, f32::NAN);
2511
        check_gt(f32::NAN, 1.0_f32);
2512
    }
2513
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/identities.rs
Line
Count
Source
1
use core::num::Wrapping;
2
use core::ops::{Add, Mul};
3
4
/// Defines an additive identity element for `Self`.
5
///
6
/// # Laws
7
///
8
/// ```text
9
/// a + 0 = a       ∀ a ∈ Self
10
/// 0 + a = a       ∀ a ∈ Self
11
/// ```
12
pub trait Zero: Sized + Add<Self, Output = Self> {
13
    /// Returns the additive identity element of `Self`, `0`.
14
    /// # Purity
15
    ///
16
    /// This function should return the same result at all times regardless of
17
    /// external mutable state, for example values stored in TLS or in
18
    /// `static mut`s.
19
    // This cannot be an associated constant, because of bignums.
20
    fn zero() -> Self;
21
22
    /// Sets `self` to the additive identity element of `Self`, `0`.
23
0
    fn set_zero(&mut self) {
24
0
        *self = Zero::zero();
25
0
    }
Unexecuted instantiation: _RNvYaNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYdNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYfNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYhNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYiNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYjNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYlNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYmNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYnNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYoNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYsNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYtNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYxNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
Unexecuted instantiation: _RNvYyNtNtCs7cG3k8kmkqw_10num_traits10identities4Zero8set_zeroB7_
26
27
    /// Returns `true` if `self` is equal to the additive identity.
28
    fn is_zero(&self) -> bool;
29
}
30
31
/// Defines an associated constant representing the additive identity element
32
/// for `Self`.
33
pub trait ConstZero: Zero {
34
    /// The additive identity element of `Self`, `0`.
35
    const ZERO: Self;
36
}
37
38
macro_rules! zero_impl {
39
    ($t:ty, $v:expr) => {
40
        impl Zero for $t {
41
            #[inline]
42
321k
            fn zero() -> $t {
43
321k
                $v
44
321k
            }
_RNvXsk_NtCs7cG3k8kmkqw_10num_traits10identitieslNtB5_4Zero4zeroCs4RkbDk9WRL5_5clvmr
Line
Count
Source
42
24.1k
            fn zero() -> $t {
43
24.1k
                $v
44
24.1k
            }
_RNvXs2_NtCs7cG3k8kmkqw_10num_traits10identitiesjNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
Line
Count
Source
42
243k
            fn zero() -> $t {
43
243k
                $v
44
243k
            }
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits10identitieshNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits10identitiestNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
_RNvXs8_NtCs7cG3k8kmkqw_10num_traits10identitiesmNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
Line
Count
Source
42
20.9k
            fn zero() -> $t {
43
20.9k
                $v
44
20.9k
            }
_RNvXsa_NtCs7cG3k8kmkqw_10num_traits10identitiesyNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
Line
Count
Source
42
2.07k
            fn zero() -> $t {
43
2.07k
                $v
44
2.07k
            }
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits10identitiesoNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits10identitiesiNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits10identitiesaNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits10identitiessNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
_RNvXsk_NtCs7cG3k8kmkqw_10num_traits10identitieslNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
Line
Count
Source
42
31.3k
            fn zero() -> $t {
43
31.3k
                $v
44
31.3k
            }
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits10identitiesxNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits10identitiesnNtB5_4Zero4zeroCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits10identitiesjNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits10identitieshNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits10identitiestNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits10identitiesmNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits10identitiesyNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits10identitiesoNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits10identitiesiNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits10identitiesaNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits10identitiessNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits10identitieslNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits10identitiesxNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits10identitiesnNtB5_4Zero4zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits10identitiesjNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits10identitieshNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits10identitiestNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits10identitiesmNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits10identitiesyNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits10identitiesoNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits10identitiesiNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits10identitiesaNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits10identitiessNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits10identitieslNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits10identitiesxNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits10identitiesnNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits10identitiesfNtB5_4Zero4zeroB7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits10identitiesdNtB5_4Zero4zeroB7_
45
            #[inline]
46
16.7M
            fn is_zero(&self) -> bool {
47
16.7M
                *self == $v
48
16.7M
            }
_RNvXs4_NtCs7cG3k8kmkqw_10num_traits10identitieshNtB5_4Zero7is_zeroCs4RkbDk9WRL5_5clvmr
Line
Count
Source
46
16.7M
            fn is_zero(&self) -> bool {
47
16.7M
                *self == $v
48
16.7M
            }
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits10identitiesjNtB5_4Zero7is_zeroCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits10identitieshNtB5_4Zero7is_zeroCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits10identitiestNtB5_4Zero7is_zeroCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits10identitiesmNtB5_4Zero7is_zeroCs72ekIXsOXFl_10num_bigint
_RNvXsa_NtCs7cG3k8kmkqw_10num_traits10identitiesyNtB5_4Zero7is_zeroCs72ekIXsOXFl_10num_bigint
Line
Count
Source
46
41.4k
            fn is_zero(&self) -> bool {
47
41.4k
                *self == $v
48
41.4k
            }
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits10identitiesoNtB5_4Zero7is_zeroCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits10identitiesdNtB5_4Zero7is_zeroCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits10identitiesjNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits10identitieshNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits10identitiestNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits10identitiesmNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits10identitiesyNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits10identitiesoNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits10identitiesiNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits10identitiesaNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits10identitiessNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits10identitieslNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits10identitiesxNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits10identitiesnNtB5_4Zero7is_zeroCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits10identitiesjNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits10identitieshNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits10identitiestNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits10identitiesmNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits10identitiesyNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits10identitiesoNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits10identitiesiNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits10identitiesaNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits10identitiessNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits10identitieslNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits10identitiesxNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits10identitiesnNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits10identitiesfNtB5_4Zero7is_zeroB7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits10identitiesdNtB5_4Zero7is_zeroB7_
49
        }
50
51
        impl ConstZero for $t {
52
            const ZERO: Self = $v;
53
        }
54
    };
55
}
56
57
zero_impl!(usize, 0);
58
zero_impl!(u8, 0);
59
zero_impl!(u16, 0);
60
zero_impl!(u32, 0);
61
zero_impl!(u64, 0);
62
zero_impl!(u128, 0);
63
64
zero_impl!(isize, 0);
65
zero_impl!(i8, 0);
66
zero_impl!(i16, 0);
67
zero_impl!(i32, 0);
68
zero_impl!(i64, 0);
69
zero_impl!(i128, 0);
70
71
zero_impl!(f32, 0.0);
72
zero_impl!(f64, 0.0);
73
74
impl<T: Zero> Zero for Wrapping<T>
75
where
76
    Wrapping<T>: Add<Output = Wrapping<T>>,
77
{
78
0
    fn is_zero(&self) -> bool {
79
0
        self.0.is_zero()
80
0
    }
81
82
0
    fn set_zero(&mut self) {
83
0
        self.0.set_zero();
84
0
    }
85
86
0
    fn zero() -> Self {
87
0
        Wrapping(T::zero())
88
0
    }
89
}
90
91
impl<T: ConstZero> ConstZero for Wrapping<T>
92
where
93
    Wrapping<T>: Add<Output = Wrapping<T>>,
94
{
95
    const ZERO: Self = Wrapping(T::ZERO);
96
}
97
98
/// Defines a multiplicative identity element for `Self`.
99
///
100
/// # Laws
101
///
102
/// ```text
103
/// a * 1 = a       ∀ a ∈ Self
104
/// 1 * a = a       ∀ a ∈ Self
105
/// ```
106
pub trait One: Sized + Mul<Self, Output = Self> {
107
    /// Returns the multiplicative identity element of `Self`, `1`.
108
    ///
109
    /// # Purity
110
    ///
111
    /// This function should return the same result at all times regardless of
112
    /// external mutable state, for example values stored in TLS or in
113
    /// `static mut`s.
114
    // This cannot be an associated constant, because of bignums.
115
    fn one() -> Self;
116
117
    /// Sets `self` to the multiplicative identity element of `Self`, `1`.
118
0
    fn set_one(&mut self) {
119
0
        *self = One::one();
120
0
    }
Unexecuted instantiation: _RNvYaNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYdNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYfNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYhNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYiNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYjNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYlNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYmNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYnNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYoNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYsNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYtNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYxNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
Unexecuted instantiation: _RNvYyNtNtCs7cG3k8kmkqw_10num_traits10identities3One7set_oneB7_
121
122
    /// Returns `true` if `self` is equal to the multiplicative identity.
123
    ///
124
    /// For performance reasons, it's best to implement this manually.
125
    /// After a semver bump, this method will be required, and the
126
    /// `where Self: PartialEq` bound will be removed.
127
    #[inline]
128
0
    fn is_one(&self) -> bool
129
0
    where
130
0
        Self: PartialEq,
131
0
    {
132
0
        *self == Self::one()
133
0
    }
134
}
135
136
/// Defines an associated constant representing the multiplicative identity
137
/// element for `Self`.
138
pub trait ConstOne: One {
139
    /// The multiplicative identity element of `Self`, `1`.
140
    const ONE: Self;
141
}
142
143
macro_rules! one_impl {
144
    ($t:ty, $v:expr) => {
145
        impl One for $t {
146
            #[inline]
147
0
            fn one() -> $t {
148
0
                $v
149
0
            }
Unexecuted instantiation: _RNvXsA_NtCs7cG3k8kmkqw_10num_traits10identitiesmNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsC_NtCs7cG3k8kmkqw_10num_traits10identitiesyNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsE_NtCs7cG3k8kmkqw_10num_traits10identitiesoNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsG_NtCs7cG3k8kmkqw_10num_traits10identitiesiNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsI_NtCs7cG3k8kmkqw_10num_traits10identitiesaNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsK_NtCs7cG3k8kmkqw_10num_traits10identitiessNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsM_NtCs7cG3k8kmkqw_10num_traits10identitieslNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsO_NtCs7cG3k8kmkqw_10num_traits10identitiesxNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsQ_NtCs7cG3k8kmkqw_10num_traits10identitiesnNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsu_NtCs7cG3k8kmkqw_10num_traits10identitiesjNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsw_NtCs7cG3k8kmkqw_10num_traits10identitieshNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsy_NtCs7cG3k8kmkqw_10num_traits10identitiestNtB5_3One3oneCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsu_NtCs7cG3k8kmkqw_10num_traits10identitiesjNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsw_NtCs7cG3k8kmkqw_10num_traits10identitieshNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsy_NtCs7cG3k8kmkqw_10num_traits10identitiestNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsA_NtCs7cG3k8kmkqw_10num_traits10identitiesmNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsC_NtCs7cG3k8kmkqw_10num_traits10identitiesyNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsE_NtCs7cG3k8kmkqw_10num_traits10identitiesoNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsG_NtCs7cG3k8kmkqw_10num_traits10identitiesiNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsI_NtCs7cG3k8kmkqw_10num_traits10identitiesaNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsK_NtCs7cG3k8kmkqw_10num_traits10identitiessNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsM_NtCs7cG3k8kmkqw_10num_traits10identitieslNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsO_NtCs7cG3k8kmkqw_10num_traits10identitiesxNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsQ_NtCs7cG3k8kmkqw_10num_traits10identitiesnNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsS_NtCs7cG3k8kmkqw_10num_traits10identitiesfNtB5_3One3oneB7_
Unexecuted instantiation: _RNvXsU_NtCs7cG3k8kmkqw_10num_traits10identitiesdNtB5_3One3oneB7_
150
            #[inline]
151
2.14k
            fn is_one(&self) -> bool {
152
2.14k
                *self == $v
153
2.14k
            }
_RNvXsC_NtCs7cG3k8kmkqw_10num_traits10identitiesyNtB5_3One6is_oneCs72ekIXsOXFl_10num_bigint
Line
Count
Source
151
2.14k
            fn is_one(&self) -> bool {
152
2.14k
                *self == $v
153
2.14k
            }
Unexecuted instantiation: _RNvXsu_NtCs7cG3k8kmkqw_10num_traits10identitiesjNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsw_NtCs7cG3k8kmkqw_10num_traits10identitieshNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsy_NtCs7cG3k8kmkqw_10num_traits10identitiestNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsA_NtCs7cG3k8kmkqw_10num_traits10identitiesmNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsC_NtCs7cG3k8kmkqw_10num_traits10identitiesyNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsE_NtCs7cG3k8kmkqw_10num_traits10identitiesoNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsG_NtCs7cG3k8kmkqw_10num_traits10identitiesiNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsI_NtCs7cG3k8kmkqw_10num_traits10identitiesaNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsK_NtCs7cG3k8kmkqw_10num_traits10identitiessNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsM_NtCs7cG3k8kmkqw_10num_traits10identitieslNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsO_NtCs7cG3k8kmkqw_10num_traits10identitiesxNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsQ_NtCs7cG3k8kmkqw_10num_traits10identitiesnNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsS_NtCs7cG3k8kmkqw_10num_traits10identitiesfNtB5_3One6is_oneB7_
Unexecuted instantiation: _RNvXsU_NtCs7cG3k8kmkqw_10num_traits10identitiesdNtB5_3One6is_oneB7_
154
        }
155
156
        impl ConstOne for $t {
157
            const ONE: Self = $v;
158
        }
159
    };
160
}
161
162
one_impl!(usize, 1);
163
one_impl!(u8, 1);
164
one_impl!(u16, 1);
165
one_impl!(u32, 1);
166
one_impl!(u64, 1);
167
one_impl!(u128, 1);
168
169
one_impl!(isize, 1);
170
one_impl!(i8, 1);
171
one_impl!(i16, 1);
172
one_impl!(i32, 1);
173
one_impl!(i64, 1);
174
one_impl!(i128, 1);
175
176
one_impl!(f32, 1.0);
177
one_impl!(f64, 1.0);
178
179
impl<T: One> One for Wrapping<T>
180
where
181
    Wrapping<T>: Mul<Output = Wrapping<T>>,
182
{
183
0
    fn set_one(&mut self) {
184
0
        self.0.set_one();
185
0
    }
186
187
0
    fn one() -> Self {
188
0
        Wrapping(T::one())
189
0
    }
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingaENtB5_3One3oneB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinghENtB5_3One3oneB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingiENtB5_3One3oneB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingjENtB5_3One3oneB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinglENtB5_3One3oneB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingmENtB5_3One3oneB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingnENtB5_3One3oneB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingoENtB5_3One3oneB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingsENtB5_3One3oneB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingtENtB5_3One3oneB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingxENtB5_3One3oneB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits10identitiesINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingyENtB5_3One3oneB7_
190
}
191
192
impl<T: ConstOne> ConstOne for Wrapping<T>
193
where
194
    Wrapping<T>: Mul<Output = Wrapping<T>>,
195
{
196
    const ONE: Self = Wrapping(T::ONE);
197
}
198
199
// Some helper functions provided for backwards compatibility.
200
201
/// Returns the additive identity, `0`.
202
#[inline(always)]
203
0
pub fn zero<T: Zero>() -> T {
204
0
    Zero::zero()
205
0
}
206
207
/// Returns the multiplicative identity, `1`.
208
#[inline(always)]
209
0
pub fn one<T: One>() -> T {
210
0
    One::one()
211
0
}
212
213
#[test]
214
fn wrapping_identities() {
215
    macro_rules! test_wrapping_identities {
216
        ($($t:ty)+) => {
217
            $(
218
                assert_eq!(zero::<$t>(), zero::<Wrapping<$t>>().0);
219
                assert_eq!(one::<$t>(), one::<Wrapping<$t>>().0);
220
                assert_eq!((0 as $t).is_zero(), Wrapping(0 as $t).is_zero());
221
                assert_eq!((1 as $t).is_zero(), Wrapping(1 as $t).is_zero());
222
            )+
223
        };
224
    }
225
226
    test_wrapping_identities!(isize i8 i16 i32 i64 usize u8 u16 u32 u64);
227
}
228
229
#[test]
230
fn wrapping_is_zero() {
231
    fn require_zero<T: Zero>(_: &T) {}
232
    require_zero(&Wrapping(42));
233
}
234
#[test]
235
fn wrapping_is_one() {
236
    fn require_one<T: One>(_: &T) {}
237
    require_one(&Wrapping(42));
238
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/int.rs
Line
Count
Source
1
use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
2
3
use crate::bounds::Bounded;
4
use crate::ops::checked::*;
5
use crate::ops::saturating::Saturating;
6
use crate::{Num, NumCast};
7
8
/// Generic trait for primitive integers.
9
///
10
/// The `PrimInt` trait is an abstraction over the builtin primitive integer types (e.g., `u8`,
11
/// `u32`, `isize`, `i128`, ...). It inherits the basic numeric traits and extends them with
12
/// bitwise operators and non-wrapping arithmetic.
13
///
14
/// The trait explicitly inherits `Copy`, `Eq`, `Ord`, and `Sized`. The intention is that all
15
/// types implementing this trait behave like primitive types that are passed by value by default
16
/// and behave like builtin integers. Furthermore, the types are expected to expose the integer
17
/// value in binary representation and support bitwise operators. The standard bitwise operations
18
/// (e.g., bitwise-and, bitwise-or, right-shift, left-shift) are inherited and the trait extends
19
/// these with introspective queries (e.g., `PrimInt::count_ones()`, `PrimInt::leading_zeros()`),
20
/// bitwise combinators (e.g., `PrimInt::rotate_left()`), and endianness converters (e.g.,
21
/// `PrimInt::to_be()`).
22
///
23
/// All `PrimInt` types are expected to be fixed-width binary integers. The width can be queried
24
/// via `T::zero().count_zeros()`. The trait currently lacks a way to query the width at
25
/// compile-time.
26
///
27
/// While a default implementation for all builtin primitive integers is provided, the trait is in
28
/// no way restricted to these. Other integer types that fulfil the requirements are free to
29
/// implement the trait was well.
30
///
31
/// This trait and many of the method names originate in the unstable `core::num::Int` trait from
32
/// the rust standard library. The original trait was never stabilized and thus removed from the
33
/// standard library.
34
pub trait PrimInt:
35
    Sized
36
    + Copy
37
    + Num
38
    + NumCast
39
    + Bounded
40
    + PartialOrd
41
    + Ord
42
    + Eq
43
    + Not<Output = Self>
44
    + BitAnd<Output = Self>
45
    + BitOr<Output = Self>
46
    + BitXor<Output = Self>
47
    + Shl<usize, Output = Self>
48
    + Shr<usize, Output = Self>
49
    + CheckedAdd<Output = Self>
50
    + CheckedSub<Output = Self>
51
    + CheckedMul<Output = Self>
52
    + CheckedDiv<Output = Self>
53
    + Saturating
54
{
55
    /// Returns the number of ones in the binary representation of `self`.
56
    ///
57
    /// # Examples
58
    ///
59
    /// ```
60
    /// use num_traits::PrimInt;
61
    ///
62
    /// let n = 0b01001100u8;
63
    ///
64
    /// assert_eq!(n.count_ones(), 3);
65
    /// ```
66
    fn count_ones(self) -> u32;
67
68
    /// Returns the number of zeros in the binary representation of `self`.
69
    ///
70
    /// # Examples
71
    ///
72
    /// ```
73
    /// use num_traits::PrimInt;
74
    ///
75
    /// let n = 0b01001100u8;
76
    ///
77
    /// assert_eq!(n.count_zeros(), 5);
78
    /// ```
79
    fn count_zeros(self) -> u32;
80
81
    /// Returns the number of leading ones in the binary representation
82
    /// of `self`.
83
    ///
84
    /// # Examples
85
    ///
86
    /// ```
87
    /// use num_traits::PrimInt;
88
    ///
89
    /// let n = 0xF00Du16;
90
    ///
91
    /// assert_eq!(n.leading_ones(), 4);
92
    /// ```
93
0
    fn leading_ones(self) -> u32 {
94
0
        (!self).leading_zeros()
95
0
    }
96
97
    /// Returns the number of leading zeros in the binary representation
98
    /// of `self`.
99
    ///
100
    /// # Examples
101
    ///
102
    /// ```
103
    /// use num_traits::PrimInt;
104
    ///
105
    /// let n = 0b0101000u16;
106
    ///
107
    /// assert_eq!(n.leading_zeros(), 10);
108
    /// ```
109
    fn leading_zeros(self) -> u32;
110
111
    /// Returns the number of trailing ones in the binary representation
112
    /// of `self`.
113
    ///
114
    /// # Examples
115
    ///
116
    /// ```
117
    /// use num_traits::PrimInt;
118
    ///
119
    /// let n = 0xBEEFu16;
120
    ///
121
    /// assert_eq!(n.trailing_ones(), 4);
122
    /// ```
123
0
    fn trailing_ones(self) -> u32 {
124
0
        (!self).trailing_zeros()
125
0
    }
126
127
    /// Returns the number of trailing zeros in the binary representation
128
    /// of `self`.
129
    ///
130
    /// # Examples
131
    ///
132
    /// ```
133
    /// use num_traits::PrimInt;
134
    ///
135
    /// let n = 0b0101000u16;
136
    ///
137
    /// assert_eq!(n.trailing_zeros(), 3);
138
    /// ```
139
    fn trailing_zeros(self) -> u32;
140
141
    /// Shifts the bits to the left by a specified amount, `n`, wrapping
142
    /// the truncated bits to the end of the resulting integer.
143
    ///
144
    /// # Examples
145
    ///
146
    /// ```
147
    /// use num_traits::PrimInt;
148
    ///
149
    /// let n = 0x0123456789ABCDEFu64;
150
    /// let m = 0x3456789ABCDEF012u64;
151
    ///
152
    /// assert_eq!(n.rotate_left(12), m);
153
    /// ```
154
    fn rotate_left(self, n: u32) -> Self;
155
156
    /// Shifts the bits to the right by a specified amount, `n`, wrapping
157
    /// the truncated bits to the beginning of the resulting integer.
158
    ///
159
    /// # Examples
160
    ///
161
    /// ```
162
    /// use num_traits::PrimInt;
163
    ///
164
    /// let n = 0x0123456789ABCDEFu64;
165
    /// let m = 0xDEF0123456789ABCu64;
166
    ///
167
    /// assert_eq!(n.rotate_right(12), m);
168
    /// ```
169
    fn rotate_right(self, n: u32) -> Self;
170
171
    /// Shifts the bits to the left by a specified amount, `n`, filling
172
    /// zeros in the least significant bits.
173
    ///
174
    /// This is bitwise equivalent to signed `Shl`.
175
    ///
176
    /// # Examples
177
    ///
178
    /// ```
179
    /// use num_traits::PrimInt;
180
    ///
181
    /// let n = 0x0123456789ABCDEFu64;
182
    /// let m = 0x3456789ABCDEF000u64;
183
    ///
184
    /// assert_eq!(n.signed_shl(12), m);
185
    /// ```
186
    fn signed_shl(self, n: u32) -> Self;
187
188
    /// Shifts the bits to the right by a specified amount, `n`, copying
189
    /// the "sign bit" in the most significant bits even for unsigned types.
190
    ///
191
    /// This is bitwise equivalent to signed `Shr`.
192
    ///
193
    /// # Examples
194
    ///
195
    /// ```
196
    /// use num_traits::PrimInt;
197
    ///
198
    /// let n = 0xFEDCBA9876543210u64;
199
    /// let m = 0xFFFFEDCBA9876543u64;
200
    ///
201
    /// assert_eq!(n.signed_shr(12), m);
202
    /// ```
203
    fn signed_shr(self, n: u32) -> Self;
204
205
    /// Shifts the bits to the left by a specified amount, `n`, filling
206
    /// zeros in the least significant bits.
207
    ///
208
    /// This is bitwise equivalent to unsigned `Shl`.
209
    ///
210
    /// # Examples
211
    ///
212
    /// ```
213
    /// use num_traits::PrimInt;
214
    ///
215
    /// let n = 0x0123456789ABCDEFi64;
216
    /// let m = 0x3456789ABCDEF000i64;
217
    ///
218
    /// assert_eq!(n.unsigned_shl(12), m);
219
    /// ```
220
    fn unsigned_shl(self, n: u32) -> Self;
221
222
    /// Shifts the bits to the right by a specified amount, `n`, filling
223
    /// zeros in the most significant bits.
224
    ///
225
    /// This is bitwise equivalent to unsigned `Shr`.
226
    ///
227
    /// # Examples
228
    ///
229
    /// ```
230
    /// use num_traits::PrimInt;
231
    ///
232
    /// let n = -8i8; // 0b11111000
233
    /// let m = 62i8; // 0b00111110
234
    ///
235
    /// assert_eq!(n.unsigned_shr(2), m);
236
    /// ```
237
    fn unsigned_shr(self, n: u32) -> Self;
238
239
    /// Reverses the byte order of the integer.
240
    ///
241
    /// # Examples
242
    ///
243
    /// ```
244
    /// use num_traits::PrimInt;
245
    ///
246
    /// let n = 0x0123456789ABCDEFu64;
247
    /// let m = 0xEFCDAB8967452301u64;
248
    ///
249
    /// assert_eq!(n.swap_bytes(), m);
250
    /// ```
251
    fn swap_bytes(self) -> Self;
252
253
    /// Reverses the order of bits in the integer.
254
    ///
255
    /// The least significant bit becomes the most significant bit, second least-significant bit
256
    /// becomes second most-significant bit, etc.
257
    ///
258
    /// # Examples
259
    ///
260
    /// ```
261
    /// use num_traits::PrimInt;
262
    ///
263
    /// let n = 0x12345678u32;
264
    /// let m = 0x1e6a2c48u32;
265
    ///
266
    /// assert_eq!(n.reverse_bits(), m);
267
    /// assert_eq!(0u32.reverse_bits(), 0);
268
    /// ```
269
0
    fn reverse_bits(self) -> Self {
270
0
        reverse_bits_fallback(self)
271
0
    }
272
273
    /// Convert an integer from big endian to the target's endianness.
274
    ///
275
    /// On big endian this is a no-op. On little endian the bytes are swapped.
276
    ///
277
    /// # Examples
278
    ///
279
    /// ```
280
    /// use num_traits::PrimInt;
281
    ///
282
    /// let n = 0x0123456789ABCDEFu64;
283
    ///
284
    /// if cfg!(target_endian = "big") {
285
    ///     assert_eq!(u64::from_be(n), n)
286
    /// } else {
287
    ///     assert_eq!(u64::from_be(n), n.swap_bytes())
288
    /// }
289
    /// ```
290
    fn from_be(x: Self) -> Self;
291
292
    /// Convert an integer from little endian to the target's endianness.
293
    ///
294
    /// On little endian this is a no-op. On big endian the bytes are swapped.
295
    ///
296
    /// # Examples
297
    ///
298
    /// ```
299
    /// use num_traits::PrimInt;
300
    ///
301
    /// let n = 0x0123456789ABCDEFu64;
302
    ///
303
    /// if cfg!(target_endian = "little") {
304
    ///     assert_eq!(u64::from_le(n), n)
305
    /// } else {
306
    ///     assert_eq!(u64::from_le(n), n.swap_bytes())
307
    /// }
308
    /// ```
309
    fn from_le(x: Self) -> Self;
310
311
    /// Convert `self` to big endian from the target's endianness.
312
    ///
313
    /// On big endian this is a no-op. On little endian the bytes are swapped.
314
    ///
315
    /// # Examples
316
    ///
317
    /// ```
318
    /// use num_traits::PrimInt;
319
    ///
320
    /// let n = 0x0123456789ABCDEFu64;
321
    ///
322
    /// if cfg!(target_endian = "big") {
323
    ///     assert_eq!(n.to_be(), n)
324
    /// } else {
325
    ///     assert_eq!(n.to_be(), n.swap_bytes())
326
    /// }
327
    /// ```
328
    fn to_be(self) -> Self;
329
330
    /// Convert `self` to little endian from the target's endianness.
331
    ///
332
    /// On little endian this is a no-op. On big endian the bytes are swapped.
333
    ///
334
    /// # Examples
335
    ///
336
    /// ```
337
    /// use num_traits::PrimInt;
338
    ///
339
    /// let n = 0x0123456789ABCDEFu64;
340
    ///
341
    /// if cfg!(target_endian = "little") {
342
    ///     assert_eq!(n.to_le(), n)
343
    /// } else {
344
    ///     assert_eq!(n.to_le(), n.swap_bytes())
345
    /// }
346
    /// ```
347
    fn to_le(self) -> Self;
348
349
    /// Raises self to the power of `exp`, using exponentiation by squaring.
350
    ///
351
    /// # Examples
352
    ///
353
    /// ```
354
    /// use num_traits::PrimInt;
355
    ///
356
    /// assert_eq!(2i32.pow(4), 16);
357
    /// ```
358
    fn pow(self, exp: u32) -> Self;
359
}
360
361
0
fn one_per_byte<P: PrimInt>() -> P {
362
0
    // i8, u8: return 0x01
363
0
    // i16, u16: return 0x0101 = (0x01 << 8) | 0x01
364
0
    // i32, u32: return 0x01010101 = (0x0101 << 16) | 0x0101
365
0
    // ...
366
0
    let mut ret = P::one();
367
0
    let mut shift = 8;
368
0
    let mut b = ret.count_zeros() >> 3;
369
0
    while b != 0 {
370
0
        ret = (ret << shift) | ret;
371
0
        shift <<= 1;
372
0
        b >>= 1;
373
0
    }
374
0
    ret
375
0
}
376
377
0
fn reverse_bits_fallback<P: PrimInt>(i: P) -> P {
378
0
    let rep_01: P = one_per_byte();
379
0
    let rep_03 = (rep_01 << 1) | rep_01;
380
0
    let rep_05 = (rep_01 << 2) | rep_01;
381
0
    let rep_0f = (rep_03 << 2) | rep_03;
382
0
    let rep_33 = (rep_03 << 4) | rep_03;
383
0
    let rep_55 = (rep_05 << 4) | rep_05;
384
0
385
0
    // code above only used to determine rep_0f, rep_33, rep_55;
386
0
    // optimizer should be able to do it in compile time
387
0
    let mut ret = i.swap_bytes();
388
0
    ret = ((ret & rep_0f) << 4) | ((ret >> 4) & rep_0f);
389
0
    ret = ((ret & rep_33) << 2) | ((ret >> 2) & rep_33);
390
0
    ret = ((ret & rep_55) << 1) | ((ret >> 1) & rep_55);
391
0
    ret
392
0
}
393
394
macro_rules! prim_int_impl {
395
    ($T:ty, $S:ty, $U:ty) => {
396
        impl PrimInt for $T {
397
            #[inline]
398
0
            fn count_ones(self) -> u32 {
399
0
                <$T>::count_ones(self)
400
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt10count_onesB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt10count_onesB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt10count_onesB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt10count_onesB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt10count_onesB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt10count_onesB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt10count_onesB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt10count_onesB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt10count_onesB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt10count_onesB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt10count_onesB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt10count_onesB7_
401
402
            #[inline]
403
0
            fn count_zeros(self) -> u32 {
404
0
                <$T>::count_zeros(self)
405
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt11count_zerosB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt11count_zerosB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt11count_zerosB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt11count_zerosB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt11count_zerosB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt11count_zerosB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt11count_zerosB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt11count_zerosB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt11count_zerosB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt11count_zerosB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt11count_zerosB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt11count_zerosB7_
406
407
            #[inline]
408
0
            fn leading_ones(self) -> u32 {
409
0
                <$T>::leading_ones(self)
410
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt12leading_onesB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt12leading_onesB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt12leading_onesB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt12leading_onesB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt12leading_onesB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt12leading_onesB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt12leading_onesB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt12leading_onesB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt12leading_onesB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt12leading_onesB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt12leading_onesB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt12leading_onesB7_
411
412
            #[inline]
413
0
            fn leading_zeros(self) -> u32 {
414
0
                <$T>::leading_zeros(self)
415
0
            }
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt13leading_zerosCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt13leading_zerosCs72ekIXsOXFl_10num_bigint
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt13leading_zerosCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt13leading_zerosCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt13leading_zerosCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt13leading_zerosCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt13leading_zerosCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt13leading_zerosCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt13leading_zerosB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt13leading_zerosB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt13leading_zerosB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt13leading_zerosB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt13leading_zerosB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt13leading_zerosB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt13leading_zerosB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt13leading_zerosB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt13leading_zerosB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt13leading_zerosB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt13leading_zerosB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt13leading_zerosB7_
416
417
            #[inline]
418
0
            fn trailing_ones(self) -> u32 {
419
0
                <$T>::trailing_ones(self)
420
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt13trailing_onesB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt13trailing_onesB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt13trailing_onesB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt13trailing_onesB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt13trailing_onesB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt13trailing_onesB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt13trailing_onesB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt13trailing_onesB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt13trailing_onesB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt13trailing_onesB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt13trailing_onesB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt13trailing_onesB7_
421
422
            #[inline]
423
0
            fn trailing_zeros(self) -> u32 {
424
0
                <$T>::trailing_zeros(self)
425
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt14trailing_zerosB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt14trailing_zerosB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt14trailing_zerosB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt14trailing_zerosB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt14trailing_zerosB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt14trailing_zerosB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt14trailing_zerosB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt14trailing_zerosB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt14trailing_zerosB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt14trailing_zerosB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt14trailing_zerosB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt14trailing_zerosB7_
426
427
            #[inline]
428
0
            fn rotate_left(self, n: u32) -> Self {
429
0
                <$T>::rotate_left(self, n)
430
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt11rotate_leftB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt11rotate_leftB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt11rotate_leftB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt11rotate_leftB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt11rotate_leftB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt11rotate_leftB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt11rotate_leftB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt11rotate_leftB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt11rotate_leftB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt11rotate_leftB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt11rotate_leftB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt11rotate_leftB7_
431
432
            #[inline]
433
0
            fn rotate_right(self, n: u32) -> Self {
434
0
                <$T>::rotate_right(self, n)
435
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt12rotate_rightB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt12rotate_rightB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt12rotate_rightB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt12rotate_rightB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt12rotate_rightB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt12rotate_rightB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt12rotate_rightB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt12rotate_rightB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt12rotate_rightB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt12rotate_rightB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt12rotate_rightB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt12rotate_rightB7_
436
437
            #[inline]
438
0
            fn signed_shl(self, n: u32) -> Self {
439
0
                ((self as $S) << n) as $T
440
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt10signed_shlB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt10signed_shlB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt10signed_shlB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt10signed_shlB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt10signed_shlB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt10signed_shlB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt10signed_shlB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt10signed_shlB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt10signed_shlB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt10signed_shlB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt10signed_shlB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt10signed_shlB7_
441
442
            #[inline]
443
0
            fn signed_shr(self, n: u32) -> Self {
444
0
                ((self as $S) >> n) as $T
445
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt10signed_shrB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt10signed_shrB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt10signed_shrB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt10signed_shrB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt10signed_shrB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt10signed_shrB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt10signed_shrB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt10signed_shrB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt10signed_shrB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt10signed_shrB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt10signed_shrB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt10signed_shrB7_
446
447
            #[inline]
448
0
            fn unsigned_shl(self, n: u32) -> Self {
449
0
                ((self as $U) << n) as $T
450
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt12unsigned_shlB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt12unsigned_shlB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt12unsigned_shlB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt12unsigned_shlB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt12unsigned_shlB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt12unsigned_shlB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt12unsigned_shlB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt12unsigned_shlB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt12unsigned_shlB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt12unsigned_shlB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt12unsigned_shlB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt12unsigned_shlB7_
451
452
            #[inline]
453
0
            fn unsigned_shr(self, n: u32) -> Self {
454
0
                ((self as $U) >> n) as $T
455
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt12unsigned_shrB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt12unsigned_shrB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt12unsigned_shrB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt12unsigned_shrB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt12unsigned_shrB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt12unsigned_shrB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt12unsigned_shrB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt12unsigned_shrB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt12unsigned_shrB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt12unsigned_shrB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt12unsigned_shrB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt12unsigned_shrB7_
456
457
            #[inline]
458
0
            fn swap_bytes(self) -> Self {
459
0
                <$T>::swap_bytes(self)
460
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt10swap_bytesB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt10swap_bytesB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt10swap_bytesB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt10swap_bytesB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt10swap_bytesB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt10swap_bytesB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt10swap_bytesB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt10swap_bytesB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt10swap_bytesB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt10swap_bytesB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt10swap_bytesB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt10swap_bytesB7_
461
462
            #[inline]
463
0
            fn reverse_bits(self) -> Self {
464
0
                <$T>::reverse_bits(self)
465
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt12reverse_bitsB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt12reverse_bitsB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt12reverse_bitsB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt12reverse_bitsB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt12reverse_bitsB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt12reverse_bitsB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt12reverse_bitsB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt12reverse_bitsB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt12reverse_bitsB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt12reverse_bitsB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt12reverse_bitsB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt12reverse_bitsB7_
466
467
            #[inline]
468
0
            fn from_be(x: Self) -> Self {
469
0
                <$T>::from_be(x)
470
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt7from_beB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt7from_beB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt7from_beB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt7from_beB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt7from_beB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt7from_beB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt7from_beB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt7from_beB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt7from_beB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt7from_beB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt7from_beB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt7from_beB7_
471
472
            #[inline]
473
0
            fn from_le(x: Self) -> Self {
474
0
                <$T>::from_le(x)
475
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt7from_leB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt7from_leB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt7from_leB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt7from_leB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt7from_leB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt7from_leB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt7from_leB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt7from_leB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt7from_leB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt7from_leB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt7from_leB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt7from_leB7_
476
477
            #[inline]
478
0
            fn to_be(self) -> Self {
479
0
                <$T>::to_be(self)
480
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt5to_beB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt5to_beB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt5to_beB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt5to_beB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt5to_beB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt5to_beB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt5to_beB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt5to_beB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt5to_beB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt5to_beB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt5to_beB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt5to_beB7_
481
482
            #[inline]
483
0
            fn to_le(self) -> Self {
484
0
                <$T>::to_le(self)
485
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt5to_leB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt5to_leB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt5to_leB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt5to_leB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt5to_leB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt5to_leB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt5to_leB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt5to_leB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt5to_leB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt5to_leB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt5to_leB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt5to_leB7_
486
487
            #[inline]
488
0
            fn pow(self, exp: u32) -> Self {
489
0
                <$T>::pow(self, exp)
490
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3inthNtB2_7PrimInt3powB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3inttNtB4_7PrimInt3powB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3intmNtB5_7PrimInt3powB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3intyNtB5_7PrimInt3powB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3intoNtB5_7PrimInt3powB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3intjNtB5_7PrimInt3powB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3intaNtB5_7PrimInt3powB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3intsNtB5_7PrimInt3powB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3intlNtB5_7PrimInt3powB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3intxNtB5_7PrimInt3powB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3intnNtB5_7PrimInt3powB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3intiNtB5_7PrimInt3powB7_
491
        }
492
    };
493
}
494
495
// prim_int_impl!(type, signed, unsigned);
496
prim_int_impl!(u8, i8, u8);
497
prim_int_impl!(u16, i16, u16);
498
prim_int_impl!(u32, i32, u32);
499
prim_int_impl!(u64, i64, u64);
500
prim_int_impl!(u128, i128, u128);
501
prim_int_impl!(usize, isize, usize);
502
prim_int_impl!(i8, i8, u8);
503
prim_int_impl!(i16, i16, u16);
504
prim_int_impl!(i32, i32, u32);
505
prim_int_impl!(i64, i64, u64);
506
prim_int_impl!(i128, i128, u128);
507
prim_int_impl!(isize, isize, usize);
508
509
#[cfg(test)]
510
mod tests {
511
    use crate::int::PrimInt;
512
513
    #[test]
514
    pub fn reverse_bits() {
515
        use core::{i16, i32, i64, i8};
516
517
        assert_eq!(
518
            PrimInt::reverse_bits(0x0123_4567_89ab_cdefu64),
519
            0xf7b3_d591_e6a2_c480
520
        );
521
522
        assert_eq!(PrimInt::reverse_bits(0i8), 0);
523
        assert_eq!(PrimInt::reverse_bits(-1i8), -1);
524
        assert_eq!(PrimInt::reverse_bits(1i8), i8::MIN);
525
        assert_eq!(PrimInt::reverse_bits(i8::MIN), 1);
526
        assert_eq!(PrimInt::reverse_bits(-2i8), i8::MAX);
527
        assert_eq!(PrimInt::reverse_bits(i8::MAX), -2);
528
529
        assert_eq!(PrimInt::reverse_bits(0i16), 0);
530
        assert_eq!(PrimInt::reverse_bits(-1i16), -1);
531
        assert_eq!(PrimInt::reverse_bits(1i16), i16::MIN);
532
        assert_eq!(PrimInt::reverse_bits(i16::MIN), 1);
533
        assert_eq!(PrimInt::reverse_bits(-2i16), i16::MAX);
534
        assert_eq!(PrimInt::reverse_bits(i16::MAX), -2);
535
536
        assert_eq!(PrimInt::reverse_bits(0i32), 0);
537
        assert_eq!(PrimInt::reverse_bits(-1i32), -1);
538
        assert_eq!(PrimInt::reverse_bits(1i32), i32::MIN);
539
        assert_eq!(PrimInt::reverse_bits(i32::MIN), 1);
540
        assert_eq!(PrimInt::reverse_bits(-2i32), i32::MAX);
541
        assert_eq!(PrimInt::reverse_bits(i32::MAX), -2);
542
543
        assert_eq!(PrimInt::reverse_bits(0i64), 0);
544
        assert_eq!(PrimInt::reverse_bits(-1i64), -1);
545
        assert_eq!(PrimInt::reverse_bits(1i64), i64::MIN);
546
        assert_eq!(PrimInt::reverse_bits(i64::MIN), 1);
547
        assert_eq!(PrimInt::reverse_bits(-2i64), i64::MAX);
548
        assert_eq!(PrimInt::reverse_bits(i64::MAX), -2);
549
    }
550
551
    #[test]
552
    pub fn reverse_bits_i128() {
553
        use core::i128;
554
555
        assert_eq!(PrimInt::reverse_bits(0i128), 0);
556
        assert_eq!(PrimInt::reverse_bits(-1i128), -1);
557
        assert_eq!(PrimInt::reverse_bits(1i128), i128::MIN);
558
        assert_eq!(PrimInt::reverse_bits(i128::MIN), 1);
559
        assert_eq!(PrimInt::reverse_bits(-2i128), i128::MAX);
560
        assert_eq!(PrimInt::reverse_bits(i128::MAX), -2);
561
    }
562
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/lib.rs
Line
Count
Source
1
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2
// file at the top-level directory of this distribution and at
3
// http://rust-lang.org/COPYRIGHT.
4
//
5
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8
// option. This file may not be copied, modified, or distributed
9
// except according to those terms.
10
11
//! Numeric traits for generic mathematics
12
//!
13
//! ## Compatibility
14
//!
15
//! The `num-traits` crate is tested for rustc 1.60 and greater.
16
17
#![doc(html_root_url = "https://docs.rs/num-traits/0.2")]
18
#![deny(unconditional_recursion)]
19
#![no_std]
20
21
// Need to explicitly bring the crate in for inherent float methods
22
#[cfg(feature = "std")]
23
extern crate std;
24
25
use core::fmt;
26
use core::num::Wrapping;
27
use core::ops::{Add, Div, Mul, Rem, Sub};
28
use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
29
30
pub use crate::bounds::Bounded;
31
#[cfg(any(feature = "std", feature = "libm"))]
32
pub use crate::float::Float;
33
pub use crate::float::FloatConst;
34
// pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
35
pub use crate::cast::{cast, AsPrimitive, FromPrimitive, NumCast, ToPrimitive};
36
pub use crate::identities::{one, zero, ConstOne, ConstZero, One, Zero};
37
pub use crate::int::PrimInt;
38
pub use crate::ops::bytes::{FromBytes, ToBytes};
39
pub use crate::ops::checked::{
40
    CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
41
};
42
pub use crate::ops::euclid::{CheckedEuclid, Euclid};
43
pub use crate::ops::inv::Inv;
44
pub use crate::ops::mul_add::{MulAdd, MulAddAssign};
45
pub use crate::ops::saturating::{Saturating, SaturatingAdd, SaturatingMul, SaturatingSub};
46
pub use crate::ops::wrapping::{
47
    WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub,
48
};
49
pub use crate::pow::{checked_pow, pow, Pow};
50
pub use crate::sign::{abs, abs_sub, signum, Signed, Unsigned};
51
52
#[macro_use]
53
mod macros;
54
55
pub mod bounds;
56
pub mod cast;
57
pub mod float;
58
pub mod identities;
59
pub mod int;
60
pub mod ops;
61
pub mod pow;
62
pub mod real;
63
pub mod sign;
64
65
/// The base trait for numeric types, covering `0` and `1` values,
66
/// comparisons, basic numeric operations, and string conversion.
67
pub trait Num: PartialEq + Zero + One + NumOps {
68
    type FromStrRadixErr;
69
70
    /// Convert from a string and radix (typically `2..=36`).
71
    ///
72
    /// # Examples
73
    ///
74
    /// ```rust
75
    /// use num_traits::Num;
76
    ///
77
    /// let result = <i32 as Num>::from_str_radix("27", 10);
78
    /// assert_eq!(result, Ok(27));
79
    ///
80
    /// let result = <i32 as Num>::from_str_radix("foo", 10);
81
    /// assert!(result.is_err());
82
    /// ```
83
    ///
84
    /// # Supported radices
85
    ///
86
    /// The exact range of supported radices is at the discretion of each type implementation. For
87
    /// primitive integers, this is implemented by the inherent `from_str_radix` methods in the
88
    /// standard library, which **panic** if the radix is not in the range from 2 to 36. The
89
    /// implementation in this crate for primitive floats is similar.
90
    ///
91
    /// For third-party types, it is suggested that implementations should follow suit and at least
92
    /// accept `2..=36` without panicking, but an `Err` may be returned for any unsupported radix.
93
    /// It's possible that a type might not even support the common radix 10, nor any, if string
94
    /// parsing doesn't make sense for that type.
95
    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>;
96
}
97
98
/// Generic trait for types implementing basic numeric operations
99
///
100
/// This is automatically implemented for types which implement the operators.
101
pub trait NumOps<Rhs = Self, Output = Self>:
102
    Add<Rhs, Output = Output>
103
    + Sub<Rhs, Output = Output>
104
    + Mul<Rhs, Output = Output>
105
    + Div<Rhs, Output = Output>
106
    + Rem<Rhs, Output = Output>
107
{
108
}
109
110
impl<T, Rhs, Output> NumOps<Rhs, Output> for T where
111
    T: Add<Rhs, Output = Output>
112
        + Sub<Rhs, Output = Output>
113
        + Mul<Rhs, Output = Output>
114
        + Div<Rhs, Output = Output>
115
        + Rem<Rhs, Output = Output>
116
{
117
}
118
119
/// The trait for `Num` types which also implement numeric operations taking
120
/// the second operand by reference.
121
///
122
/// This is automatically implemented for types which implement the operators.
123
pub trait NumRef: Num + for<'r> NumOps<&'r Self> {}
124
impl<T> NumRef for T where T: Num + for<'r> NumOps<&'r T> {}
125
126
/// The trait for `Num` references which implement numeric operations, taking the
127
/// second operand either by value or by reference.
128
///
129
/// This is automatically implemented for all types which implement the operators. It covers
130
/// every type implementing the operations though, regardless of it being a reference or
131
/// related to `Num`.
132
pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
133
impl<T, Base> RefNum<Base> for T where T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
134
135
/// Generic trait for types implementing numeric assignment operators (like `+=`).
136
///
137
/// This is automatically implemented for types which implement the operators.
138
pub trait NumAssignOps<Rhs = Self>:
139
    AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
140
{
141
}
142
143
impl<T, Rhs> NumAssignOps<Rhs> for T where
144
    T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
145
{
146
}
147
148
/// The trait for `Num` types which also implement assignment operators.
149
///
150
/// This is automatically implemented for types which implement the operators.
151
pub trait NumAssign: Num + NumAssignOps {}
152
impl<T> NumAssign for T where T: Num + NumAssignOps {}
153
154
/// The trait for `NumAssign` types which also implement assignment operations
155
/// taking the second operand by reference.
156
///
157
/// This is automatically implemented for types which implement the operators.
158
pub trait NumAssignRef: NumAssign + for<'r> NumAssignOps<&'r Self> {}
159
impl<T> NumAssignRef for T where T: NumAssign + for<'r> NumAssignOps<&'r T> {}
160
161
macro_rules! int_trait_impl {
162
    ($name:ident for $($t:ty)*) => ($(
163
        impl $name for $t {
164
            type FromStrRadixErr = ::core::num::ParseIntError;
165
            #[inline]
166
0
            fn from_str_radix(s: &str, radix: u32)
167
0
                              -> Result<Self, ::core::num::ParseIntError>
168
0
            {
169
0
                <$t>::from_str_radix(s, radix)
170
0
            }
Unexecuted instantiation: _RNvXs6_Cs7cG3k8kmkqw_10num_traitsjNtB5_3Num14from_str_radixB5_
Unexecuted instantiation: _RNvXs7_Cs7cG3k8kmkqw_10num_traitshNtB5_3Num14from_str_radixB5_
Unexecuted instantiation: _RNvXs8_Cs7cG3k8kmkqw_10num_traitstNtB5_3Num14from_str_radixB5_
Unexecuted instantiation: _RNvXs9_Cs7cG3k8kmkqw_10num_traitsmNtB5_3Num14from_str_radixB5_
Unexecuted instantiation: _RNvXsa_Cs7cG3k8kmkqw_10num_traitsyNtB5_3Num14from_str_radixB5_
Unexecuted instantiation: _RNvXsb_Cs7cG3k8kmkqw_10num_traitsoNtB5_3Num14from_str_radixB5_
Unexecuted instantiation: _RNvXsc_Cs7cG3k8kmkqw_10num_traitsiNtB5_3Num14from_str_radixB5_
Unexecuted instantiation: _RNvXsd_Cs7cG3k8kmkqw_10num_traitsaNtB5_3Num14from_str_radixB5_
Unexecuted instantiation: _RNvXse_Cs7cG3k8kmkqw_10num_traitssNtB5_3Num14from_str_radixB5_
Unexecuted instantiation: _RNvXsf_Cs7cG3k8kmkqw_10num_traitslNtB5_3Num14from_str_radixB5_
Unexecuted instantiation: _RNvXsg_Cs7cG3k8kmkqw_10num_traitsxNtB5_3Num14from_str_radixB5_
Unexecuted instantiation: _RNvXsh_Cs7cG3k8kmkqw_10num_traitsnNtB5_3Num14from_str_radixB5_
171
        }
172
    )*)
173
}
174
int_trait_impl!(Num for usize u8 u16 u32 u64 u128);
175
int_trait_impl!(Num for isize i8 i16 i32 i64 i128);
176
177
impl<T: Num> Num for Wrapping<T>
178
where
179
    Wrapping<T>: NumOps,
180
{
181
    type FromStrRadixErr = T::FromStrRadixErr;
182
0
    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
183
0
        T::from_str_radix(str, radix).map(Wrapping)
184
0
    }
185
}
186
187
#[derive(Debug)]
188
pub enum FloatErrorKind {
189
    Empty,
190
    Invalid,
191
}
192
// FIXME: core::num::ParseFloatError is stable in 1.0, but opaque to us,
193
// so there's not really any way for us to reuse it.
194
#[derive(Debug)]
195
pub struct ParseFloatError {
196
    pub kind: FloatErrorKind,
197
}
198
199
impl fmt::Display for ParseFloatError {
200
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201
0
        let description = match self.kind {
202
0
            FloatErrorKind::Empty => "cannot parse float from empty string",
203
0
            FloatErrorKind::Invalid => "invalid float literal",
204
        };
205
206
0
        description.fmt(f)
207
0
    }
208
}
209
210
0
fn str_to_ascii_lower_eq_str(a: &str, b: &str) -> bool {
211
0
    a.len() == b.len()
212
0
        && a.bytes().zip(b.bytes()).all(|(a, b)| {
213
0
            let a_to_ascii_lower = a | (((b'A' <= a && a <= b'Z') as u8) << 5);
214
0
            a_to_ascii_lower == b
215
0
        })
216
0
}
217
218
// FIXME: The standard library from_str_radix on floats was deprecated, so we're stuck
219
// with this implementation ourselves until we want to make a breaking change.
220
// (would have to drop it from `Num` though)
221
macro_rules! float_trait_impl {
222
    ($name:ident for $($t:ident)*) => ($(
223
        impl $name for $t {
224
            type FromStrRadixErr = ParseFloatError;
225
226
0
            fn from_str_radix(src: &str, radix: u32)
227
0
                              -> Result<Self, Self::FromStrRadixErr>
228
0
            {
229
                use self::FloatErrorKind::*;
230
                use self::ParseFloatError as PFE;
231
232
                // Special case radix 10 to use more accurate standard library implementation
233
0
                if radix == 10 {
234
0
                    return src.parse().map_err(|_| PFE {
235
0
                        kind: if src.is_empty() { Empty } else { Invalid },
236
0
                    });
Unexecuted instantiation: _RNCNvXsk_Cs7cG3k8kmkqw_10num_traitsfNtB7_3Num14from_str_radix0B7_
Unexecuted instantiation: _RNCNvXsl_Cs7cG3k8kmkqw_10num_traitsdNtB7_3Num14from_str_radix0B7_
237
0
                }
238
0
239
0
                // Special values
240
0
                if str_to_ascii_lower_eq_str(src, "inf")
241
0
                    || str_to_ascii_lower_eq_str(src, "infinity")
242
                {
243
0
                    return Ok(core::$t::INFINITY);
244
0
                } else if str_to_ascii_lower_eq_str(src, "-inf")
245
0
                    || str_to_ascii_lower_eq_str(src, "-infinity")
246
                {
247
0
                    return Ok(core::$t::NEG_INFINITY);
248
0
                } else if str_to_ascii_lower_eq_str(src, "nan") {
249
0
                    return Ok(core::$t::NAN);
250
0
                } else if str_to_ascii_lower_eq_str(src, "-nan") {
251
0
                    return Ok(-core::$t::NAN);
252
0
                }
253
254
0
                fn slice_shift_char(src: &str) -> Option<(char, &str)> {
255
0
                    let mut chars = src.chars();
256
0
                    Some((chars.next()?, chars.as_str()))
257
0
                }
Unexecuted instantiation: _RNvNvXsk_Cs7cG3k8kmkqw_10num_traitsfNtB7_3Num14from_str_radix16slice_shift_char
Unexecuted instantiation: _RNvNvXsl_Cs7cG3k8kmkqw_10num_traitsdNtB7_3Num14from_str_radix16slice_shift_char
258
259
0
                let (is_positive, src) =  match slice_shift_char(src) {
260
0
                    None             => return Err(PFE { kind: Empty }),
261
0
                    Some(('-', ""))  => return Err(PFE { kind: Empty }),
262
0
                    Some(('-', src)) => (false, src),
263
0
                    Some((_, _))     => (true,  src),
264
                };
265
266
                // The significand to accumulate
267
0
                let mut sig = if is_positive { 0.0 } else { -0.0 };
268
                // Necessary to detect overflow
269
0
                let mut prev_sig = sig;
270
0
                let mut cs = src.chars().enumerate();
271
0
                // Exponent prefix and exponent index offset
272
0
                let mut exp_info = None::<(char, usize)>;
273
274
                // Parse the integer part of the significand
275
0
                for (i, c) in cs.by_ref() {
276
0
                    match c.to_digit(radix) {
277
0
                        Some(digit) => {
278
0
                            // shift significand one digit left
279
0
                            sig *= radix as $t;
280
0
281
0
                            // add/subtract current digit depending on sign
282
0
                            if is_positive {
283
0
                                sig += (digit as isize) as $t;
284
0
                            } else {
285
0
                                sig -= (digit as isize) as $t;
286
0
                            }
287
288
                            // Detect overflow by comparing to last value, except
289
                            // if we've not seen any non-zero digits.
290
0
                            if prev_sig != 0.0 {
291
0
                                if is_positive && sig <= prev_sig
292
0
                                    { return Ok(core::$t::INFINITY); }
293
0
                                if !is_positive && sig >= prev_sig
294
0
                                    { return Ok(core::$t::NEG_INFINITY); }
295
0
296
0
                                // Detect overflow by reversing the shift-and-add process
297
0
                                if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
298
0
                                    { return Ok(core::$t::INFINITY); }
299
0
                                if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
300
0
                                    { return Ok(core::$t::NEG_INFINITY); }
301
0
                            }
302
0
                            prev_sig = sig;
303
                        },
304
0
                        None => match c {
305
                            'e' | 'E' | 'p' | 'P' => {
306
0
                                exp_info = Some((c, i + 1));
307
0
                                break;  // start of exponent
308
                            },
309
                            '.' => {
310
0
                                break;  // start of fractional part
311
                            },
312
                            _ => {
313
0
                                return Err(PFE { kind: Invalid });
314
                            },
315
                        },
316
                    }
317
                }
318
319
                // If we are not yet at the exponent parse the fractional
320
                // part of the significand
321
0
                if exp_info.is_none() {
322
0
                    let mut power = 1.0;
323
0
                    for (i, c) in cs.by_ref() {
324
0
                        match c.to_digit(radix) {
325
0
                            Some(digit) => {
326
0
                                // Decrease power one order of magnitude
327
0
                                power /= radix as $t;
328
0
                                // add/subtract current digit depending on sign
329
0
                                sig = if is_positive {
330
0
                                    sig + (digit as $t) * power
331
                                } else {
332
0
                                    sig - (digit as $t) * power
333
                                };
334
                                // Detect overflow by comparing to last value
335
0
                                if is_positive && sig < prev_sig
336
0
                                    { return Ok(core::$t::INFINITY); }
337
0
                                if !is_positive && sig > prev_sig
338
0
                                    { return Ok(core::$t::NEG_INFINITY); }
339
0
                                prev_sig = sig;
340
                            },
341
0
                            None => match c {
342
                                'e' | 'E' | 'p' | 'P' => {
343
0
                                    exp_info = Some((c, i + 1));
344
0
                                    break; // start of exponent
345
                                },
346
                                _ => {
347
0
                                    return Err(PFE { kind: Invalid });
348
                                },
349
                            },
350
                        }
351
                    }
352
0
                }
353
354
                // Parse and calculate the exponent
355
0
                let exp = match exp_info {
356
0
                    Some((c, offset)) => {
357
0
                        let base = match c {
358
0
                            'E' | 'e' if radix == 10 => 10.0,
359
0
                            'P' | 'p' if radix == 16 => 2.0,
360
0
                            _ => return Err(PFE { kind: Invalid }),
361
                        };
362
363
                        // Parse the exponent as decimal integer
364
0
                        let src = &src[offset..];
365
0
                        let (is_positive, exp) = match slice_shift_char(src) {
366
0
                            Some(('-', src)) => (false, src.parse::<usize>()),
367
0
                            Some(('+', src)) => (true,  src.parse::<usize>()),
368
0
                            Some((_, _))     => (true,  src.parse::<usize>()),
369
0
                            None             => return Err(PFE { kind: Invalid }),
370
                        };
371
372
                        #[cfg(feature = "std")]
373
0
                        fn pow(base: $t, exp: usize) -> $t {
374
0
                            Float::powi(base, exp as i32)
375
0
                        }
Unexecuted instantiation: _RNvNvXsk_Cs7cG3k8kmkqw_10num_traitsfNtB7_3Num14from_str_radix3pow
Unexecuted instantiation: _RNvNvXsl_Cs7cG3k8kmkqw_10num_traitsdNtB7_3Num14from_str_radix3pow
376
                        // otherwise uses the generic `pow` from the root
377
378
0
                        match (is_positive, exp) {
379
0
                            (true,  Ok(exp)) => pow(base, exp),
380
0
                            (false, Ok(exp)) => 1.0 / pow(base, exp),
381
0
                            (_, Err(_))      => return Err(PFE { kind: Invalid }),
382
                        }
383
                    },
384
0
                    None => 1.0, // no exponent
385
                };
386
387
0
                Ok(sig * exp)
388
0
            }
Unexecuted instantiation: _RNvXsk_Cs7cG3k8kmkqw_10num_traitsfNtB5_3Num14from_str_radix
Unexecuted instantiation: _RNvXsl_Cs7cG3k8kmkqw_10num_traitsdNtB5_3Num14from_str_radix
389
        }
390
    )*)
391
}
392
float_trait_impl!(Num for f32 f64);
393
394
/// A value bounded by a minimum and a maximum
395
///
396
///  If input is less than min then this returns min.
397
///  If input is greater than max then this returns max.
398
///  Otherwise this returns input.
399
///
400
/// **Panics** in debug mode if `!(min <= max)`.
401
#[inline]
402
0
pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T {
403
0
    debug_assert!(min <= max, "min must be less than or equal to max");
404
0
    if input < min {
405
0
        min
406
0
    } else if input > max {
407
0
        max
408
    } else {
409
0
        input
410
    }
411
0
}
412
413
/// A value bounded by a minimum value
414
///
415
///  If input is less than min then this returns min.
416
///  Otherwise this returns input.
417
///  `clamp_min(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::min(std::f32::NAN, 1.0)`.
418
///
419
/// **Panics** in debug mode if `!(min == min)`. (This occurs if `min` is `NAN`.)
420
#[inline]
421
#[allow(clippy::eq_op)]
422
0
pub fn clamp_min<T: PartialOrd>(input: T, min: T) -> T {
423
0
    debug_assert!(min == min, "min must not be NAN");
424
0
    if input < min {
425
0
        min
426
    } else {
427
0
        input
428
    }
429
0
}
430
431
/// A value bounded by a maximum value
432
///
433
///  If input is greater than max then this returns max.
434
///  Otherwise this returns input.
435
///  `clamp_max(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::max(std::f32::NAN, 1.0)`.
436
///
437
/// **Panics** in debug mode if `!(max == max)`. (This occurs if `max` is `NAN`.)
438
#[inline]
439
#[allow(clippy::eq_op)]
440
0
pub fn clamp_max<T: PartialOrd>(input: T, max: T) -> T {
441
0
    debug_assert!(max == max, "max must not be NAN");
442
0
    if input > max {
443
0
        max
444
    } else {
445
0
        input
446
    }
447
0
}
448
449
#[test]
450
fn clamp_test() {
451
    // Int test
452
    assert_eq!(1, clamp(1, -1, 2));
453
    assert_eq!(-1, clamp(-2, -1, 2));
454
    assert_eq!(2, clamp(3, -1, 2));
455
    assert_eq!(1, clamp_min(1, -1));
456
    assert_eq!(-1, clamp_min(-2, -1));
457
    assert_eq!(-1, clamp_max(1, -1));
458
    assert_eq!(-2, clamp_max(-2, -1));
459
460
    // Float test
461
    assert_eq!(1.0, clamp(1.0, -1.0, 2.0));
462
    assert_eq!(-1.0, clamp(-2.0, -1.0, 2.0));
463
    assert_eq!(2.0, clamp(3.0, -1.0, 2.0));
464
    assert_eq!(1.0, clamp_min(1.0, -1.0));
465
    assert_eq!(-1.0, clamp_min(-2.0, -1.0));
466
    assert_eq!(-1.0, clamp_max(1.0, -1.0));
467
    assert_eq!(-2.0, clamp_max(-2.0, -1.0));
468
    assert!(clamp(::core::f32::NAN, -1.0, 1.0).is_nan());
469
    assert!(clamp_min(::core::f32::NAN, 1.0).is_nan());
470
    assert!(clamp_max(::core::f32::NAN, 1.0).is_nan());
471
}
472
473
#[test]
474
#[should_panic]
475
#[cfg(debug_assertions)]
476
fn clamp_nan_min() {
477
    clamp(0., ::core::f32::NAN, 1.);
478
}
479
480
#[test]
481
#[should_panic]
482
#[cfg(debug_assertions)]
483
fn clamp_nan_max() {
484
    clamp(0., -1., ::core::f32::NAN);
485
}
486
487
#[test]
488
#[should_panic]
489
#[cfg(debug_assertions)]
490
fn clamp_nan_min_max() {
491
    clamp(0., ::core::f32::NAN, ::core::f32::NAN);
492
}
493
494
#[test]
495
#[should_panic]
496
#[cfg(debug_assertions)]
497
fn clamp_min_nan_min() {
498
    clamp_min(0., ::core::f32::NAN);
499
}
500
501
#[test]
502
#[should_panic]
503
#[cfg(debug_assertions)]
504
fn clamp_max_nan_max() {
505
    clamp_max(0., ::core::f32::NAN);
506
}
507
508
#[test]
509
fn from_str_radix_unwrap() {
510
    // The Result error must impl Debug to allow unwrap()
511
512
    let i: i32 = Num::from_str_radix("0", 10).unwrap();
513
    assert_eq!(i, 0);
514
515
    let f: f32 = Num::from_str_radix("0.0", 10).unwrap();
516
    assert_eq!(f, 0.0);
517
}
518
519
#[test]
520
fn from_str_radix_multi_byte_fail() {
521
    // Ensure parsing doesn't panic, even on invalid sign characters
522
    assert!(f32::from_str_radix("™0.2", 10).is_err());
523
524
    // Even when parsing the exponent sign
525
    assert!(f32::from_str_radix("0.2E™1", 10).is_err());
526
}
527
528
#[test]
529
fn from_str_radix_ignore_case() {
530
    assert_eq!(
531
        f32::from_str_radix("InF", 16).unwrap(),
532
        ::core::f32::INFINITY
533
    );
534
    assert_eq!(
535
        f32::from_str_radix("InfinitY", 16).unwrap(),
536
        ::core::f32::INFINITY
537
    );
538
    assert_eq!(
539
        f32::from_str_radix("-InF", 8).unwrap(),
540
        ::core::f32::NEG_INFINITY
541
    );
542
    assert_eq!(
543
        f32::from_str_radix("-InfinitY", 8).unwrap(),
544
        ::core::f32::NEG_INFINITY
545
    );
546
    assert!(f32::from_str_radix("nAn", 4).unwrap().is_nan());
547
    assert!(f32::from_str_radix("-nAn", 4).unwrap().is_nan());
548
}
549
550
#[test]
551
fn wrapping_is_num() {
552
    fn require_num<T: Num>(_: &T) {}
553
    require_num(&Wrapping(42_u32));
554
    require_num(&Wrapping(-42));
555
}
556
557
#[test]
558
fn wrapping_from_str_radix() {
559
    macro_rules! test_wrapping_from_str_radix {
560
        ($($t:ty)+) => {
561
            $(
562
                for &(s, r) in &[("42", 10), ("42", 2), ("-13.0", 10), ("foo", 10)] {
563
                    let w = Wrapping::<$t>::from_str_radix(s, r).map(|w| w.0);
564
                    assert_eq!(w, <$t as Num>::from_str_radix(s, r));
565
                }
566
            )+
567
        };
568
    }
569
570
    test_wrapping_from_str_radix!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
571
}
572
573
#[test]
574
fn check_num_ops() {
575
    fn compute<T: Num + Copy>(x: T, y: T) -> T {
576
        x * y / y % y + y - y
577
    }
578
    assert_eq!(compute(1, 2), 1)
579
}
580
581
#[test]
582
fn check_numref_ops() {
583
    fn compute<T: NumRef>(x: T, y: &T) -> T {
584
        x * y / y % y + y - y
585
    }
586
    assert_eq!(compute(1, &2), 1)
587
}
588
589
#[test]
590
fn check_refnum_ops() {
591
    fn compute<T: Copy>(x: &T, y: T) -> T
592
    where
593
        for<'a> &'a T: RefNum<T>,
594
    {
595
        &(&(&(&(x * y) / y) % y) + y) - y
596
    }
597
    assert_eq!(compute(&1, 2), 1)
598
}
599
600
#[test]
601
fn check_refref_ops() {
602
    fn compute<T>(x: &T, y: &T) -> T
603
    where
604
        for<'a> &'a T: RefNum<T>,
605
    {
606
        &(&(&(&(x * y) / y) % y) + y) - y
607
    }
608
    assert_eq!(compute(&1, &2), 1)
609
}
610
611
#[test]
612
fn check_numassign_ops() {
613
    fn compute<T: NumAssign + Copy>(mut x: T, y: T) -> T {
614
        x *= y;
615
        x /= y;
616
        x %= y;
617
        x += y;
618
        x -= y;
619
        x
620
    }
621
    assert_eq!(compute(1, 2), 1)
622
}
623
624
#[test]
625
fn check_numassignref_ops() {
626
    fn compute<T: NumAssignRef + Copy>(mut x: T, y: &T) -> T {
627
        x *= y;
628
        x /= y;
629
        x %= y;
630
        x += y;
631
        x -= y;
632
        x
633
    }
634
    assert_eq!(compute(1, &2), 1)
635
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/macros.rs
Line
Count
Source
1
// not all are used in all features configurations
2
#![allow(unused)]
3
4
/// Forward a method to an inherent method or a base trait method.
5
macro_rules! forward {
6
    ($( Self :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
7
        => {$(
8
            #[inline]
9
0
            fn $method(self $( , $arg : $ty )* ) -> $ret {
10
0
                Self::$method(self $( , $arg )* )
11
0
            }
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float7mul_addB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float7mul_addB7_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore6is_nanB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore11is_infiniteB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore9is_finiteB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore9is_normalB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore12is_subnormalB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore5clampB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore8classifyB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore16is_sign_positiveB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore16is_sign_negativeB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore3minB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore3maxB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore5recipB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore10to_degreesB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore10to_radiansB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore5floorB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore4ceilB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore5roundB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore5truncB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore5fractB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore3absB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore6signumB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore4powiB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore6is_nanB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore11is_infiniteB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore9is_finiteB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore9is_normalB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore12is_subnormalB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore5clampB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore8classifyB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore16is_sign_positiveB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore16is_sign_negativeB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore3minB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore3maxB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore5recipB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore10to_degreesB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore10to_radiansB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore5floorB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore4ceilB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore5roundB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore5truncB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore5fractB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore3absB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore6signumB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore4powiB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float6is_nanB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float11is_infiniteB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float9is_finiteB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float9is_normalB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float12is_subnormalB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float8classifyB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5clampB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5floorB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4ceilB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5roundB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5truncB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5fractB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float3absB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float6signumB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float16is_sign_positiveB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float16is_sign_negativeB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5recipB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4powiB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4powfB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4sqrtB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float3expB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4exp2B7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float2lnB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float3logB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4log2B7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5log10B7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float10to_degreesB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float10to_radiansB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float3maxB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float3minB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4cbrtB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5hypotB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float3sinB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float3cosB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float3tanB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4asinB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4acosB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4atanB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5atan2B7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float7sin_cosB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float6exp_m1B7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5ln_1pB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4sinhB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4coshB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float4tanhB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5asinhB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5acoshB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float5atanhB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float8copysignB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float6is_nanB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float11is_infiniteB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float9is_finiteB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float9is_normalB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float12is_subnormalB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float8classifyB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5clampB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5floorB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4ceilB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5roundB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5truncB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5fractB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float3absB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float6signumB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float16is_sign_positiveB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float16is_sign_negativeB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5recipB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4powiB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4powfB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4sqrtB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float3expB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4exp2B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float2lnB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float3logB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4log2B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5log10B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float10to_degreesB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float10to_radiansB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float3maxB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float3minB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4cbrtB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5hypotB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float3sinB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float3cosB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float3tanB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4asinB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4acosB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4atanB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5atan2B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float7sin_cosB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float6exp_m1B7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5ln_1pB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4sinhB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4coshB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float4tanhB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5asinhB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5acoshB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float5atanhB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float8copysignB7_
12
        )*};
13
    ($( $base:ident :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
14
        => {$(
15
            #[inline]
16
0
            fn $method(self $( , $arg : $ty )* ) -> $ret {
17
0
                <Self as $base>::$method(self $( , $arg )* )
18
0
            }
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5floorB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4ceilB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5roundB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5truncB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5fractB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real3absB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real6signumB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real16is_sign_positiveB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real16is_sign_negativeB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real7mul_addB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5recipB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4powiB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4powfB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4sqrtB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real3expB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4exp2B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real2lnB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real3logB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4log2B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5log10B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real10to_degreesB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real10to_radiansB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real3maxB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real3minB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real7abs_subB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4cbrtB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5hypotB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real3sinB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real3cosB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real3tanB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4asinB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4acosB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4atanB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5atan2B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real7sin_cosB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real6exp_m1B7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5ln_1pB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4sinhB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4coshB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real4tanhB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5asinhB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5acoshB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real5atanhB7_
19
        )*};
20
    ($( $base:ident :: $method:ident ( $( $arg:ident : $ty:ty ),* ) -> $ret:ty ; )*)
21
        => {$(
22
            #[inline]
23
0
            fn $method( $( $arg : $ty ),* ) -> $ret {
24
0
                <Self as $base>::$method( $( $arg ),* )
25
0
            }
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real9min_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real18min_positive_valueB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real7epsilonB7_
Unexecuted instantiation: _RNvXININtCs7cG3k8kmkqw_10num_traits4real0pEpNtB5_4Real9max_valueB7_
26
        )*};
27
    ($( $imp:path as $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
28
        => {$(
29
            #[inline]
30
            fn $method(self $( , $arg : $ty )* ) -> $ret {
31
                $imp(self $( , $arg )* )
32
            }
33
        )*};
34
}
35
36
macro_rules! constant {
37
    ($( $method:ident () -> $ret:expr ; )*)
38
        => {$(
39
            #[inline]
40
0
            fn $method() -> Self {
41
0
                $ret
42
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore8infinityB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore12neg_infinityB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore3nanB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore8neg_zeroB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore9min_valueB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore18min_positive_valueB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore7epsilonB4_
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits5floatfNtB2_9FloatCore9max_valueB4_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore8infinityB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore12neg_infinityB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore3nanB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore8neg_zeroB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore9min_valueB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore18min_positive_valueB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore7epsilonB6_
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits5floatdNtB4_9FloatCore9max_valueB6_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float3nanB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float8infinityB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float12neg_infinityB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float8neg_zeroB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float9min_valueB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float18min_positive_valueB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float7epsilonB7_
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_5Float9max_valueB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float3nanB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float8infinityB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float12neg_infinityB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float8neg_zeroB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float9min_valueB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float18min_positive_valueB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float7epsilonB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_5Float9max_valueB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst1EB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst9FRAC_1_PIB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst13FRAC_1_SQRT_2B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst9FRAC_2_PIB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst14FRAC_2_SQRT_PIB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst9FRAC_PI_2B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst9FRAC_PI_3B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst9FRAC_PI_4B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst9FRAC_PI_6B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst9FRAC_PI_8B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst5LN_10B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst4LN_2B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst7LOG10_EB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst6LOG2_EB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst2PIB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst6SQRT_2B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst3TAUB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst7LOG10_2B7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits5floatfNtB5_10FloatConst7LOG2_10B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst1EB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst9FRAC_1_PIB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst13FRAC_1_SQRT_2B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst9FRAC_2_PIB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst14FRAC_2_SQRT_PIB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst9FRAC_PI_2B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst9FRAC_PI_3B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst9FRAC_PI_4B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst9FRAC_PI_6B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst9FRAC_PI_8B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst5LN_10B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst4LN_2B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst7LOG10_EB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst6LOG2_EB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst2PIB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst6SQRT_2B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst3TAUB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst7LOG10_2B7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits5floatdNtB5_10FloatConst7LOG2_10B7_
43
        )*};
44
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/ops/bytes.rs
Line
Count
Source
1
use core::borrow::{Borrow, BorrowMut};
2
use core::cmp::{Eq, Ord, PartialEq, PartialOrd};
3
use core::fmt::Debug;
4
use core::hash::Hash;
5
6
pub trait NumBytes:
7
    Debug
8
    + AsRef<[u8]>
9
    + AsMut<[u8]>
10
    + PartialEq
11
    + Eq
12
    + PartialOrd
13
    + Ord
14
    + Hash
15
    + Borrow<[u8]>
16
    + BorrowMut<[u8]>
17
{
18
}
19
20
impl<T> NumBytes for T where
21
    T: Debug
22
        + AsRef<[u8]>
23
        + AsMut<[u8]>
24
        + PartialEq
25
        + Eq
26
        + PartialOrd
27
        + Ord
28
        + Hash
29
        + Borrow<[u8]>
30
        + BorrowMut<[u8]>
31
        + ?Sized
32
{
33
}
34
35
pub trait ToBytes {
36
    type Bytes: NumBytes;
37
38
    /// Return the memory representation of this number as a byte array in big-endian byte order.
39
    ///
40
    /// # Examples
41
    ///
42
    /// ```
43
    /// use num_traits::ToBytes;
44
    ///
45
    /// let bytes = ToBytes::to_be_bytes(&0x12345678u32);
46
    /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]);
47
    /// ```
48
    fn to_be_bytes(&self) -> Self::Bytes;
49
50
    /// Return the memory representation of this number as a byte array in little-endian byte order.
51
    ///
52
    /// # Examples
53
    ///
54
    /// ```
55
    /// use num_traits::ToBytes;
56
    ///
57
    /// let bytes = ToBytes::to_le_bytes(&0x12345678u32);
58
    /// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]);
59
    /// ```
60
    fn to_le_bytes(&self) -> Self::Bytes;
61
62
    /// Return the memory representation of this number as a byte array in native byte order.
63
    ///
64
    /// As the target platform's native endianness is used,
65
    /// portable code should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
66
    ///
67
    /// [`to_be_bytes`]: #method.to_be_bytes
68
    /// [`to_le_bytes`]: #method.to_le_bytes
69
    ///
70
    /// # Examples
71
    ///
72
    /// ```
73
    /// use num_traits::ToBytes;
74
    ///
75
    /// #[cfg(target_endian = "big")]
76
    /// let expected = [0x12, 0x34, 0x56, 0x78];
77
    ///
78
    /// #[cfg(target_endian = "little")]
79
    /// let expected = [0x78, 0x56, 0x34, 0x12];
80
    ///
81
    /// let bytes = ToBytes::to_ne_bytes(&0x12345678u32);
82
    /// assert_eq!(bytes, expected)
83
    /// ```
84
0
    fn to_ne_bytes(&self) -> Self::Bytes {
85
0
        #[cfg(target_endian = "big")]
86
0
        let bytes = self.to_be_bytes();
87
0
        #[cfg(target_endian = "little")]
88
0
        let bytes = self.to_le_bytes();
89
0
        bytes
90
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtNtCs7cG3k8kmkqw_10num_traits3ops5bytes7ToBytes11to_ne_bytesB6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtNtCs7cG3k8kmkqw_10num_traits3ops5bytes7ToBytes11to_ne_bytesB6_
Unexecuted instantiation: _RNvYpNtNtNtCs7cG3k8kmkqw_10num_traits3ops5bytes7ToBytes11to_ne_bytesB9_
91
}
92
93
pub trait FromBytes: Sized {
94
    type Bytes: NumBytes + ?Sized;
95
96
    /// Create a number from its representation as a byte array in big endian.
97
    ///
98
    /// # Examples
99
    ///
100
    /// ```
101
    /// use num_traits::FromBytes;
102
    ///
103
    /// let value: u32 = FromBytes::from_be_bytes(&[0x12, 0x34, 0x56, 0x78]);
104
    /// assert_eq!(value, 0x12345678);
105
    /// ```
106
    fn from_be_bytes(bytes: &Self::Bytes) -> Self;
107
108
    /// Create a number from its representation as a byte array in little endian.
109
    ///
110
    /// # Examples
111
    ///
112
    /// ```
113
    /// use num_traits::FromBytes;
114
    ///
115
    /// let value: u32 = FromBytes::from_le_bytes(&[0x78, 0x56, 0x34, 0x12]);
116
    /// assert_eq!(value, 0x12345678);
117
    /// ```
118
    fn from_le_bytes(bytes: &Self::Bytes) -> Self;
119
120
    /// Create a number from its memory representation as a byte array in native endianness.
121
    ///
122
    /// As the target platform's native endianness is used,
123
    /// portable code likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as appropriate instead.
124
    ///
125
    /// [`from_be_bytes`]: #method.from_be_bytes
126
    /// [`from_le_bytes`]: #method.from_le_bytes
127
    ///
128
    /// # Examples
129
    ///
130
    /// ```
131
    /// use num_traits::FromBytes;
132
    ///
133
    /// #[cfg(target_endian = "big")]
134
    /// let bytes = [0x12, 0x34, 0x56, 0x78];
135
    ///
136
    /// #[cfg(target_endian = "little")]
137
    /// let bytes = [0x78, 0x56, 0x34, 0x12];
138
    ///
139
    /// let value: u32 = FromBytes::from_ne_bytes(&bytes);
140
    /// assert_eq!(value, 0x12345678)
141
    /// ```
142
0
    fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
143
0
        #[cfg(target_endian = "big")]
144
0
        let this = Self::from_be_bytes(bytes);
145
0
        #[cfg(target_endian = "little")]
146
0
        let this = Self::from_le_bytes(bytes);
147
0
        this
148
0
    }
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntNtNtNtCs7cG3k8kmkqw_10num_traits3ops5bytes9FromBytes13from_ne_bytesB6_
Unexecuted instantiation: _RNvYNtNtCs72ekIXsOXFl_10num_bigint7biguint7BigUintNtNtNtCs7cG3k8kmkqw_10num_traits3ops5bytes9FromBytes13from_ne_bytesB6_
Unexecuted instantiation: _RNvYpNtNtNtCs7cG3k8kmkqw_10num_traits3ops5bytes9FromBytes13from_ne_bytesB9_
149
}
150
151
macro_rules! float_to_from_bytes_impl {
152
    ($T:ty, $L:expr) => {
153
        impl ToBytes for $T {
154
            type Bytes = [u8; $L];
155
156
            #[inline]
157
0
            fn to_be_bytes(&self) -> Self::Bytes {
158
0
                <$T>::to_be_bytes(*self)
159
0
            }
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesfNtB5_7ToBytes11to_be_bytesB9_
Unexecuted instantiation: _RNvXsp_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesdNtB5_7ToBytes11to_be_bytesB9_
160
161
            #[inline]
162
0
            fn to_le_bytes(&self) -> Self::Bytes {
163
0
                <$T>::to_le_bytes(*self)
164
0
            }
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesfNtB5_7ToBytes11to_le_bytesB9_
Unexecuted instantiation: _RNvXsp_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesdNtB5_7ToBytes11to_le_bytesB9_
165
166
            #[inline]
167
0
            fn to_ne_bytes(&self) -> Self::Bytes {
168
0
                <$T>::to_ne_bytes(*self)
169
0
            }
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesfNtB5_7ToBytes11to_ne_bytesB9_
Unexecuted instantiation: _RNvXsp_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesdNtB5_7ToBytes11to_ne_bytesB9_
170
        }
171
172
        impl FromBytes for $T {
173
            type Bytes = [u8; $L];
174
175
            #[inline]
176
0
            fn from_be_bytes(bytes: &Self::Bytes) -> Self {
177
0
                <$T>::from_be_bytes(*bytes)
178
0
            }
Unexecuted instantiation: _RNvXso_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesfNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXsq_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesdNtB5_9FromBytes13from_be_bytesB9_
179
180
            #[inline]
181
0
            fn from_le_bytes(bytes: &Self::Bytes) -> Self {
182
0
                <$T>::from_le_bytes(*bytes)
183
0
            }
Unexecuted instantiation: _RNvXso_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesfNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXsq_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesdNtB5_9FromBytes13from_le_bytesB9_
184
185
            #[inline]
186
0
            fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
187
0
                <$T>::from_ne_bytes(*bytes)
188
0
            }
Unexecuted instantiation: _RNvXso_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesfNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXsq_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesdNtB5_9FromBytes13from_ne_bytesB9_
189
        }
190
    };
191
}
192
193
macro_rules! int_to_from_bytes_impl {
194
    ($T:ty, $L:expr) => {
195
        impl ToBytes for $T {
196
            type Bytes = [u8; $L];
197
198
            #[inline]
199
0
            fn to_be_bytes(&self) -> Self::Bytes {
200
0
                <$T>::to_be_bytes(*self)
201
0
            }
Unexecuted instantiation: _RNvXs_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteshNtB4_7ToBytes11to_be_bytesB8_
Unexecuted instantiation: _RNvXs1_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytestNtB5_7ToBytes11to_be_bytesB9_
Unexecuted instantiation: _RNvXs3_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesmNtB5_7ToBytes11to_be_bytesB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesyNtB5_7ToBytes11to_be_bytesB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesoNtB5_7ToBytes11to_be_bytesB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesjNtB5_7ToBytes11to_be_bytesB9_
Unexecuted instantiation: _RNvXsb_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesaNtB5_7ToBytes11to_be_bytesB9_
Unexecuted instantiation: _RNvXsd_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytessNtB5_7ToBytes11to_be_bytesB9_
Unexecuted instantiation: _RNvXsf_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteslNtB5_7ToBytes11to_be_bytesB9_
Unexecuted instantiation: _RNvXsh_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesxNtB5_7ToBytes11to_be_bytesB9_
Unexecuted instantiation: _RNvXsj_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesnNtB5_7ToBytes11to_be_bytesB9_
Unexecuted instantiation: _RNvXsl_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesiNtB5_7ToBytes11to_be_bytesB9_
202
203
            #[inline]
204
0
            fn to_le_bytes(&self) -> Self::Bytes {
205
0
                <$T>::to_le_bytes(*self)
206
0
            }
Unexecuted instantiation: _RNvXs_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteshNtB4_7ToBytes11to_le_bytesB8_
Unexecuted instantiation: _RNvXs1_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytestNtB5_7ToBytes11to_le_bytesB9_
Unexecuted instantiation: _RNvXs3_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesmNtB5_7ToBytes11to_le_bytesB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesyNtB5_7ToBytes11to_le_bytesB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesoNtB5_7ToBytes11to_le_bytesB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesjNtB5_7ToBytes11to_le_bytesB9_
Unexecuted instantiation: _RNvXsb_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesaNtB5_7ToBytes11to_le_bytesB9_
Unexecuted instantiation: _RNvXsd_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytessNtB5_7ToBytes11to_le_bytesB9_
Unexecuted instantiation: _RNvXsf_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteslNtB5_7ToBytes11to_le_bytesB9_
Unexecuted instantiation: _RNvXsh_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesxNtB5_7ToBytes11to_le_bytesB9_
Unexecuted instantiation: _RNvXsj_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesnNtB5_7ToBytes11to_le_bytesB9_
Unexecuted instantiation: _RNvXsl_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesiNtB5_7ToBytes11to_le_bytesB9_
207
208
            #[inline]
209
0
            fn to_ne_bytes(&self) -> Self::Bytes {
210
0
                <$T>::to_ne_bytes(*self)
211
0
            }
Unexecuted instantiation: _RNvXs_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteshNtB4_7ToBytes11to_ne_bytesB8_
Unexecuted instantiation: _RNvXs1_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytestNtB5_7ToBytes11to_ne_bytesB9_
Unexecuted instantiation: _RNvXs3_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesmNtB5_7ToBytes11to_ne_bytesB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesyNtB5_7ToBytes11to_ne_bytesB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesoNtB5_7ToBytes11to_ne_bytesB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesjNtB5_7ToBytes11to_ne_bytesB9_
Unexecuted instantiation: _RNvXsb_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesaNtB5_7ToBytes11to_ne_bytesB9_
Unexecuted instantiation: _RNvXsd_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytessNtB5_7ToBytes11to_ne_bytesB9_
Unexecuted instantiation: _RNvXsf_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteslNtB5_7ToBytes11to_ne_bytesB9_
Unexecuted instantiation: _RNvXsh_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesxNtB5_7ToBytes11to_ne_bytesB9_
Unexecuted instantiation: _RNvXsj_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesnNtB5_7ToBytes11to_ne_bytesB9_
Unexecuted instantiation: _RNvXsl_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesiNtB5_7ToBytes11to_ne_bytesB9_
212
        }
213
214
        impl FromBytes for $T {
215
            type Bytes = [u8; $L];
216
217
            #[inline]
218
0
            fn from_be_bytes(bytes: &Self::Bytes) -> Self {
219
0
                <$T>::from_be_bytes(*bytes)
220
0
            }
Unexecuted instantiation: _RNvXs0_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteshNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXs2_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytestNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesmNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesyNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesoNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXsa_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesjNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXsc_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesaNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXse_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytessNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXsg_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteslNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXsi_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesxNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXsk_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesnNtB5_9FromBytes13from_be_bytesB9_
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesiNtB5_9FromBytes13from_be_bytesB9_
221
222
            #[inline]
223
0
            fn from_le_bytes(bytes: &Self::Bytes) -> Self {
224
0
                <$T>::from_le_bytes(*bytes)
225
0
            }
Unexecuted instantiation: _RNvXs0_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteshNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXs2_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytestNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesmNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesyNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesoNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXsa_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesjNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXsc_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesaNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXse_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytessNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXsg_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteslNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXsi_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesxNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXsk_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesnNtB5_9FromBytes13from_le_bytesB9_
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesiNtB5_9FromBytes13from_le_bytesB9_
226
227
            #[inline]
228
0
            fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
229
0
                <$T>::from_ne_bytes(*bytes)
230
0
            }
Unexecuted instantiation: _RNvXs0_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteshNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXs2_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytestNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesmNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesyNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesoNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXsa_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesjNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXsc_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesaNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXse_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytessNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXsg_NtNtCs7cG3k8kmkqw_10num_traits3ops5byteslNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXsi_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesxNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXsk_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesnNtB5_9FromBytes13from_ne_bytesB9_
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3ops5bytesiNtB5_9FromBytes13from_ne_bytesB9_
231
        }
232
    };
233
}
234
235
int_to_from_bytes_impl!(u8, 1);
236
int_to_from_bytes_impl!(u16, 2);
237
int_to_from_bytes_impl!(u32, 4);
238
int_to_from_bytes_impl!(u64, 8);
239
int_to_from_bytes_impl!(u128, 16);
240
#[cfg(target_pointer_width = "64")]
241
int_to_from_bytes_impl!(usize, 8);
242
#[cfg(target_pointer_width = "32")]
243
int_to_from_bytes_impl!(usize, 4);
244
245
int_to_from_bytes_impl!(i8, 1);
246
int_to_from_bytes_impl!(i16, 2);
247
int_to_from_bytes_impl!(i32, 4);
248
int_to_from_bytes_impl!(i64, 8);
249
int_to_from_bytes_impl!(i128, 16);
250
#[cfg(target_pointer_width = "64")]
251
int_to_from_bytes_impl!(isize, 8);
252
#[cfg(target_pointer_width = "32")]
253
int_to_from_bytes_impl!(isize, 4);
254
255
float_to_from_bytes_impl!(f32, 4);
256
float_to_from_bytes_impl!(f64, 8);
257
258
#[cfg(test)]
259
mod tests {
260
    use super::*;
261
262
    macro_rules! check_to_from_bytes {
263
        ($( $ty:ty )+) => {$({
264
            let n = 1;
265
            let be = <$ty as ToBytes>::to_be_bytes(&n);
266
            let le = <$ty as ToBytes>::to_le_bytes(&n);
267
            let ne = <$ty as ToBytes>::to_ne_bytes(&n);
268
269
            assert_eq!(*be.last().unwrap(), 1);
270
            assert_eq!(*le.first().unwrap(), 1);
271
            if cfg!(target_endian = "big") {
272
                assert_eq!(*ne.last().unwrap(), 1);
273
            } else {
274
                assert_eq!(*ne.first().unwrap(), 1);
275
            }
276
277
            assert_eq!(<$ty as FromBytes>::from_be_bytes(&be), n);
278
            assert_eq!(<$ty as FromBytes>::from_le_bytes(&le), n);
279
            if cfg!(target_endian = "big") {
280
                assert_eq!(<$ty as FromBytes>::from_ne_bytes(&be), n);
281
            } else {
282
                assert_eq!(<$ty as FromBytes>::from_ne_bytes(&le), n);
283
            }
284
        })+}
285
    }
286
287
    #[test]
288
    fn convert_between_int_and_bytes() {
289
        check_to_from_bytes!(u8 u16 u32 u64 u128 usize);
290
        check_to_from_bytes!(i8 i16 i32 i64 i128 isize);
291
    }
292
293
    #[test]
294
    fn convert_between_float_and_bytes() {
295
        macro_rules! check_to_from_bytes {
296
            ($( $ty:ty )+) => {$(
297
                let n: $ty = 3.14;
298
299
                let be = <$ty as ToBytes>::to_be_bytes(&n);
300
                let le = <$ty as ToBytes>::to_le_bytes(&n);
301
                let ne = <$ty as ToBytes>::to_ne_bytes(&n);
302
303
                assert_eq!(<$ty as FromBytes>::from_be_bytes(&be), n);
304
                assert_eq!(<$ty as FromBytes>::from_le_bytes(&le), n);
305
                if cfg!(target_endian = "big") {
306
                    assert_eq!(ne, be);
307
                    assert_eq!(<$ty as FromBytes>::from_ne_bytes(&be), n);
308
                } else {
309
                    assert_eq!(ne, le);
310
                    assert_eq!(<$ty as FromBytes>::from_ne_bytes(&le), n);
311
                }
312
            )+}
313
        }
314
315
        check_to_from_bytes!(f32 f64);
316
    }
317
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/ops/checked.rs
Line
Count
Source
1
use core::ops::{Add, Div, Mul, Rem, Shl, Shr, Sub};
2
3
/// Performs addition that returns `None` instead of wrapping around on
4
/// overflow.
5
pub trait CheckedAdd: Sized + Add<Self, Output = Self> {
6
    /// Adds two numbers, checking for overflow. If overflow happens, `None` is
7
    /// returned.
8
    fn checked_add(&self, v: &Self) -> Option<Self>;
9
}
10
11
macro_rules! checked_impl {
12
    ($trait_name:ident, $method:ident, $t:ty) => {
13
        impl $trait_name for $t {
14
            #[inline]
15
0
            fn $method(&self, v: &$t) -> Option<$t> {
16
0
                <$t>::$method(*self, *v)
17
0
            }
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedhNtB5_10CheckedMul11checked_mulCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedtNtB5_10CheckedMul11checked_mulCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXso_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedmNtB5_10CheckedMul11checked_mulCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsp_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedyNtB5_10CheckedMul11checked_mulCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsq_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedjNtB5_10CheckedMul11checked_mulCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXsr_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedoNtB5_10CheckedMul11checked_mulCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXNtNtCs7cG3k8kmkqw_10num_traits3ops7checkedhNtB2_10CheckedAdd11checked_addB6_
Unexecuted instantiation: _RNvXs_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedtNtB4_10CheckedAdd11checked_addB8_
Unexecuted instantiation: _RNvXs0_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedmNtB5_10CheckedAdd11checked_addB9_
Unexecuted instantiation: _RNvXs1_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedyNtB5_10CheckedAdd11checked_addB9_
Unexecuted instantiation: _RNvXs2_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedjNtB5_10CheckedAdd11checked_addB9_
Unexecuted instantiation: _RNvXs3_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedoNtB5_10CheckedAdd11checked_addB9_
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedaNtB5_10CheckedAdd11checked_addB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedsNtB5_10CheckedAdd11checked_addB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedlNtB5_10CheckedAdd11checked_addB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedxNtB5_10CheckedAdd11checked_addB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkediNtB5_10CheckedAdd11checked_addB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkednNtB5_10CheckedAdd11checked_addB9_
Unexecuted instantiation: _RNvXsa_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedhNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXsb_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedtNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXsc_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedmNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXsd_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedyNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXse_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedjNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXsf_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedoNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXsg_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedaNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXsh_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedsNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXsi_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedlNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXsj_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedxNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXsk_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkediNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXsl_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkednNtB5_10CheckedSub11checked_subB9_
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedhNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedtNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXso_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedmNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXsp_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedyNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXsq_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedjNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXsr_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedoNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXss_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedaNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXst_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedsNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXsu_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedlNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXsv_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedxNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXsw_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkediNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXsx_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkednNtB5_10CheckedMul11checked_mulB9_
Unexecuted instantiation: _RNvXsy_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedhNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsz_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedtNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsA_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedmNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsB_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedyNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsC_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedjNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsD_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedoNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsE_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedaNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsF_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedsNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsG_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedlNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsH_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedxNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsI_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkediNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkednNtB5_10CheckedDiv11checked_divB9_
Unexecuted instantiation: _RNvXsK_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedhNtB5_10CheckedRem11checked_remB9_
Unexecuted instantiation: _RNvXsL_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedtNtB5_10CheckedRem11checked_remB9_
Unexecuted instantiation: _RNvXsM_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedmNtB5_10CheckedRem11checked_remB9_
Unexecuted instantiation: _RNvXsN_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedyNtB5_10CheckedRem11checked_remB9_
Unexecuted instantiation: _RNvXsO_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedjNtB5_10CheckedRem11checked_remB9_
Unexecuted instantiation: _RNvXsP_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedoNtB5_10CheckedRem11checked_remB9_
Unexecuted instantiation: _RNvXsQ_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedaNtB5_10CheckedRem11checked_remB9_
Unexecuted instantiation: _RNvXsR_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedsNtB5_10CheckedRem11checked_remB9_
Unexecuted instantiation: _RNvXsS_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedlNtB5_10CheckedRem11checked_remB9_
Unexecuted instantiation: _RNvXsT_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedxNtB5_10CheckedRem11checked_remB9_
Unexecuted instantiation: _RNvXsU_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkediNtB5_10CheckedRem11checked_remB9_
Unexecuted instantiation: _RNvXsV_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkednNtB5_10CheckedRem11checked_remB9_
18
        }
19
    };
20
}
21
22
checked_impl!(CheckedAdd, checked_add, u8);
23
checked_impl!(CheckedAdd, checked_add, u16);
24
checked_impl!(CheckedAdd, checked_add, u32);
25
checked_impl!(CheckedAdd, checked_add, u64);
26
checked_impl!(CheckedAdd, checked_add, usize);
27
checked_impl!(CheckedAdd, checked_add, u128);
28
29
checked_impl!(CheckedAdd, checked_add, i8);
30
checked_impl!(CheckedAdd, checked_add, i16);
31
checked_impl!(CheckedAdd, checked_add, i32);
32
checked_impl!(CheckedAdd, checked_add, i64);
33
checked_impl!(CheckedAdd, checked_add, isize);
34
checked_impl!(CheckedAdd, checked_add, i128);
35
36
/// Performs subtraction that returns `None` instead of wrapping around on underflow.
37
pub trait CheckedSub: Sized + Sub<Self, Output = Self> {
38
    /// Subtracts two numbers, checking for underflow. If underflow happens,
39
    /// `None` is returned.
40
    fn checked_sub(&self, v: &Self) -> Option<Self>;
41
}
42
43
checked_impl!(CheckedSub, checked_sub, u8);
44
checked_impl!(CheckedSub, checked_sub, u16);
45
checked_impl!(CheckedSub, checked_sub, u32);
46
checked_impl!(CheckedSub, checked_sub, u64);
47
checked_impl!(CheckedSub, checked_sub, usize);
48
checked_impl!(CheckedSub, checked_sub, u128);
49
50
checked_impl!(CheckedSub, checked_sub, i8);
51
checked_impl!(CheckedSub, checked_sub, i16);
52
checked_impl!(CheckedSub, checked_sub, i32);
53
checked_impl!(CheckedSub, checked_sub, i64);
54
checked_impl!(CheckedSub, checked_sub, isize);
55
checked_impl!(CheckedSub, checked_sub, i128);
56
57
/// Performs multiplication that returns `None` instead of wrapping around on underflow or
58
/// overflow.
59
pub trait CheckedMul: Sized + Mul<Self, Output = Self> {
60
    /// Multiplies two numbers, checking for underflow or overflow. If underflow
61
    /// or overflow happens, `None` is returned.
62
    fn checked_mul(&self, v: &Self) -> Option<Self>;
63
}
64
65
checked_impl!(CheckedMul, checked_mul, u8);
66
checked_impl!(CheckedMul, checked_mul, u16);
67
checked_impl!(CheckedMul, checked_mul, u32);
68
checked_impl!(CheckedMul, checked_mul, u64);
69
checked_impl!(CheckedMul, checked_mul, usize);
70
checked_impl!(CheckedMul, checked_mul, u128);
71
72
checked_impl!(CheckedMul, checked_mul, i8);
73
checked_impl!(CheckedMul, checked_mul, i16);
74
checked_impl!(CheckedMul, checked_mul, i32);
75
checked_impl!(CheckedMul, checked_mul, i64);
76
checked_impl!(CheckedMul, checked_mul, isize);
77
checked_impl!(CheckedMul, checked_mul, i128);
78
79
/// Performs division that returns `None` instead of panicking on division by zero and instead of
80
/// wrapping around on underflow and overflow.
81
pub trait CheckedDiv: Sized + Div<Self, Output = Self> {
82
    /// Divides two numbers, checking for underflow, overflow and division by
83
    /// zero. If any of that happens, `None` is returned.
84
    fn checked_div(&self, v: &Self) -> Option<Self>;
85
}
86
87
checked_impl!(CheckedDiv, checked_div, u8);
88
checked_impl!(CheckedDiv, checked_div, u16);
89
checked_impl!(CheckedDiv, checked_div, u32);
90
checked_impl!(CheckedDiv, checked_div, u64);
91
checked_impl!(CheckedDiv, checked_div, usize);
92
checked_impl!(CheckedDiv, checked_div, u128);
93
94
checked_impl!(CheckedDiv, checked_div, i8);
95
checked_impl!(CheckedDiv, checked_div, i16);
96
checked_impl!(CheckedDiv, checked_div, i32);
97
checked_impl!(CheckedDiv, checked_div, i64);
98
checked_impl!(CheckedDiv, checked_div, isize);
99
checked_impl!(CheckedDiv, checked_div, i128);
100
101
/// Performs an integral remainder that returns `None` instead of panicking on division by zero and
102
/// instead of wrapping around on underflow and overflow.
103
pub trait CheckedRem: Sized + Rem<Self, Output = Self> {
104
    /// Finds the remainder of dividing two numbers, checking for underflow, overflow and division
105
    /// by zero. If any of that happens, `None` is returned.
106
    ///
107
    /// # Examples
108
    ///
109
    /// ```
110
    /// use num_traits::CheckedRem;
111
    /// use std::i32::MIN;
112
    ///
113
    /// assert_eq!(CheckedRem::checked_rem(&10, &7), Some(3));
114
    /// assert_eq!(CheckedRem::checked_rem(&10, &-7), Some(3));
115
    /// assert_eq!(CheckedRem::checked_rem(&-10, &7), Some(-3));
116
    /// assert_eq!(CheckedRem::checked_rem(&-10, &-7), Some(-3));
117
    ///
118
    /// assert_eq!(CheckedRem::checked_rem(&10, &0), None);
119
    ///
120
    /// assert_eq!(CheckedRem::checked_rem(&MIN, &1), Some(0));
121
    /// assert_eq!(CheckedRem::checked_rem(&MIN, &-1), None);
122
    /// ```
123
    fn checked_rem(&self, v: &Self) -> Option<Self>;
124
}
125
126
checked_impl!(CheckedRem, checked_rem, u8);
127
checked_impl!(CheckedRem, checked_rem, u16);
128
checked_impl!(CheckedRem, checked_rem, u32);
129
checked_impl!(CheckedRem, checked_rem, u64);
130
checked_impl!(CheckedRem, checked_rem, usize);
131
checked_impl!(CheckedRem, checked_rem, u128);
132
133
checked_impl!(CheckedRem, checked_rem, i8);
134
checked_impl!(CheckedRem, checked_rem, i16);
135
checked_impl!(CheckedRem, checked_rem, i32);
136
checked_impl!(CheckedRem, checked_rem, i64);
137
checked_impl!(CheckedRem, checked_rem, isize);
138
checked_impl!(CheckedRem, checked_rem, i128);
139
140
macro_rules! checked_impl_unary {
141
    ($trait_name:ident, $method:ident, $t:ty) => {
142
        impl $trait_name for $t {
143
            #[inline]
144
0
            fn $method(&self) -> Option<$t> {
145
0
                <$t>::$method(*self)
146
0
            }
Unexecuted instantiation: _RNvXsW_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedhNtB5_10CheckedNeg11checked_negB9_
Unexecuted instantiation: _RNvXsX_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedtNtB5_10CheckedNeg11checked_negB9_
Unexecuted instantiation: _RNvXsY_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedmNtB5_10CheckedNeg11checked_negB9_
Unexecuted instantiation: _RNvXsZ_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedyNtB5_10CheckedNeg11checked_negB9_
Unexecuted instantiation: _RNvXs10_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedjNtB6_10CheckedNeg11checked_negBa_
Unexecuted instantiation: _RNvXs11_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedoNtB6_10CheckedNeg11checked_negBa_
Unexecuted instantiation: _RNvXs12_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedaNtB6_10CheckedNeg11checked_negBa_
Unexecuted instantiation: _RNvXs13_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedsNtB6_10CheckedNeg11checked_negBa_
Unexecuted instantiation: _RNvXs14_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedlNtB6_10CheckedNeg11checked_negBa_
Unexecuted instantiation: _RNvXs15_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedxNtB6_10CheckedNeg11checked_negBa_
Unexecuted instantiation: _RNvXs16_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkediNtB6_10CheckedNeg11checked_negBa_
Unexecuted instantiation: _RNvXs17_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkednNtB6_10CheckedNeg11checked_negBa_
147
        }
148
    };
149
}
150
151
/// Performs negation that returns `None` if the result can't be represented.
152
pub trait CheckedNeg: Sized {
153
    /// Negates a number, returning `None` for results that can't be represented, like signed `MIN`
154
    /// values that can't be positive, or non-zero unsigned values that can't be negative.
155
    ///
156
    /// # Examples
157
    ///
158
    /// ```
159
    /// use num_traits::CheckedNeg;
160
    /// use std::i32::MIN;
161
    ///
162
    /// assert_eq!(CheckedNeg::checked_neg(&1_i32), Some(-1));
163
    /// assert_eq!(CheckedNeg::checked_neg(&-1_i32), Some(1));
164
    /// assert_eq!(CheckedNeg::checked_neg(&MIN), None);
165
    ///
166
    /// assert_eq!(CheckedNeg::checked_neg(&0_u32), Some(0));
167
    /// assert_eq!(CheckedNeg::checked_neg(&1_u32), None);
168
    /// ```
169
    fn checked_neg(&self) -> Option<Self>;
170
}
171
172
checked_impl_unary!(CheckedNeg, checked_neg, u8);
173
checked_impl_unary!(CheckedNeg, checked_neg, u16);
174
checked_impl_unary!(CheckedNeg, checked_neg, u32);
175
checked_impl_unary!(CheckedNeg, checked_neg, u64);
176
checked_impl_unary!(CheckedNeg, checked_neg, usize);
177
checked_impl_unary!(CheckedNeg, checked_neg, u128);
178
179
checked_impl_unary!(CheckedNeg, checked_neg, i8);
180
checked_impl_unary!(CheckedNeg, checked_neg, i16);
181
checked_impl_unary!(CheckedNeg, checked_neg, i32);
182
checked_impl_unary!(CheckedNeg, checked_neg, i64);
183
checked_impl_unary!(CheckedNeg, checked_neg, isize);
184
checked_impl_unary!(CheckedNeg, checked_neg, i128);
185
186
/// Performs a left shift that returns `None` on shifts larger than
187
/// or equal to the type width.
188
pub trait CheckedShl: Sized + Shl<u32, Output = Self> {
189
    /// Checked shift left. Computes `self << rhs`, returning `None`
190
    /// if `rhs` is larger than or equal to the number of bits in `self`.
191
    ///
192
    /// ```
193
    /// use num_traits::CheckedShl;
194
    ///
195
    /// let x: u16 = 0x0001;
196
    ///
197
    /// assert_eq!(CheckedShl::checked_shl(&x, 0),  Some(0x0001));
198
    /// assert_eq!(CheckedShl::checked_shl(&x, 1),  Some(0x0002));
199
    /// assert_eq!(CheckedShl::checked_shl(&x, 15), Some(0x8000));
200
    /// assert_eq!(CheckedShl::checked_shl(&x, 16), None);
201
    /// ```
202
    fn checked_shl(&self, rhs: u32) -> Option<Self>;
203
}
204
205
macro_rules! checked_shift_impl {
206
    ($trait_name:ident, $method:ident, $t:ty) => {
207
        impl $trait_name for $t {
208
            #[inline]
209
0
            fn $method(&self, rhs: u32) -> Option<$t> {
210
0
                <$t>::$method(*self, rhs)
211
0
            }
Unexecuted instantiation: _RNvXs18_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedhNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs19_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedtNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs1a_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedmNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs1b_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedyNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs1c_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedjNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs1d_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedoNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs1e_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedaNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs1f_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedsNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs1g_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedlNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs1h_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedxNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs1i_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkediNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs1j_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkednNtB6_10CheckedShl11checked_shlBa_
Unexecuted instantiation: _RNvXs1k_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedhNtB6_10CheckedShr11checked_shrBa_
Unexecuted instantiation: _RNvXs1l_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedtNtB6_10CheckedShr11checked_shrBa_
Unexecuted instantiation: _RNvXs1m_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedmNtB6_10CheckedShr11checked_shrBa_
Unexecuted instantiation: _RNvXs1n_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedyNtB6_10CheckedShr11checked_shrBa_
Unexecuted instantiation: _RNvXs1o_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedjNtB6_10CheckedShr11checked_shrBa_
Unexecuted instantiation: _RNvXs1p_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedoNtB6_10CheckedShr11checked_shrBa_
Unexecuted instantiation: _RNvXs1q_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedaNtB6_10CheckedShr11checked_shrBa_
Unexecuted instantiation: _RNvXs1r_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedsNtB6_10CheckedShr11checked_shrBa_
Unexecuted instantiation: _RNvXs1s_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedlNtB6_10CheckedShr11checked_shrBa_
Unexecuted instantiation: _RNvXs1t_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkedxNtB6_10CheckedShr11checked_shrBa_
Unexecuted instantiation: _RNvXs1u_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkediNtB6_10CheckedShr11checked_shrBa_
Unexecuted instantiation: _RNvXs1v_NtNtCs7cG3k8kmkqw_10num_traits3ops7checkednNtB6_10CheckedShr11checked_shrBa_
212
        }
213
    };
214
}
215
216
checked_shift_impl!(CheckedShl, checked_shl, u8);
217
checked_shift_impl!(CheckedShl, checked_shl, u16);
218
checked_shift_impl!(CheckedShl, checked_shl, u32);
219
checked_shift_impl!(CheckedShl, checked_shl, u64);
220
checked_shift_impl!(CheckedShl, checked_shl, usize);
221
checked_shift_impl!(CheckedShl, checked_shl, u128);
222
223
checked_shift_impl!(CheckedShl, checked_shl, i8);
224
checked_shift_impl!(CheckedShl, checked_shl, i16);
225
checked_shift_impl!(CheckedShl, checked_shl, i32);
226
checked_shift_impl!(CheckedShl, checked_shl, i64);
227
checked_shift_impl!(CheckedShl, checked_shl, isize);
228
checked_shift_impl!(CheckedShl, checked_shl, i128);
229
230
/// Performs a right shift that returns `None` on shifts larger than
231
/// or equal to the type width.
232
pub trait CheckedShr: Sized + Shr<u32, Output = Self> {
233
    /// Checked shift right. Computes `self >> rhs`, returning `None`
234
    /// if `rhs` is larger than or equal to the number of bits in `self`.
235
    ///
236
    /// ```
237
    /// use num_traits::CheckedShr;
238
    ///
239
    /// let x: u16 = 0x8000;
240
    ///
241
    /// assert_eq!(CheckedShr::checked_shr(&x, 0),  Some(0x8000));
242
    /// assert_eq!(CheckedShr::checked_shr(&x, 1),  Some(0x4000));
243
    /// assert_eq!(CheckedShr::checked_shr(&x, 15), Some(0x0001));
244
    /// assert_eq!(CheckedShr::checked_shr(&x, 16), None);
245
    /// ```
246
    fn checked_shr(&self, rhs: u32) -> Option<Self>;
247
}
248
249
checked_shift_impl!(CheckedShr, checked_shr, u8);
250
checked_shift_impl!(CheckedShr, checked_shr, u16);
251
checked_shift_impl!(CheckedShr, checked_shr, u32);
252
checked_shift_impl!(CheckedShr, checked_shr, u64);
253
checked_shift_impl!(CheckedShr, checked_shr, usize);
254
checked_shift_impl!(CheckedShr, checked_shr, u128);
255
256
checked_shift_impl!(CheckedShr, checked_shr, i8);
257
checked_shift_impl!(CheckedShr, checked_shr, i16);
258
checked_shift_impl!(CheckedShr, checked_shr, i32);
259
checked_shift_impl!(CheckedShr, checked_shr, i64);
260
checked_shift_impl!(CheckedShr, checked_shr, isize);
261
checked_shift_impl!(CheckedShr, checked_shr, i128);
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/ops/euclid.rs
Line
Count
Source
1
use core::ops::{Div, Rem};
2
3
pub trait Euclid: Sized + Div<Self, Output = Self> + Rem<Self, Output = Self> {
4
    /// Calculates Euclidean division, the matching method for `rem_euclid`.
5
    ///
6
    /// This computes the integer `n` such that
7
    /// `self = n * v + self.rem_euclid(v)`.
8
    /// In other words, the result is `self / v` rounded to the integer `n`
9
    /// such that `self >= n * v`.
10
    ///
11
    /// # Examples
12
    ///
13
    /// ```
14
    /// use num_traits::Euclid;
15
    ///
16
    /// let a: i32 = 7;
17
    /// let b: i32 = 4;
18
    /// assert_eq!(Euclid::div_euclid(&a, &b), 1); // 7 > 4 * 1
19
    /// assert_eq!(Euclid::div_euclid(&-a, &b), -2); // -7 >= 4 * -2
20
    /// assert_eq!(Euclid::div_euclid(&a, &-b), -1); // 7 >= -4 * -1
21
    /// assert_eq!(Euclid::div_euclid(&-a, &-b), 2); // -7 >= -4 * 2
22
    /// ```
23
    fn div_euclid(&self, v: &Self) -> Self;
24
25
    /// Calculates the least nonnegative remainder of `self (mod v)`.
26
    ///
27
    /// In particular, the return value `r` satisfies `0.0 <= r < v.abs()` in
28
    /// most cases. However, due to a floating point round-off error it can
29
    /// result in `r == v.abs()`, violating the mathematical definition, if
30
    /// `self` is much smaller than `v.abs()` in magnitude and `self < 0.0`.
31
    /// This result is not an element of the function's codomain, but it is the
32
    /// closest floating point number in the real numbers and thus fulfills the
33
    /// property `self == self.div_euclid(v) * v + self.rem_euclid(v)`
34
    /// approximatively.
35
    ///
36
    /// # Examples
37
    ///
38
    /// ```
39
    /// use num_traits::Euclid;
40
    ///
41
    /// let a: i32 = 7;
42
    /// let b: i32 = 4;
43
    /// assert_eq!(Euclid::rem_euclid(&a, &b), 3);
44
    /// assert_eq!(Euclid::rem_euclid(&-a, &b), 1);
45
    /// assert_eq!(Euclid::rem_euclid(&a, &-b), 3);
46
    /// assert_eq!(Euclid::rem_euclid(&-a, &-b), 1);
47
    /// ```
48
    fn rem_euclid(&self, v: &Self) -> Self;
49
50
    /// Returns both the quotient and remainder from Euclidean division.
51
    ///
52
    /// By default, it internally calls both `Euclid::div_euclid` and `Euclid::rem_euclid`,
53
    /// but it can be overridden in order to implement some optimization.
54
    ///
55
    /// # Examples
56
    ///
57
    /// ```
58
    /// # use num_traits::Euclid;
59
    /// let x = 5u8;
60
    /// let y = 3u8;
61
    ///
62
    /// let div = Euclid::div_euclid(&x, &y);
63
    /// let rem = Euclid::rem_euclid(&x, &y);
64
    ///
65
    /// assert_eq!((div, rem), Euclid::div_rem_euclid(&x, &y));
66
    /// ```
67
0
    fn div_rem_euclid(&self, v: &Self) -> (Self, Self) {
68
0
        (self.div_euclid(v), self.rem_euclid(v))
69
0
    }
Unexecuted instantiation: _RNvYaNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYdNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYfNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYhNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYiNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYjNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYlNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYmNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYnNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYoNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYsNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYtNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYxNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
Unexecuted instantiation: _RNvYyNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid6Euclid14div_rem_euclidB9_
70
}
71
72
macro_rules! euclid_forward_impl {
73
    ($($t:ty)*) => {$(
74
        impl Euclid for $t {
75
            #[inline]
76
0
            fn div_euclid(&self, v: &$t) -> Self {
77
0
                <$t>::div_euclid(*self, *v)
78
0
            }
Unexecuted instantiation: _RNvXNtNtCs7cG3k8kmkqw_10num_traits3ops6euclidiNtB2_6Euclid10div_euclidB6_
Unexecuted instantiation: _RNvXs_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidaNtB4_6Euclid10div_euclidB8_
Unexecuted instantiation: _RNvXs0_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidsNtB5_6Euclid10div_euclidB9_
Unexecuted instantiation: _RNvXs1_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidlNtB5_6Euclid10div_euclidB9_
Unexecuted instantiation: _RNvXs2_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidxNtB5_6Euclid10div_euclidB9_
Unexecuted instantiation: _RNvXs3_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidnNtB5_6Euclid10div_euclidB9_
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidjNtB5_6Euclid10div_euclidB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidhNtB5_6Euclid10div_euclidB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidtNtB5_6Euclid10div_euclidB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidmNtB5_6Euclid10div_euclidB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidyNtB5_6Euclid10div_euclidB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidoNtB5_6Euclid10div_euclidB9_
Unexecuted instantiation: _RNvXsa_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidfNtB5_6Euclid10div_euclidB9_
Unexecuted instantiation: _RNvXsb_NtNtCs7cG3k8kmkqw_10num_traits3ops6eucliddNtB5_6Euclid10div_euclidB9_
79
80
            #[inline]
81
0
            fn rem_euclid(&self, v: &$t) -> Self {
82
0
                <$t>::rem_euclid(*self, *v)
83
0
            }
Unexecuted instantiation: _RNvXNtNtCs7cG3k8kmkqw_10num_traits3ops6euclidiNtB2_6Euclid10rem_euclidB6_
Unexecuted instantiation: _RNvXs_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidaNtB4_6Euclid10rem_euclidB8_
Unexecuted instantiation: _RNvXs0_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidsNtB5_6Euclid10rem_euclidB9_
Unexecuted instantiation: _RNvXs1_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidlNtB5_6Euclid10rem_euclidB9_
Unexecuted instantiation: _RNvXs2_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidxNtB5_6Euclid10rem_euclidB9_
Unexecuted instantiation: _RNvXs3_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidnNtB5_6Euclid10rem_euclidB9_
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidjNtB5_6Euclid10rem_euclidB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidhNtB5_6Euclid10rem_euclidB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidtNtB5_6Euclid10rem_euclidB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidmNtB5_6Euclid10rem_euclidB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidyNtB5_6Euclid10rem_euclidB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidoNtB5_6Euclid10rem_euclidB9_
Unexecuted instantiation: _RNvXsa_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidfNtB5_6Euclid10rem_euclidB9_
Unexecuted instantiation: _RNvXsb_NtNtCs7cG3k8kmkqw_10num_traits3ops6eucliddNtB5_6Euclid10rem_euclidB9_
84
        }
85
    )*}
86
}
87
88
euclid_forward_impl!(isize i8 i16 i32 i64 i128);
89
euclid_forward_impl!(usize u8 u16 u32 u64 u128);
90
91
#[cfg(feature = "std")]
92
euclid_forward_impl!(f32 f64);
93
94
#[cfg(not(feature = "std"))]
95
impl Euclid for f32 {
96
    #[inline]
97
    fn div_euclid(&self, v: &f32) -> f32 {
98
        let q = <f32 as crate::float::FloatCore>::trunc(self / v);
99
        if self % v < 0.0 {
100
            return if *v > 0.0 { q - 1.0 } else { q + 1.0 };
101
        }
102
        q
103
    }
104
105
    #[inline]
106
    fn rem_euclid(&self, v: &f32) -> f32 {
107
        let r = self % v;
108
        if r < 0.0 {
109
            r + <f32 as crate::float::FloatCore>::abs(*v)
110
        } else {
111
            r
112
        }
113
    }
114
}
115
116
#[cfg(not(feature = "std"))]
117
impl Euclid for f64 {
118
    #[inline]
119
    fn div_euclid(&self, v: &f64) -> f64 {
120
        let q = <f64 as crate::float::FloatCore>::trunc(self / v);
121
        if self % v < 0.0 {
122
            return if *v > 0.0 { q - 1.0 } else { q + 1.0 };
123
        }
124
        q
125
    }
126
127
    #[inline]
128
    fn rem_euclid(&self, v: &f64) -> f64 {
129
        let r = self % v;
130
        if r < 0.0 {
131
            r + <f64 as crate::float::FloatCore>::abs(*v)
132
        } else {
133
            r
134
        }
135
    }
136
}
137
138
pub trait CheckedEuclid: Euclid {
139
    /// Performs euclid division that returns `None` instead of panicking on division by zero
140
    /// and instead of wrapping around on underflow and overflow.
141
    fn checked_div_euclid(&self, v: &Self) -> Option<Self>;
142
143
    /// Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
144
    /// division by zero. If any of that happens, `None` is returned.
145
    fn checked_rem_euclid(&self, v: &Self) -> Option<Self>;
146
147
    /// Returns both the quotient and remainder from checked Euclidean division.
148
    ///
149
    /// By default, it internally calls both `CheckedEuclid::checked_div_euclid` and `CheckedEuclid::checked_rem_euclid`,
150
    /// but it can be overridden in order to implement some optimization.
151
    /// # Examples
152
    ///
153
    /// ```
154
    /// # use num_traits::CheckedEuclid;
155
    /// let x = 5u8;
156
    /// let y = 3u8;
157
    ///
158
    /// let div = CheckedEuclid::checked_div_euclid(&x, &y);
159
    /// let rem = CheckedEuclid::checked_rem_euclid(&x, &y);
160
    ///
161
    /// assert_eq!(Some((div.unwrap(), rem.unwrap())), CheckedEuclid::checked_div_rem_euclid(&x, &y));
162
    /// ```
163
0
    fn checked_div_rem_euclid(&self, v: &Self) -> Option<(Self, Self)> {
164
0
        Some((self.checked_div_euclid(v)?, self.checked_rem_euclid(v)?))
165
0
    }
Unexecuted instantiation: _RNvYaNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
Unexecuted instantiation: _RNvYhNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
Unexecuted instantiation: _RNvYiNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
Unexecuted instantiation: _RNvYjNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
Unexecuted instantiation: _RNvYlNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
Unexecuted instantiation: _RNvYmNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
Unexecuted instantiation: _RNvYnNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
Unexecuted instantiation: _RNvYoNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
Unexecuted instantiation: _RNvYsNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
Unexecuted instantiation: _RNvYtNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
Unexecuted instantiation: _RNvYxNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
Unexecuted instantiation: _RNvYyNtNtNtCs7cG3k8kmkqw_10num_traits3ops6euclid13CheckedEuclid22checked_div_rem_euclidB9_
166
}
167
168
macro_rules! checked_euclid_forward_impl {
169
    ($($t:ty)*) => {$(
170
        impl CheckedEuclid for $t {
171
            #[inline]
172
0
            fn checked_div_euclid(&self, v: &$t) -> Option<Self> {
173
0
                <$t>::checked_div_euclid(*self, *v)
174
0
            }
Unexecuted instantiation: _RNvXsc_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidiNtB5_13CheckedEuclid18checked_div_euclidB9_
Unexecuted instantiation: _RNvXsd_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidaNtB5_13CheckedEuclid18checked_div_euclidB9_
Unexecuted instantiation: _RNvXse_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidsNtB5_13CheckedEuclid18checked_div_euclidB9_
Unexecuted instantiation: _RNvXsf_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidlNtB5_13CheckedEuclid18checked_div_euclidB9_
Unexecuted instantiation: _RNvXsg_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidxNtB5_13CheckedEuclid18checked_div_euclidB9_
Unexecuted instantiation: _RNvXsh_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidnNtB5_13CheckedEuclid18checked_div_euclidB9_
Unexecuted instantiation: _RNvXsi_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidjNtB5_13CheckedEuclid18checked_div_euclidB9_
Unexecuted instantiation: _RNvXsj_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidhNtB5_13CheckedEuclid18checked_div_euclidB9_
Unexecuted instantiation: _RNvXsk_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidtNtB5_13CheckedEuclid18checked_div_euclidB9_
Unexecuted instantiation: _RNvXsl_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidmNtB5_13CheckedEuclid18checked_div_euclidB9_
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidyNtB5_13CheckedEuclid18checked_div_euclidB9_
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidoNtB5_13CheckedEuclid18checked_div_euclidB9_
175
176
            #[inline]
177
0
            fn checked_rem_euclid(&self, v: &$t) -> Option<Self> {
178
0
                <$t>::checked_rem_euclid(*self, *v)
179
0
            }
Unexecuted instantiation: _RNvXsc_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidiNtB5_13CheckedEuclid18checked_rem_euclidB9_
Unexecuted instantiation: _RNvXsd_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidaNtB5_13CheckedEuclid18checked_rem_euclidB9_
Unexecuted instantiation: _RNvXse_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidsNtB5_13CheckedEuclid18checked_rem_euclidB9_
Unexecuted instantiation: _RNvXsf_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidlNtB5_13CheckedEuclid18checked_rem_euclidB9_
Unexecuted instantiation: _RNvXsg_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidxNtB5_13CheckedEuclid18checked_rem_euclidB9_
Unexecuted instantiation: _RNvXsh_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidnNtB5_13CheckedEuclid18checked_rem_euclidB9_
Unexecuted instantiation: _RNvXsi_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidjNtB5_13CheckedEuclid18checked_rem_euclidB9_
Unexecuted instantiation: _RNvXsj_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidhNtB5_13CheckedEuclid18checked_rem_euclidB9_
Unexecuted instantiation: _RNvXsk_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidtNtB5_13CheckedEuclid18checked_rem_euclidB9_
Unexecuted instantiation: _RNvXsl_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidmNtB5_13CheckedEuclid18checked_rem_euclidB9_
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidyNtB5_13CheckedEuclid18checked_rem_euclidB9_
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3ops6euclidoNtB5_13CheckedEuclid18checked_rem_euclidB9_
180
        }
181
    )*}
182
}
183
184
checked_euclid_forward_impl!(isize i8 i16 i32 i64 i128);
185
checked_euclid_forward_impl!(usize u8 u16 u32 u64 u128);
186
187
#[cfg(test)]
188
mod tests {
189
    use super::*;
190
191
    #[test]
192
    fn euclid_unsigned() {
193
        macro_rules! test_euclid {
194
            ($($t:ident)+) => {
195
                $(
196
                    {
197
                        let x: $t = 10;
198
                        let y: $t = 3;
199
                        let div = Euclid::div_euclid(&x, &y);
200
                        let rem = Euclid::rem_euclid(&x, &y);
201
                        assert_eq!(div, 3);
202
                        assert_eq!(rem, 1);
203
                        assert_eq!((div, rem), Euclid::div_rem_euclid(&x, &y));
204
                    }
205
                )+
206
            };
207
        }
208
209
        test_euclid!(usize u8 u16 u32 u64);
210
    }
211
212
    #[test]
213
    fn euclid_signed() {
214
        macro_rules! test_euclid {
215
            ($($t:ident)+) => {
216
                $(
217
                    {
218
                        let x: $t = 10;
219
                        let y: $t = -3;
220
                        assert_eq!(Euclid::div_euclid(&x, &y), -3);
221
                        assert_eq!(Euclid::div_euclid(&-x, &y), 4);
222
                        assert_eq!(Euclid::rem_euclid(&x, &y), 1);
223
                        assert_eq!(Euclid::rem_euclid(&-x, &y), 2);
224
                        assert_eq!((Euclid::div_euclid(&x, &y), Euclid::rem_euclid(&x, &y)), Euclid::div_rem_euclid(&x, &y));
225
                        let x: $t = $t::min_value() + 1;
226
                        let y: $t = -1;
227
                        assert_eq!(Euclid::div_euclid(&x, &y), $t::max_value());
228
                    }
229
                )+
230
            };
231
        }
232
233
        test_euclid!(isize i8 i16 i32 i64 i128);
234
    }
235
236
    #[test]
237
    fn euclid_float() {
238
        macro_rules! test_euclid {
239
            ($($t:ident)+) => {
240
                $(
241
                    {
242
                        let x: $t = 12.1;
243
                        let y: $t = 3.2;
244
                        assert!(Euclid::div_euclid(&x, &y) * y + Euclid::rem_euclid(&x, &y) - x
245
                        <= 46.4 * <$t as crate::float::FloatCore>::epsilon());
246
                        assert!(Euclid::div_euclid(&x, &-y) * -y + Euclid::rem_euclid(&x, &-y) - x
247
                        <= 46.4 * <$t as crate::float::FloatCore>::epsilon());
248
                        assert!(Euclid::div_euclid(&-x, &y) * y + Euclid::rem_euclid(&-x, &y) + x
249
                        <= 46.4 * <$t as crate::float::FloatCore>::epsilon());
250
                        assert!(Euclid::div_euclid(&-x, &-y) * -y + Euclid::rem_euclid(&-x, &-y) + x
251
                        <= 46.4 * <$t as crate::float::FloatCore>::epsilon());
252
                        assert_eq!((Euclid::div_euclid(&x, &y), Euclid::rem_euclid(&x, &y)), Euclid::div_rem_euclid(&x, &y));
253
                    }
254
                )+
255
            };
256
        }
257
258
        test_euclid!(f32 f64);
259
    }
260
261
    #[test]
262
    fn euclid_checked() {
263
        macro_rules! test_euclid_checked {
264
            ($($t:ident)+) => {
265
                $(
266
                    {
267
                        assert_eq!(CheckedEuclid::checked_div_euclid(&$t::min_value(), &-1), None);
268
                        assert_eq!(CheckedEuclid::checked_rem_euclid(&$t::min_value(), &-1), None);
269
                        assert_eq!(CheckedEuclid::checked_div_euclid(&1, &0), None);
270
                        assert_eq!(CheckedEuclid::checked_rem_euclid(&1, &0), None);
271
                    }
272
                )+
273
            };
274
        }
275
276
        test_euclid_checked!(isize i8 i16 i32 i64 i128);
277
    }
278
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/ops/inv.rs
Line
Count
Source
1
/// Unary operator for retrieving the multiplicative inverse, or reciprocal, of a value.
2
pub trait Inv {
3
    /// The result after applying the operator.
4
    type Output;
5
6
    /// Returns the multiplicative inverse of `self`.
7
    ///
8
    /// # Examples
9
    ///
10
    /// ```
11
    /// use std::f64::INFINITY;
12
    /// use num_traits::Inv;
13
    ///
14
    /// assert_eq!(7.0.inv() * 7.0, 1.0);
15
    /// assert_eq!((-0.0).inv(), -INFINITY);
16
    /// ```
17
    fn inv(self) -> Self::Output;
18
}
19
20
impl Inv for f32 {
21
    type Output = f32;
22
    #[inline]
23
0
    fn inv(self) -> f32 {
24
0
        1.0 / self
25
0
    }
26
}
27
impl Inv for f64 {
28
    type Output = f64;
29
    #[inline]
30
0
    fn inv(self) -> f64 {
31
0
        1.0 / self
32
0
    }
33
}
34
impl<'a> Inv for &'a f32 {
35
    type Output = f32;
36
    #[inline]
37
0
    fn inv(self) -> f32 {
38
0
        1.0 / *self
39
0
    }
40
}
41
impl<'a> Inv for &'a f64 {
42
    type Output = f64;
43
    #[inline]
44
0
    fn inv(self) -> f64 {
45
0
        1.0 / *self
46
0
    }
47
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/ops/mul_add.rs
Line
Count
Source
1
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
2
/// error, yielding a more accurate result than an unfused multiply-add.
3
///
4
/// Using `mul_add` can be more performant than an unfused multiply-add if
5
/// the target architecture has a dedicated `fma` CPU instruction.
6
///
7
/// Note that `A` and `B` are `Self` by default, but this is not mandatory.
8
///
9
/// # Example
10
///
11
/// ```
12
/// use std::f32;
13
///
14
/// let m = 10.0_f32;
15
/// let x = 4.0_f32;
16
/// let b = 60.0_f32;
17
///
18
/// // 100.0
19
/// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
20
///
21
/// assert!(abs_difference <= 100.0 * f32::EPSILON);
22
/// ```
23
pub trait MulAdd<A = Self, B = Self> {
24
    /// The resulting type after applying the fused multiply-add.
25
    type Output;
26
27
    /// Performs the fused multiply-add operation `(self * a) + b`
28
    fn mul_add(self, a: A, b: B) -> Self::Output;
29
}
30
31
/// The fused multiply-add assignment operation `*self = (*self * a) + b`
32
pub trait MulAddAssign<A = Self, B = Self> {
33
    /// Performs the fused multiply-add assignment operation `*self = (*self * a) + b`
34
    fn mul_add_assign(&mut self, a: A, b: B);
35
}
36
37
#[cfg(any(feature = "std", feature = "libm"))]
38
impl MulAdd<f32, f32> for f32 {
39
    type Output = Self;
40
41
    #[inline]
42
0
    fn mul_add(self, a: Self, b: Self) -> Self::Output {
43
0
        <Self as crate::Float>::mul_add(self, a, b)
44
0
    }
45
}
46
47
#[cfg(any(feature = "std", feature = "libm"))]
48
impl MulAdd<f64, f64> for f64 {
49
    type Output = Self;
50
51
    #[inline]
52
0
    fn mul_add(self, a: Self, b: Self) -> Self::Output {
53
0
        <Self as crate::Float>::mul_add(self, a, b)
54
0
    }
55
}
56
57
macro_rules! mul_add_impl {
58
    ($trait_name:ident for $($t:ty)*) => {$(
59
        impl $trait_name for $t {
60
            type Output = Self;
61
62
            #[inline]
63
0
            fn mul_add(self, a: Self, b: Self) -> Self::Output {
64
0
                (self * a) + b
65
0
            }
Unexecuted instantiation: _RNvXs2_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addiNtB5_6MulAdd7mul_addB9_
Unexecuted instantiation: _RNvXs3_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addaNtB5_6MulAdd7mul_addB9_
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addsNtB5_6MulAdd7mul_addB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addlNtB5_6MulAdd7mul_addB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addxNtB5_6MulAdd7mul_addB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addnNtB5_6MulAdd7mul_addB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addjNtB5_6MulAdd7mul_addB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addhNtB5_6MulAdd7mul_addB9_
Unexecuted instantiation: _RNvXsa_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addtNtB5_6MulAdd7mul_addB9_
Unexecuted instantiation: _RNvXsb_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addmNtB5_6MulAdd7mul_addB9_
Unexecuted instantiation: _RNvXsc_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addyNtB5_6MulAdd7mul_addB9_
Unexecuted instantiation: _RNvXsd_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addoNtB5_6MulAdd7mul_addB9_
66
        }
67
    )*}
68
}
69
70
mul_add_impl!(MulAdd for isize i8 i16 i32 i64 i128);
71
mul_add_impl!(MulAdd for usize u8 u16 u32 u64 u128);
72
73
#[cfg(any(feature = "std", feature = "libm"))]
74
impl MulAddAssign<f32, f32> for f32 {
75
    #[inline]
76
0
    fn mul_add_assign(&mut self, a: Self, b: Self) {
77
0
        *self = <Self as crate::Float>::mul_add(*self, a, b)
78
0
    }
79
}
80
81
#[cfg(any(feature = "std", feature = "libm"))]
82
impl MulAddAssign<f64, f64> for f64 {
83
    #[inline]
84
0
    fn mul_add_assign(&mut self, a: Self, b: Self) {
85
0
        *self = <Self as crate::Float>::mul_add(*self, a, b)
86
0
    }
87
}
88
89
macro_rules! mul_add_assign_impl {
90
    ($trait_name:ident for $($t:ty)*) => {$(
91
        impl $trait_name for $t {
92
            #[inline]
93
0
            fn mul_add_assign(&mut self, a: Self, b: Self) {
94
0
                *self = (*self * a) + b
95
0
            }
Unexecuted instantiation: _RNvXse_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addiNtB5_12MulAddAssign14mul_add_assignB9_
Unexecuted instantiation: _RNvXsf_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addaNtB5_12MulAddAssign14mul_add_assignB9_
Unexecuted instantiation: _RNvXsg_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addsNtB5_12MulAddAssign14mul_add_assignB9_
Unexecuted instantiation: _RNvXsh_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addlNtB5_12MulAddAssign14mul_add_assignB9_
Unexecuted instantiation: _RNvXsi_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addxNtB5_12MulAddAssign14mul_add_assignB9_
Unexecuted instantiation: _RNvXsj_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addnNtB5_12MulAddAssign14mul_add_assignB9_
Unexecuted instantiation: _RNvXsk_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addjNtB5_12MulAddAssign14mul_add_assignB9_
Unexecuted instantiation: _RNvXsl_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addhNtB5_12MulAddAssign14mul_add_assignB9_
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addtNtB5_12MulAddAssign14mul_add_assignB9_
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addmNtB5_12MulAddAssign14mul_add_assignB9_
Unexecuted instantiation: _RNvXso_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addyNtB5_12MulAddAssign14mul_add_assignB9_
Unexecuted instantiation: _RNvXsp_NtNtCs7cG3k8kmkqw_10num_traits3ops7mul_addoNtB5_12MulAddAssign14mul_add_assignB9_
96
        }
97
    )*}
98
}
99
100
mul_add_assign_impl!(MulAddAssign for isize i8 i16 i32 i64 i128);
101
mul_add_assign_impl!(MulAddAssign for usize u8 u16 u32 u64 u128);
102
103
#[cfg(test)]
104
mod tests {
105
    use super::*;
106
107
    #[test]
108
    fn mul_add_integer() {
109
        macro_rules! test_mul_add {
110
            ($($t:ident)+) => {
111
                $(
112
                    {
113
                        let m: $t = 2;
114
                        let x: $t = 3;
115
                        let b: $t = 4;
116
117
                        assert_eq!(MulAdd::mul_add(m, x, b), (m*x + b));
118
                    }
119
                )+
120
            };
121
        }
122
123
        test_mul_add!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
124
    }
125
126
    #[test]
127
    #[cfg(feature = "std")]
128
    fn mul_add_float() {
129
        macro_rules! test_mul_add {
130
            ($($t:ident)+) => {
131
                $(
132
                    {
133
                        use core::$t;
134
135
                        let m: $t = 12.0;
136
                        let x: $t = 3.4;
137
                        let b: $t = 5.6;
138
139
                        let abs_difference = (MulAdd::mul_add(m, x, b) - (m*x + b)).abs();
140
141
                        assert!(abs_difference <= 46.4 * $t::EPSILON);
142
                    }
143
                )+
144
            };
145
        }
146
147
        test_mul_add!(f32 f64);
148
    }
149
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/ops/overflowing.rs
Line
Count
Source
1
use core::ops::{Add, Mul, Sub};
2
use core::{i128, i16, i32, i64, i8, isize};
3
use core::{u128, u16, u32, u64, u8, usize};
4
5
macro_rules! overflowing_impl {
6
    ($trait_name:ident, $method:ident, $t:ty) => {
7
        impl $trait_name for $t {
8
            #[inline]
9
0
            fn $method(&self, v: &Self) -> (Self, bool) {
10
0
                <$t>::$method(*self, *v)
11
0
            }
Unexecuted instantiation: _RNvXNtNtCs7cG3k8kmkqw_10num_traits3ops11overflowinghNtB2_14OverflowingAdd15overflowing_addB6_
Unexecuted instantiation: _RNvXs_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingtNtB4_14OverflowingAdd15overflowing_addB8_
Unexecuted instantiation: _RNvXs0_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingmNtB5_14OverflowingAdd15overflowing_addB9_
Unexecuted instantiation: _RNvXs1_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingyNtB5_14OverflowingAdd15overflowing_addB9_
Unexecuted instantiation: _RNvXs2_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingjNtB5_14OverflowingAdd15overflowing_addB9_
Unexecuted instantiation: _RNvXs3_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingoNtB5_14OverflowingAdd15overflowing_addB9_
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingaNtB5_14OverflowingAdd15overflowing_addB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingsNtB5_14OverflowingAdd15overflowing_addB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowinglNtB5_14OverflowingAdd15overflowing_addB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingxNtB5_14OverflowingAdd15overflowing_addB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingiNtB5_14OverflowingAdd15overflowing_addB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingnNtB5_14OverflowingAdd15overflowing_addB9_
Unexecuted instantiation: _RNvXsa_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowinghNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXsb_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingtNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXsc_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingmNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXsd_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingyNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXse_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingjNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXsf_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingoNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXsg_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingaNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXsh_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingsNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXsi_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowinglNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXsj_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingxNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXsk_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingiNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXsl_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingnNtB5_14OverflowingSub15overflowing_subB9_
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowinghNtB5_14OverflowingMul15overflowing_mulB9_
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingtNtB5_14OverflowingMul15overflowing_mulB9_
Unexecuted instantiation: _RNvXso_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingmNtB5_14OverflowingMul15overflowing_mulB9_
Unexecuted instantiation: _RNvXsp_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingyNtB5_14OverflowingMul15overflowing_mulB9_
Unexecuted instantiation: _RNvXsq_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingjNtB5_14OverflowingMul15overflowing_mulB9_
Unexecuted instantiation: _RNvXsr_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingoNtB5_14OverflowingMul15overflowing_mulB9_
Unexecuted instantiation: _RNvXss_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingaNtB5_14OverflowingMul15overflowing_mulB9_
Unexecuted instantiation: _RNvXst_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingsNtB5_14OverflowingMul15overflowing_mulB9_
Unexecuted instantiation: _RNvXsu_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowinglNtB5_14OverflowingMul15overflowing_mulB9_
Unexecuted instantiation: _RNvXsv_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingxNtB5_14OverflowingMul15overflowing_mulB9_
Unexecuted instantiation: _RNvXsw_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingiNtB5_14OverflowingMul15overflowing_mulB9_
Unexecuted instantiation: _RNvXsx_NtNtCs7cG3k8kmkqw_10num_traits3ops11overflowingnNtB5_14OverflowingMul15overflowing_mulB9_
12
        }
13
    };
14
}
15
16
/// Performs addition with a flag for overflow.
17
pub trait OverflowingAdd: Sized + Add<Self, Output = Self> {
18
    /// Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow would occur.
19
    /// If an overflow would have occurred then the wrapped value is returned.
20
    fn overflowing_add(&self, v: &Self) -> (Self, bool);
21
}
22
23
overflowing_impl!(OverflowingAdd, overflowing_add, u8);
24
overflowing_impl!(OverflowingAdd, overflowing_add, u16);
25
overflowing_impl!(OverflowingAdd, overflowing_add, u32);
26
overflowing_impl!(OverflowingAdd, overflowing_add, u64);
27
overflowing_impl!(OverflowingAdd, overflowing_add, usize);
28
overflowing_impl!(OverflowingAdd, overflowing_add, u128);
29
30
overflowing_impl!(OverflowingAdd, overflowing_add, i8);
31
overflowing_impl!(OverflowingAdd, overflowing_add, i16);
32
overflowing_impl!(OverflowingAdd, overflowing_add, i32);
33
overflowing_impl!(OverflowingAdd, overflowing_add, i64);
34
overflowing_impl!(OverflowingAdd, overflowing_add, isize);
35
overflowing_impl!(OverflowingAdd, overflowing_add, i128);
36
37
/// Performs substraction with a flag for overflow.
38
pub trait OverflowingSub: Sized + Sub<Self, Output = Self> {
39
    /// Returns a tuple of the difference along with a boolean indicating whether an arithmetic overflow would occur.
40
    /// If an overflow would have occurred then the wrapped value is returned.
41
    fn overflowing_sub(&self, v: &Self) -> (Self, bool);
42
}
43
44
overflowing_impl!(OverflowingSub, overflowing_sub, u8);
45
overflowing_impl!(OverflowingSub, overflowing_sub, u16);
46
overflowing_impl!(OverflowingSub, overflowing_sub, u32);
47
overflowing_impl!(OverflowingSub, overflowing_sub, u64);
48
overflowing_impl!(OverflowingSub, overflowing_sub, usize);
49
overflowing_impl!(OverflowingSub, overflowing_sub, u128);
50
51
overflowing_impl!(OverflowingSub, overflowing_sub, i8);
52
overflowing_impl!(OverflowingSub, overflowing_sub, i16);
53
overflowing_impl!(OverflowingSub, overflowing_sub, i32);
54
overflowing_impl!(OverflowingSub, overflowing_sub, i64);
55
overflowing_impl!(OverflowingSub, overflowing_sub, isize);
56
overflowing_impl!(OverflowingSub, overflowing_sub, i128);
57
58
/// Performs multiplication with a flag for overflow.
59
pub trait OverflowingMul: Sized + Mul<Self, Output = Self> {
60
    /// Returns a tuple of the product along with a boolean indicating whether an arithmetic overflow would occur.
61
    /// If an overflow would have occurred then the wrapped value is returned.
62
    fn overflowing_mul(&self, v: &Self) -> (Self, bool);
63
}
64
65
overflowing_impl!(OverflowingMul, overflowing_mul, u8);
66
overflowing_impl!(OverflowingMul, overflowing_mul, u16);
67
overflowing_impl!(OverflowingMul, overflowing_mul, u32);
68
overflowing_impl!(OverflowingMul, overflowing_mul, u64);
69
overflowing_impl!(OverflowingMul, overflowing_mul, usize);
70
overflowing_impl!(OverflowingMul, overflowing_mul, u128);
71
72
overflowing_impl!(OverflowingMul, overflowing_mul, i8);
73
overflowing_impl!(OverflowingMul, overflowing_mul, i16);
74
overflowing_impl!(OverflowingMul, overflowing_mul, i32);
75
overflowing_impl!(OverflowingMul, overflowing_mul, i64);
76
overflowing_impl!(OverflowingMul, overflowing_mul, isize);
77
overflowing_impl!(OverflowingMul, overflowing_mul, i128);
78
79
#[test]
80
fn test_overflowing_traits() {
81
    fn overflowing_add<T: OverflowingAdd>(a: T, b: T) -> (T, bool) {
82
        a.overflowing_add(&b)
83
    }
84
    fn overflowing_sub<T: OverflowingSub>(a: T, b: T) -> (T, bool) {
85
        a.overflowing_sub(&b)
86
    }
87
    fn overflowing_mul<T: OverflowingMul>(a: T, b: T) -> (T, bool) {
88
        a.overflowing_mul(&b)
89
    }
90
    assert_eq!(overflowing_add(5i16, 2), (7, false));
91
    assert_eq!(overflowing_add(i16::MAX, 1), (i16::MIN, true));
92
    assert_eq!(overflowing_sub(5i16, 2), (3, false));
93
    assert_eq!(overflowing_sub(i16::MIN, 1), (i16::MAX, true));
94
    assert_eq!(overflowing_mul(5i16, 2), (10, false));
95
    assert_eq!(overflowing_mul(1_000_000_000i32, 10), (1410065408, true));
96
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/ops/saturating.rs
Line
Count
Source
1
use core::ops::{Add, Mul, Sub};
2
3
/// Saturating math operations. Deprecated, use `SaturatingAdd`, `SaturatingSub` and
4
/// `SaturatingMul` instead.
5
pub trait Saturating {
6
    /// Saturating addition operator.
7
    /// Returns a+b, saturating at the numeric bounds instead of overflowing.
8
    fn saturating_add(self, v: Self) -> Self;
9
10
    /// Saturating subtraction operator.
11
    /// Returns a-b, saturating at the numeric bounds instead of overflowing.
12
    fn saturating_sub(self, v: Self) -> Self;
13
}
14
15
macro_rules! deprecated_saturating_impl {
16
    ($trait_name:ident for $($t:ty)*) => {$(
17
        impl $trait_name for $t {
18
            #[inline]
19
0
            fn saturating_add(self, v: Self) -> Self {
20
0
                Self::saturating_add(self, v)
21
0
            }
Unexecuted instantiation: _RNvXNtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingiNtB2_10Saturating14saturating_addB6_
Unexecuted instantiation: _RNvXs_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingaNtB4_10Saturating14saturating_addB8_
Unexecuted instantiation: _RNvXs0_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingsNtB5_10Saturating14saturating_addB9_
Unexecuted instantiation: _RNvXs1_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatinglNtB5_10Saturating14saturating_addB9_
Unexecuted instantiation: _RNvXs2_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingxNtB5_10Saturating14saturating_addB9_
Unexecuted instantiation: _RNvXs3_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingnNtB5_10Saturating14saturating_addB9_
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingjNtB5_10Saturating14saturating_addB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatinghNtB5_10Saturating14saturating_addB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingtNtB5_10Saturating14saturating_addB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingmNtB5_10Saturating14saturating_addB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingyNtB5_10Saturating14saturating_addB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingoNtB5_10Saturating14saturating_addB9_
22
23
            #[inline]
24
0
            fn saturating_sub(self, v: Self) -> Self {
25
0
                Self::saturating_sub(self, v)
26
0
            }
Unexecuted instantiation: _RNvXNtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingiNtB2_10Saturating14saturating_subB6_
Unexecuted instantiation: _RNvXs_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingaNtB4_10Saturating14saturating_subB8_
Unexecuted instantiation: _RNvXs0_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingsNtB5_10Saturating14saturating_subB9_
Unexecuted instantiation: _RNvXs1_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatinglNtB5_10Saturating14saturating_subB9_
Unexecuted instantiation: _RNvXs2_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingxNtB5_10Saturating14saturating_subB9_
Unexecuted instantiation: _RNvXs3_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingnNtB5_10Saturating14saturating_subB9_
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingjNtB5_10Saturating14saturating_subB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatinghNtB5_10Saturating14saturating_subB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingtNtB5_10Saturating14saturating_subB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingmNtB5_10Saturating14saturating_subB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingyNtB5_10Saturating14saturating_subB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingoNtB5_10Saturating14saturating_subB9_
27
        }
28
    )*}
29
}
30
31
deprecated_saturating_impl!(Saturating for isize i8 i16 i32 i64 i128);
32
deprecated_saturating_impl!(Saturating for usize u8 u16 u32 u64 u128);
33
34
macro_rules! saturating_impl {
35
    ($trait_name:ident, $method:ident, $t:ty) => {
36
        impl $trait_name for $t {
37
            #[inline]
38
0
            fn $method(&self, v: &Self) -> Self {
39
0
                <$t>::$method(*self, *v)
40
0
            }
Unexecuted instantiation: _RNvXsa_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatinghNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXsb_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingtNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXsc_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingmNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXsd_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingyNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXse_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingjNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXsf_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingoNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXsg_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingaNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXsh_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingsNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXsi_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatinglNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXsj_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingxNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXsk_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingiNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXsl_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingnNtB5_13SaturatingAdd14saturating_addB9_
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatinghNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingtNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXso_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingmNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXsp_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingyNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXsq_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingjNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXsr_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingoNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXss_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingaNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXst_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingsNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXsu_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatinglNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXsv_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingxNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXsw_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingiNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXsx_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingnNtB5_13SaturatingSub14saturating_subB9_
Unexecuted instantiation: _RNvXsy_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatinghNtB5_13SaturatingMul14saturating_mulB9_
Unexecuted instantiation: _RNvXsz_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingtNtB5_13SaturatingMul14saturating_mulB9_
Unexecuted instantiation: _RNvXsA_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingmNtB5_13SaturatingMul14saturating_mulB9_
Unexecuted instantiation: _RNvXsB_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingyNtB5_13SaturatingMul14saturating_mulB9_
Unexecuted instantiation: _RNvXsC_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingjNtB5_13SaturatingMul14saturating_mulB9_
Unexecuted instantiation: _RNvXsD_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingoNtB5_13SaturatingMul14saturating_mulB9_
Unexecuted instantiation: _RNvXsE_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingaNtB5_13SaturatingMul14saturating_mulB9_
Unexecuted instantiation: _RNvXsF_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingsNtB5_13SaturatingMul14saturating_mulB9_
Unexecuted instantiation: _RNvXsG_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatinglNtB5_13SaturatingMul14saturating_mulB9_
Unexecuted instantiation: _RNvXsH_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingxNtB5_13SaturatingMul14saturating_mulB9_
Unexecuted instantiation: _RNvXsI_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingiNtB5_13SaturatingMul14saturating_mulB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs7cG3k8kmkqw_10num_traits3ops10saturatingnNtB5_13SaturatingMul14saturating_mulB9_
41
        }
42
    };
43
}
44
45
/// Performs addition that saturates at the numeric bounds instead of overflowing.
46
pub trait SaturatingAdd: Sized + Add<Self, Output = Self> {
47
    /// Saturating addition. Computes `self + other`, saturating at the relevant high or low boundary of
48
    /// the type.
49
    fn saturating_add(&self, v: &Self) -> Self;
50
}
51
52
saturating_impl!(SaturatingAdd, saturating_add, u8);
53
saturating_impl!(SaturatingAdd, saturating_add, u16);
54
saturating_impl!(SaturatingAdd, saturating_add, u32);
55
saturating_impl!(SaturatingAdd, saturating_add, u64);
56
saturating_impl!(SaturatingAdd, saturating_add, usize);
57
saturating_impl!(SaturatingAdd, saturating_add, u128);
58
59
saturating_impl!(SaturatingAdd, saturating_add, i8);
60
saturating_impl!(SaturatingAdd, saturating_add, i16);
61
saturating_impl!(SaturatingAdd, saturating_add, i32);
62
saturating_impl!(SaturatingAdd, saturating_add, i64);
63
saturating_impl!(SaturatingAdd, saturating_add, isize);
64
saturating_impl!(SaturatingAdd, saturating_add, i128);
65
66
/// Performs subtraction that saturates at the numeric bounds instead of overflowing.
67
pub trait SaturatingSub: Sized + Sub<Self, Output = Self> {
68
    /// Saturating subtraction. Computes `self - other`, saturating at the relevant high or low boundary of
69
    /// the type.
70
    fn saturating_sub(&self, v: &Self) -> Self;
71
}
72
73
saturating_impl!(SaturatingSub, saturating_sub, u8);
74
saturating_impl!(SaturatingSub, saturating_sub, u16);
75
saturating_impl!(SaturatingSub, saturating_sub, u32);
76
saturating_impl!(SaturatingSub, saturating_sub, u64);
77
saturating_impl!(SaturatingSub, saturating_sub, usize);
78
saturating_impl!(SaturatingSub, saturating_sub, u128);
79
80
saturating_impl!(SaturatingSub, saturating_sub, i8);
81
saturating_impl!(SaturatingSub, saturating_sub, i16);
82
saturating_impl!(SaturatingSub, saturating_sub, i32);
83
saturating_impl!(SaturatingSub, saturating_sub, i64);
84
saturating_impl!(SaturatingSub, saturating_sub, isize);
85
saturating_impl!(SaturatingSub, saturating_sub, i128);
86
87
/// Performs multiplication that saturates at the numeric bounds instead of overflowing.
88
pub trait SaturatingMul: Sized + Mul<Self, Output = Self> {
89
    /// Saturating multiplication. Computes `self * other`, saturating at the relevant high or low boundary of
90
    /// the type.
91
    fn saturating_mul(&self, v: &Self) -> Self;
92
}
93
94
saturating_impl!(SaturatingMul, saturating_mul, u8);
95
saturating_impl!(SaturatingMul, saturating_mul, u16);
96
saturating_impl!(SaturatingMul, saturating_mul, u32);
97
saturating_impl!(SaturatingMul, saturating_mul, u64);
98
saturating_impl!(SaturatingMul, saturating_mul, usize);
99
saturating_impl!(SaturatingMul, saturating_mul, u128);
100
101
saturating_impl!(SaturatingMul, saturating_mul, i8);
102
saturating_impl!(SaturatingMul, saturating_mul, i16);
103
saturating_impl!(SaturatingMul, saturating_mul, i32);
104
saturating_impl!(SaturatingMul, saturating_mul, i64);
105
saturating_impl!(SaturatingMul, saturating_mul, isize);
106
saturating_impl!(SaturatingMul, saturating_mul, i128);
107
108
// TODO: add SaturatingNeg for signed integer primitives once the saturating_neg() API is stable.
109
110
#[test]
111
fn test_saturating_traits() {
112
    fn saturating_add<T: SaturatingAdd>(a: T, b: T) -> T {
113
        a.saturating_add(&b)
114
    }
115
    fn saturating_sub<T: SaturatingSub>(a: T, b: T) -> T {
116
        a.saturating_sub(&b)
117
    }
118
    fn saturating_mul<T: SaturatingMul>(a: T, b: T) -> T {
119
        a.saturating_mul(&b)
120
    }
121
    assert_eq!(saturating_add(255, 1), 255u8);
122
    assert_eq!(saturating_add(127, 1), 127i8);
123
    assert_eq!(saturating_add(-128, -1), -128i8);
124
    assert_eq!(saturating_sub(0, 1), 0u8);
125
    assert_eq!(saturating_sub(-128, 1), -128i8);
126
    assert_eq!(saturating_sub(127, -1), 127i8);
127
    assert_eq!(saturating_mul(255, 2), 255u8);
128
    assert_eq!(saturating_mul(127, 2), 127i8);
129
    assert_eq!(saturating_mul(-128, 2), -128i8);
130
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/ops/wrapping.rs
Line
Count
Source
1
use core::num::Wrapping;
2
use core::ops::{Add, Mul, Neg, Shl, Shr, Sub};
3
4
macro_rules! wrapping_impl {
5
    ($trait_name:ident, $method:ident, $t:ty) => {
6
        impl $trait_name for $t {
7
            #[inline]
8
0
            fn $method(&self, v: &Self) -> Self {
9
0
                <$t>::$method(*self, *v)
10
0
            }
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinghNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingtNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingmNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingyNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingjNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingoNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXsa_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingaNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXsb_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingsNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXsc_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinglNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXsd_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingxNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXse_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingiNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXsf_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingnNtB5_11WrappingAdd12wrapping_addB9_
Unexecuted instantiation: _RNvXsg_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinghNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXsh_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingtNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXsi_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingmNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXsj_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingyNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXsk_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingjNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXsl_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingoNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingaNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingsNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXso_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinglNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXsp_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingxNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXsq_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingiNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXsr_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingnNtB5_11WrappingSub12wrapping_subB9_
Unexecuted instantiation: _RNvXss_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinghNtB5_11WrappingMul12wrapping_mulB9_
Unexecuted instantiation: _RNvXst_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingtNtB5_11WrappingMul12wrapping_mulB9_
Unexecuted instantiation: _RNvXsu_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingmNtB5_11WrappingMul12wrapping_mulB9_
Unexecuted instantiation: _RNvXsv_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingyNtB5_11WrappingMul12wrapping_mulB9_
Unexecuted instantiation: _RNvXsw_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingjNtB5_11WrappingMul12wrapping_mulB9_
Unexecuted instantiation: _RNvXsx_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingoNtB5_11WrappingMul12wrapping_mulB9_
Unexecuted instantiation: _RNvXsy_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingaNtB5_11WrappingMul12wrapping_mulB9_
Unexecuted instantiation: _RNvXsz_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingsNtB5_11WrappingMul12wrapping_mulB9_
Unexecuted instantiation: _RNvXsA_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinglNtB5_11WrappingMul12wrapping_mulB9_
Unexecuted instantiation: _RNvXsB_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingxNtB5_11WrappingMul12wrapping_mulB9_
Unexecuted instantiation: _RNvXsC_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingiNtB5_11WrappingMul12wrapping_mulB9_
Unexecuted instantiation: _RNvXsD_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingnNtB5_11WrappingMul12wrapping_mulB9_
11
        }
12
    };
13
    ($trait_name:ident, $method:ident, $t:ty, $rhs:ty) => {
14
        impl $trait_name<$rhs> for $t {
15
            #[inline]
16
            fn $method(&self, v: &$rhs) -> Self {
17
                <$t>::$method(*self, *v)
18
            }
19
        }
20
    };
21
}
22
23
/// Performs addition that wraps around on overflow.
24
pub trait WrappingAdd: Sized + Add<Self, Output = Self> {
25
    /// Wrapping (modular) addition. Computes `self + other`, wrapping around at the boundary of
26
    /// the type.
27
    fn wrapping_add(&self, v: &Self) -> Self;
28
}
29
30
wrapping_impl!(WrappingAdd, wrapping_add, u8);
31
wrapping_impl!(WrappingAdd, wrapping_add, u16);
32
wrapping_impl!(WrappingAdd, wrapping_add, u32);
33
wrapping_impl!(WrappingAdd, wrapping_add, u64);
34
wrapping_impl!(WrappingAdd, wrapping_add, usize);
35
wrapping_impl!(WrappingAdd, wrapping_add, u128);
36
37
wrapping_impl!(WrappingAdd, wrapping_add, i8);
38
wrapping_impl!(WrappingAdd, wrapping_add, i16);
39
wrapping_impl!(WrappingAdd, wrapping_add, i32);
40
wrapping_impl!(WrappingAdd, wrapping_add, i64);
41
wrapping_impl!(WrappingAdd, wrapping_add, isize);
42
wrapping_impl!(WrappingAdd, wrapping_add, i128);
43
44
/// Performs subtraction that wraps around on overflow.
45
pub trait WrappingSub: Sized + Sub<Self, Output = Self> {
46
    /// Wrapping (modular) subtraction. Computes `self - other`, wrapping around at the boundary
47
    /// of the type.
48
    fn wrapping_sub(&self, v: &Self) -> Self;
49
}
50
51
wrapping_impl!(WrappingSub, wrapping_sub, u8);
52
wrapping_impl!(WrappingSub, wrapping_sub, u16);
53
wrapping_impl!(WrappingSub, wrapping_sub, u32);
54
wrapping_impl!(WrappingSub, wrapping_sub, u64);
55
wrapping_impl!(WrappingSub, wrapping_sub, usize);
56
wrapping_impl!(WrappingSub, wrapping_sub, u128);
57
58
wrapping_impl!(WrappingSub, wrapping_sub, i8);
59
wrapping_impl!(WrappingSub, wrapping_sub, i16);
60
wrapping_impl!(WrappingSub, wrapping_sub, i32);
61
wrapping_impl!(WrappingSub, wrapping_sub, i64);
62
wrapping_impl!(WrappingSub, wrapping_sub, isize);
63
wrapping_impl!(WrappingSub, wrapping_sub, i128);
64
65
/// Performs multiplication that wraps around on overflow.
66
pub trait WrappingMul: Sized + Mul<Self, Output = Self> {
67
    /// Wrapping (modular) multiplication. Computes `self * other`, wrapping around at the boundary
68
    /// of the type.
69
    fn wrapping_mul(&self, v: &Self) -> Self;
70
}
71
72
wrapping_impl!(WrappingMul, wrapping_mul, u8);
73
wrapping_impl!(WrappingMul, wrapping_mul, u16);
74
wrapping_impl!(WrappingMul, wrapping_mul, u32);
75
wrapping_impl!(WrappingMul, wrapping_mul, u64);
76
wrapping_impl!(WrappingMul, wrapping_mul, usize);
77
wrapping_impl!(WrappingMul, wrapping_mul, u128);
78
79
wrapping_impl!(WrappingMul, wrapping_mul, i8);
80
wrapping_impl!(WrappingMul, wrapping_mul, i16);
81
wrapping_impl!(WrappingMul, wrapping_mul, i32);
82
wrapping_impl!(WrappingMul, wrapping_mul, i64);
83
wrapping_impl!(WrappingMul, wrapping_mul, isize);
84
wrapping_impl!(WrappingMul, wrapping_mul, i128);
85
86
macro_rules! wrapping_unary_impl {
87
    ($trait_name:ident, $method:ident, $t:ty) => {
88
        impl $trait_name for $t {
89
            #[inline]
90
0
            fn $method(&self) -> $t {
91
0
                <$t>::$method(*self)
92
0
            }
Unexecuted instantiation: _RNvXsE_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinghNtB5_11WrappingNeg12wrapping_negB9_
Unexecuted instantiation: _RNvXsF_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingtNtB5_11WrappingNeg12wrapping_negB9_
Unexecuted instantiation: _RNvXsG_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingmNtB5_11WrappingNeg12wrapping_negB9_
Unexecuted instantiation: _RNvXsH_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingyNtB5_11WrappingNeg12wrapping_negB9_
Unexecuted instantiation: _RNvXsI_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingjNtB5_11WrappingNeg12wrapping_negB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingoNtB5_11WrappingNeg12wrapping_negB9_
Unexecuted instantiation: _RNvXsK_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingaNtB5_11WrappingNeg12wrapping_negB9_
Unexecuted instantiation: _RNvXsL_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingsNtB5_11WrappingNeg12wrapping_negB9_
Unexecuted instantiation: _RNvXsM_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinglNtB5_11WrappingNeg12wrapping_negB9_
Unexecuted instantiation: _RNvXsN_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingxNtB5_11WrappingNeg12wrapping_negB9_
Unexecuted instantiation: _RNvXsO_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingiNtB5_11WrappingNeg12wrapping_negB9_
Unexecuted instantiation: _RNvXsP_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingnNtB5_11WrappingNeg12wrapping_negB9_
93
        }
94
    };
95
}
96
97
/// Performs a negation that does not panic.
98
pub trait WrappingNeg: Sized {
99
    /// Wrapping (modular) negation. Computes `-self`,
100
    /// wrapping around at the boundary of the type.
101
    ///
102
    /// Since unsigned types do not have negative equivalents
103
    /// all applications of this function will wrap (except for `-0`).
104
    /// For values smaller than the corresponding signed type's maximum
105
    /// the result is the same as casting the corresponding signed value.
106
    /// Any larger values are equivalent to `MAX + 1 - (val - MAX - 1)` where
107
    /// `MAX` is the corresponding signed type's maximum.
108
    ///
109
    /// ```
110
    /// use num_traits::WrappingNeg;
111
    ///
112
    /// assert_eq!(100i8.wrapping_neg(), -100);
113
    /// assert_eq!((-100i8).wrapping_neg(), 100);
114
    /// assert_eq!((-128i8).wrapping_neg(), -128); // wrapped!
115
    /// ```
116
    fn wrapping_neg(&self) -> Self;
117
}
118
119
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u8);
120
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u16);
121
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u32);
122
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u64);
123
wrapping_unary_impl!(WrappingNeg, wrapping_neg, usize);
124
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u128);
125
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i8);
126
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i16);
127
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i32);
128
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i64);
129
wrapping_unary_impl!(WrappingNeg, wrapping_neg, isize);
130
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i128);
131
132
macro_rules! wrapping_shift_impl {
133
    ($trait_name:ident, $method:ident, $t:ty) => {
134
        impl $trait_name for $t {
135
            #[inline]
136
0
            fn $method(&self, rhs: u32) -> $t {
137
0
                <$t>::$method(*self, rhs)
138
0
            }
Unexecuted instantiation: _RNvXsQ_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinghNtB5_11WrappingShl12wrapping_shlB9_
Unexecuted instantiation: _RNvXsR_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingtNtB5_11WrappingShl12wrapping_shlB9_
Unexecuted instantiation: _RNvXsS_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingmNtB5_11WrappingShl12wrapping_shlB9_
Unexecuted instantiation: _RNvXsT_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingyNtB5_11WrappingShl12wrapping_shlB9_
Unexecuted instantiation: _RNvXsU_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingjNtB5_11WrappingShl12wrapping_shlB9_
Unexecuted instantiation: _RNvXsV_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingoNtB5_11WrappingShl12wrapping_shlB9_
Unexecuted instantiation: _RNvXsW_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingaNtB5_11WrappingShl12wrapping_shlB9_
Unexecuted instantiation: _RNvXsX_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingsNtB5_11WrappingShl12wrapping_shlB9_
Unexecuted instantiation: _RNvXsY_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinglNtB5_11WrappingShl12wrapping_shlB9_
Unexecuted instantiation: _RNvXsZ_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingxNtB5_11WrappingShl12wrapping_shlB9_
Unexecuted instantiation: _RNvXs10_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingiNtB6_11WrappingShl12wrapping_shlBa_
Unexecuted instantiation: _RNvXs11_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingnNtB6_11WrappingShl12wrapping_shlBa_
Unexecuted instantiation: _RNvXs12_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinghNtB6_11WrappingShr12wrapping_shrBa_
Unexecuted instantiation: _RNvXs13_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingtNtB6_11WrappingShr12wrapping_shrBa_
Unexecuted instantiation: _RNvXs14_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingmNtB6_11WrappingShr12wrapping_shrBa_
Unexecuted instantiation: _RNvXs15_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingyNtB6_11WrappingShr12wrapping_shrBa_
Unexecuted instantiation: _RNvXs16_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingjNtB6_11WrappingShr12wrapping_shrBa_
Unexecuted instantiation: _RNvXs17_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingoNtB6_11WrappingShr12wrapping_shrBa_
Unexecuted instantiation: _RNvXs18_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingaNtB6_11WrappingShr12wrapping_shrBa_
Unexecuted instantiation: _RNvXs19_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingsNtB6_11WrappingShr12wrapping_shrBa_
Unexecuted instantiation: _RNvXs1a_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappinglNtB6_11WrappingShr12wrapping_shrBa_
Unexecuted instantiation: _RNvXs1b_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingxNtB6_11WrappingShr12wrapping_shrBa_
Unexecuted instantiation: _RNvXs1c_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingiNtB6_11WrappingShr12wrapping_shrBa_
Unexecuted instantiation: _RNvXs1d_NtNtCs7cG3k8kmkqw_10num_traits3ops8wrappingnNtB6_11WrappingShr12wrapping_shrBa_
139
        }
140
    };
141
}
142
143
/// Performs a left shift that does not panic.
144
pub trait WrappingShl: Sized + Shl<usize, Output = Self> {
145
    /// Panic-free bitwise shift-left; yields `self << mask(rhs)`,
146
    /// where `mask` removes any high order bits of `rhs` that would
147
    /// cause the shift to exceed the bitwidth of the type.
148
    ///
149
    /// ```
150
    /// use num_traits::WrappingShl;
151
    ///
152
    /// let x: u16 = 0x0001;
153
    ///
154
    /// assert_eq!(WrappingShl::wrapping_shl(&x, 0),  0x0001);
155
    /// assert_eq!(WrappingShl::wrapping_shl(&x, 1),  0x0002);
156
    /// assert_eq!(WrappingShl::wrapping_shl(&x, 15), 0x8000);
157
    /// assert_eq!(WrappingShl::wrapping_shl(&x, 16), 0x0001);
158
    /// ```
159
    fn wrapping_shl(&self, rhs: u32) -> Self;
160
}
161
162
wrapping_shift_impl!(WrappingShl, wrapping_shl, u8);
163
wrapping_shift_impl!(WrappingShl, wrapping_shl, u16);
164
wrapping_shift_impl!(WrappingShl, wrapping_shl, u32);
165
wrapping_shift_impl!(WrappingShl, wrapping_shl, u64);
166
wrapping_shift_impl!(WrappingShl, wrapping_shl, usize);
167
wrapping_shift_impl!(WrappingShl, wrapping_shl, u128);
168
169
wrapping_shift_impl!(WrappingShl, wrapping_shl, i8);
170
wrapping_shift_impl!(WrappingShl, wrapping_shl, i16);
171
wrapping_shift_impl!(WrappingShl, wrapping_shl, i32);
172
wrapping_shift_impl!(WrappingShl, wrapping_shl, i64);
173
wrapping_shift_impl!(WrappingShl, wrapping_shl, isize);
174
wrapping_shift_impl!(WrappingShl, wrapping_shl, i128);
175
176
/// Performs a right shift that does not panic.
177
pub trait WrappingShr: Sized + Shr<usize, Output = Self> {
178
    /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`,
179
    /// where `mask` removes any high order bits of `rhs` that would
180
    /// cause the shift to exceed the bitwidth of the type.
181
    ///
182
    /// ```
183
    /// use num_traits::WrappingShr;
184
    ///
185
    /// let x: u16 = 0x8000;
186
    ///
187
    /// assert_eq!(WrappingShr::wrapping_shr(&x, 0),  0x8000);
188
    /// assert_eq!(WrappingShr::wrapping_shr(&x, 1),  0x4000);
189
    /// assert_eq!(WrappingShr::wrapping_shr(&x, 15), 0x0001);
190
    /// assert_eq!(WrappingShr::wrapping_shr(&x, 16), 0x8000);
191
    /// ```
192
    fn wrapping_shr(&self, rhs: u32) -> Self;
193
}
194
195
wrapping_shift_impl!(WrappingShr, wrapping_shr, u8);
196
wrapping_shift_impl!(WrappingShr, wrapping_shr, u16);
197
wrapping_shift_impl!(WrappingShr, wrapping_shr, u32);
198
wrapping_shift_impl!(WrappingShr, wrapping_shr, u64);
199
wrapping_shift_impl!(WrappingShr, wrapping_shr, usize);
200
wrapping_shift_impl!(WrappingShr, wrapping_shr, u128);
201
202
wrapping_shift_impl!(WrappingShr, wrapping_shr, i8);
203
wrapping_shift_impl!(WrappingShr, wrapping_shr, i16);
204
wrapping_shift_impl!(WrappingShr, wrapping_shr, i32);
205
wrapping_shift_impl!(WrappingShr, wrapping_shr, i64);
206
wrapping_shift_impl!(WrappingShr, wrapping_shr, isize);
207
wrapping_shift_impl!(WrappingShr, wrapping_shr, i128);
208
209
// Well this is a bit funny, but all the more appropriate.
210
impl<T: WrappingAdd> WrappingAdd for Wrapping<T>
211
where
212
    Wrapping<T>: Add<Output = Wrapping<T>>,
213
{
214
0
    fn wrapping_add(&self, v: &Self) -> Self {
215
0
        Wrapping(self.0.wrapping_add(&v.0))
216
0
    }
217
}
218
impl<T: WrappingSub> WrappingSub for Wrapping<T>
219
where
220
    Wrapping<T>: Sub<Output = Wrapping<T>>,
221
{
222
0
    fn wrapping_sub(&self, v: &Self) -> Self {
223
0
        Wrapping(self.0.wrapping_sub(&v.0))
224
0
    }
225
}
226
impl<T: WrappingMul> WrappingMul for Wrapping<T>
227
where
228
    Wrapping<T>: Mul<Output = Wrapping<T>>,
229
{
230
0
    fn wrapping_mul(&self, v: &Self) -> Self {
231
0
        Wrapping(self.0.wrapping_mul(&v.0))
232
0
    }
233
}
234
impl<T: WrappingNeg> WrappingNeg for Wrapping<T>
235
where
236
    Wrapping<T>: Neg<Output = Wrapping<T>>,
237
{
238
0
    fn wrapping_neg(&self) -> Self {
239
0
        Wrapping(self.0.wrapping_neg())
240
0
    }
241
}
242
impl<T: WrappingShl> WrappingShl for Wrapping<T>
243
where
244
    Wrapping<T>: Shl<usize, Output = Wrapping<T>>,
245
{
246
0
    fn wrapping_shl(&self, rhs: u32) -> Self {
247
0
        Wrapping(self.0.wrapping_shl(rhs))
248
0
    }
249
}
250
impl<T: WrappingShr> WrappingShr for Wrapping<T>
251
where
252
    Wrapping<T>: Shr<usize, Output = Wrapping<T>>,
253
{
254
0
    fn wrapping_shr(&self, rhs: u32) -> Self {
255
0
        Wrapping(self.0.wrapping_shr(rhs))
256
0
    }
257
}
258
259
#[test]
260
fn test_wrapping_traits() {
261
    fn wrapping_add<T: WrappingAdd>(a: T, b: T) -> T {
262
        a.wrapping_add(&b)
263
    }
264
    fn wrapping_sub<T: WrappingSub>(a: T, b: T) -> T {
265
        a.wrapping_sub(&b)
266
    }
267
    fn wrapping_mul<T: WrappingMul>(a: T, b: T) -> T {
268
        a.wrapping_mul(&b)
269
    }
270
    fn wrapping_neg<T: WrappingNeg>(a: T) -> T {
271
        a.wrapping_neg()
272
    }
273
    fn wrapping_shl<T: WrappingShl>(a: T, b: u32) -> T {
274
        a.wrapping_shl(b)
275
    }
276
    fn wrapping_shr<T: WrappingShr>(a: T, b: u32) -> T {
277
        a.wrapping_shr(b)
278
    }
279
    assert_eq!(wrapping_add(255, 1), 0u8);
280
    assert_eq!(wrapping_sub(0, 1), 255u8);
281
    assert_eq!(wrapping_mul(255, 2), 254u8);
282
    assert_eq!(wrapping_neg(255), 1u8);
283
    assert_eq!(wrapping_shl(255, 8), 255u8);
284
    assert_eq!(wrapping_shr(255, 8), 255u8);
285
    assert_eq!(wrapping_add(255, 1), (Wrapping(255u8) + Wrapping(1u8)).0);
286
    assert_eq!(wrapping_sub(0, 1), (Wrapping(0u8) - Wrapping(1u8)).0);
287
    assert_eq!(wrapping_mul(255, 2), (Wrapping(255u8) * Wrapping(2u8)).0);
288
    assert_eq!(wrapping_neg(255), (-Wrapping(255u8)).0);
289
    assert_eq!(wrapping_shl(255, 8), (Wrapping(255u8) << 8).0);
290
    assert_eq!(wrapping_shr(255, 8), (Wrapping(255u8) >> 8).0);
291
}
292
293
#[test]
294
fn wrapping_is_wrappingadd() {
295
    fn require_wrappingadd<T: WrappingAdd>(_: &T) {}
296
    require_wrappingadd(&Wrapping(42));
297
}
298
299
#[test]
300
fn wrapping_is_wrappingsub() {
301
    fn require_wrappingsub<T: WrappingSub>(_: &T) {}
302
    require_wrappingsub(&Wrapping(42));
303
}
304
305
#[test]
306
fn wrapping_is_wrappingmul() {
307
    fn require_wrappingmul<T: WrappingMul>(_: &T) {}
308
    require_wrappingmul(&Wrapping(42));
309
}
310
311
#[test]
312
fn wrapping_is_wrappingneg() {
313
    fn require_wrappingneg<T: WrappingNeg>(_: &T) {}
314
    require_wrappingneg(&Wrapping(42));
315
}
316
317
#[test]
318
fn wrapping_is_wrappingshl() {
319
    fn require_wrappingshl<T: WrappingShl>(_: &T) {}
320
    require_wrappingshl(&Wrapping(42));
321
}
322
323
#[test]
324
fn wrapping_is_wrappingshr() {
325
    fn require_wrappingshr<T: WrappingShr>(_: &T) {}
326
    require_wrappingshr(&Wrapping(42));
327
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/pow.rs
Line
Count
Source
1
use crate::{CheckedMul, One};
2
use core::num::Wrapping;
3
use core::ops::Mul;
4
5
/// Binary operator for raising a value to a power.
6
pub trait Pow<RHS> {
7
    /// The result after applying the operator.
8
    type Output;
9
10
    /// Returns `self` to the power `rhs`.
11
    ///
12
    /// # Examples
13
    ///
14
    /// ```
15
    /// use num_traits::Pow;
16
    /// assert_eq!(Pow::pow(10u32, 2u32), 100);
17
    /// ```
18
    fn pow(self, rhs: RHS) -> Self::Output;
19
}
20
21
macro_rules! pow_impl {
22
    ($t:ty) => {
23
        pow_impl!($t, u8);
24
        pow_impl!($t, usize);
25
26
        // FIXME: these should be possible
27
        // pow_impl!($t, u16);
28
        // pow_impl!($t, u32);
29
        // pow_impl!($t, u64);
30
    };
31
    ($t:ty, $rhs:ty) => {
32
        pow_impl!($t, $rhs, usize, pow);
33
    };
34
    ($t:ty, $rhs:ty, $desired_rhs:ty, $method:expr) => {
35
        impl Pow<$rhs> for $t {
36
            type Output = $t;
37
            #[inline]
38
0
            fn pow(self, rhs: $rhs) -> $t {
39
0
                ($method)(self, <$desired_rhs>::from(rhs))
40
0
            }
Unexecuted instantiation: _RNvXNtCs7cG3k8kmkqw_10num_traits3powhINtB2_3PowhE3powB4_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits3powhINtB5_3PowtE3powB7_
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits3powhINtB5_3PowmE3powB7_
Unexecuted instantiation: _RNvXsa_NtCs7cG3k8kmkqw_10num_traits3powhINtB5_3PowjE3powB7_
Unexecuted instantiation: _RNvXse_NtCs7cG3k8kmkqw_10num_traits3powaINtB5_3PowhE3powB7_
Unexecuted instantiation: _RNvXsi_NtCs7cG3k8kmkqw_10num_traits3powaINtB5_3PowtE3powB7_
Unexecuted instantiation: _RNvXsm_NtCs7cG3k8kmkqw_10num_traits3powaINtB5_3PowmE3powB7_
Unexecuted instantiation: _RNvXsq_NtCs7cG3k8kmkqw_10num_traits3powaINtB5_3PowjE3powB7_
Unexecuted instantiation: _RNvXsu_NtCs7cG3k8kmkqw_10num_traits3powtINtB5_3PowhE3powB7_
Unexecuted instantiation: _RNvXsy_NtCs7cG3k8kmkqw_10num_traits3powtINtB5_3PowtE3powB7_
Unexecuted instantiation: _RNvXsC_NtCs7cG3k8kmkqw_10num_traits3powtINtB5_3PowmE3powB7_
Unexecuted instantiation: _RNvXsG_NtCs7cG3k8kmkqw_10num_traits3powtINtB5_3PowjE3powB7_
Unexecuted instantiation: _RNvXsK_NtCs7cG3k8kmkqw_10num_traits3powsINtB5_3PowhE3powB7_
Unexecuted instantiation: _RNvXsO_NtCs7cG3k8kmkqw_10num_traits3powsINtB5_3PowtE3powB7_
Unexecuted instantiation: _RNvXsS_NtCs7cG3k8kmkqw_10num_traits3powsINtB5_3PowmE3powB7_
Unexecuted instantiation: _RNvXsW_NtCs7cG3k8kmkqw_10num_traits3powsINtB5_3PowjE3powB7_
Unexecuted instantiation: _RNvXs10_NtCs7cG3k8kmkqw_10num_traits3powmINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs14_NtCs7cG3k8kmkqw_10num_traits3powmINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs18_NtCs7cG3k8kmkqw_10num_traits3powmINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs1c_NtCs7cG3k8kmkqw_10num_traits3powmINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs1g_NtCs7cG3k8kmkqw_10num_traits3powlINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs1k_NtCs7cG3k8kmkqw_10num_traits3powlINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs1o_NtCs7cG3k8kmkqw_10num_traits3powlINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs1s_NtCs7cG3k8kmkqw_10num_traits3powlINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs1w_NtCs7cG3k8kmkqw_10num_traits3powyINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs1A_NtCs7cG3k8kmkqw_10num_traits3powyINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs1E_NtCs7cG3k8kmkqw_10num_traits3powyINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs1I_NtCs7cG3k8kmkqw_10num_traits3powyINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs1M_NtCs7cG3k8kmkqw_10num_traits3powxINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs1Q_NtCs7cG3k8kmkqw_10num_traits3powxINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs1U_NtCs7cG3k8kmkqw_10num_traits3powxINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs1Y_NtCs7cG3k8kmkqw_10num_traits3powxINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs22_NtCs7cG3k8kmkqw_10num_traits3powoINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs26_NtCs7cG3k8kmkqw_10num_traits3powoINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs2a_NtCs7cG3k8kmkqw_10num_traits3powoINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs2e_NtCs7cG3k8kmkqw_10num_traits3powoINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs2i_NtCs7cG3k8kmkqw_10num_traits3pownINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs2m_NtCs7cG3k8kmkqw_10num_traits3pownINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs2q_NtCs7cG3k8kmkqw_10num_traits3pownINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs2u_NtCs7cG3k8kmkqw_10num_traits3pownINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs2y_NtCs7cG3k8kmkqw_10num_traits3powjINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs2C_NtCs7cG3k8kmkqw_10num_traits3powjINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs2G_NtCs7cG3k8kmkqw_10num_traits3powjINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs2K_NtCs7cG3k8kmkqw_10num_traits3powjINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs2O_NtCs7cG3k8kmkqw_10num_traits3powiINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs2S_NtCs7cG3k8kmkqw_10num_traits3powiINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs2W_NtCs7cG3k8kmkqw_10num_traits3powiINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs30_NtCs7cG3k8kmkqw_10num_traits3powiINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs34_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinghEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs38_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinghEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3c_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingaEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3g_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingaEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3k_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingtEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3o_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingtEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3s_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingsEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3w_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingsEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3A_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingmEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3E_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingmEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3I_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinglEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3M_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinglEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3Q_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingyEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3U_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingyEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3Y_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingxEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs42_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingxEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs46_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingoEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs4a_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingoEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs4e_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingnEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs4i_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingnEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs4m_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingjEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs4q_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingjEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs4u_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingiEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs4y_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingiEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXNtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB4_3PowaE3powB6_
Unexecuted instantiation: _RNvXs2_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB7_3PowhE3powB9_
Unexecuted instantiation: _RNvXs6_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB7_3PowsE3powB9_
Unexecuted instantiation: _RNvXsa_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB7_3PowtE3powB9_
Unexecuted instantiation: _RNvXse_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB7_3PowlE3powB9_
Unexecuted instantiation: _RNvXsi_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowaE3powB9_
Unexecuted instantiation: _RNvXsm_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowhE3powB9_
Unexecuted instantiation: _RNvXsq_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowsE3powB9_
Unexecuted instantiation: _RNvXsu_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowtE3powB9_
Unexecuted instantiation: _RNvXsy_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowlE3powB9_
Unexecuted instantiation: _RNvXsC_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB7_3PowfE3powB9_
Unexecuted instantiation: _RNvXsG_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowfE3powB9_
Unexecuted instantiation: _RNvXsK_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowdE3powB9_
41
        }
42
43
        impl<'a> Pow<&'a $rhs> for $t {
44
            type Output = $t;
45
            #[inline]
46
0
            fn pow(self, rhs: &'a $rhs) -> $t {
47
0
                ($method)(self, <$desired_rhs>::from(*rhs))
48
0
            }
Unexecuted instantiation: _RNvXs_NtCs7cG3k8kmkqw_10num_traits3powhINtB4_3PowRhE3powB6_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits3powhINtB5_3PowRtE3powB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits3powhINtB5_3PowRmE3powB7_
Unexecuted instantiation: _RNvXsb_NtCs7cG3k8kmkqw_10num_traits3powhINtB5_3PowRjE3powB7_
Unexecuted instantiation: _RNvXsf_NtCs7cG3k8kmkqw_10num_traits3powaINtB5_3PowRhE3powB7_
Unexecuted instantiation: _RNvXsj_NtCs7cG3k8kmkqw_10num_traits3powaINtB5_3PowRtE3powB7_
Unexecuted instantiation: _RNvXsn_NtCs7cG3k8kmkqw_10num_traits3powaINtB5_3PowRmE3powB7_
Unexecuted instantiation: _RNvXsr_NtCs7cG3k8kmkqw_10num_traits3powaINtB5_3PowRjE3powB7_
Unexecuted instantiation: _RNvXsv_NtCs7cG3k8kmkqw_10num_traits3powtINtB5_3PowRhE3powB7_
Unexecuted instantiation: _RNvXsz_NtCs7cG3k8kmkqw_10num_traits3powtINtB5_3PowRtE3powB7_
Unexecuted instantiation: _RNvXsD_NtCs7cG3k8kmkqw_10num_traits3powtINtB5_3PowRmE3powB7_
Unexecuted instantiation: _RNvXsH_NtCs7cG3k8kmkqw_10num_traits3powtINtB5_3PowRjE3powB7_
Unexecuted instantiation: _RNvXsL_NtCs7cG3k8kmkqw_10num_traits3powsINtB5_3PowRhE3powB7_
Unexecuted instantiation: _RNvXsP_NtCs7cG3k8kmkqw_10num_traits3powsINtB5_3PowRtE3powB7_
Unexecuted instantiation: _RNvXsT_NtCs7cG3k8kmkqw_10num_traits3powsINtB5_3PowRmE3powB7_
Unexecuted instantiation: _RNvXsX_NtCs7cG3k8kmkqw_10num_traits3powsINtB5_3PowRjE3powB7_
Unexecuted instantiation: _RNvXs11_NtCs7cG3k8kmkqw_10num_traits3powmINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs15_NtCs7cG3k8kmkqw_10num_traits3powmINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs19_NtCs7cG3k8kmkqw_10num_traits3powmINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs1d_NtCs7cG3k8kmkqw_10num_traits3powmINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs1h_NtCs7cG3k8kmkqw_10num_traits3powlINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs1l_NtCs7cG3k8kmkqw_10num_traits3powlINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs1p_NtCs7cG3k8kmkqw_10num_traits3powlINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs1t_NtCs7cG3k8kmkqw_10num_traits3powlINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs1x_NtCs7cG3k8kmkqw_10num_traits3powyINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs1B_NtCs7cG3k8kmkqw_10num_traits3powyINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs1F_NtCs7cG3k8kmkqw_10num_traits3powyINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs1J_NtCs7cG3k8kmkqw_10num_traits3powyINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs1N_NtCs7cG3k8kmkqw_10num_traits3powxINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs1R_NtCs7cG3k8kmkqw_10num_traits3powxINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs1V_NtCs7cG3k8kmkqw_10num_traits3powxINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs1Z_NtCs7cG3k8kmkqw_10num_traits3powxINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs23_NtCs7cG3k8kmkqw_10num_traits3powoINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs27_NtCs7cG3k8kmkqw_10num_traits3powoINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs2b_NtCs7cG3k8kmkqw_10num_traits3powoINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs2f_NtCs7cG3k8kmkqw_10num_traits3powoINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs2j_NtCs7cG3k8kmkqw_10num_traits3pownINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs2n_NtCs7cG3k8kmkqw_10num_traits3pownINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs2r_NtCs7cG3k8kmkqw_10num_traits3pownINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs2v_NtCs7cG3k8kmkqw_10num_traits3pownINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs2z_NtCs7cG3k8kmkqw_10num_traits3powjINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs2D_NtCs7cG3k8kmkqw_10num_traits3powjINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs2H_NtCs7cG3k8kmkqw_10num_traits3powjINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs2L_NtCs7cG3k8kmkqw_10num_traits3powjINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs2P_NtCs7cG3k8kmkqw_10num_traits3powiINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs2T_NtCs7cG3k8kmkqw_10num_traits3powiINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs2X_NtCs7cG3k8kmkqw_10num_traits3powiINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs31_NtCs7cG3k8kmkqw_10num_traits3powiINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs35_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinghEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs39_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinghEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3d_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingaEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3h_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingaEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3l_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingtEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3p_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingtEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3t_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingsEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3x_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingsEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3B_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingmEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3F_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingmEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3J_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinglEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3N_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinglEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3R_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingyEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3V_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingyEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3Z_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingxEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs43_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingxEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs47_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingoEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs4b_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingoEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs4f_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingnEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs4j_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingnEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs4n_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingjEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs4r_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingjEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs4v_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingiEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs4z_NtCs7cG3k8kmkqw_10num_traits3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingiEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB6_3PowRaE3powB8_
Unexecuted instantiation: _RNvXs3_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB7_3PowRhE3powB9_
Unexecuted instantiation: _RNvXs7_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB7_3PowRsE3powB9_
Unexecuted instantiation: _RNvXsb_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB7_3PowRtE3powB9_
Unexecuted instantiation: _RNvXsf_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB7_3PowRlE3powB9_
Unexecuted instantiation: _RNvXsj_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowRaE3powB9_
Unexecuted instantiation: _RNvXsn_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowRhE3powB9_
Unexecuted instantiation: _RNvXsr_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowRsE3powB9_
Unexecuted instantiation: _RNvXsv_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowRtE3powB9_
Unexecuted instantiation: _RNvXsz_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowRlE3powB9_
Unexecuted instantiation: _RNvXsD_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsfINtB7_3PowRfE3powB9_
Unexecuted instantiation: _RNvXsH_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowRfE3powB9_
Unexecuted instantiation: _RNvXsL_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsdINtB7_3PowRdE3powB9_
49
        }
50
51
        impl<'a> Pow<$rhs> for &'a $t {
52
            type Output = $t;
53
            #[inline]
54
0
            fn pow(self, rhs: $rhs) -> $t {
55
0
                ($method)(*self, <$desired_rhs>::from(rhs))
56
0
            }
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits3powRhINtB5_3PowhE3powB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits3powRhINtB5_3PowtE3powB7_
Unexecuted instantiation: _RNvXs8_NtCs7cG3k8kmkqw_10num_traits3powRhINtB5_3PowmE3powB7_
Unexecuted instantiation: _RNvXsc_NtCs7cG3k8kmkqw_10num_traits3powRhINtB5_3PowjE3powB7_
Unexecuted instantiation: _RNvXsg_NtCs7cG3k8kmkqw_10num_traits3powRaINtB5_3PowhE3powB7_
Unexecuted instantiation: _RNvXsk_NtCs7cG3k8kmkqw_10num_traits3powRaINtB5_3PowtE3powB7_
Unexecuted instantiation: _RNvXso_NtCs7cG3k8kmkqw_10num_traits3powRaINtB5_3PowmE3powB7_
Unexecuted instantiation: _RNvXss_NtCs7cG3k8kmkqw_10num_traits3powRaINtB5_3PowjE3powB7_
Unexecuted instantiation: _RNvXsw_NtCs7cG3k8kmkqw_10num_traits3powRtINtB5_3PowhE3powB7_
Unexecuted instantiation: _RNvXsA_NtCs7cG3k8kmkqw_10num_traits3powRtINtB5_3PowtE3powB7_
Unexecuted instantiation: _RNvXsE_NtCs7cG3k8kmkqw_10num_traits3powRtINtB5_3PowmE3powB7_
Unexecuted instantiation: _RNvXsI_NtCs7cG3k8kmkqw_10num_traits3powRtINtB5_3PowjE3powB7_
Unexecuted instantiation: _RNvXsM_NtCs7cG3k8kmkqw_10num_traits3powRsINtB5_3PowhE3powB7_
Unexecuted instantiation: _RNvXsQ_NtCs7cG3k8kmkqw_10num_traits3powRsINtB5_3PowtE3powB7_
Unexecuted instantiation: _RNvXsU_NtCs7cG3k8kmkqw_10num_traits3powRsINtB5_3PowmE3powB7_
Unexecuted instantiation: _RNvXsY_NtCs7cG3k8kmkqw_10num_traits3powRsINtB5_3PowjE3powB7_
Unexecuted instantiation: _RNvXs12_NtCs7cG3k8kmkqw_10num_traits3powRmINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs16_NtCs7cG3k8kmkqw_10num_traits3powRmINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs1a_NtCs7cG3k8kmkqw_10num_traits3powRmINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs1e_NtCs7cG3k8kmkqw_10num_traits3powRmINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs1i_NtCs7cG3k8kmkqw_10num_traits3powRlINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs1m_NtCs7cG3k8kmkqw_10num_traits3powRlINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs1q_NtCs7cG3k8kmkqw_10num_traits3powRlINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs1u_NtCs7cG3k8kmkqw_10num_traits3powRlINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs1y_NtCs7cG3k8kmkqw_10num_traits3powRyINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs1C_NtCs7cG3k8kmkqw_10num_traits3powRyINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs1G_NtCs7cG3k8kmkqw_10num_traits3powRyINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs1K_NtCs7cG3k8kmkqw_10num_traits3powRyINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs1O_NtCs7cG3k8kmkqw_10num_traits3powRxINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs1S_NtCs7cG3k8kmkqw_10num_traits3powRxINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs1W_NtCs7cG3k8kmkqw_10num_traits3powRxINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs20_NtCs7cG3k8kmkqw_10num_traits3powRxINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs24_NtCs7cG3k8kmkqw_10num_traits3powRoINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs28_NtCs7cG3k8kmkqw_10num_traits3powRoINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs2c_NtCs7cG3k8kmkqw_10num_traits3powRoINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs2g_NtCs7cG3k8kmkqw_10num_traits3powRoINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs2k_NtCs7cG3k8kmkqw_10num_traits3powRnINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs2o_NtCs7cG3k8kmkqw_10num_traits3powRnINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs2s_NtCs7cG3k8kmkqw_10num_traits3powRnINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs2w_NtCs7cG3k8kmkqw_10num_traits3powRnINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs2A_NtCs7cG3k8kmkqw_10num_traits3powRjINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs2E_NtCs7cG3k8kmkqw_10num_traits3powRjINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs2I_NtCs7cG3k8kmkqw_10num_traits3powRjINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs2M_NtCs7cG3k8kmkqw_10num_traits3powRjINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs2Q_NtCs7cG3k8kmkqw_10num_traits3powRiINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs2U_NtCs7cG3k8kmkqw_10num_traits3powRiINtB6_3PowtE3powB8_
Unexecuted instantiation: _RNvXs2Y_NtCs7cG3k8kmkqw_10num_traits3powRiINtB6_3PowmE3powB8_
Unexecuted instantiation: _RNvXs32_NtCs7cG3k8kmkqw_10num_traits3powRiINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs36_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinghEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3a_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinghEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3e_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingaEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3i_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingaEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3m_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingtEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3q_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingtEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3u_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingsEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3y_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingsEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3C_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingmEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3G_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingmEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3K_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinglEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3O_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinglEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs3S_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingyEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs3W_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingyEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs40_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingxEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs44_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingxEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs48_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingoEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs4c_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingoEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs4g_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingnEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs4k_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingnEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs4o_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingjEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs4s_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingjEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs4w_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingiEINtB6_3PowhE3powB8_
Unexecuted instantiation: _RNvXs4A_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingiEINtB6_3PowjE3powB8_
Unexecuted instantiation: _RNvXs0_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowaE3powB9_
Unexecuted instantiation: _RNvXs4_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowhE3powB9_
Unexecuted instantiation: _RNvXs8_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowsE3powB9_
Unexecuted instantiation: _RNvXsc_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowtE3powB9_
Unexecuted instantiation: _RNvXsg_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowlE3powB9_
Unexecuted instantiation: _RNvXsk_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowaE3powB9_
Unexecuted instantiation: _RNvXso_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowhE3powB9_
Unexecuted instantiation: _RNvXss_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowsE3powB9_
Unexecuted instantiation: _RNvXsw_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowtE3powB9_
Unexecuted instantiation: _RNvXsA_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowlE3powB9_
Unexecuted instantiation: _RNvXsE_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowfE3powB9_
Unexecuted instantiation: _RNvXsI_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowfE3powB9_
Unexecuted instantiation: _RNvXsM_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowdE3powB9_
57
        }
58
59
        impl<'a, 'b> Pow<&'a $rhs> for &'b $t {
60
            type Output = $t;
61
            #[inline]
62
0
            fn pow(self, rhs: &'a $rhs) -> $t {
63
0
                ($method)(*self, <$desired_rhs>::from(*rhs))
64
0
            }
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits3powRhINtB5_3PowBB_E3powB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits3powRhINtB5_3PowRtE3powB7_
Unexecuted instantiation: _RNvXs9_NtCs7cG3k8kmkqw_10num_traits3powRhINtB5_3PowRmE3powB7_
Unexecuted instantiation: _RNvXsd_NtCs7cG3k8kmkqw_10num_traits3powRhINtB5_3PowRjE3powB7_
Unexecuted instantiation: _RNvXsh_NtCs7cG3k8kmkqw_10num_traits3powRaINtB5_3PowRhE3powB7_
Unexecuted instantiation: _RNvXsl_NtCs7cG3k8kmkqw_10num_traits3powRaINtB5_3PowRtE3powB7_
Unexecuted instantiation: _RNvXsp_NtCs7cG3k8kmkqw_10num_traits3powRaINtB5_3PowRmE3powB7_
Unexecuted instantiation: _RNvXst_NtCs7cG3k8kmkqw_10num_traits3powRaINtB5_3PowRjE3powB7_
Unexecuted instantiation: _RNvXsx_NtCs7cG3k8kmkqw_10num_traits3powRtINtB5_3PowRhE3powB7_
Unexecuted instantiation: _RNvXsB_NtCs7cG3k8kmkqw_10num_traits3powRtINtB5_3PowBB_E3powB7_
Unexecuted instantiation: _RNvXsF_NtCs7cG3k8kmkqw_10num_traits3powRtINtB5_3PowRmE3powB7_
Unexecuted instantiation: _RNvXsJ_NtCs7cG3k8kmkqw_10num_traits3powRtINtB5_3PowRjE3powB7_
Unexecuted instantiation: _RNvXsN_NtCs7cG3k8kmkqw_10num_traits3powRsINtB5_3PowRhE3powB7_
Unexecuted instantiation: _RNvXsR_NtCs7cG3k8kmkqw_10num_traits3powRsINtB5_3PowRtE3powB7_
Unexecuted instantiation: _RNvXsV_NtCs7cG3k8kmkqw_10num_traits3powRsINtB5_3PowRmE3powB7_
Unexecuted instantiation: _RNvXsZ_NtCs7cG3k8kmkqw_10num_traits3powRsINtB5_3PowRjE3powB7_
Unexecuted instantiation: _RNvXs13_NtCs7cG3k8kmkqw_10num_traits3powRmINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs17_NtCs7cG3k8kmkqw_10num_traits3powRmINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs1b_NtCs7cG3k8kmkqw_10num_traits3powRmINtB6_3PowBC_E3powB8_
Unexecuted instantiation: _RNvXs1f_NtCs7cG3k8kmkqw_10num_traits3powRmINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs1j_NtCs7cG3k8kmkqw_10num_traits3powRlINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs1n_NtCs7cG3k8kmkqw_10num_traits3powRlINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs1r_NtCs7cG3k8kmkqw_10num_traits3powRlINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs1v_NtCs7cG3k8kmkqw_10num_traits3powRlINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs1z_NtCs7cG3k8kmkqw_10num_traits3powRyINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs1D_NtCs7cG3k8kmkqw_10num_traits3powRyINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs1H_NtCs7cG3k8kmkqw_10num_traits3powRyINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs1L_NtCs7cG3k8kmkqw_10num_traits3powRyINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs1P_NtCs7cG3k8kmkqw_10num_traits3powRxINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs1T_NtCs7cG3k8kmkqw_10num_traits3powRxINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs1X_NtCs7cG3k8kmkqw_10num_traits3powRxINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs21_NtCs7cG3k8kmkqw_10num_traits3powRxINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs25_NtCs7cG3k8kmkqw_10num_traits3powRoINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs29_NtCs7cG3k8kmkqw_10num_traits3powRoINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs2d_NtCs7cG3k8kmkqw_10num_traits3powRoINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs2h_NtCs7cG3k8kmkqw_10num_traits3powRoINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs2l_NtCs7cG3k8kmkqw_10num_traits3powRnINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs2p_NtCs7cG3k8kmkqw_10num_traits3powRnINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs2t_NtCs7cG3k8kmkqw_10num_traits3powRnINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs2x_NtCs7cG3k8kmkqw_10num_traits3powRnINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs2B_NtCs7cG3k8kmkqw_10num_traits3powRjINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs2F_NtCs7cG3k8kmkqw_10num_traits3powRjINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs2J_NtCs7cG3k8kmkqw_10num_traits3powRjINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs2N_NtCs7cG3k8kmkqw_10num_traits3powRjINtB6_3PowBC_E3powB8_
Unexecuted instantiation: _RNvXs2R_NtCs7cG3k8kmkqw_10num_traits3powRiINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs2V_NtCs7cG3k8kmkqw_10num_traits3powRiINtB6_3PowRtE3powB8_
Unexecuted instantiation: _RNvXs2Z_NtCs7cG3k8kmkqw_10num_traits3powRiINtB6_3PowRmE3powB8_
Unexecuted instantiation: _RNvXs33_NtCs7cG3k8kmkqw_10num_traits3powRiINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs37_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinghEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3b_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinghEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3f_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingaEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3j_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingaEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3n_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingtEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3r_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingtEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3v_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingsEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3z_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingsEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3D_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingmEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3H_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingmEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3L_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinglEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3P_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinglEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs3T_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingyEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs3X_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingyEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs41_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingxEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs45_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingxEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs49_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingoEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs4d_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingoEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs4h_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingnEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs4l_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingnEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs4p_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingjEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs4t_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingjEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs4x_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingiEINtB6_3PowRhE3powB8_
Unexecuted instantiation: _RNvXs4B_NtCs7cG3k8kmkqw_10num_traits3powRINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingiEINtB6_3PowRjE3powB8_
Unexecuted instantiation: _RNvXs1_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowRaE3powB9_
Unexecuted instantiation: _RNvXs5_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowRhE3powB9_
Unexecuted instantiation: _RNvXs9_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowRsE3powB9_
Unexecuted instantiation: _RNvXsd_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowRtE3powB9_
Unexecuted instantiation: _RNvXsh_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowRlE3powB9_
Unexecuted instantiation: _RNvXsl_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowRaE3powB9_
Unexecuted instantiation: _RNvXsp_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowRhE3powB9_
Unexecuted instantiation: _RNvXst_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowRsE3powB9_
Unexecuted instantiation: _RNvXsx_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowRtE3powB9_
Unexecuted instantiation: _RNvXsB_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowRlE3powB9_
Unexecuted instantiation: _RNvXsF_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRfINtB7_3PowBQ_E3powB9_
Unexecuted instantiation: _RNvXsJ_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowRfE3powB9_
Unexecuted instantiation: _RNvXsN_NtNtCs7cG3k8kmkqw_10num_traits3pow11float_implsRdINtB7_3PowBQ_E3powB9_
65
        }
66
    };
67
}
68
69
pow_impl!(u8, u8, u32, u8::pow);
70
pow_impl!(u8, u16, u32, u8::pow);
71
pow_impl!(u8, u32, u32, u8::pow);
72
pow_impl!(u8, usize);
73
pow_impl!(i8, u8, u32, i8::pow);
74
pow_impl!(i8, u16, u32, i8::pow);
75
pow_impl!(i8, u32, u32, i8::pow);
76
pow_impl!(i8, usize);
77
pow_impl!(u16, u8, u32, u16::pow);
78
pow_impl!(u16, u16, u32, u16::pow);
79
pow_impl!(u16, u32, u32, u16::pow);
80
pow_impl!(u16, usize);
81
pow_impl!(i16, u8, u32, i16::pow);
82
pow_impl!(i16, u16, u32, i16::pow);
83
pow_impl!(i16, u32, u32, i16::pow);
84
pow_impl!(i16, usize);
85
pow_impl!(u32, u8, u32, u32::pow);
86
pow_impl!(u32, u16, u32, u32::pow);
87
pow_impl!(u32, u32, u32, u32::pow);
88
pow_impl!(u32, usize);
89
pow_impl!(i32, u8, u32, i32::pow);
90
pow_impl!(i32, u16, u32, i32::pow);
91
pow_impl!(i32, u32, u32, i32::pow);
92
pow_impl!(i32, usize);
93
pow_impl!(u64, u8, u32, u64::pow);
94
pow_impl!(u64, u16, u32, u64::pow);
95
pow_impl!(u64, u32, u32, u64::pow);
96
pow_impl!(u64, usize);
97
pow_impl!(i64, u8, u32, i64::pow);
98
pow_impl!(i64, u16, u32, i64::pow);
99
pow_impl!(i64, u32, u32, i64::pow);
100
pow_impl!(i64, usize);
101
102
pow_impl!(u128, u8, u32, u128::pow);
103
pow_impl!(u128, u16, u32, u128::pow);
104
pow_impl!(u128, u32, u32, u128::pow);
105
pow_impl!(u128, usize);
106
107
pow_impl!(i128, u8, u32, i128::pow);
108
pow_impl!(i128, u16, u32, i128::pow);
109
pow_impl!(i128, u32, u32, i128::pow);
110
pow_impl!(i128, usize);
111
112
pow_impl!(usize, u8, u32, usize::pow);
113
pow_impl!(usize, u16, u32, usize::pow);
114
pow_impl!(usize, u32, u32, usize::pow);
115
pow_impl!(usize, usize);
116
pow_impl!(isize, u8, u32, isize::pow);
117
pow_impl!(isize, u16, u32, isize::pow);
118
pow_impl!(isize, u32, u32, isize::pow);
119
pow_impl!(isize, usize);
120
pow_impl!(Wrapping<u8>);
121
pow_impl!(Wrapping<i8>);
122
pow_impl!(Wrapping<u16>);
123
pow_impl!(Wrapping<i16>);
124
pow_impl!(Wrapping<u32>);
125
pow_impl!(Wrapping<i32>);
126
pow_impl!(Wrapping<u64>);
127
pow_impl!(Wrapping<i64>);
128
pow_impl!(Wrapping<u128>);
129
pow_impl!(Wrapping<i128>);
130
pow_impl!(Wrapping<usize>);
131
pow_impl!(Wrapping<isize>);
132
133
// FIXME: these should be possible
134
// pow_impl!(u8, u64);
135
// pow_impl!(i16, u64);
136
// pow_impl!(i8, u64);
137
// pow_impl!(u16, u64);
138
// pow_impl!(u32, u64);
139
// pow_impl!(i32, u64);
140
// pow_impl!(u64, u64);
141
// pow_impl!(i64, u64);
142
// pow_impl!(usize, u64);
143
// pow_impl!(isize, u64);
144
145
#[cfg(any(feature = "std", feature = "libm"))]
146
mod float_impls {
147
    use super::Pow;
148
    use crate::Float;
149
150
    pow_impl!(f32, i8, i32, <f32 as Float>::powi);
151
    pow_impl!(f32, u8, i32, <f32 as Float>::powi);
152
    pow_impl!(f32, i16, i32, <f32 as Float>::powi);
153
    pow_impl!(f32, u16, i32, <f32 as Float>::powi);
154
    pow_impl!(f32, i32, i32, <f32 as Float>::powi);
155
    pow_impl!(f64, i8, i32, <f64 as Float>::powi);
156
    pow_impl!(f64, u8, i32, <f64 as Float>::powi);
157
    pow_impl!(f64, i16, i32, <f64 as Float>::powi);
158
    pow_impl!(f64, u16, i32, <f64 as Float>::powi);
159
    pow_impl!(f64, i32, i32, <f64 as Float>::powi);
160
    pow_impl!(f32, f32, f32, <f32 as Float>::powf);
161
    pow_impl!(f64, f32, f64, <f64 as Float>::powf);
162
    pow_impl!(f64, f64, f64, <f64 as Float>::powf);
163
}
164
165
/// Raises a value to the power of exp, using exponentiation by squaring.
166
///
167
/// Note that `0⁰` (`pow(0, 0)`) returns `1`. Mathematically this is undefined.
168
///
169
/// # Example
170
///
171
/// ```rust
172
/// use num_traits::pow;
173
///
174
/// assert_eq!(pow(2i8, 4), 16);
175
/// assert_eq!(pow(6u8, 3), 216);
176
/// assert_eq!(pow(0u8, 0), 1); // Be aware if this case affects you
177
/// ```
178
#[inline]
179
0
pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T {
180
0
    if exp == 0 {
181
0
        return T::one();
182
0
    }
183
184
0
    while exp & 1 == 0 {
185
0
        base = base.clone() * base;
186
0
        exp >>= 1;
187
0
    }
188
0
    if exp == 1 {
189
0
        return base;
190
0
    }
191
0
192
0
    let mut acc = base.clone();
193
0
    while exp > 1 {
194
0
        exp >>= 1;
195
0
        base = base.clone() * base;
196
0
        if exp & 1 == 1 {
197
0
            acc = acc * base.clone();
198
0
        }
199
    }
200
0
    acc
201
0
}
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingaEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinghEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingiEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingjEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappinglEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingmEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingnEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingoEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingsEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingtEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingxEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingyEEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powaEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powhEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powiEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powjEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powlEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powmEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3pownEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powoEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powsEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powtEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powxEB4_
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow3powyEB4_
202
203
/// Raises a value to the power of exp, returning `None` if an overflow occurred.
204
///
205
/// Note that `0⁰` (`checked_pow(0, 0)`) returns `Some(1)`. Mathematically this is undefined.
206
///
207
/// Otherwise same as the `pow` function.
208
///
209
/// # Example
210
///
211
/// ```rust
212
/// use num_traits::checked_pow;
213
///
214
/// assert_eq!(checked_pow(2i8, 4), Some(16));
215
/// assert_eq!(checked_pow(7i8, 8), None);
216
/// assert_eq!(checked_pow(7u32, 8), Some(5_764_801));
217
/// assert_eq!(checked_pow(0u32, 0), Some(1)); // Be aware if this case affect you
218
/// ```
219
#[inline]
220
0
pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) -> Option<T> {
221
0
    if exp == 0 {
222
0
        return Some(T::one());
223
0
    }
224
225
0
    while exp & 1 == 0 {
226
0
        base = base.checked_mul(&base)?;
227
0
        exp >>= 1;
228
    }
229
0
    if exp == 1 {
230
0
        return Some(base);
231
0
    }
232
0
233
0
    let mut acc = base.clone();
234
0
    while exp > 1 {
235
0
        exp >>= 1;
236
0
        base = base.checked_mul(&base)?;
237
0
        if exp & 1 == 1 {
238
0
            acc = acc.checked_mul(&base)?;
239
0
        }
240
    }
241
0
    Some(acc)
242
0
}
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow11checked_powhECsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow11checked_powjECsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow11checked_powmECsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow11checked_powoECsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow11checked_powtECsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow11checked_powyECsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RINvNtCs7cG3k8kmkqw_10num_traits3pow11checked_powpEB4_
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/sign.rs
Line
Count
Source
1
use core::num::Wrapping;
2
use core::ops::Neg;
3
4
use crate::float::FloatCore;
5
use crate::Num;
6
7
/// Useful functions for signed numbers (i.e. numbers that can be negative).
8
pub trait Signed: Sized + Num + Neg<Output = Self> {
9
    /// Computes the absolute value.
10
    ///
11
    /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`.
12
    ///
13
    /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
14
    fn abs(&self) -> Self;
15
16
    /// The positive difference of two numbers.
17
    ///
18
    /// Returns `zero` if the number is less than or equal to `other`, otherwise the difference
19
    /// between `self` and `other` is returned.
20
    fn abs_sub(&self, other: &Self) -> Self;
21
22
    /// Returns the sign of the number.
23
    ///
24
    /// For `f32` and `f64`:
25
    ///
26
    /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
27
    /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
28
    /// * `NaN` if the number is `NaN`
29
    ///
30
    /// For signed integers:
31
    ///
32
    /// * `0` if the number is zero
33
    /// * `1` if the number is positive
34
    /// * `-1` if the number is negative
35
    fn signum(&self) -> Self;
36
37
    /// Returns true if the number is positive and false if the number is zero or negative.
38
    fn is_positive(&self) -> bool;
39
40
    /// Returns true if the number is negative and false if the number is zero or positive.
41
    fn is_negative(&self) -> bool;
42
}
43
44
macro_rules! signed_impl {
45
    ($($t:ty)*) => ($(
46
        impl Signed for $t {
47
            #[inline]
48
0
            fn abs(&self) -> $t {
49
0
                if self.is_negative() { -*self } else { *self }
50
0
            }
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4signaNtB5_6Signed3absCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4signsNtB5_6Signed3absCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4signlNtB5_6Signed3absCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4signxNtB5_6Signed3absCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4signnNtB5_6Signed3absCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits4signiNtB5_6Signed3absCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits4signiNtB5_6Signed3absB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4signaNtB5_6Signed3absB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4signsNtB5_6Signed3absB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4signlNtB5_6Signed3absB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4signxNtB5_6Signed3absB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4signnNtB5_6Signed3absB7_
51
52
            #[inline]
53
0
            fn abs_sub(&self, other: &$t) -> $t {
54
0
                if *self <= *other { 0 } else { *self - *other }
55
0
            }
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits4signiNtB5_6Signed7abs_subB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4signaNtB5_6Signed7abs_subB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4signsNtB5_6Signed7abs_subB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4signlNtB5_6Signed7abs_subB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4signxNtB5_6Signed7abs_subB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4signnNtB5_6Signed7abs_subB7_
56
57
            #[inline]
58
0
            fn signum(&self) -> $t {
59
0
                match *self {
60
0
                    n if n > 0 => 1,
61
0
                    0 => 0,
62
0
                    _ => -1,
63
                }
64
0
            }
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits4signiNtB5_6Signed6signumB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4signaNtB5_6Signed6signumB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4signsNtB5_6Signed6signumB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4signlNtB5_6Signed6signumB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4signxNtB5_6Signed6signumB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4signnNtB5_6Signed6signumB7_
65
66
            #[inline]
67
0
            fn is_positive(&self) -> bool { *self > 0 }
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits4signiNtB5_6Signed11is_positiveB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4signaNtB5_6Signed11is_positiveB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4signsNtB5_6Signed11is_positiveB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4signlNtB5_6Signed11is_positiveB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4signxNtB5_6Signed11is_positiveB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4signnNtB5_6Signed11is_positiveB7_
68
69
            #[inline]
70
0
            fn is_negative(&self) -> bool { *self < 0 }
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4signaNtB5_6Signed11is_negativeCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4signsNtB5_6Signed11is_negativeCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4signlNtB5_6Signed11is_negativeCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4signxNtB5_6Signed11is_negativeCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4signnNtB5_6Signed11is_negativeCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits4signiNtB5_6Signed11is_negativeCsd1gRxjdwU23_11num_integer
Unexecuted instantiation: _RNvXs0_NtCs7cG3k8kmkqw_10num_traits4signiNtB5_6Signed11is_negativeB7_
Unexecuted instantiation: _RNvXs1_NtCs7cG3k8kmkqw_10num_traits4signaNtB5_6Signed11is_negativeB7_
Unexecuted instantiation: _RNvXs2_NtCs7cG3k8kmkqw_10num_traits4signsNtB5_6Signed11is_negativeB7_
Unexecuted instantiation: _RNvXs3_NtCs7cG3k8kmkqw_10num_traits4signlNtB5_6Signed11is_negativeB7_
Unexecuted instantiation: _RNvXs4_NtCs7cG3k8kmkqw_10num_traits4signxNtB5_6Signed11is_negativeB7_
Unexecuted instantiation: _RNvXs5_NtCs7cG3k8kmkqw_10num_traits4signnNtB5_6Signed11is_negativeB7_
71
        }
72
    )*)
73
}
74
75
signed_impl!(isize i8 i16 i32 i64 i128);
76
77
impl<T: Signed> Signed for Wrapping<T>
78
where
79
    Wrapping<T>: Num + Neg<Output = Wrapping<T>>,
80
{
81
    #[inline]
82
0
    fn abs(&self) -> Self {
83
0
        Wrapping(self.0.abs())
84
0
    }
85
86
    #[inline]
87
0
    fn abs_sub(&self, other: &Self) -> Self {
88
0
        Wrapping(self.0.abs_sub(&other.0))
89
0
    }
90
91
    #[inline]
92
0
    fn signum(&self) -> Self {
93
0
        Wrapping(self.0.signum())
94
0
    }
95
96
    #[inline]
97
0
    fn is_positive(&self) -> bool {
98
0
        self.0.is_positive()
99
0
    }
100
101
    #[inline]
102
0
    fn is_negative(&self) -> bool {
103
0
        self.0.is_negative()
104
0
    }
105
}
106
107
macro_rules! signed_float_impl {
108
    ($t:ty) => {
109
        impl Signed for $t {
110
            /// Computes the absolute value. Returns `NAN` if the number is `NAN`.
111
            #[inline]
112
0
            fn abs(&self) -> $t {
113
0
                FloatCore::abs(*self)
114
0
            }
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4signfNtB5_6Signed3absB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4signdNtB5_6Signed3absB7_
115
116
            /// The positive difference of two numbers. Returns `0.0` if the number is
117
            /// less than or equal to `other`, otherwise the difference between`self`
118
            /// and `other` is returned.
119
            #[inline]
120
0
            fn abs_sub(&self, other: &$t) -> $t {
121
0
                if *self <= *other {
122
0
                    0.
123
                } else {
124
0
                    *self - *other
125
                }
126
0
            }
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4signfNtB5_6Signed7abs_subB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4signdNtB5_6Signed7abs_subB7_
127
128
            /// # Returns
129
            ///
130
            /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
131
            /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
132
            /// - `NAN` if the number is NaN
133
            #[inline]
134
0
            fn signum(&self) -> $t {
135
0
                FloatCore::signum(*self)
136
0
            }
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4signfNtB5_6Signed6signumB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4signdNtB5_6Signed6signumB7_
137
138
            /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
139
            #[inline]
140
0
            fn is_positive(&self) -> bool {
141
0
                FloatCore::is_sign_positive(*self)
142
0
            }
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4signfNtB5_6Signed11is_positiveB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4signdNtB5_6Signed11is_positiveB7_
143
144
            /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
145
            #[inline]
146
0
            fn is_negative(&self) -> bool {
147
0
                FloatCore::is_sign_negative(*self)
148
0
            }
Unexecuted instantiation: _RNvXs6_NtCs7cG3k8kmkqw_10num_traits4signfNtB5_6Signed11is_negativeB7_
Unexecuted instantiation: _RNvXs7_NtCs7cG3k8kmkqw_10num_traits4signdNtB5_6Signed11is_negativeB7_
149
        }
150
    };
151
}
152
153
signed_float_impl!(f32);
154
signed_float_impl!(f64);
155
156
/// Computes the absolute value.
157
///
158
/// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`
159
///
160
/// For signed integers, `::MIN` will be returned if the number is `::MIN`.
161
#[inline(always)]
162
0
pub fn abs<T: Signed>(value: T) -> T {
163
0
    value.abs()
164
0
}
165
166
/// The positive difference of two numbers.
167
///
168
/// Returns zero if `x` is less than or equal to `y`, otherwise the difference
169
/// between `x` and `y` is returned.
170
#[inline(always)]
171
0
pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
172
0
    x.abs_sub(&y)
173
0
}
174
175
/// Returns the sign of the number.
176
///
177
/// For `f32` and `f64`:
178
///
179
/// * `1.0` if the number is positive, `+0.0` or `INFINITY`
180
/// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
181
/// * `NaN` if the number is `NaN`
182
///
183
/// For signed integers:
184
///
185
/// * `0` if the number is zero
186
/// * `1` if the number is positive
187
/// * `-1` if the number is negative
188
#[inline(always)]
189
0
pub fn signum<T: Signed>(value: T) -> T {
190
0
    value.signum()
191
0
}
192
193
/// A trait for values which cannot be negative
194
pub trait Unsigned: Num {}
195
196
macro_rules! empty_trait_impl {
197
    ($name:ident for $($t:ty)*) => ($(
198
        impl $name for $t {}
199
    )*)
200
}
201
202
empty_trait_impl!(Unsigned for usize u8 u16 u32 u64 u128);
203
204
impl<T: Unsigned> Unsigned for Wrapping<T> where Wrapping<T>: Num {}
205
206
#[test]
207
fn unsigned_wrapping_is_unsigned() {
208
    fn require_unsigned<T: Unsigned>(_: &T) {}
209
    require_unsigned(&Wrapping(42_u32));
210
}
211
212
#[test]
213
fn signed_wrapping_is_signed() {
214
    fn require_signed<T: Signed>(_: &T) {}
215
    require_signed(&Wrapping(-42));
216
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num_cpus-1.16.0/src/lib.rs
Line
Count
Source
1
//! A crate with utilities to determine the number of CPUs available on the
2
//! current system.
3
//!
4
//! Sometimes the CPU will exaggerate the number of CPUs it contains, because it can use
5
//! [processor tricks] to deliver increased performance when there are more threads. This 
6
//! crate provides methods to get both the logical and physical numbers of cores.
7
//!
8
//! This information can be used as a guide to how many tasks can be run in parallel.
9
//! There are many properties of the system architecture that will affect parallelism,
10
//! for example memory access speeds (for all the caches and RAM) and the physical
11
//! architecture of the processor, so the number of CPUs should be used as a rough guide
12
//! only.
13
//!
14
//!
15
//! ## Examples
16
//!
17
//! Fetch the number of logical CPUs.
18
//!
19
//! ```
20
//! let cpus = num_cpus::get();
21
//! ```
22
//!
23
//! See [`rayon::Threadpool`] for an example of where the number of CPUs could be
24
//! used when setting up parallel jobs (Where the threadpool example uses a fixed
25
//! number 8, it could use the number of CPUs).
26
//!
27
//! [processor tricks]: https://en.wikipedia.org/wiki/Simultaneous_multithreading
28
//! [`rayon::ThreadPool`]: https://docs.rs/rayon/1.*/rayon/struct.ThreadPool.html
29
#![cfg_attr(test, deny(warnings))]
30
#![deny(missing_docs)]
31
#![allow(non_snake_case)]
32
33
#[cfg(not(windows))]
34
extern crate libc;
35
36
#[cfg(target_os = "hermit")]
37
extern crate hermit_abi;
38
39
#[cfg(target_os = "linux")]
40
mod linux;
41
#[cfg(target_os = "linux")]
42
use linux::{get_num_cpus, get_num_physical_cpus};
43
44
/// Returns the number of available CPUs of the current system.
45
///
46
/// This function will get the number of logical cores. Sometimes this is different from the number
47
/// of physical cores (See [Simultaneous multithreading on Wikipedia][smt]).
48
///
49
/// This will always return at least `1`.
50
///
51
/// # Examples
52
///
53
/// ```
54
/// let cpus = num_cpus::get();
55
/// if cpus > 1 {
56
///     println!("We are on a multicore system with {} CPUs", cpus);
57
/// } else {
58
///     println!("We are on a single core system");
59
/// }
60
/// ```
61
///
62
/// # Note
63
///
64
/// This will check [sched affinity] on Linux, showing a lower number of CPUs if the current
65
/// thread does not have access to all the computer's CPUs.
66
///
67
/// This will also check [cgroups], frequently used in containers to constrain CPU usage.
68
///
69
/// [smt]: https://en.wikipedia.org/wiki/Simultaneous_multithreading
70
/// [sched affinity]: http://www.gnu.org/software/libc/manual/html_node/CPU-Affinity.html
71
/// [cgroups]: https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt
72
#[inline]
73
0
pub fn get() -> usize {
74
0
    get_num_cpus()
75
0
}
Unexecuted instantiation: _RNvCsh9AfkWWthE7_8num_cpus3getB1_
Unexecuted instantiation: _RNvCsh9AfkWWthE7_8num_cpus3getCs4c1Xk16ziyI_10threadpool
76
77
/// Returns the number of physical cores of the current system.
78
///
79
/// This will always return at least `1`.
80
///
81
/// # Note
82
///
83
/// Physical count is supported only on Linux, mac OS and Windows platforms.
84
/// On other platforms, or if the physical count fails on supported platforms,
85
/// this function returns the same as [`get()`], which is the number of logical
86
/// CPUS.
87
///
88
/// # Examples
89
///
90
/// ```
91
/// let logical_cpus = num_cpus::get();
92
/// let physical_cpus = num_cpus::get_physical();
93
/// if logical_cpus > physical_cpus {
94
///     println!("We have simultaneous multithreading with about {:.2} \
95
///               logical cores to 1 physical core.", 
96
///               (logical_cpus as f64) / (physical_cpus as f64));
97
/// } else if logical_cpus == physical_cpus {
98
///     println!("Either we don't have simultaneous multithreading, or our \
99
///               system doesn't support getting the number of physical CPUs.");
100
/// } else {
101
///     println!("We have less logical CPUs than physical CPUs, maybe we only have access to \
102
///               some of the CPUs on our system.");
103
/// }
104
/// ```
105
///
106
/// [`get()`]: fn.get.html
107
#[inline]
108
0
pub fn get_physical() -> usize {
109
0
    get_num_physical_cpus()
110
0
}
111
112
113
#[cfg(not(any(
114
    target_os = "linux",
115
    target_os = "windows",
116
    target_os = "macos",
117
    target_os = "openbsd",
118
    target_os = "aix")))]
119
#[inline]
120
fn get_num_physical_cpus() -> usize {
121
    // Not implemented, fall back
122
    get_num_cpus()
123
}
124
125
#[cfg(target_os = "windows")]
126
fn get_num_physical_cpus() -> usize {
127
    match get_num_physical_cpus_windows() {
128
        Some(num) => num,
129
        None => get_num_cpus()
130
    }
131
}
132
133
#[cfg(target_os = "windows")]
134
fn get_num_physical_cpus_windows() -> Option<usize> {
135
    // Inspired by https://msdn.microsoft.com/en-us/library/ms683194
136
137
    use std::ptr;
138
    use std::mem;
139
140
    #[allow(non_upper_case_globals)]
141
    const RelationProcessorCore: u32 = 0;
142
143
    #[repr(C)]
144
    #[allow(non_camel_case_types)]
145
    struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION {
146
        mask: usize,
147
        relationship: u32,
148
        _unused: [u64; 2]
149
    }
150
151
    extern "system" {
152
        fn GetLogicalProcessorInformation(
153
            info: *mut SYSTEM_LOGICAL_PROCESSOR_INFORMATION,
154
            length: &mut u32
155
        ) -> u32;
156
    }
157
158
    // First we need to determine how much space to reserve.
159
160
    // The required size of the buffer, in bytes.
161
    let mut needed_size = 0;
162
163
    unsafe {
164
        GetLogicalProcessorInformation(ptr::null_mut(), &mut needed_size);
165
    }
166
167
    let struct_size = mem::size_of::<SYSTEM_LOGICAL_PROCESSOR_INFORMATION>() as u32;
168
169
    // Could be 0, or some other bogus size.
170
    if needed_size == 0 || needed_size < struct_size || needed_size % struct_size != 0 {
171
        return None;
172
    }
173
174
    let count = needed_size / struct_size;
175
176
    // Allocate some memory where we will store the processor info.
177
    let mut buf = Vec::with_capacity(count as usize);
178
179
    let result;
180
181
    unsafe {
182
        result = GetLogicalProcessorInformation(buf.as_mut_ptr(), &mut needed_size);
183
    }
184
185
    // Failed for any reason.
186
    if result == 0 {
187
        return None;
188
    }
189
190
    let count = needed_size / struct_size;
191
192
    unsafe {
193
        buf.set_len(count as usize);
194
    }
195
196
    let phys_proc_count = buf.iter()
197
        // Only interested in processor packages (physical processors.)
198
        .filter(|proc_info| proc_info.relationship == RelationProcessorCore)
199
        .count();
200
201
    if phys_proc_count == 0 {
202
        None
203
    } else {
204
        Some(phys_proc_count)
205
    }
206
}
207
208
#[cfg(windows)]
209
fn get_num_cpus() -> usize {
210
    #[repr(C)]
211
    struct SYSTEM_INFO {
212
        wProcessorArchitecture: u16,
213
        wReserved: u16,
214
        dwPageSize: u32,
215
        lpMinimumApplicationAddress: *mut u8,
216
        lpMaximumApplicationAddress: *mut u8,
217
        dwActiveProcessorMask: *mut u8,
218
        dwNumberOfProcessors: u32,
219
        dwProcessorType: u32,
220
        dwAllocationGranularity: u32,
221
        wProcessorLevel: u16,
222
        wProcessorRevision: u16,
223
    }
224
225
    extern "system" {
226
        fn GetSystemInfo(lpSystemInfo: *mut SYSTEM_INFO);
227
    }
228
229
    unsafe {
230
        let mut sysinfo: SYSTEM_INFO = std::mem::zeroed();
231
        GetSystemInfo(&mut sysinfo);
232
        sysinfo.dwNumberOfProcessors as usize
233
    }
234
}
235
236
#[cfg(any(target_os = "freebsd",
237
          target_os = "dragonfly",
238
          target_os = "netbsd"))]
239
fn get_num_cpus() -> usize {
240
    use std::ptr;
241
242
    let mut cpus: libc::c_uint = 0;
243
    let mut cpus_size = std::mem::size_of_val(&cpus);
244
245
    unsafe {
246
        cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint;
247
    }
248
    if cpus < 1 {
249
        let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
250
        unsafe {
251
            libc::sysctl(mib.as_mut_ptr(),
252
                         2,
253
                         &mut cpus as *mut _ as *mut _,
254
                         &mut cpus_size as *mut _ as *mut _,
255
                         ptr::null_mut(),
256
                         0);
257
        }
258
        if cpus < 1 {
259
            cpus = 1;
260
        }
261
    }
262
    cpus as usize
263
}
264
265
#[cfg(target_os = "openbsd")]
266
fn get_num_cpus() -> usize {
267
    use std::ptr;
268
269
    let mut cpus: libc::c_uint = 0;
270
    let mut cpus_size = std::mem::size_of_val(&cpus);
271
    let mut mib = [libc::CTL_HW, libc::HW_NCPUONLINE, 0, 0];
272
    let rc: libc::c_int;
273
274
    unsafe {
275
        rc = libc::sysctl(mib.as_mut_ptr(),
276
                          2,
277
                          &mut cpus as *mut _ as *mut _,
278
                          &mut cpus_size as *mut _ as *mut _,
279
                          ptr::null_mut(),
280
                          0);
281
    }
282
    if rc < 0 {
283
        cpus = 1;
284
    }
285
    cpus as usize
286
}
287
288
#[cfg(target_os = "openbsd")]
289
fn get_num_physical_cpus() -> usize {
290
    use std::ptr;
291
292
    let mut cpus: libc::c_uint = 0;
293
    let mut cpus_size = std::mem::size_of_val(&cpus);
294
    let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
295
    let rc: libc::c_int;
296
297
    unsafe {
298
        rc = libc::sysctl(mib.as_mut_ptr(),
299
                          2,
300
                          &mut cpus as *mut _ as *mut _,
301
                          &mut cpus_size as *mut _ as *mut _,
302
                          ptr::null_mut(),
303
                          0);
304
    }
305
    if rc < 0 {
306
        cpus = 1;
307
    }
308
    cpus as usize
309
}
310
311
312
#[cfg(target_os = "macos")]
313
fn get_num_physical_cpus() -> usize {
314
    use std::ffi::CStr;
315
    use std::ptr;
316
317
    let mut cpus: i32 = 0;
318
    let mut cpus_size = std::mem::size_of_val(&cpus);
319
320
    let sysctl_name = CStr::from_bytes_with_nul(b"hw.physicalcpu\0")
321
        .expect("byte literal is missing NUL");
322
323
    unsafe {
324
        if 0 != libc::sysctlbyname(sysctl_name.as_ptr(),
325
                                   &mut cpus as *mut _ as *mut _,
326
                                   &mut cpus_size as *mut _ as *mut _,
327
                                   ptr::null_mut(),
328
                                   0) {
329
            return get_num_cpus();
330
        }
331
    }
332
    cpus as usize
333
}
334
335
#[cfg(target_os = "aix")]
336
fn get_num_physical_cpus() -> usize {
337
    match get_smt_threads_aix() {
338
        Some(num) => get_num_cpus() / num,
339
        None => get_num_cpus(),
340
    }
341
}
342
343
#[cfg(target_os = "aix")]
344
fn get_smt_threads_aix() -> Option<usize> {
345
    let smt = unsafe {
346
        libc::getsystemcfg(libc::SC_SMT_TC)
347
    };
348
    if smt == u64::MAX {
349
        return None;
350
    }
351
    Some(smt as usize)
352
}
353
354
#[cfg(any(
355
    target_os = "nacl",
356
    target_os = "macos",
357
    target_os = "ios",
358
    target_os = "android",
359
    target_os = "aix",
360
    target_os = "solaris",
361
    target_os = "illumos",
362
    target_os = "fuchsia")
363
)]
364
fn get_num_cpus() -> usize {
365
    // On ARM targets, processors could be turned off to save power.
366
    // Use `_SC_NPROCESSORS_CONF` to get the real number.
367
    #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
368
    const CONF_NAME: libc::c_int = libc::_SC_NPROCESSORS_CONF;
369
    #[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))]
370
    const CONF_NAME: libc::c_int = libc::_SC_NPROCESSORS_ONLN;
371
372
    let cpus = unsafe { libc::sysconf(CONF_NAME) };
373
    if cpus < 1 {
374
        1
375
    } else {
376
        cpus as usize
377
    }
378
}
379
380
#[cfg(target_os = "haiku")]
381
fn get_num_cpus() -> usize {
382
    use std::mem;
383
384
    #[allow(non_camel_case_types)]
385
    type bigtime_t = i64;
386
    #[allow(non_camel_case_types)]
387
    type status_t = i32;
388
389
    #[repr(C)]
390
    pub struct system_info {
391
        pub boot_time: bigtime_t,
392
        pub cpu_count: u32,
393
        pub max_pages: u64,
394
        pub used_pages: u64,
395
        pub cached_pages: u64,
396
        pub block_cache_pages: u64,
397
        pub ignored_pages: u64,
398
        pub needed_memory: u64,
399
        pub free_memory: u64,
400
        pub max_swap_pages: u64,
401
        pub free_swap_pages: u64,
402
        pub page_faults: u32,
403
        pub max_sems: u32,
404
        pub used_sems: u32,
405
        pub max_ports: u32,
406
        pub used_ports: u32,
407
        pub max_threads: u32,
408
        pub used_threads: u32,
409
        pub max_teams: u32,
410
        pub used_teams: u32,
411
        pub kernel_name: [::std::os::raw::c_char; 256usize],
412
        pub kernel_build_date: [::std::os::raw::c_char; 32usize],
413
        pub kernel_build_time: [::std::os::raw::c_char; 32usize],
414
        pub kernel_version: i64,
415
        pub abi: u32,
416
    }
417
418
    extern {
419
        fn get_system_info(info: *mut system_info) -> status_t;
420
    }
421
422
    let mut info: system_info = unsafe { mem::zeroed() };
423
    let status = unsafe { get_system_info(&mut info as *mut _) };
424
    if status == 0 {
425
        info.cpu_count as usize
426
    } else {
427
        1
428
    }
429
}
430
431
#[cfg(target_os = "hermit")]
432
fn get_num_cpus() -> usize {
433
    unsafe { hermit_abi::get_processor_count() }
434
}
435
436
#[cfg(not(any(
437
    target_os = "nacl",
438
    target_os = "macos",
439
    target_os = "ios",
440
    target_os = "android",
441
    target_os = "aix",
442
    target_os = "solaris",
443
    target_os = "illumos",
444
    target_os = "fuchsia",
445
    target_os = "linux",
446
    target_os = "openbsd",
447
    target_os = "freebsd",
448
    target_os = "dragonfly",
449
    target_os = "netbsd",
450
    target_os = "haiku",
451
    target_os = "hermit",
452
    windows,
453
)))]
454
fn get_num_cpus() -> usize {
455
    1
456
}
457
458
#[cfg(test)]
459
mod tests {
460
    fn env_var(name: &'static str) -> Option<usize> {
461
        ::std::env::var(name).ok().map(|val| val.parse().unwrap())
462
    }
463
464
    #[test]
465
    fn test_get() {
466
        let num = super::get();
467
        if let Some(n) = env_var("NUM_CPUS_TEST_GET") {
468
            assert_eq!(num, n);
469
        } else {
470
            assert!(num > 0);
471
            assert!(num < 236_451);
472
        }
473
    }
474
475
    #[test]
476
    fn test_get_physical() {
477
        let num = super::get_physical();
478
        if let Some(n) = env_var("NUM_CPUS_TEST_GET_PHYSICAL") {
479
            assert_eq!(num, n);
480
        } else {
481
            assert!(num > 0);
482
            assert!(num < 236_451);
483
        }
484
    }
485
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/num_cpus-1.16.0/src/linux.rs
Line
Count
Source
1
use std::collections::HashMap;
2
use std::fs::File;
3
use std::io::{BufRead, BufReader, Read};
4
use std::mem;
5
use std::path::{Path, PathBuf};
6
use std::sync::atomic::{AtomicUsize, Ordering};
7
use std::sync::Once;
8
9
use libc;
10
11
macro_rules! debug {
12
    ($($args:expr),*) => ({
13
        if false {
14
        //if true {
15
            println!($($args),*);
16
        }
17
    });
18
}
19
20
macro_rules! some {
21
    ($e:expr) => {{
22
        match $e {
23
            Some(v) => v,
24
            None => {
25
                debug!("NONE: {:?}", stringify!($e));
26
                return None;
27
            }
28
        }
29
    }};
30
}
31
32
0
pub fn get_num_cpus() -> usize {
33
0
    match cgroups_num_cpus() {
34
0
        Some(n) => n,
35
0
        None => logical_cpus(),
36
    }
37
0
}
38
39
0
fn logical_cpus() -> usize {
40
0
    let mut set: libc::cpu_set_t = unsafe { mem::zeroed() };
41
0
    if unsafe { libc::sched_getaffinity(0, mem::size_of::<libc::cpu_set_t>(), &mut set) } == 0 {
42
0
        let mut count: u32 = 0;
43
0
        for i in 0..libc::CPU_SETSIZE as usize {
44
0
            if unsafe { libc::CPU_ISSET(i, &set) } {
45
0
                count += 1
46
0
            }
47
        }
48
0
        count as usize
49
    } else {
50
0
        let cpus = unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) };
51
0
        if cpus < 1 {
52
0
            1
53
        } else {
54
0
            cpus as usize
55
        }
56
    }
57
0
}
58
59
0
pub fn get_num_physical_cpus() -> usize {
60
0
    let file = match File::open("/proc/cpuinfo") {
61
0
        Ok(val) => val,
62
0
        Err(_) => return get_num_cpus(),
63
    };
64
0
    let reader = BufReader::new(file);
65
0
    let mut map = HashMap::new();
66
0
    let mut physid: u32 = 0;
67
0
    let mut cores: usize = 0;
68
0
    let mut chgcount = 0;
69
0
    for line in reader.lines().filter_map(|result| result.ok()) {
70
0
        let mut it = line.split(':');
71
0
        let (key, value) = match (it.next(), it.next()) {
72
0
            (Some(key), Some(value)) => (key.trim(), value.trim()),
73
0
            _ => continue,
74
        };
75
0
        if key == "physical id" {
76
0
            match value.parse() {
77
0
                Ok(val) => physid = val,
78
0
                Err(_) => break,
79
            };
80
0
            chgcount += 1;
81
0
        }
82
0
        if key == "cpu cores" {
83
0
            match value.parse() {
84
0
                Ok(val) => cores = val,
85
0
                Err(_) => break,
86
            };
87
0
            chgcount += 1;
88
0
        }
89
0
        if chgcount == 2 {
90
0
            map.insert(physid, cores);
91
0
            chgcount = 0;
92
0
        }
93
    }
94
0
    let count = map.into_iter().fold(0, |acc, (_, cores)| acc + cores);
95
0
96
0
    if count == 0 {
97
0
        get_num_cpus()
98
    } else {
99
0
        count
100
    }
101
0
}
102
103
/// Cached CPUs calculated from cgroups.
104
///
105
/// If 0, check logical cpus.
106
// Allow deprecation warnings, we want to work on older rustc
107
#[allow(warnings)]
108
static CGROUPS_CPUS: AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT;
109
110
0
fn cgroups_num_cpus() -> Option<usize> {
111
    #[allow(warnings)]
112
    static ONCE: Once = ::std::sync::ONCE_INIT;
113
114
0
    ONCE.call_once(init_cgroups);
115
0
116
0
    let cpus = CGROUPS_CPUS.load(Ordering::Acquire);
117
0
118
0
    if cpus > 0 {
119
0
        Some(cpus)
120
    } else {
121
0
        None
122
    }
123
0
}
124
125
0
fn init_cgroups() {
126
0
    // Should only be called once
127
0
    debug_assert!(CGROUPS_CPUS.load(Ordering::SeqCst) == 0);
128
129
    // Fails in Miri by default (cannot open files), and Miri does not have parallelism anyway.
130
0
    if cfg!(miri) {
131
0
        return;
132
0
    }
133
134
0
    if let Some(quota) = load_cgroups("/proc/self/cgroup", "/proc/self/mountinfo") {
135
0
        if quota == 0 {
136
0
            return;
137
0
        }
138
0
139
0
        let logical = logical_cpus();
140
0
        let count = ::std::cmp::min(quota, logical);
141
0
142
0
        CGROUPS_CPUS.store(count, Ordering::SeqCst);
143
0
    }
144
0
}
145
146
0
fn load_cgroups<P1, P2>(cgroup_proc: P1, mountinfo_proc: P2) -> Option<usize>
147
0
where
148
0
    P1: AsRef<Path>,
149
0
    P2: AsRef<Path>,
150
0
{
151
0
    let subsys = some!(Subsys::load_cpu(cgroup_proc));
152
0
    let mntinfo = some!(MountInfo::load_cpu(mountinfo_proc, subsys.version));
153
0
    let cgroup = some!(Cgroup::translate(mntinfo, subsys));
154
0
    cgroup.cpu_quota()
155
0
}
156
157
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
158
enum CgroupVersion {
159
    V1,
160
    V2,
161
}
162
163
struct Cgroup {
164
    version: CgroupVersion,
165
    base: PathBuf,
166
}
167
168
struct MountInfo {
169
    version: CgroupVersion,
170
    root: String,
171
    mount_point: String,
172
}
173
174
struct Subsys {
175
    version: CgroupVersion,
176
    base: String,
177
}
178
179
impl Cgroup {
180
0
    fn new(version: CgroupVersion, dir: PathBuf) -> Cgroup {
181
0
        Cgroup { version: version, base: dir }
182
0
    }
183
184
0
    fn translate(mntinfo: MountInfo, subsys: Subsys) -> Option<Cgroup> {
185
0
        // Translate the subsystem directory via the host paths.
186
0
        debug!(
187
0
            "subsys = {:?}; root = {:?}; mount_point = {:?}",
188
            subsys.base, mntinfo.root, mntinfo.mount_point
189
        );
190
191
0
        let rel_from_root = some!(Path::new(&subsys.base).strip_prefix(&mntinfo.root).ok());
192
193
0
        debug!("rel_from_root: {:?}", rel_from_root);
194
195
        // join(mp.MountPoint, relPath)
196
0
        let mut path = PathBuf::from(mntinfo.mount_point);
197
0
        path.push(rel_from_root);
198
0
        Some(Cgroup::new(mntinfo.version, path))
199
0
    }
200
201
0
    fn cpu_quota(&self) -> Option<usize> {
202
0
        let (quota_us, period_us) = match self.version {
203
0
            CgroupVersion::V1 => (some!(self.quota_us()), some!(self.period_us())),
204
0
            CgroupVersion::V2 => some!(self.max()),
205
        };
206
207
        // protect against dividing by zero
208
0
        if period_us == 0 {
209
0
            return None;
210
0
        }
211
0
212
0
        // Ceil the division, since we want to be able to saturate
213
0
        // the available CPUs, and flooring would leave a CPU un-utilized.
214
0
215
0
        Some((quota_us as f64 / period_us as f64).ceil() as usize)
216
0
    }
217
218
0
    fn quota_us(&self) -> Option<usize> {
219
0
        self.param("cpu.cfs_quota_us")
220
0
    }
221
222
0
    fn period_us(&self) -> Option<usize> {
223
0
        self.param("cpu.cfs_period_us")
224
0
    }
225
226
0
    fn max(&self) -> Option<(usize, usize)> {
227
0
        let max = some!(self.raw_param("cpu.max"));
228
0
        let mut max = some!(max.lines().next()).split(' ');
229
230
0
        let quota = some!(max.next().and_then(|quota| quota.parse().ok()));
231
0
        let period = some!(max.next().and_then(|period| period.parse().ok()));
232
233
0
        Some((quota, period))
234
0
    }
235
236
0
    fn param(&self, param: &str) -> Option<usize> {
237
0
        let buf = some!(self.raw_param(param));
238
239
0
        buf.trim().parse().ok()
240
0
    }
241
242
0
    fn raw_param(&self, param: &str) -> Option<String> {
243
0
        let mut file = some!(File::open(self.base.join(param)).ok());
244
245
0
        let mut buf = String::new();
246
0
        some!(file.read_to_string(&mut buf).ok());
247
248
0
        Some(buf)
249
0
    }
250
}
251
252
impl MountInfo {
253
0
    fn load_cpu<P: AsRef<Path>>(proc_path: P, version: CgroupVersion) -> Option<MountInfo> {
254
0
        let file = some!(File::open(proc_path).ok());
255
0
        let file = BufReader::new(file);
256
0
257
0
        file.lines()
258
0
            .filter_map(|result| result.ok())
259
0
            .filter_map(MountInfo::parse_line)
260
0
            .find(|mount_info| mount_info.version == version)
261
0
    }
262
263
0
    fn parse_line(line: String) -> Option<MountInfo> {
264
0
        let mut fields = line.split(' ');
265
266
        // 7 5 0:6 </> /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:7 - cgroup cgroup rw,cpu,cpuacct
267
0
        let mnt_root = some!(fields.nth(3));
268
        // 7 5 0:6 / </sys/fs/cgroup/cpu,cpuacct> rw,nosuid,nodev,noexec,relatime shared:7 - cgroup cgroup rw,cpu,cpuacct
269
0
        let mnt_point = some!(fields.next());
270
271
        // Ignore all fields until the separator(-).
272
        // Note: there could be zero or more optional fields before hyphen.
273
        // See: https://man7.org/linux/man-pages/man5/proc.5.html
274
        // 7 5 0:6 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:7 <-> cgroup cgroup rw,cpu,cpuacct
275
        // Note: we cannot use `?` here because we need to support Rust 1.13.
276
0
        match fields.find(|&s| s == "-") {
277
0
            Some(_) => {}
278
0
            None => return None,
279
        };
280
281
        // 7 5 0:6 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:7 - <cgroup> cgroup rw,cpu,cpuacct
282
0
        let version = match fields.next() {
283
0
            Some("cgroup") => CgroupVersion::V1,
284
0
            Some("cgroup2") => CgroupVersion::V2,
285
0
            _ => return None,
286
        };
287
288
        // cgroups2 only has a single mount point
289
0
        if version == CgroupVersion::V1 {
290
            // 7 5 0:6 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:7 - cgroup cgroup <rw,cpu,cpuacct>
291
0
            let super_opts = some!(fields.nth(1));
292
293
            // We only care about the 'cpu' option
294
0
            if !super_opts.split(',').any(|opt| opt == "cpu") {
295
0
                return None;
296
0
            }
297
0
        }
298
299
0
        Some(MountInfo {
300
0
            version: version,
301
0
            root: mnt_root.to_owned(),
302
0
            mount_point: mnt_point.to_owned(),
303
0
        })
304
0
    }
305
}
306
307
impl Subsys {
308
0
    fn load_cpu<P: AsRef<Path>>(proc_path: P) -> Option<Subsys> {
309
0
        let file = some!(File::open(proc_path).ok());
310
0
        let file = BufReader::new(file);
311
0
312
0
        file.lines()
313
0
            .filter_map(|result| result.ok())
314
0
            .filter_map(Subsys::parse_line)
315
0
            .fold(None, |previous, line| {
316
0
                // already-found v1 trumps v2 since it explicitly specifies its controllers
317
0
                if previous.is_some() && line.version == CgroupVersion::V2 {
318
0
                    return previous;
319
0
                }
320
0
321
0
                Some(line)
322
0
            })
323
0
    }
324
325
0
    fn parse_line(line: String) -> Option<Subsys> {
326
0
        // Example format:
327
0
        // 11:cpu,cpuacct:/
328
0
        let mut fields = line.split(':');
329
330
0
        let sub_systems = some!(fields.nth(1));
331
332
0
        let version = if sub_systems.is_empty() {
333
0
            CgroupVersion::V2
334
        } else {
335
0
            CgroupVersion::V1
336
        };
337
338
0
        if version == CgroupVersion::V1 && !sub_systems.split(',').any(|sub| sub == "cpu") {
339
0
            return None;
340
0
        }
341
0
342
0
        fields.next().map(|path| Subsys {
343
0
            version: version,
344
0
            base: path.to_owned(),
345
0
        })
346
0
    }
347
}
348
349
#[cfg(test)]
350
mod tests {
351
    mod v1 {
352
        use super::super::{Cgroup, CgroupVersion, MountInfo, Subsys};
353
        use std::path::{Path, PathBuf};
354
355
        // `static_in_const` feature is not stable in Rust 1.13.
356
        static FIXTURES_PROC: &'static str = "fixtures/cgroups/proc/cgroups";
357
358
        static FIXTURES_CGROUPS: &'static str = "fixtures/cgroups/cgroups";
359
360
        macro_rules! join {
361
            ($base:expr, $($path:expr),+) => ({
362
                Path::new($base)
363
                    $(.join($path))+
364
            })
365
        }
366
367
        #[test]
368
        fn test_load_mountinfo() {
369
            // test only one optional fields
370
            let path = join!(FIXTURES_PROC, "mountinfo");
371
372
            let mnt_info = MountInfo::load_cpu(path, CgroupVersion::V1).unwrap();
373
374
            assert_eq!(mnt_info.root, "/");
375
            assert_eq!(mnt_info.mount_point, "/sys/fs/cgroup/cpu,cpuacct");
376
377
            // test zero optional field
378
            let path = join!(FIXTURES_PROC, "mountinfo_zero_opt");
379
380
            let mnt_info = MountInfo::load_cpu(path, CgroupVersion::V1).unwrap();
381
382
            assert_eq!(mnt_info.root, "/");
383
            assert_eq!(mnt_info.mount_point, "/sys/fs/cgroup/cpu,cpuacct");
384
385
            // test multi optional fields
386
            let path = join!(FIXTURES_PROC, "mountinfo_multi_opt");
387
388
            let mnt_info = MountInfo::load_cpu(path, CgroupVersion::V1).unwrap();
389
390
            assert_eq!(mnt_info.root, "/");
391
            assert_eq!(mnt_info.mount_point, "/sys/fs/cgroup/cpu,cpuacct");
392
        }
393
394
        #[test]
395
        fn test_load_subsys() {
396
            let path = join!(FIXTURES_PROC, "cgroup");
397
398
            let subsys = Subsys::load_cpu(path).unwrap();
399
400
            assert_eq!(subsys.base, "/");
401
            assert_eq!(subsys.version, CgroupVersion::V1);
402
        }
403
404
        #[test]
405
        fn test_cgroup_mount() {
406
            let cases = &[
407
                ("/", "/sys/fs/cgroup/cpu", "/", Some("/sys/fs/cgroup/cpu")),
408
                (
409
                    "/docker/01abcd",
410
                    "/sys/fs/cgroup/cpu",
411
                    "/docker/01abcd",
412
                    Some("/sys/fs/cgroup/cpu"),
413
                ),
414
                (
415
                    "/docker/01abcd",
416
                    "/sys/fs/cgroup/cpu",
417
                    "/docker/01abcd/",
418
                    Some("/sys/fs/cgroup/cpu"),
419
                ),
420
                (
421
                    "/docker/01abcd",
422
                    "/sys/fs/cgroup/cpu",
423
                    "/docker/01abcd/large",
424
                    Some("/sys/fs/cgroup/cpu/large"),
425
                ),
426
                // fails
427
                ("/docker/01abcd", "/sys/fs/cgroup/cpu", "/", None),
428
                ("/docker/01abcd", "/sys/fs/cgroup/cpu", "/docker", None),
429
                ("/docker/01abcd", "/sys/fs/cgroup/cpu", "/elsewhere", None),
430
                (
431
                    "/docker/01abcd",
432
                    "/sys/fs/cgroup/cpu",
433
                    "/docker/01abcd-other-dir",
434
                    None,
435
                ),
436
            ];
437
438
            for &(root, mount_point, subsys, expected) in cases.iter() {
439
                let mnt_info = MountInfo {
440
                    version: CgroupVersion::V1,
441
                    root: root.into(),
442
                    mount_point: mount_point.into(),
443
                };
444
                let subsys = Subsys {
445
                    version: CgroupVersion::V1,
446
                    base: subsys.into(),
447
                };
448
449
                let actual = Cgroup::translate(mnt_info, subsys).map(|c| c.base);
450
                let expected = expected.map(PathBuf::from);
451
                assert_eq!(actual, expected);
452
            }
453
        }
454
455
        #[test]
456
        fn test_cgroup_cpu_quota() {
457
            let cgroup = Cgroup::new(CgroupVersion::V1, join!(FIXTURES_CGROUPS, "good"));
458
            assert_eq!(cgroup.cpu_quota(), Some(6));
459
        }
460
461
        #[test]
462
        fn test_cgroup_cpu_quota_divide_by_zero() {
463
            let cgroup = Cgroup::new(CgroupVersion::V1, join!(FIXTURES_CGROUPS, "zero-period"));
464
            assert!(cgroup.quota_us().is_some());
465
            assert_eq!(cgroup.period_us(), Some(0));
466
            assert_eq!(cgroup.cpu_quota(), None);
467
        }
468
469
        #[test]
470
        fn test_cgroup_cpu_quota_ceil() {
471
            let cgroup = Cgroup::new(CgroupVersion::V1, join!(FIXTURES_CGROUPS, "ceil"));
472
            assert_eq!(cgroup.cpu_quota(), Some(2));
473
        }
474
    }
475
476
    mod v2 {
477
        use super::super::{Cgroup, CgroupVersion, MountInfo, Subsys};
478
        use std::path::{Path, PathBuf};
479
480
        // `static_in_const` feature is not stable in Rust 1.13.
481
        static FIXTURES_PROC: &'static str = "fixtures/cgroups2/proc/cgroups";
482
483
        static FIXTURES_CGROUPS: &'static str = "fixtures/cgroups2/cgroups";
484
485
        macro_rules! join {
486
            ($base:expr, $($path:expr),+) => ({
487
                Path::new($base)
488
                    $(.join($path))+
489
            })
490
        }
491
492
        #[test]
493
        fn test_load_mountinfo() {
494
            // test only one optional fields
495
            let path = join!(FIXTURES_PROC, "mountinfo");
496
497
            let mnt_info = MountInfo::load_cpu(path, CgroupVersion::V2).unwrap();
498
499
            assert_eq!(mnt_info.root, "/");
500
            assert_eq!(mnt_info.mount_point, "/sys/fs/cgroup");
501
        }
502
503
        #[test]
504
        fn test_load_subsys() {
505
            let path = join!(FIXTURES_PROC, "cgroup");
506
507
            let subsys = Subsys::load_cpu(path).unwrap();
508
509
            assert_eq!(subsys.base, "/");
510
            assert_eq!(subsys.version, CgroupVersion::V2);
511
        }
512
513
        #[test]
514
        fn test_load_subsys_multi() {
515
            let path = join!(FIXTURES_PROC, "cgroup_multi");
516
517
            let subsys = Subsys::load_cpu(path).unwrap();
518
519
            assert_eq!(subsys.base, "/");
520
            assert_eq!(subsys.version, CgroupVersion::V1);
521
        }
522
523
        #[test]
524
        fn test_cgroup_mount() {
525
            let cases = &[
526
                ("/", "/sys/fs/cgroup/cpu", "/", Some("/sys/fs/cgroup/cpu")),
527
                (
528
                    "/docker/01abcd",
529
                    "/sys/fs/cgroup/cpu",
530
                    "/docker/01abcd",
531
                    Some("/sys/fs/cgroup/cpu"),
532
                ),
533
                (
534
                    "/docker/01abcd",
535
                    "/sys/fs/cgroup/cpu",
536
                    "/docker/01abcd/",
537
                    Some("/sys/fs/cgroup/cpu"),
538
                ),
539
                (
540
                    "/docker/01abcd",
541
                    "/sys/fs/cgroup/cpu",
542
                    "/docker/01abcd/large",
543
                    Some("/sys/fs/cgroup/cpu/large"),
544
                ),
545
                // fails
546
                ("/docker/01abcd", "/sys/fs/cgroup/cpu", "/", None),
547
                ("/docker/01abcd", "/sys/fs/cgroup/cpu", "/docker", None),
548
                ("/docker/01abcd", "/sys/fs/cgroup/cpu", "/elsewhere", None),
549
                (
550
                    "/docker/01abcd",
551
                    "/sys/fs/cgroup/cpu",
552
                    "/docker/01abcd-other-dir",
553
                    None,
554
                ),
555
            ];
556
557
            for &(root, mount_point, subsys, expected) in cases.iter() {
558
                let mnt_info = MountInfo {
559
                    version: CgroupVersion::V1,
560
                    root: root.into(),
561
                    mount_point: mount_point.into(),
562
                };
563
                let subsys = Subsys {
564
                    version: CgroupVersion::V1,
565
                    base: subsys.into(),
566
                };
567
568
                let actual = Cgroup::translate(mnt_info, subsys).map(|c| c.base);
569
                let expected = expected.map(PathBuf::from);
570
                assert_eq!(actual, expected);
571
            }
572
        }
573
574
        #[test]
575
        fn test_cgroup_cpu_quota() {
576
            let cgroup = Cgroup::new(CgroupVersion::V2, join!(FIXTURES_CGROUPS, "good"));
577
            assert_eq!(cgroup.cpu_quota(), Some(6));
578
        }
579
580
        #[test]
581
        fn test_cgroup_cpu_quota_divide_by_zero() {
582
            let cgroup = Cgroup::new(CgroupVersion::V2, join!(FIXTURES_CGROUPS, "zero-period"));
583
            let period = cgroup.max().map(|max| max.1);
584
585
            assert_eq!(period, Some(0));
586
            assert_eq!(cgroup.cpu_quota(), None);
587
        }
588
589
        #[test]
590
        fn test_cgroup_cpu_quota_ceil() {
591
            let cgroup = Cgroup::new(CgroupVersion::V2, join!(FIXTURES_CGROUPS, "ceil"));
592
            assert_eq!(cgroup.cpu_quota(), Some(2));
593
        }
594
    }
595
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.19.0/src/imp_std.rs
Line
Count
Source
1
// There's a lot of scary concurrent code in this module, but it is copied from
2
// `std::sync::Once` with two changes:
3
//   * no poisoning
4
//   * init function can fail
5
6
use std::{
7
    cell::{Cell, UnsafeCell},
8
    panic::{RefUnwindSafe, UnwindSafe},
9
    sync::atomic::{AtomicBool, AtomicPtr, Ordering},
10
    thread::{self, Thread},
11
};
12
13
#[derive(Debug)]
14
pub(crate) struct OnceCell<T> {
15
    // This `queue` field is the core of the implementation. It encodes two
16
    // pieces of information:
17
    //
18
    // * The current state of the cell (`INCOMPLETE`, `RUNNING`, `COMPLETE`)
19
    // * Linked list of threads waiting for the current cell.
20
    //
21
    // State is encoded in two low bits. Only `INCOMPLETE` and `RUNNING` states
22
    // allow waiters.
23
    queue: AtomicPtr<Waiter>,
24
    value: UnsafeCell<Option<T>>,
25
}
26
27
// Why do we need `T: Send`?
28
// Thread A creates a `OnceCell` and shares it with
29
// scoped thread B, which fills the cell, which is
30
// then destroyed by A. That is, destructor observes
31
// a sent value.
32
unsafe impl<T: Sync + Send> Sync for OnceCell<T> {}
33
unsafe impl<T: Send> Send for OnceCell<T> {}
34
35
impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceCell<T> {}
36
impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
37
38
impl<T> OnceCell<T> {
39
0
    pub(crate) const fn new() -> OnceCell<T> {
40
0
        OnceCell { queue: AtomicPtr::new(INCOMPLETE_PTR), value: UnsafeCell::new(None) }
41
0
    }
42
43
0
    pub(crate) const fn with_value(value: T) -> OnceCell<T> {
44
0
        OnceCell { queue: AtomicPtr::new(COMPLETE_PTR), value: UnsafeCell::new(Some(value)) }
45
0
    }
46
47
    /// Safety: synchronizes with store to value via Release/(Acquire|SeqCst).
48
    #[inline]
49
0
    pub(crate) fn is_initialized(&self) -> bool {
50
0
        // An `Acquire` load is enough because that makes all the initialization
51
0
        // operations visible to us, and, this being a fast path, weaker
52
0
        // ordering helps with performance. This `Acquire` synchronizes with
53
0
        // `SeqCst` operations on the slow path.
54
0
        self.queue.load(Ordering::Acquire) == COMPLETE_PTR
55
0
    }
Unexecuted instantiation: _RNvMs2_NtCs5GpVQlmD7AC_9once_cell3impINtB5_8OnceCellANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_E14is_initializedBV_
Unexecuted instantiation: _RNvMs2_NtCs5GpVQlmD7AC_9once_cell3impINtB5_8OnceCellpE14is_initializedB7_
56
57
    /// Safety: synchronizes with store to value via SeqCst read from state,
58
    /// writes value only once because we never get to INCOMPLETE state after a
59
    /// successful write.
60
    #[cold]
61
0
    pub(crate) fn initialize<F, E>(&self, f: F) -> Result<(), E>
62
0
    where
63
0
        F: FnOnce() -> Result<T, E>,
64
0
    {
65
0
        let mut f = Some(f);
66
0
        let mut res: Result<(), E> = Ok(());
67
0
        let slot: *mut Option<T> = self.value.get();
68
0
        initialize_or_wait(
69
0
            &self.queue,
70
0
            Some(&mut || {
71
0
                let f = unsafe { f.take().unwrap_unchecked() };
72
0
                match f() {
73
0
                    Ok(value) => {
74
0
                        unsafe { *slot = Some(value) };
75
0
                        true
76
                    }
77
0
                    Err(err) => {
78
0
                        res = Err(err);
79
0
                        false
80
                    }
81
                }
82
0
            }),
Unexecuted instantiation: _RNCINvMs2_NtCs5GpVQlmD7AC_9once_cell3impINtB8_8OnceCellANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_E10initializeNCINvMs4_NtBa_4syncINtB2a_8OnceCellBR_E11get_or_initNCNvMs9_B2a_INtB2a_4LazyBR_E5force0E0NtNvMs4_B2a_IB2l_pE11get_or_init4VoidE0BY_
Unexecuted instantiation: _RNCINvMs2_NtCs5GpVQlmD7AC_9once_cell3impINtB8_8OnceCellpE10initializeppE0Ba_
83
0
        );
84
0
        res
85
0
    }
Unexecuted instantiation: _RINvMs2_NtCs5GpVQlmD7AC_9once_cell3impINtB6_8OnceCellANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_E10initializeNCINvMs4_NtB8_4syncINtB28_8OnceCellBP_E11get_or_initNCNvMs9_B28_INtB28_4LazyBP_E5force0E0NtNvMs4_B28_IB2j_pE11get_or_init4VoidEBW_
Unexecuted instantiation: _RINvMs2_NtCs5GpVQlmD7AC_9once_cell3impINtB6_8OnceCellpE10initializeppEB8_
86
87
    #[cold]
88
0
    pub(crate) fn wait(&self) {
89
0
        initialize_or_wait(&self.queue, None);
90
0
    }
91
92
    /// Get the reference to the underlying value, without checking if the cell
93
    /// is initialized.
94
    ///
95
    /// # Safety
96
    ///
97
    /// Caller must ensure that the cell is in initialized state, and that
98
    /// the contents are acquired by (synchronized to) this thread.
99
0
    pub(crate) unsafe fn get_unchecked(&self) -> &T {
100
0
        debug_assert!(self.is_initialized());
101
0
        let slot = &*self.value.get();
102
0
        slot.as_ref().unwrap_unchecked()
103
0
    }
Unexecuted instantiation: _RNvMs2_NtCs5GpVQlmD7AC_9once_cell3impINtB5_8OnceCellANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_E13get_uncheckedBV_
Unexecuted instantiation: _RNvMs2_NtCs5GpVQlmD7AC_9once_cell3impINtB5_8OnceCellpE13get_uncheckedB7_
104
105
    /// Gets the mutable reference to the underlying value.
106
    /// Returns `None` if the cell is empty.
107
0
    pub(crate) fn get_mut(&mut self) -> Option<&mut T> {
108
0
        // Safe b/c we have a unique access.
109
0
        unsafe { &mut *self.value.get() }.as_mut()
110
0
    }
111
112
    /// Consumes this `OnceCell`, returning the wrapped value.
113
    /// Returns `None` if the cell was empty.
114
    #[inline]
115
0
    pub(crate) fn into_inner(self) -> Option<T> {
116
0
        // Because `into_inner` takes `self` by value, the compiler statically
117
0
        // verifies that it is not currently borrowed.
118
0
        // So, it is safe to move out `Option<T>`.
119
0
        self.value.into_inner()
120
0
    }
121
}
122
123
// Three states that a OnceCell can be in, encoded into the lower bits of `queue` in
124
// the OnceCell structure.
125
const INCOMPLETE: usize = 0x0;
126
const RUNNING: usize = 0x1;
127
const COMPLETE: usize = 0x2;
128
const INCOMPLETE_PTR: *mut Waiter = INCOMPLETE as *mut Waiter;
129
const COMPLETE_PTR: *mut Waiter = COMPLETE as *mut Waiter;
130
131
// Mask to learn about the state. All other bits are the queue of waiters if
132
// this is in the RUNNING state.
133
const STATE_MASK: usize = 0x3;
134
135
/// Representation of a node in the linked list of waiters in the RUNNING state.
136
/// A waiters is stored on the stack of the waiting threads.
137
#[repr(align(4))] // Ensure the two lower bits are free to use as state bits.
138
struct Waiter {
139
    thread: Cell<Option<Thread>>,
140
    signaled: AtomicBool,
141
    next: *mut Waiter,
142
}
143
144
/// Drains and notifies the queue of waiters on drop.
145
struct Guard<'a> {
146
    queue: &'a AtomicPtr<Waiter>,
147
    new_queue: *mut Waiter,
148
}
149
150
impl Drop for Guard<'_> {
151
0
    fn drop(&mut self) {
152
0
        let queue = self.queue.swap(self.new_queue, Ordering::AcqRel);
153
0
154
0
        let state = strict::addr(queue) & STATE_MASK;
155
0
        assert_eq!(state, RUNNING);
156
157
        unsafe {
158
0
            let mut waiter = strict::map_addr(queue, |q| q & !STATE_MASK);
159
0
            while !waiter.is_null() {
160
0
                let next = (*waiter).next;
161
0
                let thread = (*waiter).thread.take().unwrap();
162
0
                (*waiter).signaled.store(true, Ordering::Release);
163
0
                waiter = next;
164
0
                thread.unpark();
165
0
            }
166
        }
167
0
    }
168
}
169
170
// Corresponds to `std::sync::Once::call_inner`.
171
//
172
// Originally copied from std, but since modified to remove poisoning and to
173
// support wait.
174
//
175
// Note: this is intentionally monomorphic
176
#[inline(never)]
177
0
fn initialize_or_wait(queue: &AtomicPtr<Waiter>, mut init: Option<&mut dyn FnMut() -> bool>) {
178
0
    let mut curr_queue = queue.load(Ordering::Acquire);
179
180
    loop {
181
0
        let curr_state = strict::addr(curr_queue) & STATE_MASK;
182
0
        match (curr_state, &mut init) {
183
0
            (COMPLETE, _) => return,
184
0
            (INCOMPLETE, Some(init)) => {
185
0
                let exchange = queue.compare_exchange(
186
0
                    curr_queue,
187
0
                    strict::map_addr(curr_queue, |q| (q & !STATE_MASK) | RUNNING),
188
0
                    Ordering::Acquire,
189
0
                    Ordering::Acquire,
190
0
                );
191
0
                if let Err(new_queue) = exchange {
192
0
                    curr_queue = new_queue;
193
0
                    continue;
194
0
                }
195
0
                let mut guard = Guard { queue, new_queue: INCOMPLETE_PTR };
196
0
                if init() {
197
0
                    guard.new_queue = COMPLETE_PTR;
198
0
                }
199
0
                return;
200
            }
201
0
            (INCOMPLETE, None) | (RUNNING, _) => {
202
0
                wait(queue, curr_queue);
203
0
                curr_queue = queue.load(Ordering::Acquire);
204
0
            }
205
0
            _ => debug_assert!(false),
206
        }
207
    }
208
0
}
209
210
0
fn wait(queue: &AtomicPtr<Waiter>, mut curr_queue: *mut Waiter) {
211
0
    let curr_state = strict::addr(curr_queue) & STATE_MASK;
212
0
    loop {
213
0
        let node = Waiter {
214
0
            thread: Cell::new(Some(thread::current())),
215
0
            signaled: AtomicBool::new(false),
216
0
            next: strict::map_addr(curr_queue, |q| q & !STATE_MASK),
217
0
        };
218
0
        let me = &node as *const Waiter as *mut Waiter;
219
0
220
0
        let exchange = queue.compare_exchange(
221
0
            curr_queue,
222
0
            strict::map_addr(me, |q| q | curr_state),
223
0
            Ordering::Release,
224
0
            Ordering::Relaxed,
225
0
        );
226
0
        if let Err(new_queue) = exchange {
227
0
            if strict::addr(new_queue) & STATE_MASK != curr_state {
228
0
                return;
229
0
            }
230
0
            curr_queue = new_queue;
231
0
            continue;
232
0
        }
233
234
0
        while !node.signaled.load(Ordering::Acquire) {
235
0
            thread::park();
236
0
        }
237
0
        break;
238
    }
239
0
}
240
241
// Polyfill of strict provenance from https://crates.io/crates/sptr.
242
//
243
// Use free-standing function rather than a trait to keep things simple and
244
// avoid any potential conflicts with future stabile std API.
245
mod strict {
246
    #[must_use]
247
    #[inline]
248
0
    pub(crate) fn addr<T>(ptr: *mut T) -> usize
249
0
    where
250
0
        T: Sized,
251
0
    {
252
0
        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
253
0
        // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
254
0
        // provenance).
255
0
        unsafe { core::mem::transmute(ptr) }
256
0
    }
257
258
    #[must_use]
259
    #[inline]
260
0
    pub(crate) fn with_addr<T>(ptr: *mut T, addr: usize) -> *mut T
261
0
    where
262
0
        T: Sized,
263
0
    {
264
0
        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
265
0
        //
266
0
        // In the mean-time, this operation is defined to be "as if" it was
267
0
        // a wrapping_offset, so we can emulate it as such. This should properly
268
0
        // restore pointer provenance even under today's compiler.
269
0
        let self_addr = self::addr(ptr) as isize;
270
0
        let dest_addr = addr as isize;
271
0
        let offset = dest_addr.wrapping_sub(self_addr);
272
0
273
0
        // This is the canonical desugarring of this operation,
274
0
        // but `pointer::cast` was only stabilized in 1.38.
275
0
        // self.cast::<u8>().wrapping_offset(offset).cast::<T>()
276
0
        (ptr as *mut u8).wrapping_offset(offset) as *mut T
277
0
    }
278
279
    #[must_use]
280
    #[inline]
281
0
    pub(crate) fn map_addr<T>(ptr: *mut T, f: impl FnOnce(usize) -> usize) -> *mut T
282
0
    where
283
0
        T: Sized,
284
0
    {
285
0
        self::with_addr(ptr, f(addr(ptr)))
286
0
    }
Unexecuted instantiation: _RINvNtNtCs5GpVQlmD7AC_9once_cell3imp6strict8map_addrNtB4_6WaiterNCNvXs3_B4_NtB4_5GuardNtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4drop0EB6_
Unexecuted instantiation: _RINvNtNtCs5GpVQlmD7AC_9once_cell3imp6strict8map_addrNtB4_6WaiterNCNvB4_18initialize_or_wait0EB6_
Unexecuted instantiation: _RINvNtNtCs5GpVQlmD7AC_9once_cell3imp6strict8map_addrNtB4_6WaiterNCNvB4_4wait0EB6_
Unexecuted instantiation: _RINvNtNtCs5GpVQlmD7AC_9once_cell3imp6strict8map_addrNtB4_6WaiterNCNvB4_4waits_0EB6_
287
}
288
289
// These test are snatched from std as well.
290
#[cfg(test)]
291
mod tests {
292
    use std::panic;
293
    use std::{sync::mpsc::channel, thread};
294
295
    use super::OnceCell;
296
297
    impl<T> OnceCell<T> {
298
        fn init(&self, f: impl FnOnce() -> T) {
299
            enum Void {}
300
            let _ = self.initialize(|| Ok::<T, Void>(f()));
301
        }
302
    }
303
304
    #[test]
305
    fn smoke_once() {
306
        static O: OnceCell<()> = OnceCell::new();
307
        let mut a = 0;
308
        O.init(|| a += 1);
309
        assert_eq!(a, 1);
310
        O.init(|| a += 1);
311
        assert_eq!(a, 1);
312
    }
313
314
    #[test]
315
    fn stampede_once() {
316
        static O: OnceCell<()> = OnceCell::new();
317
        static mut RUN: bool = false;
318
319
        let (tx, rx) = channel();
320
        for _ in 0..10 {
321
            let tx = tx.clone();
322
            thread::spawn(move || {
323
                for _ in 0..4 {
324
                    thread::yield_now()
325
                }
326
                unsafe {
327
                    O.init(|| {
328
                        assert!(!RUN);
329
                        RUN = true;
330
                    });
331
                    assert!(RUN);
332
                }
333
                tx.send(()).unwrap();
334
            });
335
        }
336
337
        unsafe {
338
            O.init(|| {
339
                assert!(!RUN);
340
                RUN = true;
341
            });
342
            assert!(RUN);
343
        }
344
345
        for _ in 0..10 {
346
            rx.recv().unwrap();
347
        }
348
    }
349
350
    #[test]
351
    fn poison_bad() {
352
        static O: OnceCell<()> = OnceCell::new();
353
354
        // poison the once
355
        let t = panic::catch_unwind(|| {
356
            O.init(|| panic!());
357
        });
358
        assert!(t.is_err());
359
360
        // we can subvert poisoning, however
361
        let mut called = false;
362
        O.init(|| {
363
            called = true;
364
        });
365
        assert!(called);
366
367
        // once any success happens, we stop propagating the poison
368
        O.init(|| {});
369
    }
370
371
    #[test]
372
    fn wait_for_force_to_finish() {
373
        static O: OnceCell<()> = OnceCell::new();
374
375
        // poison the once
376
        let t = panic::catch_unwind(|| {
377
            O.init(|| panic!());
378
        });
379
        assert!(t.is_err());
380
381
        // make sure someone's waiting inside the once via a force
382
        let (tx1, rx1) = channel();
383
        let (tx2, rx2) = channel();
384
        let t1 = thread::spawn(move || {
385
            O.init(|| {
386
                tx1.send(()).unwrap();
387
                rx2.recv().unwrap();
388
            });
389
        });
390
391
        rx1.recv().unwrap();
392
393
        // put another waiter on the once
394
        let t2 = thread::spawn(|| {
395
            let mut called = false;
396
            O.init(|| {
397
                called = true;
398
            });
399
            assert!(!called);
400
        });
401
402
        tx2.send(()).unwrap();
403
404
        assert!(t1.join().is_ok());
405
        assert!(t2.join().is_ok());
406
    }
407
408
    #[test]
409
    #[cfg(target_pointer_width = "64")]
410
    fn test_size() {
411
        use std::mem::size_of;
412
413
        assert_eq!(size_of::<OnceCell<u32>>(), 4 * size_of::<u32>());
414
    }
415
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.19.0/src/lib.rs
Line
Count
Source
1
//! # Overview
2
//!
3
//! `once_cell` provides two new cell-like types, [`unsync::OnceCell`] and
4
//! [`sync::OnceCell`]. A `OnceCell` might store arbitrary non-`Copy` types, can
5
//! be assigned to at most once and provides direct access to the stored
6
//! contents. The core API looks *roughly* like this (and there's much more
7
//! inside, read on!):
8
//!
9
//! ```rust,ignore
10
//! impl<T> OnceCell<T> {
11
//!     const fn new() -> OnceCell<T> { ... }
12
//!     fn set(&self, value: T) -> Result<(), T> { ... }
13
//!     fn get(&self) -> Option<&T> { ... }
14
//! }
15
//! ```
16
//!
17
//! Note that, like with [`RefCell`] and [`Mutex`], the `set` method requires
18
//! only a shared reference. Because of the single assignment restriction `get`
19
//! can return a `&T` instead of `Ref<T>` or `MutexGuard<T>`.
20
//!
21
//! The `sync` flavor is thread-safe (that is, implements the [`Sync`] trait),
22
//! while the `unsync` one is not.
23
//!
24
//! [`unsync::OnceCell`]: unsync/struct.OnceCell.html
25
//! [`sync::OnceCell`]: sync/struct.OnceCell.html
26
//! [`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
27
//! [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
28
//! [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
29
//!
30
//! # Recipes
31
//!
32
//! `OnceCell` might be useful for a variety of patterns.
33
//!
34
//! ## Safe Initialization of Global Data
35
//!
36
//! ```rust
37
//! use std::{env, io};
38
//!
39
//! use once_cell::sync::OnceCell;
40
//!
41
//! #[derive(Debug)]
42
//! pub struct Logger {
43
//!     // ...
44
//! }
45
//! static INSTANCE: OnceCell<Logger> = OnceCell::new();
46
//!
47
//! impl Logger {
48
//!     pub fn global() -> &'static Logger {
49
//!         INSTANCE.get().expect("logger is not initialized")
50
//!     }
51
//!
52
//!     fn from_cli(args: env::Args) -> Result<Logger, std::io::Error> {
53
//!        // ...
54
//! #      Ok(Logger {})
55
//!     }
56
//! }
57
//!
58
//! fn main() {
59
//!     let logger = Logger::from_cli(env::args()).unwrap();
60
//!     INSTANCE.set(logger).unwrap();
61
//!     // use `Logger::global()` from now on
62
//! }
63
//! ```
64
//!
65
//! ## Lazy Initialized Global Data
66
//!
67
//! This is essentially the `lazy_static!` macro, but without a macro.
68
//!
69
//! ```rust
70
//! use std::{sync::Mutex, collections::HashMap};
71
//!
72
//! use once_cell::sync::OnceCell;
73
//!
74
//! fn global_data() -> &'static Mutex<HashMap<i32, String>> {
75
//!     static INSTANCE: OnceCell<Mutex<HashMap<i32, String>>> = OnceCell::new();
76
//!     INSTANCE.get_or_init(|| {
77
//!         let mut m = HashMap::new();
78
//!         m.insert(13, "Spica".to_string());
79
//!         m.insert(74, "Hoyten".to_string());
80
//!         Mutex::new(m)
81
//!     })
82
//! }
83
//! ```
84
//!
85
//! There are also the [`sync::Lazy`] and [`unsync::Lazy`] convenience types to
86
//! streamline this pattern:
87
//!
88
//! ```rust
89
//! use std::{sync::Mutex, collections::HashMap};
90
//! use once_cell::sync::Lazy;
91
//!
92
//! static GLOBAL_DATA: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| {
93
//!     let mut m = HashMap::new();
94
//!     m.insert(13, "Spica".to_string());
95
//!     m.insert(74, "Hoyten".to_string());
96
//!     Mutex::new(m)
97
//! });
98
//!
99
//! fn main() {
100
//!     println!("{:?}", GLOBAL_DATA.lock().unwrap());
101
//! }
102
//! ```
103
//!
104
//! Note that the variable that holds `Lazy` is declared as `static`, *not*
105
//! `const`. This is important: using `const` instead compiles, but works wrong.
106
//!
107
//! [`sync::Lazy`]: sync/struct.Lazy.html
108
//! [`unsync::Lazy`]: unsync/struct.Lazy.html
109
//!
110
//! ## General purpose lazy evaluation
111
//!
112
//! Unlike `lazy_static!`, `Lazy` works with local variables.
113
//!
114
//! ```rust
115
//! use once_cell::unsync::Lazy;
116
//!
117
//! fn main() {
118
//!     let ctx = vec![1, 2, 3];
119
//!     let thunk = Lazy::new(|| {
120
//!         ctx.iter().sum::<i32>()
121
//!     });
122
//!     assert_eq!(*thunk, 6);
123
//! }
124
//! ```
125
//!
126
//! If you need a lazy field in a struct, you probably should use `OnceCell`
127
//! directly, because that will allow you to access `self` during
128
//! initialization.
129
//!
130
//! ```rust
131
//! use std::{fs, path::PathBuf};
132
//!
133
//! use once_cell::unsync::OnceCell;
134
//!
135
//! struct Ctx {
136
//!     config_path: PathBuf,
137
//!     config: OnceCell<String>,
138
//! }
139
//!
140
//! impl Ctx {
141
//!     pub fn get_config(&self) -> Result<&str, std::io::Error> {
142
//!         let cfg = self.config.get_or_try_init(|| {
143
//!             fs::read_to_string(&self.config_path)
144
//!         })?;
145
//!         Ok(cfg.as_str())
146
//!     }
147
//! }
148
//! ```
149
//!
150
//! ## Lazily Compiled Regex
151
//!
152
//! This is a `regex!` macro which takes a string literal and returns an
153
//! *expression* that evaluates to a `&'static Regex`:
154
//!
155
//! ```
156
//! macro_rules! regex {
157
//!     ($re:literal $(,)?) => {{
158
//!         static RE: once_cell::sync::OnceCell<regex::Regex> = once_cell::sync::OnceCell::new();
159
//!         RE.get_or_init(|| regex::Regex::new($re).unwrap())
160
//!     }};
161
//! }
162
//! ```
163
//!
164
//! This macro can be useful to avoid the "compile regex on every loop
165
//! iteration" problem.
166
//!
167
//! ## Runtime `include_bytes!`
168
//!
169
//! The `include_bytes` macro is useful to include test resources, but it slows
170
//! down test compilation a lot. An alternative is to load the resources at
171
//! runtime:
172
//!
173
//! ```
174
//! use std::path::Path;
175
//!
176
//! use once_cell::sync::OnceCell;
177
//!
178
//! pub struct TestResource {
179
//!     path: &'static str,
180
//!     cell: OnceCell<Vec<u8>>,
181
//! }
182
//!
183
//! impl TestResource {
184
//!     pub const fn new(path: &'static str) -> TestResource {
185
//!         TestResource { path, cell: OnceCell::new() }
186
//!     }
187
//!     pub fn bytes(&self) -> &[u8] {
188
//!         self.cell.get_or_init(|| {
189
//!             let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
190
//!             let path = Path::new(dir.as_str()).join(self.path);
191
//!             std::fs::read(&path).unwrap_or_else(|_err| {
192
//!                 panic!("failed to load test resource: {}", path.display())
193
//!             })
194
//!         }).as_slice()
195
//!     }
196
//! }
197
//!
198
//! static TEST_IMAGE: TestResource = TestResource::new("test_data/lena.png");
199
//!
200
//! #[test]
201
//! fn test_sobel_filter() {
202
//!     let rgb: &[u8] = TEST_IMAGE.bytes();
203
//!     // ...
204
//! # drop(rgb);
205
//! }
206
//! ```
207
//!
208
//! ## `lateinit`
209
//!
210
//! `LateInit` type for delayed initialization. It is reminiscent of Kotlin's
211
//! `lateinit` keyword and allows construction of cyclic data structures:
212
//!
213
//!
214
//! ```
215
//! use once_cell::sync::OnceCell;
216
//!
217
//! pub struct LateInit<T> { cell: OnceCell<T> }
218
//!
219
//! impl<T> LateInit<T> {
220
//!     pub fn init(&self, value: T) {
221
//!         assert!(self.cell.set(value).is_ok())
222
//!     }
223
//! }
224
//!
225
//! impl<T> Default for LateInit<T> {
226
//!     fn default() -> Self { LateInit { cell: OnceCell::default() } }
227
//! }
228
//!
229
//! impl<T> std::ops::Deref for LateInit<T> {
230
//!     type Target = T;
231
//!     fn deref(&self) -> &T {
232
//!         self.cell.get().unwrap()
233
//!     }
234
//! }
235
//!
236
//! #[derive(Default)]
237
//! struct A<'a> {
238
//!     b: LateInit<&'a B<'a>>,
239
//! }
240
//!
241
//! #[derive(Default)]
242
//! struct B<'a> {
243
//!     a: LateInit<&'a A<'a>>
244
//! }
245
//!
246
//!
247
//! fn build_cycle() {
248
//!     let a = A::default();
249
//!     let b = B::default();
250
//!     a.b.init(&b);
251
//!     b.a.init(&a);
252
//!
253
//!     let _a = &a.b.a.b.a;
254
//! }
255
//! ```
256
//!
257
//! # Comparison with std
258
//!
259
//! |`!Sync` types         | Access Mode            | Drawbacks                                     |
260
//! |----------------------|------------------------|-----------------------------------------------|
261
//! |`Cell<T>`             | `T`                    | requires `T: Copy` for `get`                  |
262
//! |`RefCell<T>`          | `RefMut<T>` / `Ref<T>` | may panic at runtime                          |
263
//! |`unsync::OnceCell<T>` | `&T`                   | assignable only once                          |
264
//!
265
//! |`Sync` types          | Access Mode            | Drawbacks                                     |
266
//! |----------------------|------------------------|-----------------------------------------------|
267
//! |`AtomicT`             | `T`                    | works only with certain `Copy` types          |
268
//! |`Mutex<T>`            | `MutexGuard<T>`        | may deadlock at runtime, may block the thread |
269
//! |`sync::OnceCell<T>`   | `&T`                   | assignable only once, may block the thread    |
270
//!
271
//! Technically, calling `get_or_init` will also cause a panic or a deadlock if
272
//! it recursively calls itself. However, because the assignment can happen only
273
//! once, such cases should be more rare than equivalents with `RefCell` and
274
//! `Mutex`.
275
//!
276
//! # Minimum Supported `rustc` Version
277
//!
278
//! If only the `std`, `alloc`, or `race` features are enabled, MSRV will be
279
//! updated conservatively, supporting at least latest 8 versions of the compiler.
280
//! When using other features, like `parking_lot`, MSRV might be updated more
281
//! frequently, up to the latest stable. In both cases, increasing MSRV is *not*
282
//! considered a semver-breaking change and requires only a minor version bump.
283
//!
284
//! # Implementation details
285
//!
286
//! The implementation is based on the
287
//! [`lazy_static`](https://github.com/rust-lang-nursery/lazy-static.rs/) and
288
//! [`lazy_cell`](https://github.com/indiv0/lazycell/) crates and
289
//! [`std::sync::Once`]. In some sense, `once_cell` just streamlines and unifies
290
//! those APIs.
291
//!
292
//! To implement a sync flavor of `OnceCell`, this crates uses either a custom
293
//! re-implementation of `std::sync::Once` or `parking_lot::Mutex`. This is
294
//! controlled by the `parking_lot` feature (disabled by default). Performance
295
//! is the same for both cases, but the `parking_lot` based `OnceCell<T>` is
296
//! smaller by up to 16 bytes.
297
//!
298
//! This crate uses `unsafe`.
299
//!
300
//! [`std::sync::Once`]: https://doc.rust-lang.org/std/sync/struct.Once.html
301
//!
302
//! # F.A.Q.
303
//!
304
//! **Should I use the sync or unsync flavor?**
305
//!
306
//! Because Rust compiler checks thread safety for you, it's impossible to
307
//! accidentally use `unsync` where `sync` is required. So, use `unsync` in
308
//! single-threaded code and `sync` in multi-threaded. It's easy to switch
309
//! between the two if code becomes multi-threaded later.
310
//!
311
//! At the moment, `unsync` has an additional benefit that reentrant
312
//! initialization causes a panic, which might be easier to debug than a
313
//! deadlock.
314
//!
315
//! **Does this crate support async?**
316
//!
317
//! No, but you can use
318
//! [`async_once_cell`](https://crates.io/crates/async_once_cell) instead.
319
//!
320
//! **Does this crate support `no_std`?**
321
//!
322
//! Yes, but with caveats. `OnceCell` is a synchronization primitive which
323
//! _semantically_ relies on blocking. `OnceCell` guarantees that at most one
324
//! `f` will be called to compute the value. If two threads of execution call
325
//! `get_or_init` concurrently, one of them has to wait.
326
//!
327
//! Waiting fundamentally requires OS support. Execution environment needs to
328
//! understand who waits on whom to prevent deadlocks due to priority inversion.
329
//! You _could_ make code to compile by blindly using pure spinlocks, but the
330
//! runtime behavior would be subtly wrong.
331
//!
332
//! Given these constraints, `once_cell` provides the following options:
333
//!
334
//! - The `race` module provides similar, but distinct synchronization primitive
335
//!   which is compatible with `no_std`. With `race`, the `f` function can be
336
//!   called multiple times by different threads, but only one thread will win
337
//!   to install the value.
338
//! - `critical-section` feature (with a `-`, not `_`) uses `critical_section`
339
//!   to implement blocking.
340
//!
341
//! **Can I bring my own mutex?**
342
//!
343
//! There is [generic_once_cell](https://crates.io/crates/generic_once_cell) to
344
//! allow just that.
345
//!
346
//! **Should I use `std::cell::OnceCell`, `once_cell`, or `lazy_static`?**
347
//!
348
//! If you can use `std` version (your MSRV is at least 1.70, and you don't need
349
//! extra features `once_cell` provides), use `std`. Otherwise, use `once_cell`.
350
//! Don't use `lazy_static`.
351
//!
352
//! # Related crates
353
//!
354
//! * Most of this crate's functionality is available in `std` starting with
355
//!   Rust 1.70. See `std::cell::OnceCell` and `std::sync::OnceLock`.
356
//! * [double-checked-cell](https://github.com/niklasf/double-checked-cell)
357
//! * [lazy-init](https://crates.io/crates/lazy-init)
358
//! * [lazycell](https://crates.io/crates/lazycell)
359
//! * [mitochondria](https://crates.io/crates/mitochondria)
360
//! * [lazy_static](https://crates.io/crates/lazy_static)
361
//! * [async_once_cell](https://crates.io/crates/async_once_cell)
362
//! * [generic_once_cell](https://crates.io/crates/generic_once_cell) (bring
363
//!   your own mutex)
364
365
#![cfg_attr(not(feature = "std"), no_std)]
366
367
#[cfg(feature = "alloc")]
368
extern crate alloc;
369
370
#[cfg(all(feature = "critical-section", not(feature = "std")))]
371
#[path = "imp_cs.rs"]
372
mod imp;
373
374
#[cfg(all(feature = "std", feature = "parking_lot"))]
375
#[path = "imp_pl.rs"]
376
mod imp;
377
378
#[cfg(all(feature = "std", not(feature = "parking_lot")))]
379
#[path = "imp_std.rs"]
380
mod imp;
381
382
/// Single-threaded version of `OnceCell`.
383
pub mod unsync {
384
    use core::{
385
        cell::{Cell, UnsafeCell},
386
        fmt, mem,
387
        ops::{Deref, DerefMut},
388
        panic::{RefUnwindSafe, UnwindSafe},
389
    };
390
391
    /// A cell which can be written to only once. It is not thread safe.
392
    ///
393
    /// Unlike [`std::cell::RefCell`], a `OnceCell` provides simple `&`
394
    /// references to the contents.
395
    ///
396
    /// [`std::cell::RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
397
    ///
398
    /// # Example
399
    /// ```
400
    /// use once_cell::unsync::OnceCell;
401
    ///
402
    /// let cell = OnceCell::new();
403
    /// assert!(cell.get().is_none());
404
    ///
405
    /// let value: &String = cell.get_or_init(|| {
406
    ///     "Hello, World!".to_string()
407
    /// });
408
    /// assert_eq!(value, "Hello, World!");
409
    /// assert!(cell.get().is_some());
410
    /// ```
411
    pub struct OnceCell<T> {
412
        // Invariant: written to at most once.
413
        inner: UnsafeCell<Option<T>>,
414
    }
415
416
    // Similarly to a `Sync` bound on `sync::OnceCell`, we can use
417
    // `&unsync::OnceCell` to sneak a `T` through `catch_unwind`,
418
    // by initializing the cell in closure and extracting the value in the
419
    // `Drop`.
420
    impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceCell<T> {}
421
    impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
422
423
    impl<T> Default for OnceCell<T> {
424
0
        fn default() -> Self {
425
0
            Self::new()
426
0
        }
427
    }
428
429
    impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
430
0
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
431
0
            match self.get() {
432
0
                Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
433
0
                None => f.write_str("OnceCell(Uninit)"),
434
            }
435
0
        }
436
    }
437
438
    impl<T: Clone> Clone for OnceCell<T> {
439
0
        fn clone(&self) -> OnceCell<T> {
440
0
            match self.get() {
441
0
                Some(value) => OnceCell::with_value(value.clone()),
442
0
                None => OnceCell::new(),
443
            }
444
0
        }
445
446
0
        fn clone_from(&mut self, source: &Self) {
447
0
            match (self.get_mut(), source.get()) {
448
0
                (Some(this), Some(source)) => this.clone_from(source),
449
0
                _ => *self = source.clone(),
450
            }
451
0
        }
452
    }
453
454
    impl<T: PartialEq> PartialEq for OnceCell<T> {
455
0
        fn eq(&self, other: &Self) -> bool {
456
0
            self.get() == other.get()
457
0
        }
458
    }
459
460
    impl<T: Eq> Eq for OnceCell<T> {}
461
462
    impl<T> From<T> for OnceCell<T> {
463
0
        fn from(value: T) -> Self {
464
0
            OnceCell::with_value(value)
465
0
        }
466
    }
467
468
    impl<T> OnceCell<T> {
469
        /// Creates a new empty cell.
470
0
        pub const fn new() -> OnceCell<T> {
471
0
            OnceCell { inner: UnsafeCell::new(None) }
472
0
        }
473
474
        /// Creates a new initialized cell.
475
0
        pub const fn with_value(value: T) -> OnceCell<T> {
476
0
            OnceCell { inner: UnsafeCell::new(Some(value)) }
477
0
        }
478
479
        /// Gets a reference to the underlying value.
480
        ///
481
        /// Returns `None` if the cell is empty.
482
        #[inline]
483
0
        pub fn get(&self) -> Option<&T> {
484
0
            // Safe due to `inner`'s invariant of being written to at most once.
485
0
            // Had multiple writes to `inner` been allowed, a reference to the
486
0
            // value we return now would become dangling by a write of a
487
0
            // different value later.
488
0
            unsafe { &*self.inner.get() }.as_ref()
489
0
        }
490
491
        /// Gets a mutable reference to the underlying value.
492
        ///
493
        /// Returns `None` if the cell is empty.
494
        ///
495
        /// This method is allowed to violate the invariant of writing to a `OnceCell`
496
        /// at most once because it requires `&mut` access to `self`. As with all
497
        /// interior mutability, `&mut` access permits arbitrary modification:
498
        ///
499
        /// ```
500
        /// use once_cell::unsync::OnceCell;
501
        ///
502
        /// let mut cell: OnceCell<u32> = OnceCell::new();
503
        /// cell.set(92).unwrap();
504
        /// *cell.get_mut().unwrap() = 93;
505
        /// assert_eq!(cell.get(), Some(&93));
506
        /// ```
507
        #[inline]
508
0
        pub fn get_mut(&mut self) -> Option<&mut T> {
509
0
            // Safe because we have unique access
510
0
            unsafe { &mut *self.inner.get() }.as_mut()
511
0
        }
512
513
        /// Sets the contents of this cell to `value`.
514
        ///
515
        /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
516
        /// full.
517
        ///
518
        /// # Example
519
        /// ```
520
        /// use once_cell::unsync::OnceCell;
521
        ///
522
        /// let cell = OnceCell::new();
523
        /// assert!(cell.get().is_none());
524
        ///
525
        /// assert_eq!(cell.set(92), Ok(()));
526
        /// assert_eq!(cell.set(62), Err(62));
527
        ///
528
        /// assert!(cell.get().is_some());
529
        /// ```
530
0
        pub fn set(&self, value: T) -> Result<(), T> {
531
0
            match self.try_insert(value) {
532
0
                Ok(_) => Ok(()),
533
0
                Err((_, value)) => Err(value),
534
            }
535
0
        }
536
537
        /// Like [`set`](Self::set), but also returns a reference to the final cell value.
538
        ///
539
        /// # Example
540
        /// ```
541
        /// use once_cell::unsync::OnceCell;
542
        ///
543
        /// let cell = OnceCell::new();
544
        /// assert!(cell.get().is_none());
545
        ///
546
        /// assert_eq!(cell.try_insert(92), Ok(&92));
547
        /// assert_eq!(cell.try_insert(62), Err((&92, 62)));
548
        ///
549
        /// assert!(cell.get().is_some());
550
        /// ```
551
0
        pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
552
0
            if let Some(old) = self.get() {
553
0
                return Err((old, value));
554
0
            }
555
0
556
0
            let slot = unsafe { &mut *self.inner.get() };
557
0
            // This is the only place where we set the slot, no races
558
0
            // due to reentrancy/concurrency are possible, and we've
559
0
            // checked that slot is currently `None`, so this write
560
0
            // maintains the `inner`'s invariant.
561
0
            *slot = Some(value);
562
0
            Ok(unsafe { slot.as_ref().unwrap_unchecked() })
563
0
        }
564
565
        /// Gets the contents of the cell, initializing it with `f`
566
        /// if the cell was empty.
567
        ///
568
        /// # Panics
569
        ///
570
        /// If `f` panics, the panic is propagated to the caller, and the cell
571
        /// remains uninitialized.
572
        ///
573
        /// It is an error to reentrantly initialize the cell from `f`. Doing
574
        /// so results in a panic.
575
        ///
576
        /// # Example
577
        /// ```
578
        /// use once_cell::unsync::OnceCell;
579
        ///
580
        /// let cell = OnceCell::new();
581
        /// let value = cell.get_or_init(|| 92);
582
        /// assert_eq!(value, &92);
583
        /// let value = cell.get_or_init(|| unreachable!());
584
        /// assert_eq!(value, &92);
585
        /// ```
586
0
        pub fn get_or_init<F>(&self, f: F) -> &T
587
0
        where
588
0
            F: FnOnce() -> T,
589
0
        {
590
            enum Void {}
591
0
            match self.get_or_try_init(|| Ok::<T, Void>(f())) {
592
0
                Ok(val) => val,
593
0
                Err(void) => match void {},
594
0
            }
595
0
        }
596
597
        /// Gets the contents of the cell, initializing it with `f` if
598
        /// the cell was empty. If the cell was empty and `f` failed, an
599
        /// error is returned.
600
        ///
601
        /// # Panics
602
        ///
603
        /// If `f` panics, the panic is propagated to the caller, and the cell
604
        /// remains uninitialized.
605
        ///
606
        /// It is an error to reentrantly initialize the cell from `f`. Doing
607
        /// so results in a panic.
608
        ///
609
        /// # Example
610
        /// ```
611
        /// use once_cell::unsync::OnceCell;
612
        ///
613
        /// let cell = OnceCell::new();
614
        /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
615
        /// assert!(cell.get().is_none());
616
        /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
617
        ///     Ok(92)
618
        /// });
619
        /// assert_eq!(value, Ok(&92));
620
        /// assert_eq!(cell.get(), Some(&92))
621
        /// ```
622
0
        pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
623
0
        where
624
0
            F: FnOnce() -> Result<T, E>,
625
0
        {
626
0
            if let Some(val) = self.get() {
627
0
                return Ok(val);
628
0
            }
629
0
            let val = f()?;
630
            // Note that *some* forms of reentrant initialization might lead to
631
            // UB (see `reentrant_init` test). I believe that just removing this
632
            // `assert`, while keeping `set/get` would be sound, but it seems
633
            // better to panic, rather than to silently use an old value.
634
0
            assert!(self.set(val).is_ok(), "reentrant init");
635
0
            Ok(unsafe { self.get().unwrap_unchecked() })
636
0
        }
637
638
        /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
639
        ///
640
        /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized.
641
        ///
642
        /// # Examples
643
        ///
644
        /// ```
645
        /// use once_cell::unsync::OnceCell;
646
        ///
647
        /// let mut cell: OnceCell<String> = OnceCell::new();
648
        /// assert_eq!(cell.take(), None);
649
        ///
650
        /// let mut cell = OnceCell::new();
651
        /// cell.set("hello".to_string()).unwrap();
652
        /// assert_eq!(cell.take(), Some("hello".to_string()));
653
        /// assert_eq!(cell.get(), None);
654
        /// ```
655
        ///
656
        /// This method is allowed to violate the invariant of writing to a `OnceCell`
657
        /// at most once because it requires `&mut` access to `self`. As with all
658
        /// interior mutability, `&mut` access permits arbitrary modification:
659
        ///
660
        /// ```
661
        /// use once_cell::unsync::OnceCell;
662
        ///
663
        /// let mut cell: OnceCell<u32> = OnceCell::new();
664
        /// cell.set(92).unwrap();
665
        /// cell = OnceCell::new();
666
        /// ```
667
0
        pub fn take(&mut self) -> Option<T> {
668
0
            mem::take(self).into_inner()
669
0
        }
670
671
        /// Consumes the `OnceCell`, returning the wrapped value.
672
        ///
673
        /// Returns `None` if the cell was empty.
674
        ///
675
        /// # Examples
676
        ///
677
        /// ```
678
        /// use once_cell::unsync::OnceCell;
679
        ///
680
        /// let cell: OnceCell<String> = OnceCell::new();
681
        /// assert_eq!(cell.into_inner(), None);
682
        ///
683
        /// let cell = OnceCell::new();
684
        /// cell.set("hello".to_string()).unwrap();
685
        /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
686
        /// ```
687
0
        pub fn into_inner(self) -> Option<T> {
688
0
            // Because `into_inner` takes `self` by value, the compiler statically verifies
689
0
            // that it is not currently borrowed. So it is safe to move out `Option<T>`.
690
0
            self.inner.into_inner()
691
0
        }
692
    }
693
694
    /// A value which is initialized on the first access.
695
    ///
696
    /// # Example
697
    /// ```
698
    /// use once_cell::unsync::Lazy;
699
    ///
700
    /// let lazy: Lazy<i32> = Lazy::new(|| {
701
    ///     println!("initializing");
702
    ///     92
703
    /// });
704
    /// println!("ready");
705
    /// println!("{}", *lazy);
706
    /// println!("{}", *lazy);
707
    ///
708
    /// // Prints:
709
    /// //   ready
710
    /// //   initializing
711
    /// //   92
712
    /// //   92
713
    /// ```
714
    pub struct Lazy<T, F = fn() -> T> {
715
        cell: OnceCell<T>,
716
        init: Cell<Option<F>>,
717
    }
718
719
    impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where OnceCell<T>: RefUnwindSafe {}
720
721
    impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
722
0
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
723
0
            f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
724
0
        }
725
    }
726
727
    impl<T, F> Lazy<T, F> {
728
        /// Creates a new lazy value with the given initializing function.
729
        ///
730
        /// # Example
731
        /// ```
732
        /// # fn main() {
733
        /// use once_cell::unsync::Lazy;
734
        ///
735
        /// let hello = "Hello, World!".to_string();
736
        ///
737
        /// let lazy = Lazy::new(|| hello.to_uppercase());
738
        ///
739
        /// assert_eq!(&*lazy, "HELLO, WORLD!");
740
        /// # }
741
        /// ```
742
0
        pub const fn new(init: F) -> Lazy<T, F> {
743
0
            Lazy { cell: OnceCell::new(), init: Cell::new(Some(init)) }
744
0
        }
745
746
        /// Consumes this `Lazy` returning the stored value.
747
        ///
748
        /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
749
0
        pub fn into_value(this: Lazy<T, F>) -> Result<T, F> {
750
0
            let cell = this.cell;
751
0
            let init = this.init;
752
0
            cell.into_inner().ok_or_else(|| {
753
0
                init.take().unwrap_or_else(|| panic!("Lazy instance has previously been poisoned"))
754
0
            })
755
0
        }
756
    }
757
758
    impl<T, F: FnOnce() -> T> Lazy<T, F> {
759
        /// Forces the evaluation of this lazy value and returns a reference to
760
        /// the result.
761
        ///
762
        /// This is equivalent to the `Deref` impl, but is explicit.
763
        ///
764
        /// # Example
765
        /// ```
766
        /// use once_cell::unsync::Lazy;
767
        ///
768
        /// let lazy = Lazy::new(|| 92);
769
        ///
770
        /// assert_eq!(Lazy::force(&lazy), &92);
771
        /// assert_eq!(&*lazy, &92);
772
        /// ```
773
0
        pub fn force(this: &Lazy<T, F>) -> &T {
774
0
            this.cell.get_or_init(|| match this.init.take() {
775
0
                Some(f) => f(),
776
0
                None => panic!("Lazy instance has previously been poisoned"),
777
0
            })
778
0
        }
779
780
        /// Forces the evaluation of this lazy value and returns a mutable reference to
781
        /// the result.
782
        ///
783
        /// This is equivalent to the `DerefMut` impl, but is explicit.
784
        ///
785
        /// # Example
786
        /// ```
787
        /// use once_cell::unsync::Lazy;
788
        ///
789
        /// let mut lazy = Lazy::new(|| 92);
790
        ///
791
        /// assert_eq!(Lazy::force_mut(&mut lazy), &92);
792
        /// assert_eq!(*lazy, 92);
793
        /// ```
794
0
        pub fn force_mut(this: &mut Lazy<T, F>) -> &mut T {
795
0
            if this.cell.get_mut().is_none() {
796
0
                let value = match this.init.get_mut().take() {
797
0
                    Some(f) => f(),
798
0
                    None => panic!("Lazy instance has previously been poisoned"),
799
                };
800
0
                this.cell = OnceCell::with_value(value);
801
0
            }
802
0
            this.cell.get_mut().unwrap_or_else(|| unreachable!())
803
0
        }
804
805
        /// Gets the reference to the result of this lazy value if
806
        /// it was initialized, otherwise returns `None`.
807
        ///
808
        /// # Example
809
        /// ```
810
        /// use once_cell::unsync::Lazy;
811
        ///
812
        /// let lazy = Lazy::new(|| 92);
813
        ///
814
        /// assert_eq!(Lazy::get(&lazy), None);
815
        /// assert_eq!(&*lazy, &92);
816
        /// assert_eq!(Lazy::get(&lazy), Some(&92));
817
        /// ```
818
0
        pub fn get(this: &Lazy<T, F>) -> Option<&T> {
819
0
            this.cell.get()
820
0
        }
821
822
        /// Gets the mutable reference to the result of this lazy value if
823
        /// it was initialized, otherwise returns `None`.
824
        ///
825
        /// # Example
826
        /// ```
827
        /// use once_cell::unsync::Lazy;
828
        ///
829
        /// let mut lazy = Lazy::new(|| 92);
830
        ///
831
        /// assert_eq!(Lazy::get_mut(&mut lazy), None);
832
        /// assert_eq!(*lazy, 92);
833
        /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92));
834
        /// ```
835
0
        pub fn get_mut(this: &mut Lazy<T, F>) -> Option<&mut T> {
836
0
            this.cell.get_mut()
837
0
        }
838
    }
839
840
    impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
841
        type Target = T;
842
0
        fn deref(&self) -> &T {
843
0
            Lazy::force(self)
844
0
        }
845
    }
846
847
    impl<T, F: FnOnce() -> T> DerefMut for Lazy<T, F> {
848
0
        fn deref_mut(&mut self) -> &mut T {
849
0
            Lazy::force_mut(self)
850
0
        }
851
    }
852
853
    impl<T: Default> Default for Lazy<T> {
854
        /// Creates a new lazy value using `Default` as the initializing function.
855
0
        fn default() -> Lazy<T> {
856
0
            Lazy::new(T::default)
857
0
        }
858
    }
859
}
860
861
/// Thread-safe, blocking version of `OnceCell`.
862
#[cfg(any(feature = "std", feature = "critical-section"))]
863
pub mod sync {
864
    use core::{
865
        cell::Cell,
866
        fmt, mem,
867
        ops::{Deref, DerefMut},
868
        panic::RefUnwindSafe,
869
    };
870
871
    use super::imp::OnceCell as Imp;
872
873
    /// A thread-safe cell which can be written to only once.
874
    ///
875
    /// `OnceCell` provides `&` references to the contents without RAII guards.
876
    ///
877
    /// Reading a non-`None` value out of `OnceCell` establishes a
878
    /// happens-before relationship with a corresponding write. For example, if
879
    /// thread A initializes the cell with `get_or_init(f)`, and thread B
880
    /// subsequently reads the result of this call, B also observes all the side
881
    /// effects of `f`.
882
    ///
883
    /// # Example
884
    /// ```
885
    /// use once_cell::sync::OnceCell;
886
    ///
887
    /// static CELL: OnceCell<String> = OnceCell::new();
888
    /// assert!(CELL.get().is_none());
889
    ///
890
    /// std::thread::spawn(|| {
891
    ///     let value: &String = CELL.get_or_init(|| {
892
    ///         "Hello, World!".to_string()
893
    ///     });
894
    ///     assert_eq!(value, "Hello, World!");
895
    /// }).join().unwrap();
896
    ///
897
    /// let value: Option<&String> = CELL.get();
898
    /// assert!(value.is_some());
899
    /// assert_eq!(value.unwrap().as_str(), "Hello, World!");
900
    /// ```
901
    pub struct OnceCell<T>(Imp<T>);
902
903
    impl<T> Default for OnceCell<T> {
904
0
        fn default() -> OnceCell<T> {
905
0
            OnceCell::new()
906
0
        }
907
    }
908
909
    impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
910
0
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
911
0
            match self.get() {
912
0
                Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
913
0
                None => f.write_str("OnceCell(Uninit)"),
914
            }
915
0
        }
916
    }
917
918
    impl<T: Clone> Clone for OnceCell<T> {
919
0
        fn clone(&self) -> OnceCell<T> {
920
0
            match self.get() {
921
0
                Some(value) => Self::with_value(value.clone()),
922
0
                None => Self::new(),
923
            }
924
0
        }
925
926
0
        fn clone_from(&mut self, source: &Self) {
927
0
            match (self.get_mut(), source.get()) {
928
0
                (Some(this), Some(source)) => this.clone_from(source),
929
0
                _ => *self = source.clone(),
930
            }
931
0
        }
932
    }
933
934
    impl<T> From<T> for OnceCell<T> {
935
0
        fn from(value: T) -> Self {
936
0
            Self::with_value(value)
937
0
        }
938
    }
939
940
    impl<T: PartialEq> PartialEq for OnceCell<T> {
941
0
        fn eq(&self, other: &OnceCell<T>) -> bool {
942
0
            self.get() == other.get()
943
0
        }
944
    }
945
946
    impl<T: Eq> Eq for OnceCell<T> {}
947
948
    impl<T> OnceCell<T> {
949
        /// Creates a new empty cell.
950
0
        pub const fn new() -> OnceCell<T> {
951
0
            OnceCell(Imp::new())
952
0
        }
953
954
        /// Creates a new initialized cell.
955
0
        pub const fn with_value(value: T) -> OnceCell<T> {
956
0
            OnceCell(Imp::with_value(value))
957
0
        }
958
959
        /// Gets the reference to the underlying value.
960
        ///
961
        /// Returns `None` if the cell is empty, or being initialized. This
962
        /// method never blocks.
963
0
        pub fn get(&self) -> Option<&T> {
964
0
            if self.0.is_initialized() {
965
                // Safe b/c value is initialized.
966
0
                Some(unsafe { self.get_unchecked() })
967
            } else {
968
0
                None
969
            }
970
0
        }
Unexecuted instantiation: _RNvMs4_NtCs5GpVQlmD7AC_9once_cell4syncINtB5_8OnceCellANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_E3getBW_
Unexecuted instantiation: _RNvMs4_NtCs5GpVQlmD7AC_9once_cell4syncINtB5_8OnceCellpE3getB7_
971
972
        /// Gets the reference to the underlying value, blocking the current
973
        /// thread until it is set.
974
        ///
975
        /// ```
976
        /// use once_cell::sync::OnceCell;
977
        ///
978
        /// let mut cell = std::sync::Arc::new(OnceCell::new());
979
        /// let t = std::thread::spawn({
980
        ///     let cell = std::sync::Arc::clone(&cell);
981
        ///     move || cell.set(92).unwrap()
982
        /// });
983
        ///
984
        /// // Returns immediately, but might return None.
985
        /// let _value_or_none = cell.get();
986
        ///
987
        /// // Will return 92, but might block until the other thread does `.set`.
988
        /// let value: &u32 = cell.wait();
989
        /// assert_eq!(*value, 92);
990
        /// t.join().unwrap();
991
        /// ```
992
        #[cfg(feature = "std")]
993
0
        pub fn wait(&self) -> &T {
994
0
            if !self.0.is_initialized() {
995
0
                self.0.wait()
996
0
            }
997
0
            debug_assert!(self.0.is_initialized());
998
            // Safe b/c of the wait call above and the fact that we didn't
999
            // relinquish our borrow.
1000
0
            unsafe { self.get_unchecked() }
1001
0
        }
1002
1003
        /// Gets the mutable reference to the underlying value.
1004
        ///
1005
        /// Returns `None` if the cell is empty.
1006
        ///
1007
        /// This method is allowed to violate the invariant of writing to a `OnceCell`
1008
        /// at most once because it requires `&mut` access to `self`. As with all
1009
        /// interior mutability, `&mut` access permits arbitrary modification:
1010
        ///
1011
        /// ```
1012
        /// use once_cell::sync::OnceCell;
1013
        ///
1014
        /// let mut cell: OnceCell<u32> = OnceCell::new();
1015
        /// cell.set(92).unwrap();
1016
        /// cell = OnceCell::new();
1017
        /// ```
1018
        #[inline]
1019
0
        pub fn get_mut(&mut self) -> Option<&mut T> {
1020
0
            self.0.get_mut()
1021
0
        }
1022
1023
        /// Get the reference to the underlying value, without checking if the
1024
        /// cell is initialized.
1025
        ///
1026
        /// # Safety
1027
        ///
1028
        /// Caller must ensure that the cell is in initialized state, and that
1029
        /// the contents are acquired by (synchronized to) this thread.
1030
        #[inline]
1031
0
        pub unsafe fn get_unchecked(&self) -> &T {
1032
0
            self.0.get_unchecked()
1033
0
        }
Unexecuted instantiation: _RNvMs4_NtCs5GpVQlmD7AC_9once_cell4syncINtB5_8OnceCellANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_E13get_uncheckedBW_
Unexecuted instantiation: _RNvMs4_NtCs5GpVQlmD7AC_9once_cell4syncINtB5_8OnceCellpE13get_uncheckedB7_
1034
1035
        /// Sets the contents of this cell to `value`.
1036
        ///
1037
        /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
1038
        /// full.
1039
        ///
1040
        /// # Example
1041
        ///
1042
        /// ```
1043
        /// use once_cell::sync::OnceCell;
1044
        ///
1045
        /// static CELL: OnceCell<i32> = OnceCell::new();
1046
        ///
1047
        /// fn main() {
1048
        ///     assert!(CELL.get().is_none());
1049
        ///
1050
        ///     std::thread::spawn(|| {
1051
        ///         assert_eq!(CELL.set(92), Ok(()));
1052
        ///     }).join().unwrap();
1053
        ///
1054
        ///     assert_eq!(CELL.set(62), Err(62));
1055
        ///     assert_eq!(CELL.get(), Some(&92));
1056
        /// }
1057
        /// ```
1058
0
        pub fn set(&self, value: T) -> Result<(), T> {
1059
0
            match self.try_insert(value) {
1060
0
                Ok(_) => Ok(()),
1061
0
                Err((_, value)) => Err(value),
1062
            }
1063
0
        }
1064
1065
        /// Like [`set`](Self::set), but also returns a reference to the final cell value.
1066
        ///
1067
        /// # Example
1068
        ///
1069
        /// ```
1070
        /// use once_cell::unsync::OnceCell;
1071
        ///
1072
        /// let cell = OnceCell::new();
1073
        /// assert!(cell.get().is_none());
1074
        ///
1075
        /// assert_eq!(cell.try_insert(92), Ok(&92));
1076
        /// assert_eq!(cell.try_insert(62), Err((&92, 62)));
1077
        ///
1078
        /// assert!(cell.get().is_some());
1079
        /// ```
1080
0
        pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
1081
0
            let mut value = Some(value);
1082
0
            let res = self.get_or_init(|| unsafe { value.take().unwrap_unchecked() });
1083
0
            match value {
1084
0
                None => Ok(res),
1085
0
                Some(value) => Err((res, value)),
1086
            }
1087
0
        }
1088
1089
        /// Gets the contents of the cell, initializing it with `f` if the cell
1090
        /// was empty.
1091
        ///
1092
        /// Many threads may call `get_or_init` concurrently with different
1093
        /// initializing functions, but it is guaranteed that only one function
1094
        /// will be executed.
1095
        ///
1096
        /// # Panics
1097
        ///
1098
        /// If `f` panics, the panic is propagated to the caller, and the cell
1099
        /// remains uninitialized.
1100
        ///
1101
        /// It is an error to reentrantly initialize the cell from `f`. The
1102
        /// exact outcome is unspecified. Current implementation deadlocks, but
1103
        /// this may be changed to a panic in the future.
1104
        ///
1105
        /// # Example
1106
        /// ```
1107
        /// use once_cell::sync::OnceCell;
1108
        ///
1109
        /// let cell = OnceCell::new();
1110
        /// let value = cell.get_or_init(|| 92);
1111
        /// assert_eq!(value, &92);
1112
        /// let value = cell.get_or_init(|| unreachable!());
1113
        /// assert_eq!(value, &92);
1114
        /// ```
1115
0
        pub fn get_or_init<F>(&self, f: F) -> &T
1116
0
        where
1117
0
            F: FnOnce() -> T,
1118
0
        {
1119
            enum Void {}
1120
0
            match self.get_or_try_init(|| Ok::<T, Void>(f())) {
Unexecuted instantiation: _RNCINvMs4_NtCs5GpVQlmD7AC_9once_cell4syncINtB8_8OnceCellANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_E11get_or_initNCNvMs9_B8_INtB8_4LazyBS_E5force0E0BZ_
Unexecuted instantiation: _RNCINvMs4_NtCs5GpVQlmD7AC_9once_cell4syncINtB8_8OnceCellpE11get_or_initpE0Ba_
1121
0
                Ok(val) => val,
1122
0
                Err(void) => match void {},
1123
0
            }
1124
0
        }
Unexecuted instantiation: _RINvMs4_NtCs5GpVQlmD7AC_9once_cell4syncINtB6_8OnceCellANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_E11get_or_initNCNvMs9_B6_INtB6_4LazyBQ_E5force0EBX_
Unexecuted instantiation: _RINvMs4_NtCs5GpVQlmD7AC_9once_cell4syncINtB6_8OnceCellpE11get_or_initpEB8_
1125
1126
        /// Gets the contents of the cell, initializing it with `f` if
1127
        /// the cell was empty. If the cell was empty and `f` failed, an
1128
        /// error is returned.
1129
        ///
1130
        /// # Panics
1131
        ///
1132
        /// If `f` panics, the panic is propagated to the caller, and
1133
        /// the cell remains uninitialized.
1134
        ///
1135
        /// It is an error to reentrantly initialize the cell from `f`.
1136
        /// The exact outcome is unspecified. Current implementation
1137
        /// deadlocks, but this may be changed to a panic in the future.
1138
        ///
1139
        /// # Example
1140
        /// ```
1141
        /// use once_cell::sync::OnceCell;
1142
        ///
1143
        /// let cell = OnceCell::new();
1144
        /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
1145
        /// assert!(cell.get().is_none());
1146
        /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
1147
        ///     Ok(92)
1148
        /// });
1149
        /// assert_eq!(value, Ok(&92));
1150
        /// assert_eq!(cell.get(), Some(&92))
1151
        /// ```
1152
0
        pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
1153
0
        where
1154
0
            F: FnOnce() -> Result<T, E>,
1155
0
        {
1156
            // Fast path check
1157
0
            if let Some(value) = self.get() {
1158
0
                return Ok(value);
1159
0
            }
1160
0
1161
0
            self.0.initialize(f)?;
1162
1163
            // Safe b/c value is initialized.
1164
0
            debug_assert!(self.0.is_initialized());
1165
0
            Ok(unsafe { self.get_unchecked() })
1166
0
        }
Unexecuted instantiation: _RINvMs4_NtCs5GpVQlmD7AC_9once_cell4syncINtB6_8OnceCellANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_E15get_or_try_initNCINvB2_11get_or_initNCNvMs9_B6_INtB6_4LazyBQ_E5force0E0NtNvMs4_B6_IBC_pE11get_or_init4VoidEBX_
Unexecuted instantiation: _RINvMs4_NtCs5GpVQlmD7AC_9once_cell4syncINtB6_8OnceCellpE15get_or_try_initppEB8_
1167
1168
        /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
1169
        ///
1170
        /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized.
1171
        ///
1172
        /// # Examples
1173
        ///
1174
        /// ```
1175
        /// use once_cell::sync::OnceCell;
1176
        ///
1177
        /// let mut cell: OnceCell<String> = OnceCell::new();
1178
        /// assert_eq!(cell.take(), None);
1179
        ///
1180
        /// let mut cell = OnceCell::new();
1181
        /// cell.set("hello".to_string()).unwrap();
1182
        /// assert_eq!(cell.take(), Some("hello".to_string()));
1183
        /// assert_eq!(cell.get(), None);
1184
        /// ```
1185
        ///
1186
        /// This method is allowed to violate the invariant of writing to a `OnceCell`
1187
        /// at most once because it requires `&mut` access to `self`. As with all
1188
        /// interior mutability, `&mut` access permits arbitrary modification:
1189
        ///
1190
        /// ```
1191
        /// use once_cell::sync::OnceCell;
1192
        ///
1193
        /// let mut cell: OnceCell<u32> = OnceCell::new();
1194
        /// cell.set(92).unwrap();
1195
        /// cell = OnceCell::new();
1196
        /// ```
1197
0
        pub fn take(&mut self) -> Option<T> {
1198
0
            mem::take(self).into_inner()
1199
0
        }
1200
1201
        /// Consumes the `OnceCell`, returning the wrapped value. Returns
1202
        /// `None` if the cell was empty.
1203
        ///
1204
        /// # Examples
1205
        ///
1206
        /// ```
1207
        /// use once_cell::sync::OnceCell;
1208
        ///
1209
        /// let cell: OnceCell<String> = OnceCell::new();
1210
        /// assert_eq!(cell.into_inner(), None);
1211
        ///
1212
        /// let cell = OnceCell::new();
1213
        /// cell.set("hello".to_string()).unwrap();
1214
        /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
1215
        /// ```
1216
        #[inline]
1217
0
        pub fn into_inner(self) -> Option<T> {
1218
0
            self.0.into_inner()
1219
0
        }
1220
    }
1221
1222
    /// A value which is initialized on the first access.
1223
    ///
1224
    /// This type is thread-safe and can be used in statics.
1225
    ///
1226
    /// # Example
1227
    ///
1228
    /// ```
1229
    /// use std::collections::HashMap;
1230
    ///
1231
    /// use once_cell::sync::Lazy;
1232
    ///
1233
    /// static HASHMAP: Lazy<HashMap<i32, String>> = Lazy::new(|| {
1234
    ///     println!("initializing");
1235
    ///     let mut m = HashMap::new();
1236
    ///     m.insert(13, "Spica".to_string());
1237
    ///     m.insert(74, "Hoyten".to_string());
1238
    ///     m
1239
    /// });
1240
    ///
1241
    /// fn main() {
1242
    ///     println!("ready");
1243
    ///     std::thread::spawn(|| {
1244
    ///         println!("{:?}", HASHMAP.get(&13));
1245
    ///     }).join().unwrap();
1246
    ///     println!("{:?}", HASHMAP.get(&74));
1247
    ///
1248
    ///     // Prints:
1249
    ///     //   ready
1250
    ///     //   initializing
1251
    ///     //   Some("Spica")
1252
    ///     //   Some("Hoyten")
1253
    /// }
1254
    /// ```
1255
    pub struct Lazy<T, F = fn() -> T> {
1256
        cell: OnceCell<T>,
1257
        init: Cell<Option<F>>,
1258
    }
1259
1260
    impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
1261
0
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1262
0
            f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
1263
0
        }
1264
    }
1265
1266
    // We never create a `&F` from a `&Lazy<T, F>` so it is fine to not impl
1267
    // `Sync` for `F`. We do create a `&mut Option<F>` in `force`, but this is
1268
    // properly synchronized, so it only happens once so it also does not
1269
    // contribute to this impl.
1270
    unsafe impl<T, F: Send> Sync for Lazy<T, F> where OnceCell<T>: Sync {}
1271
    // auto-derived `Send` impl is OK.
1272
1273
    impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where OnceCell<T>: RefUnwindSafe {}
1274
1275
    impl<T, F> Lazy<T, F> {
1276
        /// Creates a new lazy value with the given initializing
1277
        /// function.
1278
0
        pub const fn new(f: F) -> Lazy<T, F> {
1279
0
            Lazy { cell: OnceCell::new(), init: Cell::new(Some(f)) }
1280
0
        }
1281
1282
        /// Consumes this `Lazy` returning the stored value.
1283
        ///
1284
        /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
1285
0
        pub fn into_value(this: Lazy<T, F>) -> Result<T, F> {
1286
0
            let cell = this.cell;
1287
0
            let init = this.init;
1288
0
            cell.into_inner().ok_or_else(|| {
1289
0
                init.take().unwrap_or_else(|| panic!("Lazy instance has previously been poisoned"))
1290
0
            })
1291
0
        }
1292
    }
1293
1294
    impl<T, F: FnOnce() -> T> Lazy<T, F> {
1295
        /// Forces the evaluation of this lazy value and
1296
        /// returns a reference to the result. This is equivalent
1297
        /// to the `Deref` impl, but is explicit.
1298
        ///
1299
        /// # Example
1300
        /// ```
1301
        /// use once_cell::sync::Lazy;
1302
        ///
1303
        /// let lazy = Lazy::new(|| 92);
1304
        ///
1305
        /// assert_eq!(Lazy::force(&lazy), &92);
1306
        /// assert_eq!(&*lazy, &92);
1307
        /// ```
1308
0
        pub fn force(this: &Lazy<T, F>) -> &T {
1309
0
            this.cell.get_or_init(|| match this.init.take() {
1310
0
                Some(f) => f(),
1311
0
                None => panic!("Lazy instance has previously been poisoned"),
1312
0
            })
Unexecuted instantiation: _RNCNvMs9_NtCs5GpVQlmD7AC_9once_cell4syncINtB7_4LazyANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_E5force0BU_
Unexecuted instantiation: _RNCNvMs9_NtCs5GpVQlmD7AC_9once_cell4syncINtB7_4LazyppE5force0B9_
1313
0
        }
Unexecuted instantiation: _RNvMs9_NtCs5GpVQlmD7AC_9once_cell4syncINtB5_4LazyANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_E5forceBS_
Unexecuted instantiation: _RNvMs9_NtCs5GpVQlmD7AC_9once_cell4syncINtB5_4LazyppE5forceB7_
1314
1315
        /// Forces the evaluation of this lazy value and
1316
        /// returns a mutable reference to the result. This is equivalent
1317
        /// to the `Deref` impl, but is explicit.
1318
        ///
1319
        /// # Example
1320
        /// ```
1321
        /// use once_cell::sync::Lazy;
1322
        ///
1323
        /// let mut lazy = Lazy::new(|| 92);
1324
        ///
1325
        /// assert_eq!(Lazy::force_mut(&mut lazy), &mut 92);
1326
        /// ```
1327
0
        pub fn force_mut(this: &mut Lazy<T, F>) -> &mut T {
1328
0
            if this.cell.get_mut().is_none() {
1329
0
                let value = match this.init.get_mut().take() {
1330
0
                    Some(f) => f(),
1331
0
                    None => panic!("Lazy instance has previously been poisoned"),
1332
                };
1333
0
                this.cell = OnceCell::with_value(value);
1334
0
            }
1335
0
            this.cell.get_mut().unwrap_or_else(|| unreachable!())
1336
0
        }
1337
1338
        /// Gets the reference to the result of this lazy value if
1339
        /// it was initialized, otherwise returns `None`.
1340
        ///
1341
        /// # Example
1342
        /// ```
1343
        /// use once_cell::sync::Lazy;
1344
        ///
1345
        /// let lazy = Lazy::new(|| 92);
1346
        ///
1347
        /// assert_eq!(Lazy::get(&lazy), None);
1348
        /// assert_eq!(&*lazy, &92);
1349
        /// assert_eq!(Lazy::get(&lazy), Some(&92));
1350
        /// ```
1351
0
        pub fn get(this: &Lazy<T, F>) -> Option<&T> {
1352
0
            this.cell.get()
1353
0
        }
1354
1355
        /// Gets the reference to the result of this lazy value if
1356
        /// it was initialized, otherwise returns `None`.
1357
        ///
1358
        /// # Example
1359
        /// ```
1360
        /// use once_cell::sync::Lazy;
1361
        ///
1362
        /// let mut lazy = Lazy::new(|| 92);
1363
        ///
1364
        /// assert_eq!(Lazy::get_mut(&mut lazy), None);
1365
        /// assert_eq!(&*lazy, &92);
1366
        /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92));
1367
        /// ```
1368
0
        pub fn get_mut(this: &mut Lazy<T, F>) -> Option<&mut T> {
1369
0
            this.cell.get_mut()
1370
0
        }
1371
    }
1372
1373
    impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
1374
        type Target = T;
1375
0
        fn deref(&self) -> &T {
1376
0
            Lazy::force(self)
1377
0
        }
Unexecuted instantiation: _RNvXsa_NtCs5GpVQlmD7AC_9once_cell4syncINtB5_4LazyANtNtNtCsjewTDwKBbyD_4k25610arithmetic3mul11LookupTablej21_ENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefBS_
Unexecuted instantiation: _RNvXININtCs5GpVQlmD7AC_9once_cell4syncsa_0ppEINtB5_4LazyppENtNtNtCsbQ8arDwx5Xq_4core3ops5deref5Deref5derefB7_
1378
    }
1379
1380
    impl<T, F: FnOnce() -> T> DerefMut for Lazy<T, F> {
1381
0
        fn deref_mut(&mut self) -> &mut T {
1382
0
            Lazy::force_mut(self)
1383
0
        }
1384
    }
1385
1386
    impl<T: Default> Default for Lazy<T> {
1387
        /// Creates a new lazy value using `Default` as the initializing function.
1388
0
        fn default() -> Lazy<T> {
1389
0
            Lazy::new(T::default)
1390
0
        }
1391
    }
1392
1393
    /// ```compile_fail
1394
    /// struct S(*mut ());
1395
    /// unsafe impl Sync for S {}
1396
    ///
1397
    /// fn share<T: Sync>(_: &T) {}
1398
    /// share(&once_cell::sync::OnceCell::<S>::new());
1399
    /// ```
1400
    ///
1401
    /// ```compile_fail
1402
    /// struct S(*mut ());
1403
    /// unsafe impl Sync for S {}
1404
    ///
1405
    /// fn share<T: Sync>(_: &T) {}
1406
    /// share(&once_cell::sync::Lazy::<S>::new(|| unimplemented!()));
1407
    /// ```
1408
0
    fn _dummy() {}
1409
}
1410
1411
#[cfg(feature = "race")]
1412
pub mod race;
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.19.0/src/race.rs
Line
Count
Source
1
//! Thread-safe, non-blocking, "first one wins" flavor of `OnceCell`.
2
//!
3
//! If two threads race to initialize a type from the `race` module, they
4
//! don't block, execute initialization function together, but only one of
5
//! them stores the result.
6
//!
7
//! This module does not require `std` feature.
8
//!
9
//! # Atomic orderings
10
//!
11
//! All types in this module use `Acquire` and `Release`
12
//! [atomic orderings](Ordering) for all their operations. While this is not
13
//! strictly necessary for types other than `OnceBox`, it is useful for users as
14
//! it allows them to be certain that after `get` or `get_or_init` returns on
15
//! one thread, any side-effects caused by the setter thread prior to them
16
//! calling `set` or `get_or_init` will be made visible to that thread; without
17
//! it, it's possible for it to appear as if they haven't happened yet from the
18
//! getter thread's perspective. This is an acceptable tradeoff to make since
19
//! `Acquire` and `Release` have very little performance overhead on most
20
//! architectures versus `Relaxed`.
21
22
#[cfg(feature = "critical-section")]
23
use portable_atomic as atomic;
24
#[cfg(not(feature = "critical-section"))]
25
use core::sync::atomic;
26
27
use atomic::{AtomicPtr, AtomicUsize, Ordering};
28
use core::cell::UnsafeCell;
29
use core::marker::PhantomData;
30
use core::num::NonZeroUsize;
31
use core::ptr;
32
33
/// A thread-safe cell which can be written to only once.
34
#[derive(Default, Debug)]
35
pub struct OnceNonZeroUsize {
36
    inner: AtomicUsize,
37
}
38
39
impl OnceNonZeroUsize {
40
    /// Creates a new empty cell.
41
    #[inline]
42
0
    pub const fn new() -> OnceNonZeroUsize {
43
0
        OnceNonZeroUsize { inner: AtomicUsize::new(0) }
44
0
    }
45
46
    /// Gets the underlying value.
47
    #[inline]
48
0
    pub fn get(&self) -> Option<NonZeroUsize> {
49
0
        let val = self.inner.load(Ordering::Acquire);
50
0
        NonZeroUsize::new(val)
51
0
    }
52
53
    /// Sets the contents of this cell to `value`.
54
    ///
55
    /// Returns `Ok(())` if the cell was empty and `Err(())` if it was
56
    /// full.
57
    #[inline]
58
0
    pub fn set(&self, value: NonZeroUsize) -> Result<(), ()> {
59
0
        let exchange =
60
0
            self.inner.compare_exchange(0, value.get(), Ordering::AcqRel, Ordering::Acquire);
61
0
        match exchange {
62
0
            Ok(_) => Ok(()),
63
0
            Err(_) => Err(()),
64
        }
65
0
    }
66
67
    /// Gets the contents of the cell, initializing it with `f` if the cell was
68
    /// empty.
69
    ///
70
    /// If several threads concurrently run `get_or_init`, more than one `f` can
71
    /// be called. However, all threads will return the same value, produced by
72
    /// some `f`.
73
0
    pub fn get_or_init<F>(&self, f: F) -> NonZeroUsize
74
0
    where
75
0
        F: FnOnce() -> NonZeroUsize,
76
0
    {
77
        enum Void {}
78
0
        match self.get_or_try_init(|| Ok::<NonZeroUsize, Void>(f())) {
79
0
            Ok(val) => val,
80
0
            Err(void) => match void {},
81
0
        }
82
0
    }
83
84
    /// Gets the contents of the cell, initializing it with `f` if
85
    /// the cell was empty. If the cell was empty and `f` failed, an
86
    /// error is returned.
87
    ///
88
    /// If several threads concurrently run `get_or_init`, more than one `f` can
89
    /// be called. However, all threads will return the same value, produced by
90
    /// some `f`.
91
0
    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<NonZeroUsize, E>
92
0
    where
93
0
        F: FnOnce() -> Result<NonZeroUsize, E>,
94
0
    {
95
0
        let val = self.inner.load(Ordering::Acquire);
96
0
        let res = match NonZeroUsize::new(val) {
97
0
            Some(it) => it,
98
            None => {
99
0
                let mut val = f()?.get();
100
0
                let exchange =
101
0
                    self.inner.compare_exchange(0, val, Ordering::AcqRel, Ordering::Acquire);
102
0
                if let Err(old) = exchange {
103
0
                    val = old;
104
0
                }
105
0
                unsafe { NonZeroUsize::new_unchecked(val) }
106
            }
107
        };
108
0
        Ok(res)
109
0
    }
110
}
111
112
/// A thread-safe cell which can be written to only once.
113
#[derive(Default, Debug)]
114
pub struct OnceBool {
115
    inner: OnceNonZeroUsize,
116
}
117
118
impl OnceBool {
119
    /// Creates a new empty cell.
120
    #[inline]
121
0
    pub const fn new() -> OnceBool {
122
0
        OnceBool { inner: OnceNonZeroUsize::new() }
123
0
    }
124
125
    /// Gets the underlying value.
126
    #[inline]
127
0
    pub fn get(&self) -> Option<bool> {
128
0
        self.inner.get().map(OnceBool::from_usize)
129
0
    }
130
131
    /// Sets the contents of this cell to `value`.
132
    ///
133
    /// Returns `Ok(())` if the cell was empty and `Err(())` if it was
134
    /// full.
135
    #[inline]
136
0
    pub fn set(&self, value: bool) -> Result<(), ()> {
137
0
        self.inner.set(OnceBool::to_usize(value))
138
0
    }
139
140
    /// Gets the contents of the cell, initializing it with `f` if the cell was
141
    /// empty.
142
    ///
143
    /// If several threads concurrently run `get_or_init`, more than one `f` can
144
    /// be called. However, all threads will return the same value, produced by
145
    /// some `f`.
146
0
    pub fn get_or_init<F>(&self, f: F) -> bool
147
0
    where
148
0
        F: FnOnce() -> bool,
149
0
    {
150
0
        OnceBool::from_usize(self.inner.get_or_init(|| OnceBool::to_usize(f())))
151
0
    }
152
153
    /// Gets the contents of the cell, initializing it with `f` if
154
    /// the cell was empty. If the cell was empty and `f` failed, an
155
    /// error is returned.
156
    ///
157
    /// If several threads concurrently run `get_or_init`, more than one `f` can
158
    /// be called. However, all threads will return the same value, produced by
159
    /// some `f`.
160
0
    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<bool, E>
161
0
    where
162
0
        F: FnOnce() -> Result<bool, E>,
163
0
    {
164
0
        self.inner.get_or_try_init(|| f().map(OnceBool::to_usize)).map(OnceBool::from_usize)
165
0
    }
166
167
    #[inline]
168
0
    fn from_usize(value: NonZeroUsize) -> bool {
169
0
        value.get() == 1
170
0
    }
171
172
    #[inline]
173
0
    fn to_usize(value: bool) -> NonZeroUsize {
174
0
        unsafe { NonZeroUsize::new_unchecked(if value { 1 } else { 2 }) }
175
0
    }
176
}
177
178
/// A thread-safe cell which can be written to only once.
179
pub struct OnceRef<'a, T> {
180
    inner: AtomicPtr<T>,
181
    ghost: PhantomData<UnsafeCell<&'a T>>,
182
}
183
184
// TODO: Replace UnsafeCell with SyncUnsafeCell once stabilized
185
unsafe impl<'a, T: Sync> Sync for OnceRef<'a, T> {}
186
187
impl<'a, T> core::fmt::Debug for OnceRef<'a, T> {
188
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
189
0
        write!(f, "OnceRef({:?})", self.inner)
190
0
    }
191
}
192
193
impl<'a, T> Default for OnceRef<'a, T> {
194
0
    fn default() -> Self {
195
0
        Self::new()
196
0
    }
197
}
198
199
impl<'a, T> OnceRef<'a, T> {
200
    /// Creates a new empty cell.
201
0
    pub const fn new() -> OnceRef<'a, T> {
202
0
        OnceRef { inner: AtomicPtr::new(ptr::null_mut()), ghost: PhantomData }
203
0
    }
204
205
    /// Gets a reference to the underlying value.
206
0
    pub fn get(&self) -> Option<&'a T> {
207
0
        let ptr = self.inner.load(Ordering::Acquire);
208
0
        unsafe { ptr.as_ref() }
209
0
    }
210
211
    /// Sets the contents of this cell to `value`.
212
    ///
213
    /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
214
    /// full.
215
0
    pub fn set(&self, value: &'a T) -> Result<(), ()> {
216
0
        let ptr = value as *const T as *mut T;
217
0
        let exchange =
218
0
            self.inner.compare_exchange(ptr::null_mut(), ptr, Ordering::AcqRel, Ordering::Acquire);
219
0
        match exchange {
220
0
            Ok(_) => Ok(()),
221
0
            Err(_) => Err(()),
222
        }
223
0
    }
224
225
    /// Gets the contents of the cell, initializing it with `f` if the cell was
226
    /// empty.
227
    ///
228
    /// If several threads concurrently run `get_or_init`, more than one `f` can
229
    /// be called. However, all threads will return the same value, produced by
230
    /// some `f`.
231
0
    pub fn get_or_init<F>(&self, f: F) -> &'a T
232
0
    where
233
0
        F: FnOnce() -> &'a T,
234
0
    {
235
        enum Void {}
236
0
        match self.get_or_try_init(|| Ok::<&'a T, Void>(f())) {
237
0
            Ok(val) => val,
238
0
            Err(void) => match void {},
239
0
        }
240
0
    }
241
242
    /// Gets the contents of the cell, initializing it with `f` if
243
    /// the cell was empty. If the cell was empty and `f` failed, an
244
    /// error is returned.
245
    ///
246
    /// If several threads concurrently run `get_or_init`, more than one `f` can
247
    /// be called. However, all threads will return the same value, produced by
248
    /// some `f`.
249
0
    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&'a T, E>
250
0
    where
251
0
        F: FnOnce() -> Result<&'a T, E>,
252
0
    {
253
0
        let mut ptr = self.inner.load(Ordering::Acquire);
254
0
255
0
        if ptr.is_null() {
256
            // TODO replace with `cast_mut` when MSRV reaches 1.65.0 (also in `set`)
257
0
            ptr = f()? as *const T as *mut T;
258
0
            let exchange = self.inner.compare_exchange(
259
0
                ptr::null_mut(),
260
0
                ptr,
261
0
                Ordering::AcqRel,
262
0
                Ordering::Acquire,
263
0
            );
264
0
            if let Err(old) = exchange {
265
0
                ptr = old;
266
0
            }
267
0
        }
268
269
0
        Ok(unsafe { &*ptr })
270
0
    }
271
272
    /// ```compile_fail
273
    /// use once_cell::race::OnceRef;
274
    ///
275
    /// let mut l = OnceRef::new();
276
    ///
277
    /// {
278
    ///     let y = 2;
279
    ///     let mut r = OnceRef::new();
280
    ///     r.set(&y).unwrap();
281
    ///     core::mem::swap(&mut l, &mut r);
282
    /// }
283
    ///
284
    /// // l now contains a dangling reference to y
285
    /// eprintln!("uaf: {}", l.get().unwrap());
286
    /// ```
287
0
    fn _dummy() {}
288
}
289
290
#[cfg(feature = "alloc")]
291
pub use self::once_box::OnceBox;
292
293
#[cfg(feature = "alloc")]
294
mod once_box {
295
    use super::atomic::{AtomicPtr, Ordering};
296
    use core::{marker::PhantomData, ptr};
297
298
    use alloc::boxed::Box;
299
300
    /// A thread-safe cell which can be written to only once.
301
    pub struct OnceBox<T> {
302
        inner: AtomicPtr<T>,
303
        ghost: PhantomData<Option<Box<T>>>,
304
    }
305
306
    impl<T> core::fmt::Debug for OnceBox<T> {
307
0
        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
308
0
            write!(f, "OnceBox({:?})", self.inner.load(Ordering::Relaxed))
309
0
        }
310
    }
311
312
    impl<T> Default for OnceBox<T> {
313
0
        fn default() -> Self {
314
0
            Self::new()
315
0
        }
316
    }
317
318
    impl<T> Drop for OnceBox<T> {
319
0
        fn drop(&mut self) {
320
0
            let ptr = *self.inner.get_mut();
321
0
            if !ptr.is_null() {
322
0
                drop(unsafe { Box::from_raw(ptr) })
323
0
            }
324
0
        }
Unexecuted instantiation: _RNvXs0_NtNtCs5GpVQlmD7AC_9once_cell4race8once_boxINtB5_7OnceBoxINtNtCsiBl6Lc3cFal_5alloc5boxed3BoxDNtNtCseb6QmliwlWD_5ahash12random_state12RandomSourceNtNtCsbQ8arDwx5Xq_4core6marker4SendNtB2r_4SyncEL_EENtNtNtB2t_3ops4drop4Drop4dropB1D_
Unexecuted instantiation: _RNvXININtNtCs5GpVQlmD7AC_9once_cell4race8once_boxs0_0pEINtB5_7OnceBoxpENtNtNtCsbQ8arDwx5Xq_4core3ops4drop4Drop4dropB9_
325
    }
326
327
    impl<T> OnceBox<T> {
328
        /// Creates a new empty cell.
329
0
        pub const fn new() -> OnceBox<T> {
330
0
            OnceBox { inner: AtomicPtr::new(ptr::null_mut()), ghost: PhantomData }
331
0
        }
332
333
        /// Gets a reference to the underlying value.
334
0
        pub fn get(&self) -> Option<&T> {
335
0
            let ptr = self.inner.load(Ordering::Acquire);
336
0
            if ptr.is_null() {
337
0
                return None;
338
0
            }
339
0
            Some(unsafe { &*ptr })
340
0
        }
341
342
        /// Sets the contents of this cell to `value`.
343
        ///
344
        /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
345
        /// full.
346
0
        pub fn set(&self, value: Box<T>) -> Result<(), Box<T>> {
347
0
            let ptr = Box::into_raw(value);
348
0
            let exchange = self.inner.compare_exchange(
349
0
                ptr::null_mut(),
350
0
                ptr,
351
0
                Ordering::AcqRel,
352
0
                Ordering::Acquire,
353
0
            );
354
0
            if exchange.is_err() {
355
0
                let value = unsafe { Box::from_raw(ptr) };
356
0
                return Err(value);
357
0
            }
358
0
            Ok(())
359
0
        }
360
361
        /// Gets the contents of the cell, initializing it with `f` if the cell was
362
        /// empty.
363
        ///
364
        /// If several threads concurrently run `get_or_init`, more than one `f` can
365
        /// be called. However, all threads will return the same value, produced by
366
        /// some `f`.
367
0
        pub fn get_or_init<F>(&self, f: F) -> &T
368
0
        where
369
0
            F: FnOnce() -> Box<T>,
370
0
        {
371
            enum Void {}
372
0
            match self.get_or_try_init(|| Ok::<Box<T>, Void>(f())) {
Unexecuted instantiation: _RNCINvMs1_NtNtCs5GpVQlmD7AC_9once_cell4race8once_boxINtB8_7OnceBoxINtNtCsiBl6Lc3cFal_5alloc5boxed3BoxDNtNtCseb6QmliwlWD_5ahash12random_state12RandomSourceNtNtCsbQ8arDwx5Xq_4core6marker4SendNtB2u_4SyncEL_EE11get_or_initNCNvB1E_7get_src0E0B1G_
Unexecuted instantiation: _RNCINvMs1_NtNtCs5GpVQlmD7AC_9once_cell4race8once_boxINtB8_7OnceBoxpE11get_or_initpE0Bc_
373
0
                Ok(val) => val,
374
0
                Err(void) => match void {},
375
0
            }
376
0
        }
Unexecuted instantiation: _RINvMs1_NtNtCs5GpVQlmD7AC_9once_cell4race8once_boxINtB6_7OnceBoxINtNtCsiBl6Lc3cFal_5alloc5boxed3BoxDNtNtCseb6QmliwlWD_5ahash12random_state12RandomSourceNtNtCsbQ8arDwx5Xq_4core6marker4SendNtB2s_4SyncEL_EE11get_or_initNCNvB1C_7get_src0EB1E_
Unexecuted instantiation: _RINvMs1_NtNtCs5GpVQlmD7AC_9once_cell4race8once_boxINtB6_7OnceBoxpE11get_or_initpEBa_
377
378
        /// Gets the contents of the cell, initializing it with `f` if
379
        /// the cell was empty. If the cell was empty and `f` failed, an
380
        /// error is returned.
381
        ///
382
        /// If several threads concurrently run `get_or_init`, more than one `f` can
383
        /// be called. However, all threads will return the same value, produced by
384
        /// some `f`.
385
0
        pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
386
0
        where
387
0
            F: FnOnce() -> Result<Box<T>, E>,
388
0
        {
389
0
            let mut ptr = self.inner.load(Ordering::Acquire);
390
0
391
0
            if ptr.is_null() {
392
0
                let val = f()?;
393
0
                ptr = Box::into_raw(val);
394
0
                let exchange = self.inner.compare_exchange(
395
0
                    ptr::null_mut(),
396
0
                    ptr,
397
0
                    Ordering::AcqRel,
398
0
                    Ordering::Acquire,
399
0
                );
400
0
                if let Err(old) = exchange {
401
0
                    drop(unsafe { Box::from_raw(ptr) });
402
0
                    ptr = old;
403
0
                }
404
0
            };
405
0
            Ok(unsafe { &*ptr })
406
0
        }
Unexecuted instantiation: _RINvMs1_NtNtCs5GpVQlmD7AC_9once_cell4race8once_boxINtB6_7OnceBoxINtNtCsiBl6Lc3cFal_5alloc5boxed3BoxDNtNtCseb6QmliwlWD_5ahash12random_state12RandomSourceNtNtCsbQ8arDwx5Xq_4core6marker4SendNtB2s_4SyncEL_EE15get_or_try_initNCINvB2_11get_or_initNCNvB1C_7get_src0E0NtNvMs1_B6_IBN_pE11get_or_init4VoidEB1E_
Unexecuted instantiation: _RINvMs1_NtNtCs5GpVQlmD7AC_9once_cell4race8once_boxINtB6_7OnceBoxpE15get_or_try_initppEBa_
407
    }
408
409
    unsafe impl<T: Sync + Send> Sync for OnceBox<T> {}
410
411
    /// ```compile_fail
412
    /// struct S(*mut ());
413
    /// unsafe impl Sync for S {}
414
    ///
415
    /// fn share<T: Sync>(_: &T) {}
416
    /// share(&once_cell::race::OnceBox::<S>::new());
417
    /// ```
418
0
    fn _dummy() {}
419
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/p256-0.13.2/src/arithmetic/field.rs
Line
Count
Source
1
//! Field arithmetic modulo p = 2^{224}(2^{32} − 1) + 2^{192} + 2^{96} − 1
2
3
#![allow(clippy::assign_op_pattern, clippy::op_ref)]
4
5
#[cfg_attr(target_pointer_width = "32", path = "field/field32.rs")]
6
#[cfg_attr(target_pointer_width = "64", path = "field/field64.rs")]
7
mod field_impl;
8
9
use self::field_impl::*;
10
use crate::{FieldBytes, NistP256};
11
use core::{
12
    fmt::{self, Debug},
13
    iter::{Product, Sum},
14
    ops::{AddAssign, Mul, MulAssign, Neg, SubAssign},
15
};
16
use elliptic_curve::{
17
    bigint::U256,
18
    ff::PrimeField,
19
    subtle::{Choice, ConstantTimeEq, CtOption},
20
};
21
22
/// Field modulus serialized as hex.
23
/// p = 2^{224}(2^{32} − 1) + 2^{192} + 2^{96} − 1
24
const MODULUS_HEX: &str = "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff";
25
26
/// Constant representing the modulus.
27
pub const MODULUS: U256 = U256::from_be_hex(MODULUS_HEX);
28
29
/// R^2 = 2^512 mod p
30
const R_2: U256 =
31
    U256::from_be_hex("00000004fffffffdfffffffffffffffefffffffbffffffff0000000000000003");
32
33
/// An element in the finite field modulo p = 2^{224}(2^{32} − 1) + 2^{192} + 2^{96} − 1.
34
///
35
/// The internal representation is in little-endian order. Elements are always in
36
/// Montgomery form; i.e., FieldElement(a) = aR mod p, with R = 2^256.
37
#[derive(Clone, Copy)]
38
pub struct FieldElement(pub(crate) U256);
39
40
primeorder::impl_mont_field_element!(
41
    NistP256,
42
    FieldElement,
43
    FieldBytes,
44
    U256,
45
    MODULUS,
46
    Fe,
47
    fe_from_montgomery,
48
    fe_to_montgomery,
49
    fe_add,
50
    fe_sub,
51
    fe_mul,
52
    fe_neg,
53
    fe_square
54
);
55
56
impl FieldElement {
57
    /// Returns the multiplicative inverse of self, if self is non-zero.
58
838
    pub fn invert(&self) -> CtOption<Self> {
59
838
        CtOption::new(self.invert_unchecked(), !self.is_zero())
60
838
    }
61
62
    /// Returns the multiplicative inverse of self.
63
    ///
64
    /// Does not check that self is non-zero.
65
838
    const fn invert_unchecked(&self) -> Self {
66
838
        // We need to find b such that b * a ≡ 1 mod p. As we are in a prime
67
838
        // field, we can apply Fermat's Little Theorem:
68
838
        //
69
838
        //    a^p         ≡ a mod p
70
838
        //    a^(p-1)     ≡ 1 mod p
71
838
        //    a^(p-2) * a ≡ 1 mod p
72
838
        //
73
838
        // Thus inversion can be implemented with a single exponentiation.
74
838
75
838
        let t111 = self.multiply(&self.multiply(&self.square()).square());
76
838
        let t111111 = t111.multiply(&t111.sqn(3));
77
838
        let x15 = t111111.sqn(6).multiply(&t111111).sqn(3).multiply(&t111);
78
838
        let x16 = x15.square().multiply(self);
79
838
        let i53 = x16.sqn(16).multiply(&x16).sqn(15);
80
838
        let x47 = x15.multiply(&i53);
81
838
        x47.multiply(&i53.sqn(17).multiply(self).sqn(143).multiply(&x47).sqn(47))
82
838
            .sqn(2)
83
838
            .multiply(self)
84
838
    }
85
86
    /// Returns the square root of self mod p, or `None` if no square root exists.
87
611
    pub fn sqrt(&self) -> CtOption<Self> {
88
611
        // We need to find alpha such that alpha^2 = beta mod p. For secp256r1,
89
611
        // p ≡ 3 mod 4. By Euler's Criterion, beta^(p-1)/2 ≡ 1 mod p. So:
90
611
        //
91
611
        //     alpha^2 = beta beta^((p - 1) / 2) mod p ≡ beta^((p + 1) / 2) mod p
92
611
        //     alpha = ± beta^((p + 1) / 4) mod p
93
611
        //
94
611
        // Thus sqrt can be implemented with a single exponentiation.
95
611
96
611
        let t11 = self.mul(&self.square());
97
611
        let t1111 = t11.mul(&t11.sqn(2));
98
611
        let t11111111 = t1111.mul(&t1111.sqn(4));
99
611
        let x16 = t11111111.sqn(8).mul(&t11111111);
100
611
        let sqrt = x16
101
611
            .sqn(16)
102
611
            .mul(&x16)
103
611
            .sqn(32)
104
611
            .mul(self)
105
611
            .sqn(96)
106
611
            .mul(self)
107
611
            .sqn(94);
108
611
109
611
        CtOption::new(
110
611
            sqrt,
111
611
            (&sqrt * &sqrt).ct_eq(self), // Only return Some if it's the square root.
112
611
        )
113
611
    }
114
115
    /// Returns self^(2^n) mod p
116
11.8k
    const fn sqn(&self, n: usize) -> Self {
117
11.8k
        let mut x = *self;
118
11.8k
        let mut i = 0;
119
376k
        while i < n {
120
365k
            x = x.square();
121
365k
            i += 1;
122
365k
        }
123
11.8k
        x
124
11.8k
    }
125
}
126
127
impl PrimeField for FieldElement {
128
    type Repr = FieldBytes;
129
130
    const MODULUS: &'static str = MODULUS_HEX;
131
    const NUM_BITS: u32 = 256;
132
    const CAPACITY: u32 = 255;
133
    const TWO_INV: Self = Self::from_u64(2).invert_unchecked();
134
    const MULTIPLICATIVE_GENERATOR: Self = Self::from_u64(6);
135
    const S: u32 = 1;
136
    const ROOT_OF_UNITY: Self =
137
        Self::from_hex("ffffffff00000001000000000000000000000000fffffffffffffffffffffffe");
138
    const ROOT_OF_UNITY_INV: Self = Self::ROOT_OF_UNITY.invert_unchecked();
139
    const DELTA: Self = Self::from_u64(36);
140
141
    #[inline]
142
1.72k
    fn from_repr(bytes: FieldBytes) -> CtOption<Self> {
143
1.72k
        Self::from_bytes(&bytes)
144
1.72k
    }
_RNvXs_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB4_12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField9from_reprCs4RkbDk9WRL5_5clvmr
Line
Count
Source
142
1.72k
    fn from_repr(bytes: FieldBytes) -> CtOption<Self> {
143
1.72k
        Self::from_bytes(&bytes)
144
1.72k
    }
Unexecuted instantiation: _RNvXs_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB4_12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField9from_reprB8_
145
146
    #[inline]
147
866
    fn to_repr(&self) -> FieldBytes {
148
866
        self.to_bytes()
149
866
    }
_RNvXs_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB4_12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField7to_reprCs4RkbDk9WRL5_5clvmr
Line
Count
Source
147
866
    fn to_repr(&self) -> FieldBytes {
148
866
        self.to_bytes()
149
866
    }
Unexecuted instantiation: _RNvXs_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB4_12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField7to_reprB8_
150
151
    #[inline]
152
611
    fn is_odd(&self) -> Choice {
153
611
        self.is_odd()
154
611
    }
_RNvXs_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB4_12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField6is_oddCs4RkbDk9WRL5_5clvmr
Line
Count
Source
152
611
    fn is_odd(&self) -> Choice {
153
611
        self.is_odd()
154
611
    }
Unexecuted instantiation: _RNvXs_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB4_12FieldElementNtCs1xjs03Q5HzH_2ff10PrimeField6is_oddB8_
155
}
156
157
impl Debug for FieldElement {
158
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159
0
        write!(f, "FieldElement(0x{:X})", &self.0)
160
0
    }
161
}
162
163
#[cfg(test)]
164
mod tests {
165
    use super::FieldElement;
166
    use crate::{test_vectors::field::DBL_TEST_VECTORS, FieldBytes};
167
    use elliptic_curve::{bigint::U256, ff::PrimeField};
168
    use primeorder::{
169
        impl_field_identity_tests, impl_field_invert_tests, impl_field_sqrt_tests,
170
        impl_primefield_tests,
171
    };
172
    use proptest::{num, prelude::*};
173
174
    /// t = (modulus - 1) >> S
175
    const T: [u64; 4] = [
176
        0xffffffffffffffff,
177
        0x000000007fffffff,
178
        0x8000000000000000,
179
        0x7fffffff80000000,
180
    ];
181
182
    impl_field_identity_tests!(FieldElement);
183
    impl_field_invert_tests!(FieldElement);
184
    impl_field_sqrt_tests!(FieldElement);
185
    impl_primefield_tests!(FieldElement, T);
186
187
    #[test]
188
    fn from_bytes() {
189
        assert_eq!(
190
            FieldElement::from_bytes(&FieldBytes::default()).unwrap(),
191
            FieldElement::ZERO
192
        );
193
        assert_eq!(
194
            FieldElement::from_bytes(
195
                &[
196
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
197
                    0, 0, 0, 0, 0, 1
198
                ]
199
                .into()
200
            )
201
            .unwrap(),
202
            FieldElement::ONE
203
        );
204
        assert!(bool::from(
205
            FieldElement::from_bytes(&[0xff; 32].into()).is_none()
206
        ));
207
    }
208
209
    #[test]
210
    fn to_bytes() {
211
        assert_eq!(FieldElement::ZERO.to_bytes(), FieldBytes::default());
212
        assert_eq!(
213
            FieldElement::ONE.to_bytes(),
214
            [
215
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
216
                0, 0, 0, 1
217
            ]
218
            .into()
219
        );
220
    }
221
222
    #[test]
223
    fn repeated_add() {
224
        let mut r = FieldElement::ONE;
225
        for i in 0..DBL_TEST_VECTORS.len() {
226
            assert_eq!(r.to_bytes(), DBL_TEST_VECTORS[i].into());
227
            r = r + &r;
228
        }
229
    }
230
231
    #[test]
232
    fn repeated_double() {
233
        let mut r = FieldElement::ONE;
234
        for i in 0..DBL_TEST_VECTORS.len() {
235
            assert_eq!(r.to_bytes(), DBL_TEST_VECTORS[i].into());
236
            r = r.double();
237
        }
238
    }
239
240
    #[test]
241
    fn repeated_mul() {
242
        let mut r = FieldElement::ONE;
243
        let two = r + &r;
244
        for i in 0..DBL_TEST_VECTORS.len() {
245
            assert_eq!(r.to_bytes(), DBL_TEST_VECTORS[i].into());
246
            r = r * &two;
247
        }
248
    }
249
250
    #[test]
251
    fn negation() {
252
        let two = FieldElement::ONE.double();
253
        let neg_two = -two;
254
        assert_eq!(two + &neg_two, FieldElement::ZERO);
255
        assert_eq!(-neg_two, two);
256
    }
257
258
    #[test]
259
    fn pow_vartime() {
260
        let one = FieldElement::ONE;
261
        let two = one + &one;
262
        let four = two.square();
263
        assert_eq!(two.pow_vartime(&[2, 0, 0, 0]), four);
264
    }
265
266
    proptest! {
267
        /// This checks behaviour well within the field ranges, because it doesn't set the
268
        /// highest limb.
269
        #[cfg(target_pointer_width = "32")]
270
        #[test]
271
        fn add_then_sub(
272
            a0 in num::u32::ANY,
273
            a1 in num::u32::ANY,
274
            a2 in num::u32::ANY,
275
            a3 in num::u32::ANY,
276
            a4 in num::u32::ANY,
277
            a5 in num::u32::ANY,
278
            a6 in num::u32::ANY,
279
            b0 in num::u32::ANY,
280
            b1 in num::u32::ANY,
281
            b2 in num::u32::ANY,
282
            b3 in num::u32::ANY,
283
            b4 in num::u32::ANY,
284
            b5 in num::u32::ANY,
285
            b6 in num::u32::ANY,
286
        ) {
287
            let a = FieldElement(U256::from_words([a0, a1, a2, a3, a4, a5, a6, 0]));
288
            let b = FieldElement(U256::from_words([b0, b1, b2, b3, b4, b5, b6, 0]));
289
            assert_eq!(a.add(&b).sub(&a), b);
290
        }
291
292
        /// This checks behaviour well within the field ranges, because it doesn't set the
293
        /// highest limb.
294
        #[cfg(target_pointer_width = "64")]
295
        #[test]
296
        fn add_then_sub(
297
            a0 in num::u64::ANY,
298
            a1 in num::u64::ANY,
299
            a2 in num::u64::ANY,
300
            b0 in num::u64::ANY,
301
            b1 in num::u64::ANY,
302
            b2 in num::u64::ANY,
303
        ) {
304
            let a = FieldElement(U256::from_words([a0, a1, a2, 0]));
305
            let b = FieldElement(U256::from_words([b0, b1, b2, 0]));
306
            assert_eq!(a.add(&b).sub(&a), b);
307
        }
308
    }
309
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/p256-0.13.2/src/arithmetic/field/field64.rs
Line
Count
Source
1
//! 64-bit secp256r1 base field implementation
2
3
use super::{MODULUS, R_2};
4
use crate::arithmetic::util::{adc, mac, sbb};
5
6
/// Raw field element.
7
pub type Fe = [u64; 4];
8
9
/// Translate a field element out of the Montgomery domain.
10
#[inline]
11
1.47k
pub const fn fe_from_montgomery(w: &Fe) -> Fe {
12
1.47k
    montgomery_reduce(&[w[0], w[1], w[2], w[3], 0, 0, 0, 0])
13
1.47k
}
14
15
/// Translate a field element into the Montgomery domain.
16
#[inline]
17
555k
pub const fn fe_to_montgomery(w: &Fe) -> Fe {
18
555k
    fe_mul(w, R_2.as_words())
19
555k
}
20
21
/// Returns `a + b mod p`.
22
9.46M
pub const fn fe_add(a: &Fe, b: &Fe) -> Fe {
23
9.46M
    // Bit 256 of p is set, so addition can result in five words.
24
9.46M
    let (w0, carry) = adc(a[0], b[0], 0);
25
9.46M
    let (w1, carry) = adc(a[1], b[1], carry);
26
9.46M
    let (w2, carry) = adc(a[2], b[2], carry);
27
9.46M
    let (w3, w4) = adc(a[3], b[3], carry);
28
9.46M
29
9.46M
    // Attempt to subtract the modulus, to ensure the result is in the field.
30
9.46M
    let modulus = MODULUS.as_words();
31
9.46M
    sub_inner(
32
9.46M
        &[w0, w1, w2, w3, w4],
33
9.46M
        &[modulus[0], modulus[1], modulus[2], modulus[3], 0],
34
9.46M
    )
35
9.46M
}
36
37
/// Returns `a - b mod p`.
38
3.68M
pub const fn fe_sub(a: &Fe, b: &Fe) -> Fe {
39
3.68M
    sub_inner(&[a[0], a[1], a[2], a[3], 0], &[b[0], b[1], b[2], b[3], 0])
40
3.68M
}
41
42
/// Returns `a * b mod p`.
43
8.26M
pub const fn fe_mul(a: &Fe, b: &Fe) -> Fe {
44
8.26M
    let (w0, carry) = mac(0, a[0], b[0], 0);
45
8.26M
    let (w1, carry) = mac(0, a[0], b[1], carry);
46
8.26M
    let (w2, carry) = mac(0, a[0], b[2], carry);
47
8.26M
    let (w3, w4) = mac(0, a[0], b[3], carry);
48
8.26M
49
8.26M
    let (w1, carry) = mac(w1, a[1], b[0], 0);
50
8.26M
    let (w2, carry) = mac(w2, a[1], b[1], carry);
51
8.26M
    let (w3, carry) = mac(w3, a[1], b[2], carry);
52
8.26M
    let (w4, w5) = mac(w4, a[1], b[3], carry);
53
8.26M
54
8.26M
    let (w2, carry) = mac(w2, a[2], b[0], 0);
55
8.26M
    let (w3, carry) = mac(w3, a[2], b[1], carry);
56
8.26M
    let (w4, carry) = mac(w4, a[2], b[2], carry);
57
8.26M
    let (w5, w6) = mac(w5, a[2], b[3], carry);
58
8.26M
59
8.26M
    let (w3, carry) = mac(w3, a[3], b[0], 0);
60
8.26M
    let (w4, carry) = mac(w4, a[3], b[1], carry);
61
8.26M
    let (w5, carry) = mac(w5, a[3], b[2], carry);
62
8.26M
    let (w6, w7) = mac(w6, a[3], b[3], carry);
63
8.26M
64
8.26M
    montgomery_reduce(&[w0, w1, w2, w3, w4, w5, w6, w7])
65
8.26M
}
66
67
/// Returns `-w mod p`.
68
554k
pub const fn fe_neg(w: &Fe) -> Fe {
69
554k
    fe_sub(&[0, 0, 0, 0], w)
70
554k
}
71
72
/// Returns `w * w mod p`.
73
1.67M
pub const fn fe_square(w: &Fe) -> Fe {
74
1.67M
    fe_mul(w, w)
75
1.67M
}
76
77
/// Montgomery Reduction
78
///
79
/// The general algorithm is:
80
/// ```text
81
/// A <- input (2n b-limbs)
82
/// for i in 0..n {
83
///     k <- A[i] p' mod b
84
///     A <- A + k p b^i
85
/// }
86
/// A <- A / b^n
87
/// if A >= p {
88
///     A <- A - p
89
/// }
90
/// ```
91
///
92
/// For secp256r1, we have the following simplifications:
93
///
94
/// - `p'` is 1, so our multiplicand is simply the first limb of the intermediate A.
95
///
96
/// - The first limb of p is 2^64 - 1; multiplications by this limb can be simplified
97
///   to a shift and subtraction:
98
///   ```text
99
///       a_i * (2^64 - 1) = a_i * 2^64 - a_i = (a_i << 64) - a_i
100
///   ```
101
///   However, because `p' = 1`, the first limb of p is multiplied by limb i of the
102
///   intermediate A and then immediately added to that same limb, so we simply
103
///   initialize the carry to limb i of the intermediate.
104
///
105
/// - The third limb of p is zero, so we can ignore any multiplications by it and just
106
///   add the carry.
107
///
108
/// References:
109
/// - Handbook of Applied Cryptography, Chapter 14
110
///   Algorithm 14.32
111
///   http://cacr.uwaterloo.ca/hac/about/chap14.pdf
112
///
113
/// - Efficient and Secure Elliptic Curve Cryptography Implementation of Curve P-256
114
///   Algorithm 7) Montgomery Word-by-Word Reduction
115
///   https://csrc.nist.gov/csrc/media/events/workshop-on-elliptic-curve-cryptography-standards/documents/papers/session6-adalier-mehmet.pdf
116
#[inline]
117
#[allow(clippy::too_many_arguments)]
118
8.26M
const fn montgomery_reduce(r: &[u64; 8]) -> Fe {
119
8.26M
    let r0 = r[0];
120
8.26M
    let r1 = r[1];
121
8.26M
    let r2 = r[2];
122
8.26M
    let r3 = r[3];
123
8.26M
    let r4 = r[4];
124
8.26M
    let r5 = r[5];
125
8.26M
    let r6 = r[6];
126
8.26M
    let r7 = r[7];
127
8.26M
    let modulus = MODULUS.as_words();
128
8.26M
129
8.26M
    let (r1, carry) = mac(r1, r0, modulus[1], r0);
130
8.26M
    let (r2, carry) = adc(r2, 0, carry);
131
8.26M
    let (r3, carry) = mac(r3, r0, modulus[3], carry);
132
8.26M
    let (r4, carry2) = adc(r4, 0, carry);
133
8.26M
134
8.26M
    let (r2, carry) = mac(r2, r1, modulus[1], r1);
135
8.26M
    let (r3, carry) = adc(r3, 0, carry);
136
8.26M
    let (r4, carry) = mac(r4, r1, modulus[3], carry);
137
8.26M
    let (r5, carry2) = adc(r5, carry2, carry);
138
8.26M
139
8.26M
    let (r3, carry) = mac(r3, r2, modulus[1], r2);
140
8.26M
    let (r4, carry) = adc(r4, 0, carry);
141
8.26M
    let (r5, carry) = mac(r5, r2, modulus[3], carry);
142
8.26M
    let (r6, carry2) = adc(r6, carry2, carry);
143
8.26M
144
8.26M
    let (r4, carry) = mac(r4, r3, modulus[1], r3);
145
8.26M
    let (r5, carry) = adc(r5, 0, carry);
146
8.26M
    let (r6, carry) = mac(r6, r3, modulus[3], carry);
147
8.26M
    let (r7, r8) = adc(r7, carry2, carry);
148
8.26M
149
8.26M
    // Result may be within MODULUS of the correct value
150
8.26M
    sub_inner(
151
8.26M
        &[r4, r5, r6, r7, r8],
152
8.26M
        &[modulus[0], modulus[1], modulus[2], modulus[3], 0],
153
8.26M
    )
154
8.26M
}
155
156
#[inline]
157
#[allow(clippy::too_many_arguments)]
158
21.4M
const fn sub_inner(l: &[u64; 5], r: &[u64; 5]) -> Fe {
159
21.4M
    let (w0, borrow) = sbb(l[0], r[0], 0);
160
21.4M
    let (w1, borrow) = sbb(l[1], r[1], borrow);
161
21.4M
    let (w2, borrow) = sbb(l[2], r[2], borrow);
162
21.4M
    let (w3, borrow) = sbb(l[3], r[3], borrow);
163
21.4M
    let (_, borrow) = sbb(l[4], r[4], borrow);
164
21.4M
165
21.4M
    // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise
166
21.4M
    // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the
167
21.4M
    // modulus.
168
21.4M
    let modulus = MODULUS.as_words();
169
21.4M
    let (w0, carry) = adc(w0, modulus[0] & borrow, 0);
170
21.4M
    let (w1, carry) = adc(w1, modulus[1] & borrow, carry);
171
21.4M
    let (w2, carry) = adc(w2, modulus[2] & borrow, carry);
172
21.4M
    let (w3, _) = adc(w3, modulus[3] & borrow, carry);
173
21.4M
174
21.4M
    [w0, w1, w2, w3]
175
21.4M
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/p256-0.13.2/src/arithmetic/scalar.rs
Line
Count
Source
1
//! Scalar field arithmetic modulo n = 115792089210356248762697446949407573529996955224135760342422259061068512044369
2
3
#[cfg_attr(target_pointer_width = "32", path = "scalar/scalar32.rs")]
4
#[cfg_attr(target_pointer_width = "64", path = "scalar/scalar64.rs")]
5
mod scalar_impl;
6
7
use self::scalar_impl::barrett_reduce;
8
use crate::{FieldBytes, NistP256, SecretKey, ORDER_HEX};
9
use core::{
10
    fmt::{self, Debug},
11
    iter::{Product, Sum},
12
    ops::{Add, AddAssign, Mul, MulAssign, Neg, Shr, ShrAssign, Sub, SubAssign},
13
};
14
use elliptic_curve::{
15
    bigint::{prelude::*, Limb, U256},
16
    group::ff::{self, Field, PrimeField},
17
    ops::{Invert, Reduce, ReduceNonZero},
18
    rand_core::RngCore,
19
    scalar::{FromUintUnchecked, IsHigh},
20
    subtle::{
21
        Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
22
        CtOption,
23
    },
24
    zeroize::DefaultIsZeroes,
25
    Curve, ScalarPrimitive,
26
};
27
28
#[cfg(feature = "bits")]
29
use {crate::ScalarBits, elliptic_curve::group::ff::PrimeFieldBits};
30
31
#[cfg(feature = "serde")]
32
use serdect::serde::{de, ser, Deserialize, Serialize};
33
34
/// Constant representing the modulus
35
/// n = FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551
36
pub(crate) const MODULUS: U256 = NistP256::ORDER;
37
38
/// `MODULUS / 2`
39
const FRAC_MODULUS_2: Scalar = Scalar(MODULUS.shr_vartime(1));
40
41
/// MU = floor(2^512 / n)
42
///    = 115792089264276142090721624801893421302707618245269942344307673200490803338238
43
///    = 0x100000000fffffffffffffffeffffffff43190552df1a6c21012ffd85eedf9bfe
44
pub const MU: [u64; 5] = [
45
    0x012f_fd85_eedf_9bfe,
46
    0x4319_0552_df1a_6c21,
47
    0xffff_fffe_ffff_ffff,
48
    0x0000_0000_ffff_ffff,
49
    0x0000_0000_0000_0001,
50
];
51
52
/// Scalars are elements in the finite field modulo n.
53
///
54
/// # Trait impls
55
///
56
/// Much of the important functionality of scalars is provided by traits from
57
/// the [`ff`](https://docs.rs/ff/) crate, which is re-exported as
58
/// `p256::elliptic_curve::ff`:
59
///
60
/// - [`Field`](https://docs.rs/ff/latest/ff/trait.Field.html) -
61
///   represents elements of finite fields and provides:
62
///   - [`Field::random`](https://docs.rs/ff/latest/ff/trait.Field.html#tymethod.random) -
63
///     generate a random scalar
64
///   - `double`, `square`, and `invert` operations
65
///   - Bounds for [`Add`], [`Sub`], [`Mul`], and [`Neg`] (as well as `*Assign` equivalents)
66
///   - Bounds for [`ConditionallySelectable`] from the `subtle` crate
67
/// - [`PrimeField`](https://docs.rs/ff/latest/ff/trait.PrimeField.html) -
68
///   represents elements of prime fields and provides:
69
///   - `from_repr`/`to_repr` for converting field elements from/to big integers.
70
///   - `multiplicative_generator` and `root_of_unity` constants.
71
/// - [`PrimeFieldBits`](https://docs.rs/ff/latest/ff/trait.PrimeFieldBits.html) -
72
///   operations over field elements represented as bits (requires `bits` feature)
73
///
74
/// Please see the documentation for the relevant traits for more information.
75
///
76
/// # `serde` support
77
///
78
/// When the `serde` feature of this crate is enabled, the `Serialize` and
79
/// `Deserialize` traits are impl'd for this type.
80
///
81
/// The serialization is a fixed-width big endian encoding. When used with
82
/// textual formats, the binary data is encoded as hexadecimal.
83
#[derive(Clone, Copy, Default)]
84
pub struct Scalar(pub(crate) U256);
85
86
impl Scalar {
87
    /// Zero scalar.
88
    pub const ZERO: Self = Self(U256::ZERO);
89
90
    /// Multiplicative identity.
91
    pub const ONE: Self = Self(U256::ONE);
92
93
    /// Returns the SEC1 encoding of this scalar.
94
0
    pub fn to_bytes(&self) -> FieldBytes {
95
0
        self.0.to_be_byte_array()
96
0
    }
97
98
    /// Returns self + rhs mod n
99
286k
    pub const fn add(&self, rhs: &Self) -> Self {
100
286k
        Self(self.0.add_mod(&rhs.0, &NistP256::ORDER))
101
286k
    }
102
103
    /// Returns 2*self.
104
0
    pub const fn double(&self) -> Self {
105
0
        self.add(self)
106
0
    }
107
108
    /// Returns self - rhs mod n.
109
308k
    pub const fn sub(&self, rhs: &Self) -> Self {
110
308k
        Self(self.0.sub_mod(&rhs.0, &NistP256::ORDER))
111
308k
    }
112
113
    /// Returns self * rhs mod n
114
1.67k
    pub const fn multiply(&self, rhs: &Self) -> Self {
115
1.67k
        let (lo, hi) = self.0.mul_wide(&rhs.0);
116
1.67k
        Self(barrett_reduce(lo, hi))
117
1.67k
    }
118
119
    /// Returns self * self mod p
120
0
    pub const fn square(&self) -> Self {
121
0
        // Schoolbook multiplication.
122
0
        self.multiply(self)
123
0
    }
124
125
    /// Right shifts the scalar.
126
    ///
127
    /// Note: not constant-time with respect to the `shift` parameter.
128
597k
    pub const fn shr_vartime(&self, shift: usize) -> Scalar {
129
597k
        Self(self.0.shr_vartime(shift))
130
597k
    }
131
132
    /// Returns the multiplicative inverse of self, if self is non-zero
133
0
    pub fn invert(&self) -> CtOption<Self> {
134
0
        CtOption::new(self.invert_unchecked(), !self.is_zero())
135
0
    }
136
137
    /// Returns the multiplicative inverse of self.
138
    ///
139
    /// Does not check that self is non-zero.
140
0
    const fn invert_unchecked(&self) -> Self {
141
0
        // We need to find b such that b * a ≡ 1 mod p. As we are in a prime
142
0
        // field, we can apply Fermat's Little Theorem:
143
0
        //
144
0
        //    a^p         ≡ a mod p
145
0
        //    a^(p-1)     ≡ 1 mod p
146
0
        //    a^(p-2) * a ≡ 1 mod p
147
0
        //
148
0
        // Thus inversion can be implemented with a single exponentiation.
149
0
        //
150
0
        // This is `n - 2`, so the top right two digits are `4f` instead of `51`.
151
0
        self.pow_vartime(&[
152
0
            0xf3b9_cac2_fc63_254f,
153
0
            0xbce6_faad_a717_9e84,
154
0
            0xffff_ffff_ffff_ffff,
155
0
            0xffff_ffff_0000_0000,
156
0
        ])
157
0
    }
158
159
    /// Exponentiates `self` by `exp`, where `exp` is a little-endian order integer
160
    /// exponent.
161
0
    pub const fn pow_vartime(&self, exp: &[u64]) -> Self {
162
0
        let mut res = Self::ONE;
163
0
164
0
        let mut i = exp.len();
165
0
        while i > 0 {
166
0
            i -= 1;
167
0
168
0
            let mut j = 64;
169
0
            while j > 0 {
170
0
                j -= 1;
171
0
                res = res.square();
172
0
173
0
                if ((exp[i] >> j) & 1) == 1 {
174
0
                    res = res.multiply(self);
175
0
                }
176
            }
177
        }
178
179
0
        res
180
0
    }
181
182
    /// Is integer representing equivalence class odd?
183
905k
    pub fn is_odd(&self) -> Choice {
184
905k
        self.0.is_odd()
185
905k
    }
186
187
    /// Is integer representing equivalence class even?
188
607k
    pub fn is_even(&self) -> Choice {
189
607k
        !self.is_odd()
190
607k
    }
191
}
192
193
impl AsRef<Scalar> for Scalar {
194
0
    fn as_ref(&self) -> &Scalar {
195
0
        self
196
0
    }
197
}
198
199
impl Field for Scalar {
200
    const ZERO: Self = Self::ZERO;
201
    const ONE: Self = Self::ONE;
202
203
0
    fn random(mut rng: impl RngCore) -> Self {
204
0
        let mut bytes = FieldBytes::default();
205
206
        // Generate a uniformly random scalar using rejection sampling,
207
        // which produces a uniformly random distribution of scalars.
208
        //
209
        // This method is not constant time, but should be secure so long as
210
        // rejected RNG outputs are unrelated to future ones (which is a
211
        // necessary property of a `CryptoRng`).
212
        //
213
        // With an unbiased RNG, the probability of failing to complete after 4
214
        // iterations is vanishingly small.
215
        loop {
216
0
            rng.fill_bytes(&mut bytes);
217
0
            if let Some(scalar) = Scalar::from_repr(bytes).into() {
218
0
                return scalar;
219
0
            }
220
        }
221
0
    }
222
223
    #[must_use]
224
0
    fn square(&self) -> Self {
225
0
        Scalar::square(self)
226
0
    }
227
228
    #[must_use]
229
0
    fn double(&self) -> Self {
230
0
        self.add(self)
231
0
    }
232
233
0
    fn invert(&self) -> CtOption<Self> {
234
0
        Scalar::invert(self)
235
0
    }
236
237
    /// Tonelli-Shank's algorithm for q mod 16 = 1
238
    /// <https://eprint.iacr.org/2012/685.pdf> (page 12, algorithm 5)
239
    #[allow(clippy::many_single_char_names)]
240
0
    fn sqrt(&self) -> CtOption<Self> {
241
0
        // Note: `pow_vartime` is constant-time with respect to `self`
242
0
        let w = self.pow_vartime(&[
243
0
            0x279dce5617e3192a,
244
0
            0xfde737d56d38bcf4,
245
0
            0x07ffffffffffffff,
246
0
            0x07fffffff8000000,
247
0
        ]);
248
0
249
0
        let mut v = Self::S;
250
0
        let mut x = *self * w;
251
0
        let mut b = x * w;
252
0
        let mut z = Self::ROOT_OF_UNITY;
253
254
0
        for max_v in (1..=Self::S).rev() {
255
0
            let mut k = 1;
256
0
            let mut tmp = b.square();
257
0
            let mut j_less_than_v = Choice::from(1);
258
259
0
            for j in 2..max_v {
260
0
                let tmp_is_one = tmp.ct_eq(&Self::ONE);
261
0
                let squared = Self::conditional_select(&tmp, &z, tmp_is_one).square();
262
0
                tmp = Self::conditional_select(&squared, &tmp, tmp_is_one);
263
0
                let new_z = Self::conditional_select(&z, &squared, tmp_is_one);
264
0
                j_less_than_v &= !j.ct_eq(&v);
265
0
                k = u32::conditional_select(&j, &k, tmp_is_one);
266
0
                z = Self::conditional_select(&z, &new_z, j_less_than_v);
267
0
            }
268
269
0
            let result = x * z;
270
0
            x = Self::conditional_select(&result, &x, b.ct_eq(&Self::ONE));
271
0
            z = z.square();
272
0
            b *= z;
273
0
            v = k;
274
        }
275
276
0
        CtOption::new(x, x.square().ct_eq(self))
277
0
    }
278
279
0
    fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
280
0
        ff::helpers::sqrt_ratio_generic(num, div)
281
0
    }
282
}
283
284
impl PrimeField for Scalar {
285
    type Repr = FieldBytes;
286
287
    const MODULUS: &'static str = ORDER_HEX;
288
    const NUM_BITS: u32 = 256;
289
    const CAPACITY: u32 = 255;
290
    const TWO_INV: Self = Self(U256::from_u8(2)).invert_unchecked();
291
    const MULTIPLICATIVE_GENERATOR: Self = Self(U256::from_u8(7));
292
    const S: u32 = 4;
293
    const ROOT_OF_UNITY: Self = Self(U256::from_be_hex(
294
        "ffc97f062a770992ba807ace842a3dfc1546cad004378daf0592d7fbb41e6602",
295
    ));
296
    const ROOT_OF_UNITY_INV: Self = Self::ROOT_OF_UNITY.invert_unchecked();
297
    const DELTA: Self = Self(U256::from_u64(33232930569601));
298
299
    /// Attempts to parse the given byte array as an SEC1-encoded scalar.
300
    ///
301
    /// Returns None if the byte array does not contain a big-endian integer in the range
302
    /// [0, p).
303
0
    fn from_repr(bytes: FieldBytes) -> CtOption<Self> {
304
0
        let inner = U256::from_be_byte_array(bytes);
305
0
        CtOption::new(Self(inner), inner.ct_lt(&NistP256::ORDER))
306
0
    }
307
308
0
    fn to_repr(&self) -> FieldBytes {
309
0
        self.to_bytes()
310
0
    }
311
312
0
    fn is_odd(&self) -> Choice {
313
0
        self.0.is_odd()
314
0
    }
315
}
316
317
#[cfg(feature = "bits")]
318
impl PrimeFieldBits for Scalar {
319
    #[cfg(target_pointer_width = "32")]
320
    type ReprBits = [u32; 8];
321
322
    #[cfg(target_pointer_width = "64")]
323
    type ReprBits = [u64; 4];
324
325
    fn to_le_bits(&self) -> ScalarBits {
326
        self.into()
327
    }
328
329
    fn char_le_bits() -> ScalarBits {
330
        NistP256::ORDER.to_words().into()
331
    }
332
}
333
334
impl DefaultIsZeroes for Scalar {}
335
336
impl Eq for Scalar {}
337
338
impl FromUintUnchecked for Scalar {
339
    type Uint = U256;
340
341
0
    fn from_uint_unchecked(uint: Self::Uint) -> Self {
342
0
        Self(uint)
343
0
    }
344
}
345
346
impl Invert for Scalar {
347
    type Output = CtOption<Self>;
348
349
0
    fn invert(&self) -> CtOption<Self> {
350
0
        self.invert()
351
0
    }
352
353
    /// Fast variable-time inversion using Stein's algorithm.
354
    ///
355
    /// Returns none if the scalar is zero.
356
    ///
357
    /// <https://link.springer.com/article/10.1007/s13389-016-0135-4>
358
    ///
359
    /// ⚠️ WARNING!
360
    ///
361
    /// This method should not be used with (unblinded) secret scalars, as its
362
    /// variable-time operation can potentially leak secrets through
363
    /// sidechannels.
364
    #[allow(non_snake_case)]
365
838
    fn invert_vartime(&self) -> CtOption<Self> {
366
838
        let mut u = *self;
367
838
        let mut v = Self(MODULUS);
368
838
        let mut A = Self::ONE;
369
838
        let mut C = Self::ZERO;
370
371
155k
        while !bool::from(u.is_zero()) {
372
            // u-loop
373
302k
            while bool::from(u.is_even()) {
374
147k
                u >>= 1;
375
147k
376
147k
                let was_odd: bool = A.is_odd().into();
377
147k
                A >>= 1;
378
147k
379
147k
                if was_odd {
380
70.0k
                    A += FRAC_MODULUS_2;
381
70.0k
                    A += Self::ONE;
382
77.7k
                }
383
            }
384
385
            // v-loop
386
304k
            while bool::from(v.is_even()) {
387
150k
                v >>= 1;
388
150k
389
150k
                let was_odd: bool = C.is_odd().into();
390
150k
                C >>= 1;
391
150k
392
150k
                if was_odd {
393
73.1k
                    C += FRAC_MODULUS_2;
394
73.1k
                    C += Self::ONE;
395
77.5k
                }
396
            }
397
398
            // sub-step
399
154k
            if u >= v {
400
74.0k
                u -= &v;
401
74.0k
                A -= &C;
402
80.1k
            } else {
403
80.1k
                v -= &u;
404
80.1k
                C -= &A;
405
80.1k
            }
406
        }
407
408
838
        CtOption::new(C, !self.is_zero())
409
838
    }
410
}
411
412
impl IsHigh for Scalar {
413
0
    fn is_high(&self) -> Choice {
414
0
        self.0.ct_gt(&FRAC_MODULUS_2.0)
415
0
    }
416
}
417
418
impl Shr<usize> for Scalar {
419
    type Output = Self;
420
421
597k
    fn shr(self, rhs: usize) -> Self::Output {
422
597k
        self.shr_vartime(rhs)
423
597k
    }
424
}
425
426
impl Shr<usize> for &Scalar {
427
    type Output = Scalar;
428
429
0
    fn shr(self, rhs: usize) -> Self::Output {
430
0
        self.shr_vartime(rhs)
431
0
    }
432
}
433
434
impl ShrAssign<usize> for Scalar {
435
597k
    fn shr_assign(&mut self, rhs: usize) {
436
597k
        *self = *self >> rhs;
437
597k
    }
438
}
439
440
impl PartialEq for Scalar {
441
838
    fn eq(&self, other: &Self) -> bool {
442
838
        self.ct_eq(other).into()
443
838
    }
444
}
445
446
impl PartialOrd for Scalar {
447
154k
    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
448
154k
        Some(self.cmp(other))
449
154k
    }
450
}
451
452
impl Ord for Scalar {
453
154k
    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
454
154k
        self.0.cmp(&other.0)
455
154k
    }
456
}
457
458
impl From<u32> for Scalar {
459
0
    fn from(k: u32) -> Self {
460
0
        Scalar(k.into())
461
0
    }
462
}
463
464
impl From<u64> for Scalar {
465
0
    fn from(k: u64) -> Self {
466
0
        Scalar(k.into())
467
0
    }
468
}
469
470
impl From<u128> for Scalar {
471
0
    fn from(k: u128) -> Self {
472
0
        Scalar(k.into())
473
0
    }
474
}
475
476
impl From<Scalar> for FieldBytes {
477
0
    fn from(scalar: Scalar) -> Self {
478
0
        scalar.to_bytes()
479
0
    }
480
}
481
482
impl From<&Scalar> for FieldBytes {
483
0
    fn from(scalar: &Scalar) -> Self {
484
0
        scalar.to_bytes()
485
0
    }
486
}
487
488
impl From<ScalarPrimitive<NistP256>> for Scalar {
489
1.67k
    fn from(scalar: ScalarPrimitive<NistP256>) -> Scalar {
490
1.67k
        Scalar(*scalar.as_uint())
491
1.67k
    }
_RNvXsi_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalarNtB5_6ScalarINtNtCsbQ8arDwx5Xq_4core7convert4FromINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtB9_8NistP256EE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
489
1.67k
    fn from(scalar: ScalarPrimitive<NistP256>) -> Scalar {
490
1.67k
        Scalar(*scalar.as_uint())
491
1.67k
    }
Unexecuted instantiation: _RNvXsi_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalarNtB5_6ScalarINtNtCsbQ8arDwx5Xq_4core7convert4FromINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtB9_8NistP256EE4fromB9_
492
}
493
494
impl From<&ScalarPrimitive<NistP256>> for Scalar {
495
0
    fn from(scalar: &ScalarPrimitive<NistP256>) -> Scalar {
496
0
        Scalar(*scalar.as_uint())
497
0
    }
498
}
499
500
impl From<Scalar> for ScalarPrimitive<NistP256> {
501
0
    fn from(scalar: Scalar) -> ScalarPrimitive<NistP256> {
502
0
        ScalarPrimitive::from(&scalar)
503
0
    }
504
}
505
506
impl From<&Scalar> for ScalarPrimitive<NistP256> {
507
0
    fn from(scalar: &Scalar) -> ScalarPrimitive<NistP256> {
508
0
        ScalarPrimitive::new(scalar.0).unwrap()
509
0
    }
510
}
511
512
impl From<&SecretKey> for Scalar {
513
0
    fn from(secret_key: &SecretKey) -> Scalar {
514
0
        *secret_key.to_nonzero_scalar()
515
0
    }
516
}
517
518
impl From<Scalar> for U256 {
519
1.67k
    fn from(scalar: Scalar) -> U256 {
520
1.67k
        scalar.0
521
1.67k
    }
_RNvXsn_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalarINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_6ScalarE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
519
1.67k
    fn from(scalar: Scalar) -> U256 {
520
1.67k
        scalar.0
521
1.67k
    }
Unexecuted instantiation: _RNvXsn_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalarINtNtCshRehcWQJ0wE_13crypto_bigint4uint4UintKj4_EINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_6ScalarE4fromB9_
522
}
523
524
impl From<&Scalar> for U256 {
525
0
    fn from(scalar: &Scalar) -> U256 {
526
0
        scalar.0
527
0
    }
528
}
529
530
#[cfg(feature = "bits")]
531
impl From<&Scalar> for ScalarBits {
532
    fn from(scalar: &Scalar) -> ScalarBits {
533
        scalar.0.to_words().into()
534
    }
535
}
536
537
impl Add<Scalar> for Scalar {
538
    type Output = Scalar;
539
540
0
    fn add(self, other: Scalar) -> Scalar {
541
0
        Scalar::add(&self, &other)
542
0
    }
543
}
544
545
impl Add<&Scalar> for &Scalar {
546
    type Output = Scalar;
547
548
0
    fn add(self, other: &Scalar) -> Scalar {
549
0
        Scalar::add(self, other)
550
0
    }
551
}
552
553
impl Add<&Scalar> for Scalar {
554
    type Output = Scalar;
555
556
0
    fn add(self, other: &Scalar) -> Scalar {
557
0
        Scalar::add(&self, other)
558
0
    }
559
}
560
561
impl AddAssign<Scalar> for Scalar {
562
286k
    fn add_assign(&mut self, rhs: Scalar) {
563
286k
        *self = Scalar::add(self, &rhs);
564
286k
    }
565
}
566
567
impl AddAssign<&Scalar> for Scalar {
568
0
    fn add_assign(&mut self, rhs: &Scalar) {
569
0
        *self = Scalar::add(self, rhs);
570
0
    }
571
}
572
573
impl Sub<Scalar> for Scalar {
574
    type Output = Scalar;
575
576
0
    fn sub(self, other: Scalar) -> Scalar {
577
0
        Scalar::sub(&self, &other)
578
0
    }
579
}
580
581
impl Sub<&Scalar> for &Scalar {
582
    type Output = Scalar;
583
584
0
    fn sub(self, other: &Scalar) -> Scalar {
585
0
        Scalar::sub(self, other)
586
0
    }
587
}
588
589
impl Sub<&Scalar> for Scalar {
590
    type Output = Scalar;
591
592
0
    fn sub(self, other: &Scalar) -> Scalar {
593
0
        Scalar::sub(&self, other)
594
0
    }
595
}
596
597
impl SubAssign<Scalar> for Scalar {
598
0
    fn sub_assign(&mut self, rhs: Scalar) {
599
0
        *self = Scalar::sub(self, &rhs);
600
0
    }
601
}
602
603
impl SubAssign<&Scalar> for Scalar {
604
308k
    fn sub_assign(&mut self, rhs: &Scalar) {
605
308k
        *self = Scalar::sub(self, rhs);
606
308k
    }
607
}
608
609
impl Mul<Scalar> for Scalar {
610
    type Output = Scalar;
611
612
1.67k
    fn mul(self, other: Scalar) -> Scalar {
613
1.67k
        Scalar::multiply(&self, &other)
614
1.67k
    }
615
}
616
617
impl Mul<&Scalar> for &Scalar {
618
    type Output = Scalar;
619
620
0
    fn mul(self, other: &Scalar) -> Scalar {
621
0
        Scalar::multiply(self, other)
622
0
    }
623
}
624
625
impl Mul<&Scalar> for Scalar {
626
    type Output = Scalar;
627
628
0
    fn mul(self, other: &Scalar) -> Scalar {
629
0
        Scalar::multiply(&self, other)
630
0
    }
631
}
632
633
impl MulAssign<Scalar> for Scalar {
634
0
    fn mul_assign(&mut self, rhs: Scalar) {
635
0
        *self = Scalar::multiply(self, &rhs);
636
0
    }
637
}
638
639
impl MulAssign<&Scalar> for Scalar {
640
0
    fn mul_assign(&mut self, rhs: &Scalar) {
641
0
        *self = Scalar::multiply(self, rhs);
642
0
    }
643
}
644
645
impl Neg for Scalar {
646
    type Output = Scalar;
647
648
0
    fn neg(self) -> Scalar {
649
0
        Scalar::ZERO - self
650
0
    }
651
}
652
653
impl<'a> Neg for &'a Scalar {
654
    type Output = Scalar;
655
656
0
    fn neg(self) -> Scalar {
657
0
        Scalar::ZERO - self
658
0
    }
659
}
660
661
impl Reduce<U256> for Scalar {
662
    type Bytes = FieldBytes;
663
664
1.67k
    fn reduce(w: U256) -> Self {
665
1.67k
        let (r, underflow) = w.sbb(&NistP256::ORDER, Limb::ZERO);
666
1.67k
        let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8);
667
1.67k
        Self(U256::conditional_select(&w, &r, !underflow))
668
1.67k
    }
669
670
1.67k
    fn reduce_bytes(bytes: &FieldBytes) -> Self {
671
1.67k
        Self::reduce(U256::from_be_byte_array(*bytes))
672
1.67k
    }
673
}
674
675
impl ReduceNonZero<U256> for Scalar {
676
0
    fn reduce_nonzero(w: U256) -> Self {
677
        const ORDER_MINUS_ONE: U256 = NistP256::ORDER.wrapping_sub(&U256::ONE);
678
0
        let (r, underflow) = w.sbb(&ORDER_MINUS_ONE, Limb::ZERO);
679
0
        let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8);
680
0
        Self(U256::conditional_select(&w, &r, !underflow).wrapping_add(&U256::ONE))
681
0
    }
682
683
0
    fn reduce_nonzero_bytes(bytes: &FieldBytes) -> Self {
684
0
        Self::reduce_nonzero(U256::from_be_byte_array(*bytes))
685
0
    }
686
}
687
688
impl Sum for Scalar {
689
0
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
690
0
        iter.reduce(core::ops::Add::add).unwrap_or(Self::ZERO)
691
0
    }
692
}
693
694
impl<'a> Sum<&'a Scalar> for Scalar {
695
0
    fn sum<I: Iterator<Item = &'a Scalar>>(iter: I) -> Self {
696
0
        iter.copied().sum()
697
0
    }
698
}
699
700
impl Product for Scalar {
701
0
    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
702
0
        iter.reduce(core::ops::Mul::mul).unwrap_or(Self::ONE)
703
0
    }
704
}
705
706
impl<'a> Product<&'a Scalar> for Scalar {
707
0
    fn product<I: Iterator<Item = &'a Scalar>>(iter: I) -> Self {
708
0
        iter.copied().product()
709
0
    }
710
}
711
712
impl ConditionallySelectable for Scalar {
713
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
714
0
        Self(U256::conditional_select(&a.0, &b.0, choice))
715
0
    }
716
}
717
718
impl ConstantTimeEq for Scalar {
719
158k
    fn ct_eq(&self, other: &Self) -> Choice {
720
158k
        self.0.ct_eq(&other.0)
721
158k
    }
722
}
723
724
impl Debug for Scalar {
725
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
726
0
        write!(f, "Scalar(0x{:X})", &self.0)
727
0
    }
728
}
729
730
#[cfg(feature = "serde")]
731
impl Serialize for Scalar {
732
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
733
    where
734
        S: ser::Serializer,
735
    {
736
        ScalarPrimitive::from(self).serialize(serializer)
737
    }
738
}
739
740
#[cfg(feature = "serde")]
741
impl<'de> Deserialize<'de> for Scalar {
742
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
743
    where
744
        D: de::Deserializer<'de>,
745
    {
746
        Ok(ScalarPrimitive::deserialize(deserializer)?.into())
747
    }
748
}
749
750
#[cfg(test)]
751
mod tests {
752
    use super::Scalar;
753
    use crate::{FieldBytes, SecretKey};
754
    use elliptic_curve::group::ff::{Field, PrimeField};
755
    use primeorder::{
756
        impl_field_identity_tests, impl_field_invert_tests, impl_field_sqrt_tests,
757
        impl_primefield_tests,
758
    };
759
760
    /// t = (modulus - 1) >> S
761
    const T: [u64; 4] = [
762
        0x4f3b9cac2fc63255,
763
        0xfbce6faada7179e8,
764
        0x0fffffffffffffff,
765
        0x0ffffffff0000000,
766
    ];
767
768
    impl_field_identity_tests!(Scalar);
769
    impl_field_invert_tests!(Scalar);
770
    impl_field_sqrt_tests!(Scalar);
771
    impl_primefield_tests!(Scalar, T);
772
773
    #[test]
774
    fn from_to_bytes_roundtrip() {
775
        let k: u64 = 42;
776
        let mut bytes = FieldBytes::default();
777
        bytes[24..].copy_from_slice(k.to_be_bytes().as_ref());
778
779
        let scalar = Scalar::from_repr(bytes).unwrap();
780
        assert_eq!(bytes, scalar.to_bytes());
781
    }
782
783
    /// Basic tests that multiplication works.
784
    #[test]
785
    fn multiply() {
786
        let one = Scalar::ONE;
787
        let two = one + &one;
788
        let three = two + &one;
789
        let six = three + &three;
790
        assert_eq!(six, two * &three);
791
792
        let minus_two = -two;
793
        let minus_three = -three;
794
        assert_eq!(two, -minus_two);
795
796
        assert_eq!(minus_three * &minus_two, minus_two * &minus_three);
797
        assert_eq!(six, minus_two * &minus_three);
798
    }
799
800
    /// Tests that a Scalar can be safely converted to a SecretKey and back
801
    #[test]
802
    fn from_ec_secret() {
803
        let scalar = Scalar::ONE;
804
        let secret = SecretKey::from_bytes(&scalar.to_bytes()).unwrap();
805
        let rederived_scalar = Scalar::from(&secret);
806
        assert_eq!(scalar.0, rederived_scalar.0);
807
    }
808
809
    #[test]
810
    #[cfg(all(feature = "bits", target_pointer_width = "32"))]
811
    fn scalar_into_scalarbits() {
812
        use crate::ScalarBits;
813
814
        let minus_one = ScalarBits::from([
815
            0xfc63_2550,
816
            0xf3b9_cac2,
817
            0xa717_9e84,
818
            0xbce6_faad,
819
            0xffff_ffff,
820
            0xffff_ffff,
821
            0x0000_0000,
822
            0xffff_ffff,
823
        ]);
824
825
        let scalar_bits = ScalarBits::from(&-Scalar::from(1u32));
826
        assert_eq!(minus_one, scalar_bits);
827
    }
828
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/p256-0.13.2/src/arithmetic/scalar/scalar64.rs
Line
Count
Source
1
//! 64-bit secp256r1 scalar field algorithms.
2
3
use super::{MODULUS, MU};
4
use crate::{
5
    arithmetic::util::{adc, mac, sbb},
6
    U256,
7
};
8
9
/// Barrett Reduction
10
///
11
/// The general algorithm is:
12
/// ```text
13
/// p = n = order of group
14
/// b = 2^64 = 64bit machine word
15
/// k = 4
16
/// a \in [0, 2^512]
17
/// mu := floor(b^{2k} / p)
18
/// q1 := floor(a / b^{k - 1})
19
/// q2 := q1 * mu
20
/// q3 := <- floor(a / b^{k - 1})
21
/// r1 := a mod b^{k + 1}
22
/// r2 := q3 * m mod b^{k + 1}
23
/// r := r1 - r2
24
///
25
/// if r < 0: r := r + b^{k + 1}
26
/// while r >= p: do r := r - p (at most twice)
27
/// ```
28
///
29
/// References:
30
/// - Handbook of Applied Cryptography, Chapter 14
31
///   Algorithm 14.42
32
///   http://cacr.uwaterloo.ca/hac/about/chap14.pdf
33
///
34
/// - Efficient and Secure Elliptic Curve Cryptography Implementation of Curve P-256
35
///   Algorithm 6) Barrett Reduction modulo p
36
///   https://csrc.nist.gov/csrc/media/events/workshop-on-elliptic-curve-cryptography-standards/documents/papers/session6-adalier-mehmet.pdf
37
#[inline]
38
#[allow(clippy::too_many_arguments)]
39
1.67k
pub(super) const fn barrett_reduce(lo: U256, hi: U256) -> U256 {
40
1.67k
    let lo = lo.as_words();
41
1.67k
    let hi = hi.as_words();
42
1.67k
    let a0 = lo[0];
43
1.67k
    let a1 = lo[1];
44
1.67k
    let a2 = lo[2];
45
1.67k
    let a3 = lo[3];
46
1.67k
    let a4 = hi[0];
47
1.67k
    let a5 = hi[1];
48
1.67k
    let a6 = hi[2];
49
1.67k
    let a7 = hi[3];
50
1.67k
    let q1: [u64; 5] = [a3, a4, a5, a6, a7];
51
1.67k
    let q3 = q1_times_mu_shift_five(&q1);
52
1.67k
53
1.67k
    let r1: [u64; 5] = [a0, a1, a2, a3, a4];
54
1.67k
    let r2: [u64; 5] = q3_times_n_keep_five(&q3);
55
1.67k
    let r: [u64; 5] = sub_inner_five(r1, r2);
56
1.67k
57
1.67k
    // Result is in range (0, 3*n - 1),
58
1.67k
    // and 90% of the time, no subtraction will be needed.
59
1.67k
    let r = subtract_n_if_necessary(r[0], r[1], r[2], r[3], r[4]);
60
1.67k
    let r = subtract_n_if_necessary(r[0], r[1], r[2], r[3], r[4]);
61
1.67k
    U256::from_words([r[0], r[1], r[2], r[3]])
62
1.67k
}
63
64
1.67k
const fn q1_times_mu_shift_five(q1: &[u64; 5]) -> [u64; 5] {
65
1.67k
    // Schoolbook multiplication.
66
1.67k
67
1.67k
    let (_w0, carry) = mac(0, q1[0], MU[0], 0);
68
1.67k
    let (w1, carry) = mac(0, q1[0], MU[1], carry);
69
1.67k
    let (w2, carry) = mac(0, q1[0], MU[2], carry);
70
1.67k
    let (w3, carry) = mac(0, q1[0], MU[3], carry);
71
1.67k
    let (w4, w5) = mac(0, q1[0], MU[4], carry);
72
1.67k
73
1.67k
    let (_w1, carry) = mac(w1, q1[1], MU[0], 0);
74
1.67k
    let (w2, carry) = mac(w2, q1[1], MU[1], carry);
75
1.67k
    let (w3, carry) = mac(w3, q1[1], MU[2], carry);
76
1.67k
    let (w4, carry) = mac(w4, q1[1], MU[3], carry);
77
1.67k
    let (w5, w6) = mac(w5, q1[1], MU[4], carry);
78
1.67k
79
1.67k
    let (_w2, carry) = mac(w2, q1[2], MU[0], 0);
80
1.67k
    let (w3, carry) = mac(w3, q1[2], MU[1], carry);
81
1.67k
    let (w4, carry) = mac(w4, q1[2], MU[2], carry);
82
1.67k
    let (w5, carry) = mac(w5, q1[2], MU[3], carry);
83
1.67k
    let (w6, w7) = mac(w6, q1[2], MU[4], carry);
84
1.67k
85
1.67k
    let (_w3, carry) = mac(w3, q1[3], MU[0], 0);
86
1.67k
    let (w4, carry) = mac(w4, q1[3], MU[1], carry);
87
1.67k
    let (w5, carry) = mac(w5, q1[3], MU[2], carry);
88
1.67k
    let (w6, carry) = mac(w6, q1[3], MU[3], carry);
89
1.67k
    let (w7, w8) = mac(w7, q1[3], MU[4], carry);
90
1.67k
91
1.67k
    let (_w4, carry) = mac(w4, q1[4], MU[0], 0);
92
1.67k
    let (w5, carry) = mac(w5, q1[4], MU[1], carry);
93
1.67k
    let (w6, carry) = mac(w6, q1[4], MU[2], carry);
94
1.67k
    let (w7, carry) = mac(w7, q1[4], MU[3], carry);
95
1.67k
    let (w8, w9) = mac(w8, q1[4], MU[4], carry);
96
1.67k
97
1.67k
    // let q2 = [_w0, _w1, _w2, _w3, _w4, w5, w6, w7, w8, w9];
98
1.67k
    [w5, w6, w7, w8, w9]
99
1.67k
}
100
101
1.67k
const fn q3_times_n_keep_five(q3: &[u64; 5]) -> [u64; 5] {
102
1.67k
    // Schoolbook multiplication.
103
1.67k
104
1.67k
    let modulus = MODULUS.as_words();
105
1.67k
106
1.67k
    let (w0, carry) = mac(0, q3[0], modulus[0], 0);
107
1.67k
    let (w1, carry) = mac(0, q3[0], modulus[1], carry);
108
1.67k
    let (w2, carry) = mac(0, q3[0], modulus[2], carry);
109
1.67k
    let (w3, carry) = mac(0, q3[0], modulus[3], carry);
110
1.67k
    let (w4, _) = mac(0, q3[0], 0, carry);
111
1.67k
112
1.67k
    let (w1, carry) = mac(w1, q3[1], modulus[0], 0);
113
1.67k
    let (w2, carry) = mac(w2, q3[1], modulus[1], carry);
114
1.67k
    let (w3, carry) = mac(w3, q3[1], modulus[2], carry);
115
1.67k
    let (w4, _) = mac(w4, q3[1], modulus[3], carry);
116
1.67k
117
1.67k
    let (w2, carry) = mac(w2, q3[2], modulus[0], 0);
118
1.67k
    let (w3, carry) = mac(w3, q3[2], modulus[1], carry);
119
1.67k
    let (w4, _) = mac(w4, q3[2], modulus[2], carry);
120
1.67k
121
1.67k
    let (w3, carry) = mac(w3, q3[3], modulus[0], 0);
122
1.67k
    let (w4, _) = mac(w4, q3[3], modulus[1], carry);
123
1.67k
124
1.67k
    let (w4, _) = mac(w4, q3[4], modulus[0], 0);
125
1.67k
126
1.67k
    [w0, w1, w2, w3, w4]
127
1.67k
}
128
129
#[inline]
130
#[allow(clippy::too_many_arguments)]
131
1.67k
const fn sub_inner_five(l: [u64; 5], r: [u64; 5]) -> [u64; 5] {
132
1.67k
    let (w0, borrow) = sbb(l[0], r[0], 0);
133
1.67k
    let (w1, borrow) = sbb(l[1], r[1], borrow);
134
1.67k
    let (w2, borrow) = sbb(l[2], r[2], borrow);
135
1.67k
    let (w3, borrow) = sbb(l[3], r[3], borrow);
136
1.67k
    let (w4, _borrow) = sbb(l[4], r[4], borrow);
137
1.67k
138
1.67k
    // If underflow occurred on the final limb - don't care (= add b^{k+1}).
139
1.67k
    [w0, w1, w2, w3, w4]
140
1.67k
}
141
142
#[inline]
143
#[allow(clippy::too_many_arguments)]
144
3.35k
const fn subtract_n_if_necessary(r0: u64, r1: u64, r2: u64, r3: u64, r4: u64) -> [u64; 5] {
145
3.35k
    let modulus = MODULUS.as_words();
146
3.35k
147
3.35k
    let (w0, borrow) = sbb(r0, modulus[0], 0);
148
3.35k
    let (w1, borrow) = sbb(r1, modulus[1], borrow);
149
3.35k
    let (w2, borrow) = sbb(r2, modulus[2], borrow);
150
3.35k
    let (w3, borrow) = sbb(r3, modulus[3], borrow);
151
3.35k
    let (w4, borrow) = sbb(r4, 0, borrow);
152
3.35k
153
3.35k
    // If underflow occurred on the final limb, borrow = 0xfff...fff, otherwise
154
3.35k
    // borrow = 0x000...000. Thus, we use it as a mask to conditionally add the
155
3.35k
    // modulus.
156
3.35k
    let (w0, carry) = adc(w0, modulus[0] & borrow, 0);
157
3.35k
    let (w1, carry) = adc(w1, modulus[1] & borrow, carry);
158
3.35k
    let (w2, carry) = adc(w2, modulus[2] & borrow, carry);
159
3.35k
    let (w3, carry) = adc(w3, modulus[3] & borrow, carry);
160
3.35k
    let (w4, _carry) = adc(w4, 0, carry);
161
3.35k
162
3.35k
    [w0, w1, w2, w3, w4]
163
3.35k
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/p256-0.13.2/src/arithmetic/util.rs
Line
Count
Source
1
//! Helper functions.
2
// TODO(tarcieri): replace these with `crypto-bigint`
3
4
/// Computes `a + b + carry`, returning the result along with the new carry. 64-bit version.
5
#[inline(always)]
6
189M
pub const fn adc(a: u64, b: u64, carry: u64) -> (u64, u64) {
7
189M
    let ret = (a as u128) + (b as u128) + (carry as u128);
8
189M
    (ret as u64, (ret >> 64) as u64)
9
189M
}
10
11
/// Computes `a - (b + borrow)`, returning the result along with the new borrow. 64-bit version.
12
#[inline(always)]
13
107M
pub const fn sbb(a: u64, b: u64, borrow: u64) -> (u64, u64) {
14
107M
    let ret = (a as u128).wrapping_sub((b as u128) + ((borrow >> 63) as u128));
15
107M
    (ret as u64, (ret >> 64) as u64)
16
107M
}
17
18
/// Computes `a + (b * c) + carry`, returning the result along with the new carry.
19
#[inline(always)]
20
198M
pub const fn mac(a: u64, b: u64, c: u64, carry: u64) -> (u64, u64) {
21
198M
    let ret = (a as u128) + ((b as u128) * (c as u128)) + (carry as u128);
22
198M
    (ret as u64, (ret >> 64) as u64)
23
198M
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/p256-0.13.2/src/lib.rs
Line
Count
Source
1
#![no_std]
2
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3
#![doc = include_str!("../README.md")]
4
#![doc(
5
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
6
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
7
)]
8
#![forbid(unsafe_code)]
9
#![warn(
10
    clippy::mod_module_files,
11
    clippy::unwrap_used,
12
    missing_docs,
13
    rust_2018_idioms,
14
    unused_lifetimes,
15
    unused_qualifications
16
)]
17
18
//! ## `serde` support
19
//!
20
//! When the `serde` feature of this crate is enabled, `Serialize` and
21
//! `Deserialize` are impl'd for the following types:
22
//!
23
//! - [`AffinePoint`]
24
//! - [`Scalar`]
25
//! - [`ecdsa::VerifyingKey`]
26
//!
27
//! Please see type-specific documentation for more information.
28
29
#[cfg(feature = "arithmetic")]
30
mod arithmetic;
31
32
#[cfg(feature = "ecdh")]
33
pub mod ecdh;
34
35
#[cfg(feature = "ecdsa-core")]
36
pub mod ecdsa;
37
38
#[cfg(any(feature = "test-vectors", test))]
39
pub mod test_vectors;
40
41
pub use elliptic_curve::{self, bigint::U256, consts::U32};
42
43
#[cfg(feature = "arithmetic")]
44
pub use arithmetic::{scalar::Scalar, AffinePoint, ProjectivePoint};
45
46
#[cfg(feature = "expose-field")]
47
pub use arithmetic::field::FieldElement;
48
49
#[cfg(feature = "pkcs8")]
50
pub use elliptic_curve::pkcs8;
51
52
use elliptic_curve::{
53
    bigint::ArrayEncoding, consts::U33, generic_array::GenericArray, FieldBytesEncoding,
54
};
55
56
/// Order of NIST P-256's elliptic curve group (i.e. scalar modulus) serialized
57
/// as hexadecimal.
58
///
59
/// ```text
60
/// n = FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551
61
/// ```
62
///
63
/// # Calculating the order
64
/// One way to calculate the order is with `GP/PARI`:
65
///
66
/// ```text
67
/// p = (2^224) * (2^32 - 1) + 2^192 + 2^96 - 1
68
/// b = 41058363725152142129326129780047268409114441015993725554835256314039467401291
69
/// E = ellinit([Mod(-3, p), Mod(b, p)])
70
/// default(parisize, 120000000)
71
/// n = ellsea(E)
72
/// isprime(n)
73
/// ```
74
const ORDER_HEX: &str = "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551";
75
76
/// NIST P-256 elliptic curve.
77
///
78
/// This curve is also known as prime256v1 (ANSI X9.62) and secp256r1 (SECG)
79
/// and is specified in [NIST SP 800-186]:
80
/// Recommendations for Discrete Logarithm-based Cryptography:
81
/// Elliptic Curve Domain Parameters.
82
///
83
/// It's included in the US National Security Agency's "Suite B" and is widely
84
/// used in protocols like TLS and the associated X.509 PKI.
85
///
86
/// Its equation is `y² = x³ - 3x + b` over a ~256-bit prime field where `b` is
87
/// the "verifiably random"† constant:
88
///
89
/// ```text
90
/// b = 41058363725152142129326129780047268409114441015993725554835256314039467401291
91
/// ```
92
///
93
/// † *NOTE: the specific origins of this constant have never been fully disclosed
94
///   (it is the SHA-1 digest of an unknown NSA-selected constant)*
95
///
96
/// [NIST SP 800-186]: https://csrc.nist.gov/publications/detail/sp/800-186/final
97
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
98
pub struct NistP256;
99
100
impl elliptic_curve::Curve for NistP256 {
101
    /// 32-byte serialized field elements.
102
    type FieldBytesSize = U32;
103
104
    /// 256-bit integer type used for internally representing field elements.
105
    type Uint = U256;
106
107
    /// Order of NIST P-256's elliptic curve group (i.e. scalar modulus).
108
    const ORDER: U256 = U256::from_be_hex(ORDER_HEX);
109
}
110
111
impl elliptic_curve::PrimeCurve for NistP256 {}
112
113
impl elliptic_curve::point::PointCompression for NistP256 {
114
    /// NIST P-256 points are typically uncompressed.
115
    const COMPRESS_POINTS: bool = false;
116
}
117
118
impl elliptic_curve::point::PointCompaction for NistP256 {
119
    /// NIST P-256 points are typically uncompressed.
120
    const COMPACT_POINTS: bool = false;
121
}
122
123
#[cfg(feature = "jwk")]
124
impl elliptic_curve::JwkParameters for NistP256 {
125
    const CRV: &'static str = "P-256";
126
}
127
128
#[cfg(feature = "pkcs8")]
129
impl pkcs8::AssociatedOid for NistP256 {
130
    const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7");
131
}
132
133
/// Blinded scalar.
134
#[cfg(feature = "arithmetic")]
135
pub type BlindedScalar = elliptic_curve::scalar::BlindedScalar<NistP256>;
136
137
/// Compressed SEC1-encoded NIST P-256 curve point.
138
pub type CompressedPoint = GenericArray<u8, U33>;
139
140
/// NIST P-256 SEC1 encoded point.
141
pub type EncodedPoint = elliptic_curve::sec1::EncodedPoint<NistP256>;
142
143
/// NIST P-256 field element serialized as bytes.
144
///
145
/// Byte array containing a serialized field element value (base field or scalar).
146
pub type FieldBytes = elliptic_curve::FieldBytes<NistP256>;
147
148
impl FieldBytesEncoding<NistP256> for U256 {
149
3.48k
    fn decode_field_bytes(field_bytes: &FieldBytes) -> Self {
150
3.48k
        U256::from_be_byte_array(*field_bytes)
151
3.48k
    }
152
153
866
    fn encode_field_bytes(&self) -> FieldBytes {
154
866
        self.to_be_byte_array()
155
866
    }
156
}
157
158
/// Non-zero NIST P-256 scalar field element.
159
#[cfg(feature = "arithmetic")]
160
pub type NonZeroScalar = elliptic_curve::NonZeroScalar<NistP256>;
161
162
/// NIST P-256 public key.
163
#[cfg(feature = "arithmetic")]
164
pub type PublicKey = elliptic_curve::PublicKey<NistP256>;
165
166
/// NIST P-256 secret key.
167
pub type SecretKey = elliptic_curve::SecretKey<NistP256>;
168
169
#[cfg(not(feature = "arithmetic"))]
170
impl elliptic_curve::sec1::ValidatePublicKey for NistP256 {}
171
172
/// Bit representation of a NIST P-256 scalar field element.
173
#[cfg(feature = "bits")]
174
pub type ScalarBits = elliptic_curve::scalar::ScalarBits<NistP256>;
175
176
#[cfg(feature = "voprf")]
177
impl elliptic_curve::VoprfParameters for NistP256 {
178
    /// See <https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-19.html#section-4.3>.
179
    const ID: &'static str = "P256-SHA256";
180
181
    /// See <https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html#section-4.3-1.2>.
182
    type Hash = sha2::Sha256;
183
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pem-rfc7468-0.7.0/src/decoder.rs
Line
Count
Source
1
//! Decoder for PEM encapsulated data.
2
//!
3
//! From RFC 7468 Section 2:
4
//!
5
//! > Textual encoding begins with a line comprising "-----BEGIN ", a
6
//! > label, and "-----", and ends with a line comprising "-----END ", a
7
//! > label, and "-----".  Between these lines, or "encapsulation
8
//! > boundaries", are base64-encoded data according to Section 4 of
9
//! > [RFC 4648].
10
//!
11
//! [RFC 4648]: https://datatracker.ietf.org/doc/html/rfc4648
12
13
use crate::{
14
    grammar, Base64Decoder, Error, Result, BASE64_WRAP_WIDTH, POST_ENCAPSULATION_BOUNDARY,
15
    PRE_ENCAPSULATION_BOUNDARY,
16
};
17
use core::str;
18
19
#[cfg(feature = "alloc")]
20
use alloc::vec::Vec;
21
22
#[cfg(feature = "std")]
23
use std::io;
24
25
/// Decode a PEM document according to RFC 7468's "Strict" grammar.
26
///
27
/// On success, writes the decoded document into the provided buffer, returning
28
/// the decoded label and the portion of the provided buffer containing the
29
/// decoded message.
30
0
pub fn decode<'i, 'o>(pem: &'i [u8], buf: &'o mut [u8]) -> Result<(&'i str, &'o [u8])> {
31
0
    let mut decoder = Decoder::new(pem).map_err(|e| check_for_headers(pem, e))?;
32
0
    let type_label = decoder.type_label();
33
0
    let buf = buf
34
0
        .get_mut(..decoder.remaining_len())
35
0
        .ok_or(Error::Length)?;
36
0
    let decoded = decoder.decode(buf).map_err(|e| check_for_headers(pem, e))?;
37
38
0
    if decoder.base64.is_finished() {
39
0
        Ok((type_label, decoded))
40
    } else {
41
0
        Err(Error::Length)
42
    }
43
0
}
44
45
/// Decode a PEM document according to RFC 7468's "Strict" grammar, returning
46
/// the result as a [`Vec`] upon success.
47
#[cfg(feature = "alloc")]
48
0
pub fn decode_vec(pem: &[u8]) -> Result<(&str, Vec<u8>)> {
49
0
    let mut decoder = Decoder::new(pem).map_err(|e| check_for_headers(pem, e))?;
50
0
    let type_label = decoder.type_label();
51
0
    let mut buf = Vec::new();
52
0
    decoder
53
0
        .decode_to_end(&mut buf)
54
0
        .map_err(|e| check_for_headers(pem, e))?;
55
0
    Ok((type_label, buf))
56
0
}
57
58
/// Decode the encapsulation boundaries of a PEM document according to RFC 7468's "Strict" grammar.
59
///
60
/// On success, returning the decoded label.
61
0
pub fn decode_label(pem: &[u8]) -> Result<&str> {
62
0
    Ok(Encapsulation::try_from(pem)?.label())
63
0
}
64
65
/// Buffered PEM decoder.
66
///
67
/// Stateful buffered decoder type which decodes an input PEM document according
68
/// to RFC 7468's "Strict" grammar.
69
#[derive(Clone)]
70
pub struct Decoder<'i> {
71
    /// PEM type label.
72
    type_label: &'i str,
73
74
    /// Buffered Base64 decoder.
75
    base64: Base64Decoder<'i>,
76
}
77
78
impl<'i> Decoder<'i> {
79
    /// Create a new PEM [`Decoder`] with the default options.
80
    ///
81
    /// Uses the default 64-character line wrapping.
82
0
    pub fn new(pem: &'i [u8]) -> Result<Self> {
83
0
        Self::new_wrapped(pem, BASE64_WRAP_WIDTH)
84
0
    }
85
86
    /// Create a new PEM [`Decoder`] which wraps at the given line width.
87
0
    pub fn new_wrapped(pem: &'i [u8], line_width: usize) -> Result<Self> {
88
0
        let encapsulation = Encapsulation::try_from(pem)?;
89
0
        let type_label = encapsulation.label();
90
0
        let base64 = Base64Decoder::new_wrapped(encapsulation.encapsulated_text, line_width)?;
91
0
        Ok(Self { type_label, base64 })
92
0
    }
93
94
    /// Get the PEM type label for the input document.
95
0
    pub fn type_label(&self) -> &'i str {
96
0
        self.type_label
97
0
    }
Unexecuted instantiation: _RNvMNtCs7ONNNQjtL1v_11pem_rfc74687decoderNtB2_7Decoder10type_labelCscrZQdumITES_3der
Unexecuted instantiation: _RNvMNtCs7ONNNQjtL1v_11pem_rfc74687decoderNtB2_7Decoder10type_labelB4_
98
99
    /// Decode data into the provided output buffer.
100
    ///
101
    /// There must be at least as much remaining Base64 input to be decoded
102
    /// in order to completely fill `buf`.
103
0
    pub fn decode<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> {
104
0
        Ok(self.base64.decode(buf)?)
105
0
    }
106
107
    /// Decode all of the remaining data in the input buffer into `buf`.
108
    #[cfg(feature = "alloc")]
109
0
    pub fn decode_to_end<'o>(&mut self, buf: &'o mut Vec<u8>) -> Result<&'o [u8]> {
110
0
        Ok(self.base64.decode_to_end(buf)?)
111
0
    }
112
113
    /// Get the decoded length of the remaining PEM data after Base64 decoding.
114
0
    pub fn remaining_len(&self) -> usize {
115
0
        self.base64.remaining_len()
116
0
    }
Unexecuted instantiation: _RNvMNtCs7ONNNQjtL1v_11pem_rfc74687decoderNtB2_7Decoder13remaining_lenCscrZQdumITES_3der
Unexecuted instantiation: _RNvMNtCs7ONNNQjtL1v_11pem_rfc74687decoderNtB2_7Decoder13remaining_lenB4_
117
118
    /// Are we finished decoding the PEM input?
119
0
    pub fn is_finished(&self) -> bool {
120
0
        self.base64.is_finished()
121
0
    }
122
}
123
124
impl<'i> From<Decoder<'i>> for Base64Decoder<'i> {
125
0
    fn from(decoder: Decoder<'i>) -> Base64Decoder<'i> {
126
0
        decoder.base64
127
0
    }
128
}
129
130
#[cfg(feature = "std")]
131
impl<'i> io::Read for Decoder<'i> {
132
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
133
        self.base64.read(buf)
134
    }
135
136
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
137
        self.base64.read_to_end(buf)
138
    }
139
140
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
141
        self.base64.read_exact(buf)
142
    }
143
}
144
145
/// PEM encapsulation parser.
146
///
147
/// This parser performs an initial pass over the data, locating the
148
/// pre-encapsulation (`---BEGIN [...]---`) and post-encapsulation
149
/// (`---END [...]`) boundaries while attempting to avoid branching
150
/// on the potentially secret Base64-encoded data encapsulated between
151
/// the two boundaries.
152
///
153
/// It only supports a single encapsulated message at present. Future work
154
/// could potentially include extending it provide an iterator over a series
155
/// of encapsulated messages.
156
#[derive(Copy, Clone, Debug)]
157
struct Encapsulation<'a> {
158
    /// Type label extracted from the pre/post-encapsulation boundaries.
159
    ///
160
    /// From RFC 7468 Section 2:
161
    ///
162
    /// > The type of data encoded is labeled depending on the type label in
163
    /// > the "-----BEGIN " line (pre-encapsulation boundary).  For example,
164
    /// > the line may be "-----BEGIN CERTIFICATE-----" to indicate that the
165
    /// > content is a PKIX certificate (see further below).  Generators MUST
166
    /// > put the same label on the "-----END " line (post-encapsulation
167
    /// > boundary) as the corresponding "-----BEGIN " line.  Labels are
168
    /// > formally case-sensitive, uppercase, and comprised of zero or more
169
    /// > characters; they do not contain consecutive spaces or hyphen-minuses,
170
    /// > nor do they contain spaces or hyphen-minuses at either end.  Parsers
171
    /// > MAY disregard the label in the post-encapsulation boundary instead of
172
    /// > signaling an error if there is a label mismatch: some extant
173
    /// > implementations require the labels to match; others do not.
174
    label: &'a str,
175
176
    /// Encapsulated text portion contained between the boundaries.
177
    ///
178
    /// This data should be encoded as Base64, however this type performs no
179
    /// validation of it so it can be handled in constant-time.
180
    encapsulated_text: &'a [u8],
181
}
182
183
impl<'a> Encapsulation<'a> {
184
    /// Parse the type label and encapsulated text from between the
185
    /// pre/post-encapsulation boundaries.
186
0
    pub fn parse(data: &'a [u8]) -> Result<Self> {
187
        // Strip the "preamble": optional text occurring before the pre-encapsulation boundary
188
0
        let data = grammar::strip_preamble(data)?;
189
190
        // Parse pre-encapsulation boundary (including label)
191
0
        let data = data
192
0
            .strip_prefix(PRE_ENCAPSULATION_BOUNDARY)
193
0
            .ok_or(Error::PreEncapsulationBoundary)?;
194
195
0
        let (label, body) = grammar::split_label(data).ok_or(Error::Label)?;
196
197
0
        let mut body = match grammar::strip_trailing_eol(body).unwrap_or(body) {
198
0
            [head @ .., b'-', b'-', b'-', b'-', b'-'] => head,
199
0
            _ => return Err(Error::PreEncapsulationBoundary),
200
        };
201
202
        // Ensure body ends with a properly labeled post-encapsulation boundary
203
0
        for &slice in [POST_ENCAPSULATION_BOUNDARY, label.as_bytes()].iter().rev() {
204
            // Ensure the input ends with the post encapsulation boundary as
205
            // well as a matching label
206
0
            if !body.ends_with(slice) {
207
0
                return Err(Error::PostEncapsulationBoundary);
208
0
            }
209
210
0
            let len = body.len().checked_sub(slice.len()).ok_or(Error::Length)?;
211
0
            body = body.get(..len).ok_or(Error::PostEncapsulationBoundary)?;
212
        }
213
214
0
        let encapsulated_text =
215
0
            grammar::strip_trailing_eol(body).ok_or(Error::PostEncapsulationBoundary)?;
216
217
0
        Ok(Self {
218
0
            label,
219
0
            encapsulated_text,
220
0
        })
221
0
    }
222
223
    /// Get the label parsed from the encapsulation boundaries.
224
0
    pub fn label(self) -> &'a str {
225
0
        self.label
226
0
    }
227
}
228
229
impl<'a> TryFrom<&'a [u8]> for Encapsulation<'a> {
230
    type Error = Error;
231
232
0
    fn try_from(bytes: &'a [u8]) -> Result<Self> {
233
0
        Self::parse(bytes)
234
0
    }
235
}
236
237
/// Check for PEM headers in the input, as they are disallowed by RFC7468.
238
///
239
/// Returns `Error::HeaderDisallowed` if headers are encountered.
240
0
fn check_for_headers(pem: &[u8], err: Error) -> Error {
241
0
    if err == Error::Base64(base64ct::Error::InvalidEncoding)
242
0
        && pem.iter().any(|&b| b == grammar::CHAR_COLON)
243
    {
244
0
        Error::HeaderDisallowed
245
    } else {
246
0
        err
247
    }
248
0
}
249
250
#[cfg(test)]
251
mod tests {
252
    use super::Encapsulation;
253
254
    #[test]
255
    fn pkcs8_example() {
256
        let pem = include_bytes!("../tests/examples/pkcs8.pem");
257
        let encapsulation = Encapsulation::parse(pem).unwrap();
258
        assert_eq!(encapsulation.label, "PRIVATE KEY");
259
260
        assert_eq!(
261
            encapsulation.encapsulated_text,
262
            &[
263
                77, 67, 52, 67, 65, 81, 65, 119, 66, 81, 89, 68, 75, 50, 86, 119, 66, 67, 73, 69,
264
                73, 66, 102, 116, 110, 72, 80, 112, 50, 50, 83, 101, 119, 89, 109, 109, 69, 111,
265
                77, 99, 88, 56, 86, 119, 73, 52, 73, 72, 119, 97, 113, 100, 43, 57, 76, 70, 80,
266
                106, 47, 49, 53, 101, 113, 70
267
            ]
268
        );
269
    }
270
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pem-rfc7468-0.7.0/src/encoder.rs
Line
Count
Source
1
//! PEM encoder.
2
3
use crate::{
4
    grammar, Base64Encoder, Error, LineEnding, Result, BASE64_WRAP_WIDTH,
5
    ENCAPSULATION_BOUNDARY_DELIMITER, POST_ENCAPSULATION_BOUNDARY, PRE_ENCAPSULATION_BOUNDARY,
6
};
7
use base64ct::{Base64, Encoding};
8
use core::str;
9
10
#[cfg(feature = "alloc")]
11
use alloc::string::String;
12
13
#[cfg(feature = "std")]
14
use std::io;
15
16
/// Compute the length of a PEM encoded document which encapsulates a
17
/// Base64-encoded body including line endings every 64 characters.
18
///
19
/// The `input_len` parameter specifies the length of the raw input
20
/// bytes prior to Base64 encoding.
21
///
22
/// Note that the current implementation of this function computes an upper
23
/// bound of the length and the actual encoded document may be slightly shorter
24
/// (typically 1-byte). Downstream consumers of this function should check the
25
/// actual encoded length and potentially truncate buffers allocated using this
26
/// function to estimate the encapsulated size.
27
///
28
/// Use [`encoded_len`] (when possible) to obtain a precise length.
29
///
30
/// ## Returns
31
/// - `Ok(len)` on success
32
/// - `Err(Error::Length)` on length overflow
33
0
pub fn encapsulated_len(label: &str, line_ending: LineEnding, input_len: usize) -> Result<usize> {
34
0
    encapsulated_len_wrapped(label, BASE64_WRAP_WIDTH, line_ending, input_len)
35
0
}
36
37
/// Compute the length of a PEM encoded document with the Base64 body
38
/// line wrapped at the specified `width`.
39
///
40
/// This is the same as [`encapsulated_len`], which defaults to a width of 64.
41
///
42
/// Note that per [RFC7468 § 2] encoding PEM with any other wrap width besides
43
/// 64 is technically non-compliant:
44
///
45
/// > Generators MUST wrap the base64-encoded lines so that each line
46
/// > consists of exactly 64 characters except for the final line, which
47
/// > will encode the remainder of the data (within the 64-character line
48
/// > boundary)
49
///
50
/// [RFC7468 § 2]: https://datatracker.ietf.org/doc/html/rfc7468#section-2
51
0
pub fn encapsulated_len_wrapped(
52
0
    label: &str,
53
0
    line_width: usize,
54
0
    line_ending: LineEnding,
55
0
    input_len: usize,
56
0
) -> Result<usize> {
57
0
    if line_width < 4 {
58
0
        return Err(Error::Length);
59
0
    }
60
61
0
    let base64_len = input_len
62
0
        .checked_mul(4)
63
0
        .and_then(|n| n.checked_div(3))
64
0
        .and_then(|n| n.checked_add(3))
65
0
        .ok_or(Error::Length)?
66
0
        & !3;
67
68
0
    let base64_len_wrapped = base64_len_wrapped(base64_len, line_width, line_ending)?;
69
0
    encapsulated_len_inner(label, line_ending, base64_len_wrapped)
70
0
}
71
72
/// Get the length of a PEM encoded document with the given bytes and label.
73
///
74
/// This function computes a precise length of the PEM encoding of the given
75
/// `input` data.
76
///
77
/// ## Returns
78
/// - `Ok(len)` on success
79
/// - `Err(Error::Length)` on length overflow
80
0
pub fn encoded_len(label: &str, line_ending: LineEnding, input: &[u8]) -> Result<usize> {
81
0
    let base64_len = Base64::encoded_len(input);
82
0
    let base64_len_wrapped = base64_len_wrapped(base64_len, BASE64_WRAP_WIDTH, line_ending)?;
83
0
    encapsulated_len_inner(label, line_ending, base64_len_wrapped)
84
0
}
85
86
/// Encode a PEM document according to RFC 7468's "Strict" grammar.
87
0
pub fn encode<'o>(
88
0
    type_label: &str,
89
0
    line_ending: LineEnding,
90
0
    input: &[u8],
91
0
    buf: &'o mut [u8],
92
0
) -> Result<&'o str> {
93
0
    let mut encoder = Encoder::new(type_label, line_ending, buf)?;
94
0
    encoder.encode(input)?;
95
0
    let encoded_len = encoder.finish()?;
96
0
    let output = &buf[..encoded_len];
97
0
98
0
    // Sanity check
99
0
    debug_assert!(str::from_utf8(output).is_ok());
100
101
    // Ensure `output` contains characters from the lower 7-bit ASCII set
102
0
    if output.iter().fold(0u8, |acc, &byte| acc | (byte & 0x80)) == 0 {
103
        // Use unchecked conversion to avoid applying UTF-8 checks to potentially
104
        // secret PEM documents (and therefore introducing a potential timing
105
        // sidechannel)
106
        //
107
        // SAFETY: contents of this buffer are controlled entirely by the encoder,
108
        // which ensures the contents are always a valid (ASCII) subset of UTF-8.
109
        // It's also additionally sanity checked by two assertions above to ensure
110
        // the validity (with the always-on runtime check implemented in a
111
        // constant time-ish manner.
112
        #[allow(unsafe_code)]
113
0
        Ok(unsafe { str::from_utf8_unchecked(output) })
114
    } else {
115
0
        Err(Error::CharacterEncoding)
116
    }
117
0
}
118
119
/// Encode a PEM document according to RFC 7468's "Strict" grammar, returning
120
/// the result as a [`String`].
121
#[cfg(feature = "alloc")]
122
0
pub fn encode_string(label: &str, line_ending: LineEnding, input: &[u8]) -> Result<String> {
123
0
    let expected_len = encoded_len(label, line_ending, input)?;
124
0
    let mut buf = vec![0u8; expected_len];
125
0
    let actual_len = encode(label, line_ending, input, &mut buf)?.len();
126
0
    debug_assert_eq!(expected_len, actual_len);
127
0
    String::from_utf8(buf).map_err(|_| Error::CharacterEncoding)
128
0
}
129
130
/// Compute the encapsulated length of Base64 data of the given length.
131
0
fn encapsulated_len_inner(
132
0
    label: &str,
133
0
    line_ending: LineEnding,
134
0
    base64_len: usize,
135
0
) -> Result<usize> {
136
0
    [
137
0
        PRE_ENCAPSULATION_BOUNDARY.len(),
138
0
        label.as_bytes().len(),
139
0
        ENCAPSULATION_BOUNDARY_DELIMITER.len(),
140
0
        line_ending.len(),
141
0
        base64_len,
142
0
        line_ending.len(),
143
0
        POST_ENCAPSULATION_BOUNDARY.len(),
144
0
        label.as_bytes().len(),
145
0
        ENCAPSULATION_BOUNDARY_DELIMITER.len(),
146
0
        line_ending.len(),
147
0
    ]
148
0
    .into_iter()
149
0
    .try_fold(0usize, |acc, len| acc.checked_add(len))
150
0
    .ok_or(Error::Length)
151
0
}
152
153
/// Compute Base64 length line-wrapped at the specified width with the given
154
/// line ending.
155
0
fn base64_len_wrapped(
156
0
    base64_len: usize,
157
0
    line_width: usize,
158
0
    line_ending: LineEnding,
159
0
) -> Result<usize> {
160
0
    base64_len
161
0
        .saturating_sub(1)
162
0
        .checked_div(line_width)
163
0
        .and_then(|lines| lines.checked_mul(line_ending.len()))
164
0
        .and_then(|len| len.checked_add(base64_len))
165
0
        .ok_or(Error::Length)
166
0
}
167
168
/// Buffered PEM encoder.
169
///
170
/// Stateful buffered encoder type which encodes an input PEM document according
171
/// to RFC 7468's "Strict" grammar.
172
pub struct Encoder<'l, 'o> {
173
    /// PEM type label.
174
    type_label: &'l str,
175
176
    /// Line ending used to wrap Base64.
177
    line_ending: LineEnding,
178
179
    /// Buffered Base64 encoder.
180
    base64: Base64Encoder<'o>,
181
}
182
183
impl<'l, 'o> Encoder<'l, 'o> {
184
    /// Create a new PEM [`Encoder`] with the default options which
185
    /// writes output into the provided buffer.
186
    ///
187
    /// Uses the default 64-character line wrapping.
188
0
    pub fn new(type_label: &'l str, line_ending: LineEnding, out: &'o mut [u8]) -> Result<Self> {
189
0
        Self::new_wrapped(type_label, BASE64_WRAP_WIDTH, line_ending, out)
190
0
    }
191
192
    /// Create a new PEM [`Encoder`] which wraps at the given line width.
193
    ///
194
    /// Note that per [RFC7468 § 2] encoding PEM with any other wrap width besides
195
    /// 64 is technically non-compliant:
196
    ///
197
    /// > Generators MUST wrap the base64-encoded lines so that each line
198
    /// > consists of exactly 64 characters except for the final line, which
199
    /// > will encode the remainder of the data (within the 64-character line
200
    /// > boundary)
201
    ///
202
    /// This method is provided with the intended purpose of implementing the
203
    /// OpenSSH private key format, which uses a non-standard wrap width of 70.
204
    ///
205
    /// [RFC7468 § 2]: https://datatracker.ietf.org/doc/html/rfc7468#section-2
206
0
    pub fn new_wrapped(
207
0
        type_label: &'l str,
208
0
        line_width: usize,
209
0
        line_ending: LineEnding,
210
0
        mut out: &'o mut [u8],
211
0
    ) -> Result<Self> {
212
0
        grammar::validate_label(type_label.as_bytes())?;
213
214
0
        for boundary_part in [
215
            PRE_ENCAPSULATION_BOUNDARY,
216
0
            type_label.as_bytes(),
217
0
            ENCAPSULATION_BOUNDARY_DELIMITER,
218
0
            line_ending.as_bytes(),
219
        ] {
220
0
            if out.len() < boundary_part.len() {
221
0
                return Err(Error::Length);
222
0
            }
223
0
224
0
            let (part, rest) = out.split_at_mut(boundary_part.len());
225
0
            out = rest;
226
0
227
0
            part.copy_from_slice(boundary_part);
228
        }
229
230
0
        let base64 = Base64Encoder::new_wrapped(out, line_width, line_ending)?;
231
232
0
        Ok(Self {
233
0
            type_label,
234
0
            line_ending,
235
0
            base64,
236
0
        })
237
0
    }
238
239
    /// Get the PEM type label used for this document.
240
0
    pub fn type_label(&self) -> &'l str {
241
0
        self.type_label
242
0
    }
Unexecuted instantiation: _RNvMNtCs7ONNNQjtL1v_11pem_rfc74687encoderNtB2_7Encoder10type_labelCscrZQdumITES_3der
Unexecuted instantiation: _RNvMNtCs7ONNNQjtL1v_11pem_rfc74687encoderNtB2_7Encoder10type_labelB4_
243
244
    /// Encode the provided input data.
245
    ///
246
    /// This method can be called as many times as needed with any sized input
247
    /// to write data encoded data into the output buffer, so long as there is
248
    /// sufficient space in the buffer to handle the resulting Base64 encoded
249
    /// data.
250
0
    pub fn encode(&mut self, input: &[u8]) -> Result<()> {
251
0
        self.base64.encode(input)?;
252
0
        Ok(())
253
0
    }
254
255
    /// Borrow the inner [`Base64Encoder`].
256
0
    pub fn base64_encoder(&mut self) -> &mut Base64Encoder<'o> {
257
0
        &mut self.base64
258
0
    }
259
260
    /// Finish encoding PEM, writing the post-encapsulation boundary.
261
    ///
262
    /// On success, returns the total number of bytes written to the output
263
    /// buffer.
264
0
    pub fn finish(self) -> Result<usize> {
265
0
        let (base64, mut out) = self.base64.finish_with_remaining()?;
266
267
0
        for boundary_part in [
268
0
            self.line_ending.as_bytes(),
269
0
            POST_ENCAPSULATION_BOUNDARY,
270
0
            self.type_label.as_bytes(),
271
0
            ENCAPSULATION_BOUNDARY_DELIMITER,
272
0
            self.line_ending.as_bytes(),
273
        ] {
274
0
            if out.len() < boundary_part.len() {
275
0
                return Err(Error::Length);
276
0
            }
277
0
278
0
            let (part, rest) = out.split_at_mut(boundary_part.len());
279
0
            out = rest;
280
0
281
0
            part.copy_from_slice(boundary_part);
282
        }
283
284
0
        encapsulated_len_inner(self.type_label, self.line_ending, base64.len())
285
0
    }
286
}
287
288
#[cfg(feature = "std")]
289
impl<'l, 'o> io::Write for Encoder<'l, 'o> {
290
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
291
        self.encode(buf)?;
292
        Ok(buf.len())
293
    }
294
295
    fn flush(&mut self) -> io::Result<()> {
296
        // TODO(tarcieri): return an error if there's still data remaining in the buffer?
297
        Ok(())
298
    }
299
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pem-rfc7468-0.7.0/src/error.rs
Line
Count
Source
1
//! Error types
2
3
use core::fmt;
4
5
/// Result type with the `pem-rfc7468` crate's [`Error`] type.
6
pub type Result<T> = core::result::Result<T, Error>;
7
8
/// PEM errors.
9
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
10
#[non_exhaustive]
11
pub enum Error {
12
    /// Base64-related errors.
13
    Base64(base64ct::Error),
14
15
    /// Character encoding-related errors.
16
    CharacterEncoding,
17
18
    /// Errors in the encapsulated text (which aren't specifically Base64-related).
19
    EncapsulatedText,
20
21
    /// Header detected in the encapsulated text.
22
    HeaderDisallowed,
23
24
    /// Invalid label.
25
    Label,
26
27
    /// Invalid length.
28
    Length,
29
30
    /// "Preamble" (text before pre-encapsulation boundary) contains invalid data.
31
    Preamble,
32
33
    /// Errors in the pre-encapsulation boundary.
34
    PreEncapsulationBoundary,
35
36
    /// Errors in the post-encapsulation boundary.
37
    PostEncapsulationBoundary,
38
39
    /// Unexpected PEM type label.
40
    UnexpectedTypeLabel {
41
        /// Type label that was expected.
42
        expected: &'static str,
43
    },
44
}
45
46
impl fmt::Display for Error {
47
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48
0
        match self {
49
0
            Error::Base64(err) => write!(f, "PEM Base64 error: {}", err),
50
0
            Error::CharacterEncoding => f.write_str("PEM character encoding error"),
51
0
            Error::EncapsulatedText => f.write_str("PEM error in encapsulated text"),
52
0
            Error::HeaderDisallowed => f.write_str("PEM headers disallowed by RFC7468"),
53
0
            Error::Label => f.write_str("PEM type label invalid"),
54
0
            Error::Length => f.write_str("PEM length invalid"),
55
0
            Error::Preamble => f.write_str("PEM preamble contains invalid data (NUL byte)"),
56
            Error::PreEncapsulationBoundary => {
57
0
                f.write_str("PEM error in pre-encapsulation boundary")
58
            }
59
            Error::PostEncapsulationBoundary => {
60
0
                f.write_str("PEM error in post-encapsulation boundary")
61
            }
62
0
            Error::UnexpectedTypeLabel { expected } => {
63
0
                write!(f, "unexpected PEM type label: expecting \"{}\"", expected)
64
            }
65
        }
66
0
    }
67
}
68
69
#[cfg(feature = "std")]
70
impl std::error::Error for Error {}
71
72
impl From<base64ct::Error> for Error {
73
0
    fn from(err: base64ct::Error) -> Error {
74
0
        Error::Base64(err)
75
0
    }
76
}
77
78
impl From<base64ct::InvalidLengthError> for Error {
79
0
    fn from(_: base64ct::InvalidLengthError) -> Error {
80
0
        Error::Length
81
0
    }
82
}
83
84
impl From<core::str::Utf8Error> for Error {
85
0
    fn from(_: core::str::Utf8Error) -> Error {
86
0
        Error::CharacterEncoding
87
0
    }
88
}
89
90
#[cfg(feature = "std")]
91
impl From<Error> for std::io::Error {
92
    fn from(err: Error) -> std::io::Error {
93
        let kind = match err {
94
            Error::Base64(err) => return err.into(), // Use existing conversion
95
            Error::CharacterEncoding
96
            | Error::EncapsulatedText
97
            | Error::Label
98
            | Error::Preamble
99
            | Error::PreEncapsulationBoundary
100
            | Error::PostEncapsulationBoundary => std::io::ErrorKind::InvalidData,
101
            Error::Length => std::io::ErrorKind::UnexpectedEof,
102
            _ => std::io::ErrorKind::Other,
103
        };
104
105
        std::io::Error::new(kind, err)
106
    }
107
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pem-rfc7468-0.7.0/src/grammar.rs
Line
Count
Source
1
//! Helper functions and rules for enforcing the ABNF grammar for
2
//! RFC 7468-flavored PEM as described in Section 3.
3
//!
4
//! The grammar described below is intended to follow the "ABNF (Strict)"
5
//! subset of the grammar as described in Section 3 Figure 3.
6
7
use crate::{Error, Result, PRE_ENCAPSULATION_BOUNDARY};
8
use core::str;
9
10
/// NUL char
11
pub(crate) const CHAR_NUL: u8 = 0x00;
12
13
/// Horizontal tab
14
pub(crate) const CHAR_HT: u8 = 0x09;
15
16
/// Space
17
pub(crate) const CHAR_SP: u8 = 0x20;
18
19
/// Carriage return
20
pub(crate) const CHAR_CR: u8 = 0x0d;
21
22
/// Line feed
23
pub(crate) const CHAR_LF: u8 = 0x0a;
24
25
/// Colon ':'
26
pub(crate) const CHAR_COLON: u8 = 0x3A;
27
28
/// Any printable character except hyphen-minus, as defined in the
29
/// 'labelchar' production in the RFC 7468 ABNF grammar
30
0
pub(crate) fn is_labelchar(char: u8) -> bool {
31
0
    matches!(char, 0x21..=0x2C | 0x2E..=0x7E)
32
0
}
33
34
/// Does the provided byte match a character allowed in a label?
35
// TODO: allow hyphen-minus to match the 'label' production in the ABNF grammar
36
0
pub(crate) fn is_allowed_in_label(char: u8) -> bool {
37
0
    is_labelchar(char) || matches!(char, CHAR_HT | CHAR_SP)
38
0
}
39
40
/// Does the provided byte match the "WSP" ABNF production from Section 3?
41
///
42
/// > The common ABNF production WSP is congruent with "blank";
43
/// > a new production W is used for "whitespace"
44
0
pub(crate) fn is_wsp(char: u8) -> bool {
45
0
    matches!(char, CHAR_HT | CHAR_SP)
46
0
}
47
48
/// Strip the "preamble", i.e. data that appears before the PEM
49
/// pre-encapsulation boundary.
50
///
51
/// Presently no attempt is made to ensure the preamble decodes successfully
52
/// under any particular character encoding. The only byte which is disallowed
53
/// is the NUL byte. This restriction does not appear in RFC7468, but rather
54
/// is inspired by the OpenSSL PEM decoder.
55
///
56
/// Returns a slice which starts at the beginning of the encapsulated text.
57
///
58
/// From RFC7468:
59
/// > Data before the encapsulation boundaries are permitted, and
60
/// > parsers MUST NOT malfunction when processing such data.
61
0
pub(crate) fn strip_preamble(mut bytes: &[u8]) -> Result<&[u8]> {
62
0
    if bytes.starts_with(PRE_ENCAPSULATION_BOUNDARY) {
63
0
        return Ok(bytes);
64
0
    }
65
66
0
    while let Some((byte, remaining)) = bytes.split_first() {
67
0
        match *byte {
68
            CHAR_NUL => {
69
0
                return Err(Error::Preamble);
70
            }
71
0
            CHAR_LF if remaining.starts_with(PRE_ENCAPSULATION_BOUNDARY) => {
72
0
                return Ok(remaining);
73
            }
74
0
            _ => (),
75
0
        }
76
0
77
0
        bytes = remaining;
78
    }
79
80
0
    Err(Error::Preamble)
81
0
}
82
83
/// Strip a newline (`eol`) from the beginning of the provided byte slice.
84
///
85
/// The newline is considered mandatory and a decoding error will occur if it
86
/// is not present.
87
///
88
/// From RFC 7468 Section 3:
89
/// > lines are divided with CRLF, CR, or LF.
90
0
pub(crate) fn strip_leading_eol(bytes: &[u8]) -> Option<&[u8]> {
91
0
    match bytes {
92
0
        [CHAR_LF, rest @ ..] => Some(rest),
93
0
        [CHAR_CR, CHAR_LF, rest @ ..] => Some(rest),
94
0
        [CHAR_CR, rest @ ..] => Some(rest),
95
0
        _ => None,
96
    }
97
0
}
98
99
/// Strip a newline (`eol`) from the end of the provided byte slice.
100
///
101
/// The newline is considered mandatory and a decoding error will occur if it
102
/// is not present.
103
///
104
/// From RFC 7468 Section 3:
105
/// > lines are divided with CRLF, CR, or LF.
106
0
pub(crate) fn strip_trailing_eol(bytes: &[u8]) -> Option<&[u8]> {
107
0
    match bytes {
108
0
        [head @ .., CHAR_CR, CHAR_LF] => Some(head),
109
0
        [head @ .., CHAR_LF] => Some(head),
110
0
        [head @ .., CHAR_CR] => Some(head),
111
0
        _ => None,
112
    }
113
0
}
114
115
/// Split a slice beginning with a type label as located in an encapsulation
116
/// boundary. Returns the label as a `&str`, and slice beginning with the
117
/// encapsulated text with leading `-----` and newline removed.
118
///
119
/// This implementation follows the rules put forth in Section 2, which are
120
/// stricter than those found in the ABNF grammar:
121
///
122
/// > Labels are formally case-sensitive, uppercase, and comprised of zero or more
123
/// > characters; they do not contain consecutive spaces or hyphen-minuses,
124
/// > nor do they contain spaces or hyphen-minuses at either end.
125
///
126
/// We apply a slightly stricter interpretation:
127
/// - Labels MAY be empty
128
/// - Non-empty labels MUST start with an upper-case letter: `'A'..='Z'`
129
/// - The only allowable characters subsequently are `'A'..='Z'` or WSP.
130
///   (NOTE: this is an overly strict initial implementation and should be relaxed)
131
/// - Whitespace MUST NOT contain more than one consecutive WSP character
132
// TODO(tarcieri): evaluate whether this is too strict; support '-'
133
0
pub(crate) fn split_label(bytes: &[u8]) -> Option<(&str, &[u8])> {
134
0
    let mut n = 0usize;
135
0
136
0
    // TODO(tarcieri): handle hyphens in labels as well as spaces
137
0
    let mut last_was_wsp = false;
138
139
0
    for &char in bytes {
140
        // Validate character
141
0
        if is_labelchar(char) {
142
0
            last_was_wsp = false;
143
0
        } else if char == b'-' {
144
            // Possible start of encapsulation boundary delimiter
145
0
            break;
146
0
        } else if n != 0 && is_wsp(char) {
147
            // Repeated whitespace disallowed
148
0
            if last_was_wsp {
149
0
                return None;
150
0
            }
151
0
152
0
            last_was_wsp = true;
153
        } else {
154
0
            return None;
155
        }
156
157
0
        n = n.checked_add(1)?;
158
    }
159
160
0
    let (raw_label, rest) = bytes.split_at(n);
161
0
    let label = str::from_utf8(raw_label).ok()?;
162
163
0
    match rest {
164
0
        [b'-', b'-', b'-', b'-', b'-', body @ ..] => Some((label, strip_leading_eol(body)?)),
165
0
        _ => None,
166
    }
167
0
}
168
169
/// Validate that the given bytes are allowed as a PEM type label, i.e. the
170
/// label encoded in the `BEGIN` and `END` encapsulation boundaries.
171
0
pub(crate) fn validate_label(label: &[u8]) -> Result<()> {
172
0
    // TODO(tarcieri): handle hyphens in labels as well as spaces
173
0
    let mut last_was_wsp = false;
174
175
0
    for &char in label {
176
0
        if !is_allowed_in_label(char) {
177
0
            return Err(Error::Label);
178
0
        }
179
0
180
0
        if is_wsp(char) {
181
            // Double sequential whitespace characters disallowed
182
0
            if last_was_wsp {
183
0
                return Err(Error::Label);
184
0
            }
185
0
186
0
            last_was_wsp = true;
187
0
        } else {
188
0
            last_was_wsp = false;
189
0
        }
190
    }
191
192
0
    Ok(())
193
0
}
194
195
#[cfg(test)]
196
mod tests {
197
    use super::*;
198
199
    /// Empty label is OK.
200
    #[test]
201
    fn split_label_empty() {
202
        let (label, body) = split_label(b"-----\nBODY").unwrap();
203
        assert_eq!(label, "");
204
        assert_eq!(body, b"BODY");
205
    }
206
207
    /// Label containing text.
208
    #[test]
209
    fn split_label_with_text() {
210
        let (label, body) = split_label(b"PRIVATE KEY-----\nBODY").unwrap();
211
        assert_eq!(label, "PRIVATE KEY");
212
        assert_eq!(body, b"BODY");
213
    }
214
215
    /// Reject labels containing repeated spaces
216
    #[test]
217
    fn split_label_with_repeat_wsp_is_err() {
218
        assert!(split_label(b"PRIVATE  KEY-----\nBODY").is_none());
219
    }
220
221
    /// Basic validation of a label
222
    #[test]
223
    fn validate_private_key_label() {
224
        assert_eq!(validate_label(b"PRIVATE KEY"), Ok(()));
225
    }
226
227
    /// Reject labels with double spaces
228
    #[test]
229
    fn validate_private_key_label_reject_double_space() {
230
        assert_eq!(validate_label(b"PRIVATE  KEY"), Err(Error::Label));
231
    }
232
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pem-rfc7468-0.7.0/src/lib.rs
Line
Count
Source
1
#![no_std]
2
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3
#![doc = include_str!("../README.md")]
4
#![doc(
5
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
6
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
7
)]
8
#![deny(unsafe_code)]
9
#![warn(
10
    clippy::integer_arithmetic,
11
    clippy::mod_module_files,
12
    clippy::panic,
13
    clippy::panic_in_result_fn,
14
    clippy::unwrap_used,
15
    missing_docs,
16
    rust_2018_idioms,
17
    unused_lifetimes,
18
    unused_qualifications
19
)]
20
21
//! # Usage
22
//!
23
#![cfg_attr(feature = "std", doc = " ```")]
24
#![cfg_attr(not(feature = "std"), doc = " ```ignore")]
25
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
26
//! /// Example PEM document
27
//! /// NOTE: do not actually put private key literals into your source code!!!
28
//! let example_pem = "\
29
//! -----BEGIN PRIVATE KEY-----
30
//! MC4CAQAwBQYDK2VwBCIEIBftnHPp22SewYmmEoMcX8VwI4IHwaqd+9LFPj/15eqF
31
//! -----END PRIVATE KEY-----
32
//! ";
33
//!
34
//! // Decode PEM
35
//! let (type_label, data) = pem_rfc7468::decode_vec(example_pem.as_bytes())?;
36
//! assert_eq!(type_label, "PRIVATE KEY");
37
//! assert_eq!(
38
//!     data,
39
//!     &[
40
//!         48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 23, 237, 156, 115, 233, 219,
41
//!         100, 158, 193, 137, 166, 18, 131, 28, 95, 197, 112, 35, 130, 7, 193, 170, 157, 251,
42
//!         210, 197, 62, 63, 245, 229, 234, 133
43
//!     ]
44
//! );
45
//!
46
//! // Encode PEM
47
//! use pem_rfc7468::LineEnding;
48
//! let encoded_pem = pem_rfc7468::encode_string(type_label, LineEnding::default(), &data)?;
49
//! assert_eq!(&encoded_pem, example_pem);
50
//! # Ok(())
51
//! # }
52
//! ```
53
54
#[cfg(feature = "alloc")]
55
#[macro_use]
56
extern crate alloc;
57
#[cfg(feature = "std")]
58
extern crate std;
59
60
mod decoder;
61
mod encoder;
62
mod error;
63
mod grammar;
64
65
pub use crate::{
66
    decoder::{decode, decode_label, Decoder},
67
    encoder::{encapsulated_len, encapsulated_len_wrapped, encode, encoded_len, Encoder},
68
    error::{Error, Result},
69
};
70
pub use base64ct::LineEnding;
71
72
#[cfg(feature = "alloc")]
73
pub use crate::{decoder::decode_vec, encoder::encode_string};
74
75
/// The pre-encapsulation boundary appears before the encapsulated text.
76
///
77
/// From RFC 7468 Section 2:
78
/// > There are exactly five hyphen-minus (also known as dash) characters ("-")
79
/// > on both ends of the encapsulation boundaries, no more, no less.
80
const PRE_ENCAPSULATION_BOUNDARY: &[u8] = b"-----BEGIN ";
81
82
/// The post-encapsulation boundary appears immediately after the encapsulated text.
83
const POST_ENCAPSULATION_BOUNDARY: &[u8] = b"-----END ";
84
85
/// Delimiter of encapsulation boundaries.
86
const ENCAPSULATION_BOUNDARY_DELIMITER: &[u8] = b"-----";
87
88
/// Width at which the Base64 body of RFC7468-compliant PEM is wrapped.
89
///
90
/// From [RFC7468 § 2]:
91
///
92
/// > Generators MUST wrap the base64-encoded lines so that each line
93
/// > consists of exactly 64 characters except for the final line, which
94
/// > will encode the remainder of the data (within the 64-character line
95
/// > boundary), and they MUST NOT emit extraneous whitespace.  Parsers MAY
96
/// > handle other line sizes.
97
///
98
/// [RFC7468 § 2]: https://datatracker.ietf.org/doc/html/rfc7468#section-2
99
pub const BASE64_WRAP_WIDTH: usize = 64;
100
101
/// Buffered Base64 decoder type.
102
pub type Base64Decoder<'i> = base64ct::Decoder<'i, base64ct::Base64>;
103
104
/// Buffered Base64 encoder type.
105
pub type Base64Encoder<'o> = base64ct::Encoder<'o, base64ct::Base64>;
106
107
/// Marker trait for types with an associated PEM type label.
108
pub trait PemLabel {
109
    /// Expected PEM type label for a given document, e.g. `"PRIVATE KEY"`
110
    const PEM_LABEL: &'static str;
111
112
    /// Validate that a given label matches the expected label.
113
0
    fn validate_pem_label(actual: &str) -> Result<()> {
114
0
        if Self::PEM_LABEL == actual {
115
0
            Ok(())
116
        } else {
117
0
            Err(Error::UnexpectedTypeLabel {
118
0
                expected: Self::PEM_LABEL,
119
0
            })
120
        }
121
0
    }
Unexecuted instantiation: _RNvYpNtCs7ONNNQjtL1v_11pem_rfc74688PemLabel18validate_pem_labelB5_
Unexecuted instantiation: _RNvYNtNtCssr1zNgi7Nt_5pkcs816private_key_info14PrivateKeyInfoNtCs7ONNNQjtL1v_11pem_rfc74688PemLabel18validate_pem_labelB6_
Unexecuted instantiation: _RNvYNtNtCsj9qtwLkMHqH_4sec111private_key12EcPrivateKeyNtCs7ONNNQjtL1v_11pem_rfc74688PemLabel18validate_pem_labelB6_
122
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pkcs8-0.10.2/src/error.rs
Line
Count
Source
1
//! Error types
2
3
use core::fmt;
4
5
#[cfg(feature = "pem")]
6
use der::pem;
7
8
/// Result type
9
pub type Result<T> = core::result::Result<T, Error>;
10
11
/// Error type
12
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
13
#[non_exhaustive]
14
pub enum Error {
15
    /// ASN.1 DER-related errors.
16
    Asn1(der::Error),
17
18
    /// Errors relating to PKCS#5-encrypted keys.
19
    #[cfg(feature = "pkcs5")]
20
    EncryptedPrivateKey(pkcs5::Error),
21
22
    /// Malformed cryptographic key contained in a PKCS#8 document.
23
    ///
24
    /// This is intended for relaying errors related to the raw data contained
25
    /// within [`PrivateKeyInfo::private_key`][`crate::PrivateKeyInfo::private_key`]
26
    /// or [`SubjectPublicKeyInfo::subject_public_key`][`crate::SubjectPublicKeyInfo::subject_public_key`].
27
    KeyMalformed,
28
29
    /// [`AlgorithmIdentifier::parameters`][`crate::AlgorithmIdentifierRef::parameters`]
30
    /// is malformed or otherwise encoded in an unexpected manner.
31
    ParametersMalformed,
32
33
    /// Public key errors propagated from the [`spki::Error`] type.
34
    PublicKey(spki::Error),
35
}
36
37
impl fmt::Display for Error {
38
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39
0
        match self {
40
0
            Error::Asn1(err) => write!(f, "PKCS#8 ASN.1 error: {}", err),
41
            #[cfg(feature = "pkcs5")]
42
            Error::EncryptedPrivateKey(err) => write!(f, "{}", err),
43
0
            Error::KeyMalformed => f.write_str("PKCS#8 cryptographic key data malformed"),
44
0
            Error::ParametersMalformed => f.write_str("PKCS#8 algorithm parameters malformed"),
45
0
            Error::PublicKey(err) => write!(f, "public key error: {}", err),
46
        }
47
0
    }
48
}
49
50
#[cfg(feature = "std")]
51
impl std::error::Error for Error {}
52
53
impl From<der::Error> for Error {
54
0
    fn from(err: der::Error) -> Error {
55
0
        Error::Asn1(err)
56
0
    }
57
}
58
59
impl From<der::ErrorKind> for Error {
60
0
    fn from(err: der::ErrorKind) -> Error {
61
0
        Error::Asn1(err.into())
62
0
    }
63
}
64
65
#[cfg(feature = "pem")]
66
impl From<pem::Error> for Error {
67
0
    fn from(err: pem::Error) -> Error {
68
0
        der::Error::from(err).into()
69
0
    }
70
}
71
72
#[cfg(feature = "pkcs5")]
73
impl From<pkcs5::Error> for Error {
74
    fn from(err: pkcs5::Error) -> Error {
75
        Error::EncryptedPrivateKey(err)
76
    }
77
}
78
79
impl From<spki::Error> for Error {
80
0
    fn from(err: spki::Error) -> Error {
81
0
        Error::PublicKey(err)
82
0
    }
83
}
84
85
impl From<Error> for spki::Error {
86
0
    fn from(err: Error) -> spki::Error {
87
0
        match err {
88
0
            Error::Asn1(e) => spki::Error::Asn1(e),
89
0
            Error::PublicKey(e) => e,
90
0
            _ => spki::Error::KeyMalformed,
91
        }
92
0
    }
93
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pkcs8-0.10.2/src/private_key_info.rs
Line
Count
Source
1
//! PKCS#8 `PrivateKeyInfo`.
2
3
use crate::{AlgorithmIdentifierRef, Error, Result, Version};
4
use core::fmt;
5
use der::{
6
    asn1::{AnyRef, BitStringRef, ContextSpecific, OctetStringRef},
7
    Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, TagMode, TagNumber,
8
    Writer,
9
};
10
11
#[cfg(feature = "alloc")]
12
use der::SecretDocument;
13
14
#[cfg(feature = "encryption")]
15
use {
16
    crate::EncryptedPrivateKeyInfo,
17
    der::zeroize::Zeroizing,
18
    pkcs5::pbes2,
19
    rand_core::{CryptoRng, RngCore},
20
};
21
22
#[cfg(feature = "pem")]
23
use der::pem::PemLabel;
24
25
#[cfg(feature = "subtle")]
26
use subtle::{Choice, ConstantTimeEq};
27
28
/// Context-specific tag number for the public key.
29
const PUBLIC_KEY_TAG: TagNumber = TagNumber::N1;
30
31
/// PKCS#8 `PrivateKeyInfo`.
32
///
33
/// ASN.1 structure containing an `AlgorithmIdentifier`, private key
34
/// data in an algorithm specific format, and optional attributes
35
/// (ignored by this implementation).
36
///
37
/// Supports PKCS#8 v1 as described in [RFC 5208] and PKCS#8 v2 as described
38
/// in [RFC 5958]. PKCS#8 v2 keys include an additional public key field.
39
///
40
/// # PKCS#8 v1 `PrivateKeyInfo`
41
///
42
/// Described in [RFC 5208 Section 5]:
43
///
44
/// ```text
45
/// PrivateKeyInfo ::= SEQUENCE {
46
///         version                   Version,
47
///         privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
48
///         privateKey                PrivateKey,
49
///         attributes           [0]  IMPLICIT Attributes OPTIONAL }
50
///
51
/// Version ::= INTEGER
52
///
53
/// PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
54
///
55
/// PrivateKey ::= OCTET STRING
56
///
57
/// Attributes ::= SET OF Attribute
58
/// ```
59
///
60
/// # PKCS#8 v2 `OneAsymmetricKey`
61
///
62
/// PKCS#8 `OneAsymmetricKey` as described in [RFC 5958 Section 2]:
63
///
64
/// ```text
65
/// PrivateKeyInfo ::= OneAsymmetricKey
66
///
67
/// OneAsymmetricKey ::= SEQUENCE {
68
///     version                   Version,
69
///     privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
70
///     privateKey                PrivateKey,
71
///     attributes            [0] Attributes OPTIONAL,
72
///     ...,
73
///     [[2: publicKey        [1] PublicKey OPTIONAL ]],
74
///     ...
75
///   }
76
///
77
/// Version ::= INTEGER { v1(0), v2(1) } (v1, ..., v2)
78
///
79
/// PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
80
///
81
/// PrivateKey ::= OCTET STRING
82
///
83
/// Attributes ::= SET OF Attribute
84
///
85
/// PublicKey ::= BIT STRING
86
/// ```
87
///
88
/// [RFC 5208]: https://tools.ietf.org/html/rfc5208
89
/// [RFC 5958]: https://datatracker.ietf.org/doc/html/rfc5958
90
/// [RFC 5208 Section 5]: https://tools.ietf.org/html/rfc5208#section-5
91
/// [RFC 5958 Section 2]: https://datatracker.ietf.org/doc/html/rfc5958#section-2
92
#[derive(Clone)]
93
pub struct PrivateKeyInfo<'a> {
94
    /// X.509 `AlgorithmIdentifier` for the private key type.
95
    pub algorithm: AlgorithmIdentifierRef<'a>,
96
97
    /// Private key data.
98
    pub private_key: &'a [u8],
99
100
    /// Public key data, optionally available if version is V2.
101
    pub public_key: Option<&'a [u8]>,
102
}
103
104
impl<'a> PrivateKeyInfo<'a> {
105
    /// Create a new PKCS#8 [`PrivateKeyInfo`] message.
106
    ///
107
    /// This is a helper method which initializes `attributes` and `public_key`
108
    /// to `None`, helpful if you aren't using those.
109
0
    pub fn new(algorithm: AlgorithmIdentifierRef<'a>, private_key: &'a [u8]) -> Self {
110
0
        Self {
111
0
            algorithm,
112
0
            private_key,
113
0
            public_key: None,
114
0
        }
115
0
    }
116
117
    /// Get the PKCS#8 [`Version`] for this structure.
118
    ///
119
    /// [`Version::V1`] if `public_key` is `None`, [`Version::V2`] if `Some`.
120
0
    pub fn version(&self) -> Version {
121
0
        if self.public_key.is_some() {
122
0
            Version::V2
123
        } else {
124
0
            Version::V1
125
        }
126
0
    }
127
128
    /// Encrypt this private key using a symmetric encryption key derived
129
    /// from the provided password.
130
    ///
131
    /// Uses the following algorithms for encryption:
132
    /// - PBKDF: scrypt with default parameters:
133
    ///   - log₂(N): 15
134
    ///   - r: 8
135
    ///   - p: 1
136
    /// - Cipher: AES-256-CBC (best available option for PKCS#5 encryption)
137
    #[cfg(feature = "encryption")]
138
    pub fn encrypt(
139
        &self,
140
        rng: impl CryptoRng + RngCore,
141
        password: impl AsRef<[u8]>,
142
    ) -> Result<SecretDocument> {
143
        let der = Zeroizing::new(self.to_der()?);
144
        EncryptedPrivateKeyInfo::encrypt(rng, password, der.as_ref())
145
    }
146
147
    /// Encrypt this private key using a symmetric encryption key derived
148
    /// from the provided password and [`pbes2::Parameters`].
149
    #[cfg(feature = "encryption")]
150
    pub fn encrypt_with_params(
151
        &self,
152
        pbes2_params: pbes2::Parameters<'_>,
153
        password: impl AsRef<[u8]>,
154
    ) -> Result<SecretDocument> {
155
        let der = Zeroizing::new(self.to_der()?);
156
        EncryptedPrivateKeyInfo::encrypt_with(pbes2_params, password, der.as_ref())
157
    }
158
159
    /// Get a `BIT STRING` representation of the public key, if present.
160
0
    fn public_key_bit_string(&self) -> der::Result<Option<ContextSpecific<BitStringRef<'a>>>> {
161
0
        self.public_key
162
0
            .map(|pk| {
163
0
                BitStringRef::from_bytes(pk).map(|value| ContextSpecific {
164
0
                    tag_number: PUBLIC_KEY_TAG,
165
0
                    tag_mode: TagMode::Implicit,
166
0
                    value,
167
0
                })
168
0
            })
169
0
            .transpose()
170
0
    }
171
}
172
173
impl<'a> DecodeValue<'a> for PrivateKeyInfo<'a> {
174
0
    fn decode_value<R: Reader<'a>>(
175
0
        reader: &mut R,
176
0
        header: Header,
177
0
    ) -> der::Result<PrivateKeyInfo<'a>> {
178
0
        reader.read_nested(header.length, |reader| {
179
            // Parse and validate `version` INTEGER.
180
0
            let version = Version::decode(reader)?;
181
0
            let algorithm = reader.decode()?;
182
0
            let private_key = OctetStringRef::decode(reader)?.into();
183
0
            let public_key = reader
184
0
                .context_specific::<BitStringRef<'_>>(PUBLIC_KEY_TAG, TagMode::Implicit)?
185
0
                .map(|bs| {
186
0
                    bs.as_bytes()
187
0
                        .ok_or_else(|| der::Tag::BitString.value_error())
188
0
                })
189
0
                .transpose()?;
190
191
0
            if version.has_public_key() != public_key.is_some() {
192
0
                return Err(reader.error(
193
0
                    der::Tag::ContextSpecific {
194
0
                        constructed: true,
195
0
                        number: PUBLIC_KEY_TAG,
196
0
                    }
197
0
                    .value_error()
198
0
                    .kind(),
199
0
                ));
200
0
            }
201
202
            // Ignore any remaining extension fields
203
0
            while !reader.is_finished() {
204
0
                reader.decode::<ContextSpecific<AnyRef<'_>>>()?;
205
            }
206
207
0
            Ok(Self {
208
0
                algorithm,
209
0
                private_key,
210
0
                public_key,
211
0
            })
212
0
        })
213
0
    }
214
}
215
216
impl EncodeValue for PrivateKeyInfo<'_> {
217
0
    fn value_len(&self) -> der::Result<Length> {
218
0
        self.version().encoded_len()?
219
0
            + self.algorithm.encoded_len()?
220
0
            + OctetStringRef::new(self.private_key)?.encoded_len()?
221
0
            + self.public_key_bit_string()?.encoded_len()?
222
0
    }
223
224
0
    fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
225
0
        self.version().encode(writer)?;
226
0
        self.algorithm.encode(writer)?;
227
0
        OctetStringRef::new(self.private_key)?.encode(writer)?;
228
0
        self.public_key_bit_string()?.encode(writer)?;
229
0
        Ok(())
230
0
    }
231
}
232
233
impl<'a> Sequence<'a> for PrivateKeyInfo<'a> {}
234
235
impl<'a> TryFrom<&'a [u8]> for PrivateKeyInfo<'a> {
236
    type Error = Error;
237
238
0
    fn try_from(bytes: &'a [u8]) -> Result<Self> {
239
0
        Ok(Self::from_der(bytes)?)
240
0
    }
241
}
242
243
impl<'a> fmt::Debug for PrivateKeyInfo<'a> {
244
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245
0
        f.debug_struct("PrivateKeyInfo")
246
0
            .field("version", &self.version())
247
0
            .field("algorithm", &self.algorithm)
248
0
            .field("public_key", &self.public_key)
249
0
            .finish_non_exhaustive()
250
0
    }
251
}
252
253
#[cfg(feature = "alloc")]
254
impl TryFrom<PrivateKeyInfo<'_>> for SecretDocument {
255
    type Error = Error;
256
257
0
    fn try_from(private_key: PrivateKeyInfo<'_>) -> Result<SecretDocument> {
258
0
        SecretDocument::try_from(&private_key)
259
0
    }
260
}
261
262
#[cfg(feature = "alloc")]
263
impl TryFrom<&PrivateKeyInfo<'_>> for SecretDocument {
264
    type Error = Error;
265
266
0
    fn try_from(private_key: &PrivateKeyInfo<'_>) -> Result<SecretDocument> {
267
0
        Ok(Self::encode_msg(private_key)?)
268
0
    }
269
}
270
271
#[cfg(feature = "pem")]
272
impl PemLabel for PrivateKeyInfo<'_> {
273
    const PEM_LABEL: &'static str = "PRIVATE KEY";
274
}
275
276
#[cfg(feature = "subtle")]
277
impl<'a> ConstantTimeEq for PrivateKeyInfo<'a> {
278
    fn ct_eq(&self, other: &Self) -> Choice {
279
        // NOTE: public fields are not compared in constant time
280
        let public_fields_eq =
281
            self.algorithm == other.algorithm && self.public_key == other.public_key;
282
283
        self.private_key.ct_eq(other.private_key) & Choice::from(public_fields_eq as u8)
284
    }
285
}
286
287
#[cfg(feature = "subtle")]
288
impl<'a> Eq for PrivateKeyInfo<'a> {}
289
290
#[cfg(feature = "subtle")]
291
impl<'a> PartialEq for PrivateKeyInfo<'a> {
292
    fn eq(&self, other: &Self) -> bool {
293
        self.ct_eq(other).into()
294
    }
295
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pkcs8-0.10.2/src/traits.rs
Line
Count
Source
1
//! Traits for parsing objects from PKCS#8 encoded documents
2
3
use crate::{Error, PrivateKeyInfo, Result};
4
5
#[cfg(feature = "alloc")]
6
use der::SecretDocument;
7
8
#[cfg(feature = "encryption")]
9
use {
10
    crate::EncryptedPrivateKeyInfo,
11
    rand_core::{CryptoRng, RngCore},
12
};
13
14
#[cfg(feature = "pem")]
15
use {crate::LineEnding, alloc::string::String, der::zeroize::Zeroizing};
16
17
#[cfg(feature = "pem")]
18
use der::pem::PemLabel;
19
20
#[cfg(feature = "std")]
21
use std::path::Path;
22
23
/// Parse a private key object from a PKCS#8 encoded document.
24
pub trait DecodePrivateKey: Sized {
25
    /// Deserialize PKCS#8 private key from ASN.1 DER-encoded data
26
    /// (binary format).
27
    fn from_pkcs8_der(bytes: &[u8]) -> Result<Self>;
28
29
    /// Deserialize encrypted PKCS#8 private key from ASN.1 DER-encoded data
30
    /// (binary format) and attempt to decrypt it using the provided password.
31
    #[cfg(feature = "encryption")]
32
    fn from_pkcs8_encrypted_der(bytes: &[u8], password: impl AsRef<[u8]>) -> Result<Self> {
33
        let doc = EncryptedPrivateKeyInfo::try_from(bytes)?.decrypt(password)?;
34
        Self::from_pkcs8_der(doc.as_bytes())
35
    }
36
37
    /// Deserialize PKCS#8-encoded private key from PEM.
38
    ///
39
    /// Keys in this format begin with the following delimiter:
40
    ///
41
    /// ```text
42
    /// -----BEGIN PRIVATE KEY-----
43
    /// ```
44
    #[cfg(feature = "pem")]
45
0
    fn from_pkcs8_pem(s: &str) -> Result<Self> {
46
0
        let (label, doc) = SecretDocument::from_pem(s)?;
47
0
        PrivateKeyInfo::validate_pem_label(label)?;
48
0
        Self::from_pkcs8_der(doc.as_bytes())
49
0
    }
50
51
    /// Deserialize encrypted PKCS#8-encoded private key from PEM and attempt
52
    /// to decrypt it using the provided password.
53
    ///
54
    /// Keys in this format begin with the following delimiter:
55
    ///
56
    /// ```text
57
    /// -----BEGIN ENCRYPTED PRIVATE KEY-----
58
    /// ```
59
    #[cfg(all(feature = "encryption", feature = "pem"))]
60
    fn from_pkcs8_encrypted_pem(s: &str, password: impl AsRef<[u8]>) -> Result<Self> {
61
        let (label, doc) = SecretDocument::from_pem(s)?;
62
        EncryptedPrivateKeyInfo::validate_pem_label(label)?;
63
        Self::from_pkcs8_encrypted_der(doc.as_bytes(), password)
64
    }
65
66
    /// Load PKCS#8 private key from an ASN.1 DER-encoded file on the local
67
    /// filesystem (binary format).
68
    #[cfg(feature = "std")]
69
0
    fn read_pkcs8_der_file(path: impl AsRef<Path>) -> Result<Self> {
70
0
        Self::from_pkcs8_der(SecretDocument::read_der_file(path)?.as_bytes())
71
0
    }
72
73
    /// Load PKCS#8 private key from a PEM-encoded file on the local filesystem.
74
    #[cfg(all(feature = "pem", feature = "std"))]
75
0
    fn read_pkcs8_pem_file(path: impl AsRef<Path>) -> Result<Self> {
76
0
        let (label, doc) = SecretDocument::read_pem_file(path)?;
77
0
        PrivateKeyInfo::validate_pem_label(&label)?;
78
0
        Self::from_pkcs8_der(doc.as_bytes())
79
0
    }
80
}
81
82
impl<T> DecodePrivateKey for T
83
where
84
    T: for<'a> TryFrom<PrivateKeyInfo<'a>, Error = Error>,
85
{
86
0
    fn from_pkcs8_der(bytes: &[u8]) -> Result<Self> {
87
0
        Self::try_from(PrivateKeyInfo::try_from(bytes)?)
88
0
    }
89
}
90
91
/// Serialize a private key object to a PKCS#8 encoded document.
92
#[cfg(feature = "alloc")]
93
pub trait EncodePrivateKey {
94
    /// Serialize a [`SecretDocument`] containing a PKCS#8-encoded private key.
95
    fn to_pkcs8_der(&self) -> Result<SecretDocument>;
96
97
    /// Create an [`SecretDocument`] containing the ciphertext of
98
    /// a PKCS#8 encoded private key encrypted under the given `password`.
99
    #[cfg(feature = "encryption")]
100
    fn to_pkcs8_encrypted_der(
101
        &self,
102
        rng: impl CryptoRng + RngCore,
103
        password: impl AsRef<[u8]>,
104
    ) -> Result<SecretDocument> {
105
        EncryptedPrivateKeyInfo::encrypt(rng, password, self.to_pkcs8_der()?.as_bytes())
106
    }
107
108
    /// Serialize this private key as PEM-encoded PKCS#8 with the given [`LineEnding`].
109
    #[cfg(feature = "pem")]
110
0
    fn to_pkcs8_pem(&self, line_ending: LineEnding) -> Result<Zeroizing<String>> {
111
0
        let doc = self.to_pkcs8_der()?;
112
0
        Ok(doc.to_pem(PrivateKeyInfo::PEM_LABEL, line_ending)?)
113
0
    }
114
115
    /// Serialize this private key as an encrypted PEM-encoded PKCS#8 private
116
    /// key using the `provided` to derive an encryption key.
117
    #[cfg(all(feature = "encryption", feature = "pem"))]
118
    fn to_pkcs8_encrypted_pem(
119
        &self,
120
        rng: impl CryptoRng + RngCore,
121
        password: impl AsRef<[u8]>,
122
        line_ending: LineEnding,
123
    ) -> Result<Zeroizing<String>> {
124
        let doc = self.to_pkcs8_encrypted_der(rng, password)?;
125
        Ok(doc.to_pem(EncryptedPrivateKeyInfo::PEM_LABEL, line_ending)?)
126
    }
127
128
    /// Write ASN.1 DER-encoded PKCS#8 private key to the given path
129
    #[cfg(feature = "std")]
130
0
    fn write_pkcs8_der_file(&self, path: impl AsRef<Path>) -> Result<()> {
131
0
        Ok(self.to_pkcs8_der()?.write_der_file(path)?)
132
0
    }
133
134
    /// Write ASN.1 DER-encoded PKCS#8 private key to the given path
135
    #[cfg(all(feature = "pem", feature = "std"))]
136
0
    fn write_pkcs8_pem_file(&self, path: impl AsRef<Path>, line_ending: LineEnding) -> Result<()> {
137
0
        let doc = self.to_pkcs8_der()?;
138
0
        Ok(doc.write_pem_file(path, PrivateKeyInfo::PEM_LABEL, line_ending)?)
139
0
    }
140
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pkcs8-0.10.2/src/version.rs
Line
Count
Source
1
//! PKCS#8 version identifier.
2
3
use crate::Error;
4
use der::{Decode, Encode, FixedTag, Reader, Tag, Writer};
5
6
/// Version identifier for PKCS#8 documents.
7
///
8
/// (RFC 5958 designates `0` and `1` as the only valid versions for PKCS#8 documents)
9
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
10
pub enum Version {
11
    /// Denotes PKCS#8 v1: no public key field.
12
    V1 = 0,
13
14
    /// Denotes PKCS#8 v2: `OneAsymmetricKey` with public key field.
15
    V2 = 1,
16
}
17
18
impl Version {
19
    /// Is this version expected to have a public key?
20
0
    pub fn has_public_key(self) -> bool {
21
0
        match self {
22
0
            Version::V1 => false,
23
0
            Version::V2 => true,
24
        }
25
0
    }
26
}
27
28
impl<'a> Decode<'a> for Version {
29
0
    fn decode<R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> {
30
0
        Version::try_from(u8::decode(decoder)?).map_err(|_| Self::TAG.value_error())
Unexecuted instantiation: _RNCINvXs_NtCssr1zNgi7Nt_5pkcs87versionNtB7_7VersionNtNtCscrZQdumITES_3der6decode6Decode6decodeINtNtNtBR_6reader6nested12NestedReaderNtNtB1z_5slice11SliceReaderEE0B9_
Unexecuted instantiation: _RNCINvXs_NtCssr1zNgi7Nt_5pkcs87versionNtB7_7VersionNtNtCscrZQdumITES_3der6decode6Decode6decodeNtNtNtBR_6reader5slice11SliceReaderE0B9_
31
0
    }
Unexecuted instantiation: _RINvXs_NtCssr1zNgi7Nt_5pkcs87versionNtB5_7VersionNtNtCscrZQdumITES_3der6decode6Decode6decodeINtNtNtBP_6reader6nested12NestedReaderNtNtB1x_5slice11SliceReaderEEB7_
Unexecuted instantiation: _RINvXs_NtCssr1zNgi7Nt_5pkcs87versionNtB5_7VersionNtNtCscrZQdumITES_3der6decode6Decode6decodeNtNtNtBP_6reader5slice11SliceReaderEB7_
32
}
33
34
impl Encode for Version {
35
0
    fn encoded_len(&self) -> der::Result<der::Length> {
36
0
        der::Length::from(1u8).for_tlv()
37
0
    }
38
39
0
    fn encode(&self, writer: &mut impl Writer) -> der::Result<()> {
40
0
        u8::from(*self).encode(writer)
41
0
    }
42
}
43
44
impl From<Version> for u8 {
45
0
    fn from(version: Version) -> Self {
46
0
        version as u8
47
0
    }
48
}
49
50
impl TryFrom<u8> for Version {
51
    type Error = Error;
52
0
    fn try_from(byte: u8) -> Result<Version, Error> {
53
0
        match byte {
54
0
            0 => Ok(Version::V1),
55
0
            1 => Ok(Version::V2),
56
0
            _ => Err(Self::TAG.value_error().into()),
57
        }
58
0
    }
59
}
60
61
impl FixedTag for Version {
62
    const TAG: Tag = Tag::Integer;
63
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/primeorder-0.13.6/src/affine.rs
Line
Count
Source
1
//! Affine curve points.
2
3
#![allow(clippy::op_ref)]
4
5
use crate::{PrimeCurveParams, ProjectivePoint};
6
use core::{
7
    borrow::Borrow,
8
    ops::{Mul, Neg},
9
};
10
use elliptic_curve::{
11
    ff::{Field, PrimeField},
12
    generic_array::ArrayLength,
13
    group::{prime::PrimeCurveAffine, GroupEncoding},
14
    point::{AffineCoordinates, DecompactPoint, DecompressPoint, Double},
15
    sec1::{
16
        self, CompressedPoint, EncodedPoint, FromEncodedPoint, ModulusSize, ToCompactEncodedPoint,
17
        ToEncodedPoint, UncompressedPointSize,
18
    },
19
    subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, CtOption},
20
    zeroize::DefaultIsZeroes,
21
    Error, FieldBytes, FieldBytesEncoding, FieldBytesSize, PublicKey, Result, Scalar,
22
};
23
24
#[cfg(feature = "serde")]
25
use serdect::serde::{de, ser, Deserialize, Serialize};
26
27
/// Point on a Weierstrass curve in affine coordinates.
28
#[derive(Clone, Copy, Debug)]
29
pub struct AffinePoint<C: PrimeCurveParams> {
30
    /// x-coordinate
31
    pub(crate) x: C::FieldElement,
32
33
    /// y-coordinate
34
    pub(crate) y: C::FieldElement,
35
36
    /// Is this point the point at infinity? 0 = no, 1 = yes
37
    ///
38
    /// This is a proxy for [`Choice`], but uses `u8` instead to permit `const`
39
    /// constructors for `IDENTITY` and `GENERATOR`.
40
    pub(crate) infinity: u8,
41
}
42
43
impl<C> AffinePoint<C>
44
where
45
    C: PrimeCurveParams,
46
{
47
    /// Additive identity of the group a.k.a. the point at infinity.
48
    pub const IDENTITY: Self = Self {
49
        x: C::FieldElement::ZERO,
50
        y: C::FieldElement::ZERO,
51
        infinity: 1,
52
    };
53
54
    /// Base point of the curve.
55
    pub const GENERATOR: Self = Self {
56
        x: C::GENERATOR.0,
57
        y: C::GENERATOR.1,
58
        infinity: 0,
59
    };
60
61
    /// Is this point the point at infinity?
62
838
    pub fn is_identity(&self) -> Choice {
63
838
        Choice::from(self.infinity)
64
838
    }
_RNvMNtCs2J0Yj5ID6sO_10primeorder6affineINtB2_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256E11is_identityCs4RkbDk9WRL5_5clvmr
Line
Count
Source
62
838
    pub fn is_identity(&self) -> Choice {
63
838
        Choice::from(self.infinity)
64
838
    }
Unexecuted instantiation: _RNvMNtCs2J0Yj5ID6sO_10primeorder6affineINtB2_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256E11is_identityBW_
Unexecuted instantiation: _RNvMNtCs2J0Yj5ID6sO_10primeorder6affineINtB2_11AffinePointpE11is_identityB4_
65
66
    /// Conditionally negate [`AffinePoint`] for use with point compaction.
67
14
    fn to_compact(self) -> Self {
68
14
        let neg_self = -self;
69
14
        let choice = C::Uint::decode_field_bytes(&self.y.to_repr())
70
14
            .ct_gt(&C::Uint::decode_field_bytes(&neg_self.y.to_repr()));
71
14
72
14
        Self {
73
14
            x: self.x,
74
14
            y: C::FieldElement::conditional_select(&self.y, &neg_self.y, choice),
75
14
            infinity: self.infinity,
76
14
        }
77
14
    }
_RNvMNtCs2J0Yj5ID6sO_10primeorder6affineINtB2_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256E10to_compactCs4RkbDk9WRL5_5clvmr
Line
Count
Source
67
14
    fn to_compact(self) -> Self {
68
14
        let neg_self = -self;
69
14
        let choice = C::Uint::decode_field_bytes(&self.y.to_repr())
70
14
            .ct_gt(&C::Uint::decode_field_bytes(&neg_self.y.to_repr()));
71
14
72
14
        Self {
73
14
            x: self.x,
74
14
            y: C::FieldElement::conditional_select(&self.y, &neg_self.y, choice),
75
14
            infinity: self.infinity,
76
14
        }
77
14
    }
Unexecuted instantiation: _RNvMNtCs2J0Yj5ID6sO_10primeorder6affineINtB2_11AffinePointpE10to_compactB4_
78
}
79
80
impl<C> AffineCoordinates for AffinePoint<C>
81
where
82
    C: PrimeCurveParams,
83
{
84
    type FieldRepr = FieldBytes<C>;
85
86
838
    fn x(&self) -> FieldBytes<C> {
87
838
        self.x.to_repr()
88
838
    }
_RNvXs_NtCs2J0Yj5ID6sO_10primeorder6affineINtB4_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtCs8yVsO3EKNkV_14elliptic_curve5point17AffineCoordinates1xCs4RkbDk9WRL5_5clvmr
Line
Count
Source
86
838
    fn x(&self) -> FieldBytes<C> {
87
838
        self.x.to_repr()
88
838
    }
Unexecuted instantiation: _RNvXs_NtCs2J0Yj5ID6sO_10primeorder6affineINtB4_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtCs8yVsO3EKNkV_14elliptic_curve5point17AffineCoordinates1xBY_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder6affines_0pEINtB5_11AffinePointpENtNtCs8yVsO3EKNkV_14elliptic_curve5point17AffineCoordinates1xB7_
89
90
0
    fn y_is_odd(&self) -> Choice {
91
0
        self.y.is_odd()
92
0
    }
93
}
94
95
impl<C> ConditionallySelectable for AffinePoint<C>
96
where
97
    C: PrimeCurveParams,
98
{
99
    #[inline(always)]
100
2.03k
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
101
2.03k
        Self {
102
2.03k
            x: C::FieldElement::conditional_select(&a.x, &b.x, choice),
103
2.03k
            y: C::FieldElement::conditional_select(&a.y, &b.y, choice),
104
2.03k
            infinity: u8::conditional_select(&a.infinity, &b.infinity, choice),
105
2.03k
        }
106
2.03k
    }
_RNvXs0_NtCs2J0Yj5ID6sO_10primeorder6affineINtB5_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectCs4RkbDk9WRL5_5clvmr
Line
Count
Source
100
2.03k
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
101
2.03k
        Self {
102
2.03k
            x: C::FieldElement::conditional_select(&a.x, &b.x, choice),
103
2.03k
            y: C::FieldElement::conditional_select(&a.y, &b.y, choice),
104
2.03k
            infinity: u8::conditional_select(&a.infinity, &b.infinity, choice),
105
2.03k
        }
106
2.03k
    }
Unexecuted instantiation: _RNvXs0_NtCs2J0Yj5ID6sO_10primeorder6affineINtB5_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectBZ_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder6affines0_0pEINtB5_11AffinePointpENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectB7_
107
}
108
109
impl<C> ConstantTimeEq for AffinePoint<C>
110
where
111
    C: PrimeCurveParams,
112
{
113
0
    fn ct_eq(&self, other: &Self) -> Choice {
114
0
        self.x.ct_eq(&other.x) & self.y.ct_eq(&other.y) & self.infinity.ct_eq(&other.infinity)
115
0
    }
116
}
117
118
impl<C> Default for AffinePoint<C>
119
where
120
    C: PrimeCurveParams,
121
{
122
1.19k
    fn default() -> Self {
123
1.19k
        Self::IDENTITY
124
1.19k
    }
_RNvXs2_NtCs2J0Yj5ID6sO_10primeorder6affineINtB5_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs4RkbDk9WRL5_5clvmr
Line
Count
Source
122
1.19k
    fn default() -> Self {
123
1.19k
        Self::IDENTITY
124
1.19k
    }
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder6affines2_0pEINtB5_11AffinePointpENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultB7_
125
}
126
127
impl<C> DefaultIsZeroes for AffinePoint<C> where C: PrimeCurveParams {}
128
129
impl<C> DecompressPoint<C> for AffinePoint<C>
130
where
131
    C: PrimeCurveParams,
132
    FieldBytes<C>: Copy,
133
{
134
611
    fn decompress(x_bytes: &FieldBytes<C>, y_is_odd: Choice) -> CtOption<Self> {
135
611
        C::FieldElement::from_repr(*x_bytes).and_then(|x| {
136
611
            let alpha = x * &x * &x + &(C::EQUATION_A * &x) + &C::EQUATION_B;
137
611
            let beta = alpha.sqrt();
138
611
139
611
            beta.map(|beta| {
140
611
                let y = C::FieldElement::conditional_select(
141
611
                    &-beta,
142
611
                    &beta,
143
611
                    beta.is_odd().ct_eq(&y_is_odd),
144
611
                );
145
611
146
611
                Self { x, y, infinity: 0 }
147
611
            })
_RNCNCNvXs4_NtCs2J0Yj5ID6sO_10primeorder6affineINtB9_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCs8yVsO3EKNkV_14elliptic_curve5point15DecompressPointB11_E10decompress00Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
139
611
            beta.map(|beta| {
140
611
                let y = C::FieldElement::conditional_select(
141
611
                    &-beta,
142
611
                    &beta,
143
611
                    beta.is_odd().ct_eq(&y_is_odd),
144
611
                );
145
611
146
611
                Self { x, y, infinity: 0 }
147
611
            })
Unexecuted instantiation: _RNCNCNvXININtCs2J0Yj5ID6sO_10primeorder6affines4_0pEINtB9_11AffinePointpEINtNtCs8yVsO3EKNkV_14elliptic_curve5point15DecompressPointpE10decompress00Bb_
148
611
        })
_RNCNvXs4_NtCs2J0Yj5ID6sO_10primeorder6affineINtB7_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCs8yVsO3EKNkV_14elliptic_curve5point15DecompressPointBZ_E10decompress0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
135
611
        C::FieldElement::from_repr(*x_bytes).and_then(|x| {
136
611
            let alpha = x * &x * &x + &(C::EQUATION_A * &x) + &C::EQUATION_B;
137
611
            let beta = alpha.sqrt();
138
611
139
611
            beta.map(|beta| {
140
                let y = C::FieldElement::conditional_select(
141
                    &-beta,
142
                    &beta,
143
                    beta.is_odd().ct_eq(&y_is_odd),
144
                );
145
146
                Self { x, y, infinity: 0 }
147
611
            })
148
611
        })
Unexecuted instantiation: _RNCNvXININtCs2J0Yj5ID6sO_10primeorder6affines4_0pEINtB7_11AffinePointpEINtNtCs8yVsO3EKNkV_14elliptic_curve5point15DecompressPointpE10decompress0B9_
149
611
    }
_RNvXs4_NtCs2J0Yj5ID6sO_10primeorder6affineINtB5_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCs8yVsO3EKNkV_14elliptic_curve5point15DecompressPointBX_E10decompressCs4RkbDk9WRL5_5clvmr
Line
Count
Source
134
611
    fn decompress(x_bytes: &FieldBytes<C>, y_is_odd: Choice) -> CtOption<Self> {
135
611
        C::FieldElement::from_repr(*x_bytes).and_then(|x| {
136
            let alpha = x * &x * &x + &(C::EQUATION_A * &x) + &C::EQUATION_B;
137
            let beta = alpha.sqrt();
138
139
            beta.map(|beta| {
140
                let y = C::FieldElement::conditional_select(
141
                    &-beta,
142
                    &beta,
143
                    beta.is_odd().ct_eq(&y_is_odd),
144
                );
145
146
                Self { x, y, infinity: 0 }
147
            })
148
611
        })
149
611
    }
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder6affines4_0pEINtB5_11AffinePointpEINtNtCs8yVsO3EKNkV_14elliptic_curve5point15DecompressPointpE10decompressB7_
150
}
151
152
impl<C> DecompactPoint<C> for AffinePoint<C>
153
where
154
    C: PrimeCurveParams,
155
    FieldBytes<C>: Copy,
156
{
157
14
    fn decompact(x_bytes: &FieldBytes<C>) -> CtOption<Self> {
158
14
        Self::decompress(x_bytes, Choice::from(0)).map(|point| point.to_compact())
_RNCNvXs5_NtCs2J0Yj5ID6sO_10primeorder6affineINtB7_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCs8yVsO3EKNkV_14elliptic_curve5point14DecompactPointBZ_E9decompact0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
158
14
        Self::decompress(x_bytes, Choice::from(0)).map(|point| point.to_compact())
Unexecuted instantiation: _RNCNvXININtCs2J0Yj5ID6sO_10primeorder6affines5_0pEINtB7_11AffinePointpEINtNtCs8yVsO3EKNkV_14elliptic_curve5point14DecompactPointpE9decompact0B9_
159
14
    }
_RNvXs5_NtCs2J0Yj5ID6sO_10primeorder6affineINtB5_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCs8yVsO3EKNkV_14elliptic_curve5point14DecompactPointBX_E9decompactCs4RkbDk9WRL5_5clvmr
Line
Count
Source
157
14
    fn decompact(x_bytes: &FieldBytes<C>) -> CtOption<Self> {
158
14
        Self::decompress(x_bytes, Choice::from(0)).map(|point| point.to_compact())
159
14
    }
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder6affines5_0pEINtB5_11AffinePointpEINtNtCs8yVsO3EKNkV_14elliptic_curve5point14DecompactPointpE9decompactB7_
160
}
161
162
impl<C> Eq for AffinePoint<C> where C: PrimeCurveParams {}
163
164
impl<C> FromEncodedPoint<C> for AffinePoint<C>
165
where
166
    C: PrimeCurveParams,
167
    FieldBytes<C>: Copy,
168
    FieldBytesSize<C>: ModulusSize,
169
    CompressedPoint<C>: Copy,
170
{
171
    /// Attempts to parse the given [`EncodedPoint`] as an SEC1-encoded
172
    /// [`AffinePoint`].
173
    ///
174
    /// # Returns
175
    ///
176
    /// `None` value if `encoded_point` is not on the secp384r1 curve.
177
1.18k
    fn from_encoded_point(encoded_point: &EncodedPoint<C>) -> CtOption<Self> {
178
1.18k
        match encoded_point.coordinates() {
179
10
            sec1::Coordinates::Identity => CtOption::new(Self::IDENTITY, 1.into()),
180
14
            sec1::Coordinates::Compact { x } => Self::decompact(x),
181
597
            sec1::Coordinates::Compressed { x, y_is_odd } => {
182
597
                Self::decompress(x, Choice::from(y_is_odd as u8))
183
            }
184
559
            sec1::Coordinates::Uncompressed { x, y } => {
185
559
                C::FieldElement::from_repr(*y).and_then(|y| {
186
559
                    C::FieldElement::from_repr(*x).and_then(|x| {
187
559
                        let lhs = y * &y;
188
559
                        let rhs = x * &x * &x + &(C::EQUATION_A * &x) + &C::EQUATION_B;
189
559
                        CtOption::new(Self { x, y, infinity: 0 }, lhs.ct_eq(&rhs))
190
559
                    })
_RNCNCNvXs7_NtCs2J0Yj5ID6sO_10primeorder6affineINtB9_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCs8yVsO3EKNkV_14elliptic_curve4sec116FromEncodedPointB11_E18from_encoded_point00Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
186
559
                    C::FieldElement::from_repr(*x).and_then(|x| {
187
559
                        let lhs = y * &y;
188
559
                        let rhs = x * &x * &x + &(C::EQUATION_A * &x) + &C::EQUATION_B;
189
559
                        CtOption::new(Self { x, y, infinity: 0 }, lhs.ct_eq(&rhs))
190
559
                    })
Unexecuted instantiation: _RNCNCNvXININtCs2J0Yj5ID6sO_10primeorder6affines7_0pEINtB9_11AffinePointpEINtNtCs8yVsO3EKNkV_14elliptic_curve4sec116FromEncodedPointpE18from_encoded_point00Bb_
191
559
                })
_RNCNvXs7_NtCs2J0Yj5ID6sO_10primeorder6affineINtB7_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCs8yVsO3EKNkV_14elliptic_curve4sec116FromEncodedPointBZ_E18from_encoded_point0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
185
559
                C::FieldElement::from_repr(*y).and_then(|y| {
186
559
                    C::FieldElement::from_repr(*x).and_then(|x| {
187
                        let lhs = y * &y;
188
                        let rhs = x * &x * &x + &(C::EQUATION_A * &x) + &C::EQUATION_B;
189
                        CtOption::new(Self { x, y, infinity: 0 }, lhs.ct_eq(&rhs))
190
559
                    })
191
559
                })
Unexecuted instantiation: _RNCNvXININtCs2J0Yj5ID6sO_10primeorder6affines7_0pEINtB7_11AffinePointpEINtNtCs8yVsO3EKNkV_14elliptic_curve4sec116FromEncodedPointpE18from_encoded_point0B9_
192
            }
193
        }
194
1.18k
    }
_RNvXs7_NtCs2J0Yj5ID6sO_10primeorder6affineINtB5_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCs8yVsO3EKNkV_14elliptic_curve4sec116FromEncodedPointBX_E18from_encoded_pointCs4RkbDk9WRL5_5clvmr
Line
Count
Source
177
1.18k
    fn from_encoded_point(encoded_point: &EncodedPoint<C>) -> CtOption<Self> {
178
1.18k
        match encoded_point.coordinates() {
179
10
            sec1::Coordinates::Identity => CtOption::new(Self::IDENTITY, 1.into()),
180
14
            sec1::Coordinates::Compact { x } => Self::decompact(x),
181
597
            sec1::Coordinates::Compressed { x, y_is_odd } => {
182
597
                Self::decompress(x, Choice::from(y_is_odd as u8))
183
            }
184
559
            sec1::Coordinates::Uncompressed { x, y } => {
185
559
                C::FieldElement::from_repr(*y).and_then(|y| {
186
                    C::FieldElement::from_repr(*x).and_then(|x| {
187
                        let lhs = y * &y;
188
                        let rhs = x * &x * &x + &(C::EQUATION_A * &x) + &C::EQUATION_B;
189
                        CtOption::new(Self { x, y, infinity: 0 }, lhs.ct_eq(&rhs))
190
                    })
191
559
                })
192
            }
193
        }
194
1.18k
    }
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder6affines7_0pEINtB5_11AffinePointpEINtNtCs8yVsO3EKNkV_14elliptic_curve4sec116FromEncodedPointpE18from_encoded_pointB7_
195
}
196
197
impl<C> From<ProjectivePoint<C>> for AffinePoint<C>
198
where
199
    C: PrimeCurveParams,
200
{
201
0
    fn from(p: ProjectivePoint<C>) -> AffinePoint<C> {
202
0
        p.to_affine()
203
0
    }
204
}
205
206
impl<C> From<&ProjectivePoint<C>> for AffinePoint<C>
207
where
208
    C: PrimeCurveParams,
209
{
210
0
    fn from(p: &ProjectivePoint<C>) -> AffinePoint<C> {
211
0
        p.to_affine()
212
0
    }
213
}
214
215
impl<C> From<PublicKey<C>> for AffinePoint<C>
216
where
217
    C: PrimeCurveParams,
218
{
219
0
    fn from(public_key: PublicKey<C>) -> AffinePoint<C> {
220
0
        *public_key.as_affine()
221
0
    }
222
}
223
224
impl<C> From<&PublicKey<C>> for AffinePoint<C>
225
where
226
    C: PrimeCurveParams,
227
{
228
0
    fn from(public_key: &PublicKey<C>) -> AffinePoint<C> {
229
0
        AffinePoint::from(*public_key)
230
0
    }
231
}
232
233
impl<C> From<AffinePoint<C>> for EncodedPoint<C>
234
where
235
    C: PrimeCurveParams,
236
    FieldBytesSize<C>: ModulusSize,
237
    CompressedPoint<C>: Copy,
238
    <UncompressedPointSize<C> as ArrayLength<u8>>::ArrayType: Copy,
239
{
240
0
    fn from(affine: AffinePoint<C>) -> EncodedPoint<C> {
241
0
        affine.to_encoded_point(false)
242
0
    }
243
}
244
245
impl<C> GroupEncoding for AffinePoint<C>
246
where
247
    C: PrimeCurveParams,
248
    FieldBytes<C>: Copy,
249
    FieldBytesSize<C>: ModulusSize,
250
    CompressedPoint<C>: Copy,
251
    <UncompressedPointSize<C> as ArrayLength<u8>>::ArrayType: Copy,
252
{
253
    type Repr = CompressedPoint<C>;
254
255
    /// NOTE: not constant-time with respect to identity point
256
0
    fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
257
0
        EncodedPoint::<C>::from_bytes(bytes)
258
0
            .map(|point| CtOption::new(point, Choice::from(1)))
259
0
            .unwrap_or_else(|_| {
260
0
                // SEC1 identity encoding is technically 1-byte 0x00, but the
261
0
                // `GroupEncoding` API requires a fixed-width `Repr`
262
0
                let is_identity = bytes.ct_eq(&Self::Repr::default());
263
0
                CtOption::new(EncodedPoint::<C>::identity(), is_identity)
264
0
            })
265
0
            .and_then(|point| Self::from_encoded_point(&point))
266
0
    }
267
268
0
    fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
269
0
        // No unchecked conversion possible for compressed points
270
0
        Self::from_bytes(bytes)
271
0
    }
272
273
0
    fn to_bytes(&self) -> Self::Repr {
274
0
        let encoded = self.to_encoded_point(true);
275
0
        let mut result = CompressedPoint::<C>::default();
276
0
        result[..encoded.len()].copy_from_slice(encoded.as_bytes());
277
0
        result
278
0
    }
279
}
280
281
impl<C> PartialEq for AffinePoint<C>
282
where
283
    C: PrimeCurveParams,
284
{
285
0
    fn eq(&self, other: &Self) -> bool {
286
0
        self.ct_eq(other).into()
287
0
    }
288
}
289
290
impl<C> PrimeCurveAffine for AffinePoint<C>
291
where
292
    C: PrimeCurveParams,
293
    FieldBytes<C>: Copy,
294
    FieldBytesSize<C>: ModulusSize,
295
    ProjectivePoint<C>: Double,
296
    CompressedPoint<C>: Copy,
297
    <UncompressedPointSize<C> as ArrayLength<u8>>::ArrayType: Copy,
298
{
299
    type Curve = ProjectivePoint<C>;
300
    type Scalar = Scalar<C>;
301
302
0
    fn identity() -> AffinePoint<C> {
303
0
        Self::IDENTITY
304
0
    }
305
306
0
    fn generator() -> AffinePoint<C> {
307
0
        Self::GENERATOR
308
0
    }
309
310
0
    fn is_identity(&self) -> Choice {
311
0
        self.is_identity()
312
0
    }
313
314
0
    fn to_curve(&self) -> ProjectivePoint<C> {
315
0
        ProjectivePoint::from(*self)
316
0
    }
317
}
318
319
impl<C> ToCompactEncodedPoint<C> for AffinePoint<C>
320
where
321
    C: PrimeCurveParams,
322
    FieldBytesSize<C>: ModulusSize,
323
    CompressedPoint<C>: Copy,
324
    <UncompressedPointSize<C> as ArrayLength<u8>>::ArrayType: Copy,
325
{
326
    /// Serialize this value as a  SEC1 compact [`EncodedPoint`]
327
0
    fn to_compact_encoded_point(&self) -> CtOption<EncodedPoint<C>> {
328
0
        let point = self.to_compact();
329
0
330
0
        let mut bytes = CompressedPoint::<C>::default();
331
0
        bytes[0] = sec1::Tag::Compact.into();
332
0
        bytes[1..].copy_from_slice(&point.x.to_repr());
333
0
334
0
        let encoded = EncodedPoint::<C>::from_bytes(bytes);
335
0
        let is_some = point.y.ct_eq(&self.y);
336
0
        CtOption::new(encoded.unwrap_or_default(), is_some)
337
0
    }
338
}
339
340
impl<C> ToEncodedPoint<C> for AffinePoint<C>
341
where
342
    C: PrimeCurveParams,
343
    FieldBytesSize<C>: ModulusSize,
344
    CompressedPoint<C>: Copy,
345
    <UncompressedPointSize<C> as ArrayLength<u8>>::ArrayType: Copy,
346
{
347
0
    fn to_encoded_point(&self, compress: bool) -> EncodedPoint<C> {
348
0
        EncodedPoint::<C>::conditional_select(
349
0
            &EncodedPoint::<C>::from_affine_coordinates(
350
0
                &self.x.to_repr(),
351
0
                &self.y.to_repr(),
352
0
                compress,
353
0
            ),
354
0
            &EncodedPoint::<C>::identity(),
355
0
            self.is_identity(),
356
0
        )
357
0
    }
358
}
359
360
impl<C> TryFrom<EncodedPoint<C>> for AffinePoint<C>
361
where
362
    C: PrimeCurveParams,
363
    FieldBytes<C>: Copy,
364
    FieldBytesSize<C>: ModulusSize,
365
    CompressedPoint<C>: Copy,
366
{
367
    type Error = Error;
368
369
0
    fn try_from(point: EncodedPoint<C>) -> Result<AffinePoint<C>> {
370
0
        AffinePoint::try_from(&point)
371
0
    }
372
}
373
374
impl<C> TryFrom<&EncodedPoint<C>> for AffinePoint<C>
375
where
376
    C: PrimeCurveParams,
377
    FieldBytes<C>: Copy,
378
    FieldBytesSize<C>: ModulusSize,
379
    CompressedPoint<C>: Copy,
380
{
381
    type Error = Error;
382
383
0
    fn try_from(point: &EncodedPoint<C>) -> Result<AffinePoint<C>> {
384
0
        Option::from(AffinePoint::<C>::from_encoded_point(point)).ok_or(Error)
385
0
    }
386
}
387
388
impl<C> TryFrom<AffinePoint<C>> for PublicKey<C>
389
where
390
    C: PrimeCurveParams,
391
{
392
    type Error = Error;
393
394
0
    fn try_from(affine_point: AffinePoint<C>) -> Result<PublicKey<C>> {
395
0
        PublicKey::from_affine(affine_point)
396
0
    }
397
}
398
399
impl<C> TryFrom<&AffinePoint<C>> for PublicKey<C>
400
where
401
    C: PrimeCurveParams,
402
{
403
    type Error = Error;
404
405
0
    fn try_from(affine_point: &AffinePoint<C>) -> Result<PublicKey<C>> {
406
0
        PublicKey::<C>::try_from(*affine_point)
407
0
    }
408
}
409
410
//
411
// Arithmetic trait impls
412
//
413
414
impl<C, S> Mul<S> for AffinePoint<C>
415
where
416
    C: PrimeCurveParams,
417
    S: Borrow<Scalar<C>>,
418
    ProjectivePoint<C>: Double,
419
{
420
    type Output = ProjectivePoint<C>;
421
422
0
    fn mul(self, scalar: S) -> ProjectivePoint<C> {
423
0
        ProjectivePoint::<C>::from(self) * scalar
424
0
    }
425
}
426
427
impl<C> Neg for AffinePoint<C>
428
where
429
    C: PrimeCurveParams,
430
{
431
    type Output = Self;
432
433
14
    fn neg(self) -> Self {
434
14
        AffinePoint {
435
14
            x: self.x,
436
14
            y: -self.y,
437
14
            infinity: self.infinity,
438
14
        }
439
14
    }
_RNvXsn_NtCs2J0Yj5ID6sO_10primeorder6affineINtB5_11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Neg3negCs4RkbDk9WRL5_5clvmr
Line
Count
Source
433
14
    fn neg(self) -> Self {
434
14
        AffinePoint {
435
14
            x: self.x,
436
14
            y: -self.y,
437
14
            infinity: self.infinity,
438
14
        }
439
14
    }
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder6affinesn_0pEINtB5_11AffinePointpENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Neg3negB7_
440
}
441
442
impl<C> Neg for &AffinePoint<C>
443
where
444
    C: PrimeCurveParams,
445
{
446
    type Output = AffinePoint<C>;
447
448
0
    fn neg(self) -> AffinePoint<C> {
449
0
        -(*self)
450
0
    }
451
}
452
453
//
454
// serde support
455
//
456
457
#[cfg(feature = "serde")]
458
impl<C> Serialize for AffinePoint<C>
459
where
460
    C: PrimeCurveParams,
461
    FieldBytesSize<C>: ModulusSize,
462
    CompressedPoint<C>: Copy,
463
    <UncompressedPointSize<C> as ArrayLength<u8>>::ArrayType: Copy,
464
{
465
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
466
    where
467
        S: ser::Serializer,
468
    {
469
        self.to_encoded_point(true).serialize(serializer)
470
    }
471
}
472
473
#[cfg(feature = "serde")]
474
impl<'de, C> Deserialize<'de> for AffinePoint<C>
475
where
476
    C: PrimeCurveParams,
477
    FieldBytes<C>: Copy,
478
    FieldBytesSize<C>: ModulusSize,
479
    CompressedPoint<C>: Copy,
480
{
481
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
482
    where
483
        D: de::Deserializer<'de>,
484
    {
485
        EncodedPoint::<C>::deserialize(deserializer)?
486
            .try_into()
487
            .map_err(de::Error::custom)
488
    }
489
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/primeorder-0.13.6/src/field.rs
Line
Count
Source
1
/// Implements a field element type whose internal representation is in
2
/// Montgomery form, providing a combination of trait impls and inherent impls
3
/// which are `const fn` where possible.
4
///
5
/// Accepts a set of `const fn` arithmetic operation functions as arguments.
6
///
7
/// # Inherent impls
8
/// - `const ZERO: Self`
9
/// - `const ONE: Self` (multiplicative identity)
10
/// - `pub fn from_bytes`
11
/// - `pub fn from_slice`
12
/// - `pub fn from_uint`
13
/// - `fn from_uint_unchecked`
14
/// - `pub fn to_bytes`
15
/// - `pub fn to_canonical`
16
/// - `pub fn is_odd`
17
/// - `pub fn is_zero`
18
/// - `pub fn double`
19
///
20
/// NOTE: field implementations must provide their own inherent impls of
21
/// the following methods in order for the code generated by this macro to
22
/// compile:
23
///
24
/// - `pub fn invert`
25
/// - `pub fn sqrt`
26
///
27
/// # Trait impls
28
/// - `AsRef<$arr>`
29
/// - `ConditionallySelectable`
30
/// - `ConstantTimeEq`
31
/// - `ConstantTimeGreater`
32
/// - `ConstantTimeLess`
33
/// - `Default`
34
/// - `DefaultIsZeroes`
35
/// - `Eq`
36
/// - `Field`
37
/// - `PartialEq`
38
///
39
/// ## Ops
40
/// - `Add`
41
/// - `AddAssign`
42
/// - `Sub`
43
/// - `SubAssign`
44
/// - `Mul`
45
/// - `MulAssign`
46
/// - `Neg`
47
#[macro_export]
48
macro_rules! impl_mont_field_element {
49
    (
50
        $curve:tt,
51
        $fe:tt,
52
        $bytes:ty,
53
        $uint:ty,
54
        $modulus:expr,
55
        $arr:ty,
56
        $from_mont:ident,
57
        $to_mont:ident,
58
        $add:ident,
59
        $sub:ident,
60
        $mul:ident,
61
        $neg:ident,
62
        $square:ident
63
    ) => {
64
        impl $fe {
65
            /// Zero element.
66
            pub const ZERO: Self = Self(<$uint>::ZERO);
67
68
            /// Multiplicative identity.
69
            pub const ONE: Self = Self::from_uint_unchecked(<$uint>::ONE);
70
71
            /// Create a [`
72
            #[doc = stringify!($fe)]
73
            /// `] from a canonical big-endian representation.
74
1.72k
            pub fn from_bytes(repr: &$bytes) -> $crate::elliptic_curve::subtle::CtOption<Self> {
75
                use $crate::elliptic_curve::FieldBytesEncoding;
76
1.72k
                Self::from_uint(FieldBytesEncoding::<$curve>::decode_field_bytes(repr))
77
1.72k
            }
78
79
            /// Decode [`
80
            #[doc = stringify!($fe)]
81
            /// `] from a big endian byte slice.
82
0
            pub fn from_slice(slice: &[u8]) -> $crate::elliptic_curve::Result<Self> {
83
                use $crate::elliptic_curve::generic_array::{typenum::Unsigned, GenericArray};
84
85
0
                if slice.len() != <$curve as $crate::elliptic_curve::Curve>::FieldBytesSize::USIZE {
86
0
                    return Err($crate::elliptic_curve::Error);
87
0
                }
88
0
89
0
                Option::from(Self::from_bytes(GenericArray::from_slice(slice)))
90
0
                    .ok_or($crate::elliptic_curve::Error)
91
0
            }
92
0
93
0
            /// Decode [`
94
0
            #[doc = stringify!($fe)]
95
0
            /// `]
96
0
            /// from [`
97
0
            #[doc = stringify!($uint)]
98
0
            /// `] converting it into Montgomery form:
99
0
            ///
100
0
            /// ```text
101
0
            /// w * R^2 * R^-1 mod p = wR mod p
102
0
            /// ```
103
1.72k
            pub fn from_uint(uint: $uint) -> $crate::elliptic_curve::subtle::CtOption<Self> {
104
                use $crate::elliptic_curve::subtle::ConstantTimeLess as _;
105
1.72k
                let is_some = uint.ct_lt(&$modulus);
106
1.72k
                $crate::elliptic_curve::subtle::CtOption::new(
107
1.72k
                    Self::from_uint_unchecked(uint),
108
1.72k
                    is_some,
109
1.72k
                )
110
1.72k
            }
111
112
            /// Parse a [`
113
            #[doc = stringify!($fe)]
114
            /// `] from big endian hex-encoded bytes.
115
            ///
116
            /// Does *not* perform a check that the field element does not overflow the order.
117
            ///
118
            /// This method is primarily intended for defining internal constants.
119
            #[allow(dead_code)]
120
0
            pub(crate) const fn from_hex(hex: &str) -> Self {
121
0
                Self::from_uint_unchecked(<$uint>::from_be_hex(hex))
122
0
            }
123
124
            /// Convert a `u64` into a [`
125
            #[doc = stringify!($fe)]
126
            /// `].
127
0
            pub const fn from_u64(w: u64) -> Self {
128
0
                Self::from_uint_unchecked(<$uint>::from_u64(w))
129
0
            }
130
131
            /// Decode [`
132
            #[doc = stringify!($fe)]
133
            /// `] from [`
134
            #[doc = stringify!($uint)]
135
            /// `] converting it into Montgomery form.
136
            ///
137
            /// Does *not* perform a check that the field element does not overflow the order.
138
            ///
139
            /// Used incorrectly this can lead to invalid results!
140
555k
            pub(crate) const fn from_uint_unchecked(w: $uint) -> Self {
141
555k
                Self(<$uint>::from_words($to_mont(w.as_words())))
142
555k
            }
143
144
            /// Returns the big-endian encoding of this [`
145
            #[doc = stringify!($fe)]
146
            /// `].
147
866
            pub fn to_bytes(self) -> $bytes {
148
                use $crate::elliptic_curve::FieldBytesEncoding;
149
866
                FieldBytesEncoding::<$curve>::encode_field_bytes(&self.to_canonical())
150
866
            }
151
152
            /// Translate [`
153
            #[doc = stringify!($fe)]
154
            /// `] out of the Montgomery domain, returning a [`
155
            #[doc = stringify!($uint)]
156
            /// `] in canonical form.
157
            #[inline]
158
1.47k
            pub const fn to_canonical(self) -> $uint {
159
1.47k
                <$uint>::from_words($from_mont(self.0.as_words()))
160
1.47k
            }
161
162
            /// Determine if this [`
163
            #[doc = stringify!($fe)]
164
            /// `] is odd in the SEC1 sense: `self mod 2 == 1`.
165
            ///
166
            /// # Returns
167
            ///
168
            /// If odd, return `Choice(1)`.  Otherwise, return `Choice(0)`.
169
611
            pub fn is_odd(&self) -> Choice {
170
                use $crate::elliptic_curve::bigint::Integer;
171
611
                self.to_canonical().is_odd()
172
611
            }
173
174
            /// Determine if this [`
175
            #[doc = stringify!($fe)]
176
            /// `] is even in the SEC1 sense: `self mod 2 == 0`.
177
            ///
178
            /// # Returns
179
            ///
180
            /// If even, return `Choice(1)`.  Otherwise, return `Choice(0)`.
181
0
            pub fn is_even(&self) -> Choice {
182
0
                !self.is_odd()
183
0
            }
184
185
            /// Determine if this [`
186
            #[doc = stringify!($fe)]
187
            /// `] is zero.
188
            ///
189
            /// # Returns
190
            ///
191
            /// If zero, return `Choice(1)`.  Otherwise, return `Choice(0)`.
192
838
            pub fn is_zero(&self) -> Choice {
193
838
                self.ct_eq(&Self::ZERO)
194
838
            }
195
196
            /// Add elements.
197
4.38M
            pub const fn add(&self, rhs: &Self) -> Self {
198
4.38M
                Self(<$uint>::from_words($add(
199
4.38M
                    self.0.as_words(),
200
4.38M
                    rhs.0.as_words(),
201
4.38M
                )))
202
4.38M
            }
203
204
            /// Double element (add it to itself).
205
            #[must_use]
206
4.38M
            pub const fn double(&self) -> Self {
207
4.38M
                self.add(self)
208
4.38M
            }
209
210
            /// Subtract elements.
211
0
            pub const fn sub(&self, rhs: &Self) -> Self {
212
0
                Self(<$uint>::from_words($sub(
213
0
                    self.0.as_words(),
214
0
                    rhs.0.as_words(),
215
0
                )))
216
0
            }
217
218
            /// Multiply elements.
219
10.0k
            pub const fn multiply(&self, rhs: &Self) -> Self {
220
10.0k
                Self(<$uint>::from_words($mul(
221
10.0k
                    self.0.as_words(),
222
10.0k
                    rhs.0.as_words(),
223
10.0k
                )))
224
10.0k
            }
225
226
            /// Negate element.
227
0
            pub const fn neg(&self) -> Self {
228
0
                Self(<$uint>::from_words($neg(self.0.as_words())))
229
0
            }
230
231
            /// Compute modular square.
232
            #[must_use]
233
1.67M
            pub const fn square(&self) -> Self {
234
1.67M
                Self(<$uint>::from_words($square(self.0.as_words())))
235
1.67M
            }
236
237
            /// Returns `self^exp`, where `exp` is a little-endian integer exponent.
238
            ///
239
            /// **This operation is variable time with respect to the exponent.**
240
            ///
241
            /// If the exponent is fixed, this operation is effectively constant time.
242
0
            pub const fn pow_vartime(&self, exp: &[u64]) -> Self {
243
0
                let mut res = Self::ONE;
244
0
                let mut i = exp.len();
245
246
0
                while i > 0 {
247
0
                    i -= 1;
248
0
249
0
                    let mut j = 64;
250
0
                    while j > 0 {
251
0
                        j -= 1;
252
0
                        res = res.square();
253
0
254
0
                        if ((exp[i] >> j) & 1) == 1 {
255
0
                            res = res.multiply(self);
256
0
                        }
257
0
                    }
258
0
                }
259
0
260
0
                res
261
0
            }
262
        }
263
264
        $crate::impl_mont_field_element_arithmetic!(
265
            $fe, $bytes, $uint, $arr, $add, $sub, $mul, $neg
266
        );
267
    };
268
}
269
270
/// Add arithmetic impls to the given field element.
271
#[macro_export]
272
macro_rules! impl_mont_field_element_arithmetic {
273
    (
274
        $fe:tt,
275
        $bytes:ty,
276
        $uint:ty,
277
        $arr:ty,
278
        $add:ident,
279
        $sub:ident,
280
        $mul:ident,
281
        $neg:ident
282
    ) => {
283
        impl AsRef<$arr> for $fe {
284
29.0M
            fn as_ref(&self) -> &$arr {
285
29.0M
                self.0.as_ref()
286
29.0M
            }
_RNvXs4_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementINtNtCsbQ8arDwx5Xq_4core7convert5AsRefAyj4_E6as_refCs4RkbDk9WRL5_5clvmr
Line
Count
Source
284
29.0M
            fn as_ref(&self) -> &$arr {
285
29.0M
                self.0.as_ref()
286
29.0M
            }
_RNvXs4_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementINtNtCsbQ8arDwx5Xq_4core7convert5AsRefAyj4_E6as_refB9_
Line
Count
Source
284
9.77k
            fn as_ref(&self) -> &$arr {
285
9.77k
                self.0.as_ref()
286
9.77k
            }
287
        }
288
289
        impl Default for $fe {
290
3.17k
            fn default() -> Self {
291
3.17k
                Self::ZERO
292
3.17k
            }
_RNvXs5_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementNtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs4RkbDk9WRL5_5clvmr
Line
Count
Source
290
3.17k
            fn default() -> Self {
291
3.17k
                Self::ZERO
292
3.17k
            }
Unexecuted instantiation: _RNvXs5_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementNtNtCsbQ8arDwx5Xq_4core7default7Default7defaultB9_
293
        }
294
295
        impl Eq for $fe {}
296
        impl PartialEq for $fe {
297
553k
            fn eq(&self, rhs: &Self) -> bool {
298
553k
                self.0.ct_eq(&(rhs.0)).into()
299
553k
            }
300
        }
301
302
        impl From<u32> for $fe {
303
0
            fn from(n: u32) -> $fe {
304
0
                Self::from_uint_unchecked(<$uint>::from(n))
305
0
            }
306
        }
307
308
        impl From<u64> for $fe {
309
553k
            fn from(n: u64) -> $fe {
310
553k
                Self::from_uint_unchecked(<$uint>::from(n))
311
553k
            }
312
        }
313
314
        impl From<u128> for $fe {
315
0
            fn from(n: u128) -> $fe {
316
0
                Self::from_uint_unchecked(<$uint>::from(n))
317
0
            }
318
        }
319
320
        impl $crate::elliptic_curve::subtle::ConditionallySelectable for $fe {
321
4.83M
            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
322
4.83M
                Self(<$uint>::conditional_select(&a.0, &b.0, choice))
323
4.83M
            }
324
        }
325
326
        impl $crate::elliptic_curve::subtle::ConstantTimeEq for $fe {
327
2.00k
            fn ct_eq(&self, other: &Self) -> $crate::elliptic_curve::subtle::Choice {
328
2.00k
                self.0.ct_eq(&other.0)
329
2.00k
            }
330
        }
331
332
        impl $crate::elliptic_curve::subtle::ConstantTimeGreater for $fe {
333
0
            fn ct_gt(&self, other: &Self) -> $crate::elliptic_curve::subtle::Choice {
334
0
                self.0.ct_gt(&other.0)
335
0
            }
336
        }
337
338
        impl $crate::elliptic_curve::subtle::ConstantTimeLess for $fe {
339
0
            fn ct_lt(&self, other: &Self) -> $crate::elliptic_curve::subtle::Choice {
340
0
                self.0.ct_lt(&other.0)
341
0
            }
342
        }
343
344
        impl $crate::elliptic_curve::zeroize::DefaultIsZeroes for $fe {}
345
346
        impl $crate::elliptic_curve::ff::Field for $fe {
347
            const ZERO: Self = Self::ZERO;
348
            const ONE: Self = Self::ONE;
349
350
0
            fn random(mut rng: impl $crate::elliptic_curve::rand_core::RngCore) -> Self {
351
0
                // NOTE: can't use ScalarPrimitive::random due to CryptoRng bound
352
0
                let mut bytes = <$bytes>::default();
353
354
                loop {
355
0
                    rng.fill_bytes(&mut bytes);
356
0
                    if let Some(fe) = Self::from_bytes(&bytes).into() {
357
0
                        return fe;
358
0
                    }
359
0
                }
360
0
            }
361
0
362
0
            fn is_zero(&self) -> Choice {
363
0
                Self::ZERO.ct_eq(self)
364
0
            }
365
366
            #[must_use]
367
1.30M
            fn square(&self) -> Self {
368
1.30M
                self.square()
369
1.30M
            }
370
371
            #[must_use]
372
4.38M
            fn double(&self) -> Self {
373
4.38M
                self.double()
374
4.38M
            }
375
376
838
            fn invert(&self) -> CtOption<Self> {
377
838
                self.invert()
378
838
            }
379
380
611
            fn sqrt(&self) -> CtOption<Self> {
381
611
                self.sqrt()
382
611
            }
383
384
0
            fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
385
0
                $crate::elliptic_curve::ff::helpers::sqrt_ratio_generic(num, div)
386
0
            }
387
        }
388
389
        $crate::impl_field_op!($fe, Add, add, $add);
390
        $crate::impl_field_op!($fe, Sub, sub, $sub);
391
        $crate::impl_field_op!($fe, Mul, mul, $mul);
392
393
        impl AddAssign<$fe> for $fe {
394
            #[inline]
395
0
            fn add_assign(&mut self, other: $fe) {
396
0
                *self = *self + other;
397
0
            }
398
        }
399
400
        impl AddAssign<&$fe> for $fe {
401
            #[inline]
402
0
            fn add_assign(&mut self, other: &$fe) {
403
0
                *self = *self + other;
404
0
            }
405
        }
406
407
        impl SubAssign<$fe> for $fe {
408
            #[inline]
409
0
            fn sub_assign(&mut self, other: $fe) {
410
0
                *self = *self - other;
411
0
            }
412
        }
413
414
        impl SubAssign<&$fe> for $fe {
415
            #[inline]
416
0
            fn sub_assign(&mut self, other: &$fe) {
417
0
                *self = *self - other;
418
0
            }
419
        }
420
421
        impl MulAssign<&$fe> for $fe {
422
            #[inline]
423
0
            fn mul_assign(&mut self, other: &$fe) {
424
0
                *self = *self * other;
425
0
            }
426
        }
427
428
        impl MulAssign for $fe {
429
            #[inline]
430
0
            fn mul_assign(&mut self, other: $fe) {
431
0
                *self = *self * other;
432
0
            }
433
        }
434
435
        impl Neg for $fe {
436
            type Output = $fe;
437
438
            #[inline]
439
554k
            fn neg(self) -> $fe {
440
554k
                Self($neg(self.as_ref()).into())
441
554k
            }
_RNvXsn_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Neg3negCs4RkbDk9WRL5_5clvmr
Line
Count
Source
439
554k
            fn neg(self) -> $fe {
440
554k
                Self($neg(self.as_ref()).into())
441
554k
            }
Unexecuted instantiation: _RNvXsn_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Neg3negB9_
442
        }
443
444
        impl Sum for $fe {
445
0
            fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
446
0
                iter.reduce(core::ops::Add::add).unwrap_or(Self::ZERO)
447
0
            }
448
        }
449
450
        impl<'a> Sum<&'a $fe> for $fe {
451
0
            fn sum<I: Iterator<Item = &'a $fe>>(iter: I) -> Self {
452
0
                iter.copied().sum()
453
0
            }
454
        }
455
456
        impl Product for $fe {
457
0
            fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
458
0
                iter.reduce(core::ops::Mul::mul).unwrap_or(Self::ONE)
459
0
            }
460
        }
461
462
        impl<'a> Product<&'a $fe> for $fe {
463
0
            fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
464
0
                iter.copied().product()
465
0
            }
466
        }
467
    };
468
}
469
470
/// Emit impls for a `core::ops` trait for all combinations of reference types,
471
/// which thunk to the given function.
472
#[macro_export]
473
macro_rules! impl_field_op {
474
    ($fe:tt, $op:tt, $op_fn:ident, $func:ident) => {
475
        impl ::core::ops::$op for $fe {
476
            type Output = $fe;
477
478
            #[inline]
479
14.2M
            fn $op_fn(self, rhs: $fe) -> $fe {
480
14.2M
                $fe($func(self.as_ref(), rhs.as_ref()).into())
481
14.2M
            }
_RNvXss_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3addCs4RkbDk9WRL5_5clvmr
Line
Count
Source
479
5.07M
            fn $op_fn(self, rhs: $fe) -> $fe {
480
5.07M
                $fe($func(self.as_ref(), rhs.as_ref()).into())
481
5.07M
            }
_RNvXsv_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Sub3subCs4RkbDk9WRL5_5clvmr
Line
Count
Source
479
3.12M
            fn $op_fn(self, rhs: $fe) -> $fe {
480
3.12M
                $fe($func(self.as_ref(), rhs.as_ref()).into())
481
3.12M
            }
_RNvXsy_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mulCs4RkbDk9WRL5_5clvmr
Line
Count
Source
479
6.01M
            fn $op_fn(self, rhs: $fe) -> $fe {
480
6.01M
                $fe($func(self.as_ref(), rhs.as_ref()).into())
481
6.01M
            }
Unexecuted instantiation: _RNvXss_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3addB9_
Unexecuted instantiation: _RNvXsv_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Sub3subB9_
Unexecuted instantiation: _RNvXsy_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mulB9_
482
        }
483
484
        impl ::core::ops::$op<&$fe> for $fe {
485
            type Output = $fe;
486
487
            #[inline]
488
11.7k
            fn $op_fn(self, rhs: &$fe) -> $fe {
489
11.7k
                $fe($func(self.as_ref(), rhs.as_ref()).into())
490
11.7k
            }
_RNvXst_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRBK_E3addCs4RkbDk9WRL5_5clvmr
Line
Count
Source
488
2.34k
            fn $op_fn(self, rhs: &$fe) -> $fe {
489
2.34k
                $fe($func(self.as_ref(), rhs.as_ref()).into())
490
2.34k
            }
_RNvXsz_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRBK_E3mulCs4RkbDk9WRL5_5clvmr
Line
Count
Source
488
5.74k
            fn $op_fn(self, rhs: &$fe) -> $fe {
489
5.74k
                $fe($func(self.as_ref(), rhs.as_ref()).into())
490
5.74k
            }
_RNvXsz_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRBK_E3mulB9_
Line
Count
Source
488
3.66k
            fn $op_fn(self, rhs: &$fe) -> $fe {
489
3.66k
                $fe($func(self.as_ref(), rhs.as_ref()).into())
490
3.66k
            }
Unexecuted instantiation: _RNvXst_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRBK_E3addB9_
Unexecuted instantiation: _RNvXsw_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldNtB5_12FieldElementINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRBK_E3subB9_
491
        }
492
493
        impl ::core::ops::$op<&$fe> for &$fe {
494
            type Output = $fe;
495
496
            #[inline]
497
1.22k
            fn $op_fn(self, rhs: &$fe) -> $fe {
498
1.22k
                $fe($func(self.as_ref(), rhs.as_ref()).into())
499
1.22k
            }
_RNvXsA_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldRNtB5_12FieldElementNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mulB9_
Line
Count
Source
497
1.22k
            fn $op_fn(self, rhs: &$fe) -> $fe {
498
1.22k
                $fe($func(self.as_ref(), rhs.as_ref()).into())
499
1.22k
            }
Unexecuted instantiation: _RNvXsu_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldRNtB5_12FieldElementNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3addB9_
Unexecuted instantiation: _RNvXsx_NtNtCsaHRNXv1Y9Bq_4p25610arithmetic5fieldRNtB5_12FieldElementNtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Sub3subB9_
500
        }
501
    };
502
}
503
504
/// Implement Bernstein-Yang field element inversion.
505
#[macro_export]
506
macro_rules! impl_bernstein_yang_invert {
507
    (
508
        $a:expr,
509
        $one:expr,
510
        $d:expr,
511
        $nlimbs:expr,
512
        $word:ty,
513
        $from_mont:ident,
514
        $mul:ident,
515
        $neg:ident,
516
        $divstep_precomp:ident,
517
        $divstep:ident,
518
        $msat:ident,
519
        $selectznz:ident,
520
    ) => {{
521
        // See Bernstein-Yang 2019 p.366
522
        const ITERATIONS: usize = (49 * $d + 57) / 17;
523
524
        let a = $from_mont($a);
525
        let mut d = 1;
526
        let mut f = $msat();
527
        let mut g = [0; $nlimbs + 1];
528
        let mut v = [0; $nlimbs];
529
        let mut r = $one;
530
        let mut i = 0;
531
        let mut j = 0;
532
533
        while j < $nlimbs {
534
            g[j] = a[j];
535
            j += 1;
536
        }
537
538
        while i < ITERATIONS - ITERATIONS % 2 {
539
            let (out1, out2, out3, out4, out5) = $divstep(d, &f, &g, &v, &r);
540
            let (out1, out2, out3, out4, out5) = $divstep(out1, &out2, &out3, &out4, &out5);
541
            d = out1;
542
            f = out2;
543
            g = out3;
544
            v = out4;
545
            r = out5;
546
            i += 2;
547
        }
548
549
        if ITERATIONS % 2 != 0 {
550
            let (_out1, out2, _out3, out4, _out5) = $divstep(d, &f, &g, &v, &r);
551
            v = out4;
552
            f = out2;
553
        }
554
555
        let s = ((f[f.len() - 1] >> <$word>::BITS - 1) & 1) as u8;
556
        let v = $selectznz(s, &v, &$neg(&v));
557
        $mul(&v, &$divstep_precomp())
558
    }};
559
}
560
561
/// Implement field element identity tests.
562
#[macro_export]
563
macro_rules! impl_field_identity_tests {
564
    ($fe:tt) => {
565
        #[test]
566
        fn zero_is_additive_identity() {
567
            let zero = $fe::ZERO;
568
            let one = $fe::ONE;
569
            assert_eq!(zero.add(&zero), zero);
570
            assert_eq!(one.add(&zero), one);
571
        }
572
573
        #[test]
574
        fn one_is_multiplicative_identity() {
575
            let one = $fe::ONE;
576
            assert_eq!(one.multiply(&one), one);
577
        }
578
    };
579
}
580
581
/// Implement field element inversion tests.
582
#[macro_export]
583
macro_rules! impl_field_invert_tests {
584
    ($fe:tt) => {
585
        #[test]
586
        fn invert() {
587
            let one = $fe::ONE;
588
            assert_eq!(one.invert().unwrap(), one);
589
590
            let three = one + &one + &one;
591
            let inv_three = three.invert().unwrap();
592
            assert_eq!(three * &inv_three, one);
593
594
            let minus_three = -three;
595
            let inv_minus_three = minus_three.invert().unwrap();
596
            assert_eq!(inv_minus_three, -inv_three);
597
            assert_eq!(three * &inv_minus_three, -one);
598
        }
599
    };
600
}
601
602
/// Implement field element square root tests.
603
#[macro_export]
604
macro_rules! impl_field_sqrt_tests {
605
    ($fe:tt) => {
606
        #[test]
607
        fn sqrt() {
608
            for &n in &[1u64, 4, 9, 16, 25, 36, 49, 64] {
609
                let fe = $fe::from(n);
610
                let sqrt = fe.sqrt().unwrap();
611
                assert_eq!(sqrt.square(), fe);
612
            }
613
        }
614
    };
615
}
616
617
/// Implement tests for the `PrimeField` trait.
618
#[macro_export]
619
macro_rules! impl_primefield_tests {
620
    ($fe:tt, $t:expr) => {
621
        #[test]
622
        fn two_inv_constant() {
623
            assert_eq!($fe::from(2u32) * $fe::TWO_INV, $fe::ONE);
624
        }
625
626
        #[test]
627
        fn root_of_unity_constant() {
628
            assert!($fe::S < 128);
629
            let two_to_s = 1u128 << $fe::S;
630
631
            // ROOT_OF_UNITY^{2^s} mod m == 1
632
            assert_eq!(
633
                $fe::ROOT_OF_UNITY.pow_vartime(&[
634
                    (two_to_s & 0xFFFFFFFFFFFFFFFF) as u64,
635
                    (two_to_s >> 64) as u64,
636
                    0,
637
                    0
638
                ]),
639
                $fe::ONE
640
            );
641
642
            // MULTIPLICATIVE_GENERATOR^{t} mod m == ROOT_OF_UNITY
643
            assert_eq!(
644
                $fe::MULTIPLICATIVE_GENERATOR.pow_vartime(&$t),
645
                $fe::ROOT_OF_UNITY
646
            )
647
        }
648
649
        #[test]
650
        fn root_of_unity_inv_constant() {
651
            assert_eq!($fe::ROOT_OF_UNITY * $fe::ROOT_OF_UNITY_INV, $fe::ONE);
652
        }
653
654
        #[test]
655
        fn delta_constant() {
656
            // DELTA^{t} mod m == 1
657
            assert_eq!($fe::DELTA.pow_vartime(&$t), $fe::ONE);
658
        }
659
    };
660
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/primeorder-0.13.6/src/point_arithmetic.rs
Line
Count
Source
1
//! Point arithmetic implementation optimised for different curve equations
2
//!
3
//! Support for formulas specialized to the short Weierstrass equation's
4
//! 𝒂-coefficient.
5
6
use elliptic_curve::{subtle::ConditionallySelectable, Field};
7
8
use crate::{AffinePoint, PrimeCurveParams, ProjectivePoint};
9
10
mod sealed {
11
    use crate::{AffinePoint, PrimeCurveParams, ProjectivePoint};
12
13
    /// Elliptic point arithmetic implementation
14
    ///
15
    /// Provides implementation of point arithmetic (point addition, point doubling) which
16
    /// might be optimized for the curve.
17
    pub trait PointArithmetic<C: PrimeCurveParams> {
18
        /// Returns `lhs + rhs`
19
        fn add(lhs: &ProjectivePoint<C>, rhs: &ProjectivePoint<C>) -> ProjectivePoint<C>;
20
21
        /// Returns `lhs + rhs`
22
        fn add_mixed(lhs: &ProjectivePoint<C>, rhs: &AffinePoint<C>) -> ProjectivePoint<C>;
23
24
        /// Returns `point + point`
25
        fn double(point: &ProjectivePoint<C>) -> ProjectivePoint<C>;
26
    }
27
}
28
29
/// Allow crate-local visibility
30
pub(crate) use sealed::PointArithmetic;
31
32
/// The 𝒂-coefficient of the short Weierstrass equation does not have specific
33
/// properties which allow for an optimized implementation.
34
pub struct EquationAIsGeneric {}
35
36
impl<C: PrimeCurveParams> PointArithmetic<C> for EquationAIsGeneric {
37
    /// Implements complete addition for any curve
38
    ///
39
    /// Implements the complete addition formula from [Renes-Costello-Batina 2015]
40
    /// (Algorithm 1). The comments after each line indicate which algorithm steps
41
    /// are being performed.
42
    ///
43
    /// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
44
0
    fn add(lhs: &ProjectivePoint<C>, rhs: &ProjectivePoint<C>) -> ProjectivePoint<C> {
45
0
        let b3 = C::FieldElement::from(3) * C::EQUATION_B;
46
0
47
0
        let t0 = lhs.x * rhs.x; // 1
48
0
        let t1 = lhs.y * rhs.y; // 2
49
0
        let t2 = lhs.z * rhs.z; // 3
50
0
        let t3 = lhs.x + lhs.y; // 4
51
0
        let t4 = rhs.x + rhs.y; // 5
52
0
        let t3 = t3 * t4; // 6
53
0
        let t4 = t0 + t1; // 7
54
0
        let t3 = t3 - t4; // 8
55
0
        let t4 = lhs.x + lhs.z; // 9
56
0
        let t5 = rhs.x + rhs.z; // 10
57
0
        let t4 = t4 * t5; // 11
58
0
        let t5 = t0 + t2; // 12
59
0
        let t4 = t4 - t5; // 13
60
0
        let t5 = lhs.y + lhs.z; // 14
61
0
        let x3 = rhs.y + rhs.z; // 15
62
0
        let t5 = t5 * x3; // 16
63
0
        let x3 = t1 + t2; // 17
64
0
        let t5 = t5 - x3; // 18
65
0
        let z3 = C::EQUATION_A * t4; // 19
66
0
        let x3 = b3 * t2; // 20
67
0
        let z3 = x3 + z3; // 21
68
0
        let x3 = t1 - z3; // 22
69
0
        let z3 = t1 + z3; // 23
70
0
        let y3 = x3 * z3; // 24
71
0
        let t1 = t0 + t0; // 25
72
0
        let t1 = t1 + t0; // 26
73
0
        let t2 = C::EQUATION_A * t2; // 27
74
0
        let t4 = b3 * t4; // 28
75
0
        let t1 = t1 + t2; // 29
76
0
        let t2 = t0 - t2; // 30
77
0
        let t2 = C::EQUATION_A * t2; // 31
78
0
        let t4 = t4 + t2; // 32
79
0
        let t0 = t1 * t4; // 33
80
0
        let y3 = y3 + t0; // 34
81
0
        let t0 = t5 * t4; // 35
82
0
        let x3 = t3 * x3; // 36
83
0
        let x3 = x3 - t0; // 37
84
0
        let t0 = t3 * t1; // 38
85
0
        let z3 = t5 * z3; // 39
86
0
        let z3 = z3 + t0; // 40
87
0
88
0
        ProjectivePoint {
89
0
            x: x3,
90
0
            y: y3,
91
0
            z: z3,
92
0
        }
93
0
    }
94
95
    /// Implements complete mixed addition for curves with any `a`
96
    ///
97
    /// Implements the complete mixed addition formula from [Renes-Costello-Batina 2015]
98
    /// (Algorithm 2). The comments after each line indicate which algorithm
99
    /// steps are being performed.
100
    ///
101
    /// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
102
0
    fn add_mixed(lhs: &ProjectivePoint<C>, rhs: &AffinePoint<C>) -> ProjectivePoint<C> {
103
0
        let b3 = C::EQUATION_B * C::FieldElement::from(3);
104
0
105
0
        let t0 = lhs.x * rhs.x; // 1
106
0
        let t1 = lhs.y * rhs.y; // 2
107
0
        let t3 = rhs.x + rhs.y; // 3
108
0
        let t4 = lhs.x + lhs.y; // 4
109
0
        let t3 = t3 * t4; // 5
110
0
        let t4 = t0 + t1; // 6
111
0
        let t3 = t3 - t4; // 7
112
0
        let t4 = rhs.x * lhs.z; // 8
113
0
        let t4 = t4 + lhs.x; // 9
114
0
        let t5 = rhs.y * lhs.z; // 10
115
0
        let t5 = t5 + lhs.y; // 11
116
0
        let z3 = C::EQUATION_A * t4; // 12
117
0
        let x3 = b3 * lhs.z; // 13
118
0
        let z3 = x3 + z3; // 14
119
0
        let x3 = t1 - z3; // 15
120
0
        let z3 = t1 + z3; // 16
121
0
        let y3 = x3 * z3; // 17
122
0
        let t1 = t0 + t0; // 18
123
0
        let t1 = t1 + t0; // 19
124
0
        let t2 = C::EQUATION_A * lhs.z; // 20
125
0
        let t4 = b3 * t4; // 21
126
0
        let t1 = t1 + t2; // 22
127
0
        let t2 = t0 - t2; // 23
128
0
        let t2 = C::EQUATION_A * t2; // 24
129
0
        let t4 = t4 + t2; // 25
130
0
        let t0 = t1 * t4; // 26
131
0
        let y3 = y3 + t0; // 27
132
0
        let t0 = t5 * t4; // 28
133
0
        let x3 = t3 * x3; // 29
134
0
        let x3 = x3 - t0; // 30
135
0
        let t0 = t3 * t1; // 31
136
0
        let z3 = t5 * z3; // 32
137
0
        let z3 = z3 + t0; // 33
138
0
139
0
        let mut ret = ProjectivePoint {
140
0
            x: x3,
141
0
            y: y3,
142
0
            z: z3,
143
0
        };
144
0
        ret.conditional_assign(lhs, rhs.is_identity());
145
0
        ret
146
0
    }
147
148
    /// Implements point doubling for curves with any `a`
149
    ///
150
    /// Implements the exception-free point doubling formula from [Renes-Costello-Batina 2015]
151
    /// (Algorithm 3). The comments after each line indicate which algorithm
152
    /// steps are being performed.
153
    ///
154
    /// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
155
0
    fn double(point: &ProjectivePoint<C>) -> ProjectivePoint<C> {
156
0
        let b3 = C::EQUATION_B * C::FieldElement::from(3);
157
0
158
0
        let t0 = point.x * point.x; // 1
159
0
        let t1 = point.y * point.y; // 2
160
0
        let t2 = point.z * point.z; // 3
161
0
        let t3 = point.x * point.y; // 4
162
0
        let t3 = t3 + t3; // 5
163
0
        let z3 = point.x * point.z; // 6
164
0
        let z3 = z3 + z3; // 7
165
0
        let x3 = C::EQUATION_A * z3; // 8
166
0
        let y3 = b3 * t2; // 9
167
0
        let y3 = x3 + y3; // 10
168
0
        let x3 = t1 - y3; // 11
169
0
        let y3 = t1 + y3; // 12
170
0
        let y3 = x3 * y3; // 13
171
0
        let x3 = t3 * x3; // 14
172
0
        let z3 = b3 * z3; // 15
173
0
        let t2 = C::EQUATION_A * t2; // 16
174
0
        let t3 = t0 - t2; // 17
175
0
        let t3 = C::EQUATION_A * t3; // 18
176
0
        let t3 = t3 + z3; // 19
177
0
        let z3 = t0 + t0; // 20
178
0
        let t0 = z3 + t0; // 21
179
0
        let t0 = t0 + t2; // 22
180
0
        let t0 = t0 * t3; // 23
181
0
        let y3 = y3 + t0; // 24
182
0
        let t2 = point.y * point.z; // 25
183
0
        let t2 = t2 + t2; // 26
184
0
        let t0 = t2 * t3; // 27
185
0
        let x3 = x3 - t0; // 28
186
0
        let z3 = t2 * t1; // 29
187
0
        let z3 = z3 + z3; // 30
188
0
        let z3 = z3 + z3; // 31
189
0
190
0
        ProjectivePoint {
191
0
            x: x3,
192
0
            y: y3,
193
0
            z: z3,
194
0
        }
195
0
    }
196
}
197
198
/// The 𝒂-coefficient of the short Weierstrass equation is -3.
199
pub struct EquationAIsMinusThree {}
200
201
impl<C: PrimeCurveParams> PointArithmetic<C> for EquationAIsMinusThree {
202
    /// Implements complete addition for curves with `a = -3`
203
    ///
204
    /// Implements the complete addition formula from [Renes-Costello-Batina 2015]
205
    /// (Algorithm 4). The comments after each line indicate which algorithm steps
206
    /// are being performed.
207
    ///
208
    /// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
209
119k
    fn add(lhs: &ProjectivePoint<C>, rhs: &ProjectivePoint<C>) -> ProjectivePoint<C> {
210
119k
        debug_assert_eq!(
211
119k
            C::EQUATION_A,
212
119k
            -C::FieldElement::from(3),
213
0
            "this implementation is only valid for C::EQUATION_A = -3"
214
        );
215
216
119k
        let xx = lhs.x * rhs.x; // 1
217
119k
        let yy = lhs.y * rhs.y; // 2
218
119k
        let zz = lhs.z * rhs.z; // 3
219
119k
        let xy_pairs = ((lhs.x + lhs.y) * (rhs.x + rhs.y)) - (xx + yy); // 4, 5, 6, 7, 8
220
119k
        let yz_pairs = ((lhs.y + lhs.z) * (rhs.y + rhs.z)) - (yy + zz); // 9, 10, 11, 12, 13
221
119k
        let xz_pairs = ((lhs.x + lhs.z) * (rhs.x + rhs.z)) - (xx + zz); // 14, 15, 16, 17, 18
222
119k
223
119k
        let bzz_part = xz_pairs - (C::EQUATION_B * zz); // 19, 20
224
119k
        let bzz3_part = bzz_part.double() + bzz_part; // 21, 22
225
119k
        let yy_m_bzz3 = yy - bzz3_part; // 23
226
119k
        let yy_p_bzz3 = yy + bzz3_part; // 24
227
119k
228
119k
        let zz3 = zz.double() + zz; // 26, 27
229
119k
        let bxz_part = (C::EQUATION_B * xz_pairs) - (zz3 + xx); // 25, 28, 29
230
119k
        let bxz3_part = bxz_part.double() + bxz_part; // 30, 31
231
119k
        let xx3_m_zz3 = xx.double() + xx - zz3; // 32, 33, 34
232
119k
233
119k
        ProjectivePoint {
234
119k
            x: (yy_p_bzz3 * xy_pairs) - (yz_pairs * bxz3_part), // 35, 39, 40
235
119k
            y: (yy_p_bzz3 * yy_m_bzz3) + (xx3_m_zz3 * bxz3_part), // 36, 37, 38
236
119k
            z: (yy_m_bzz3 * yz_pairs) + (xy_pairs * xx3_m_zz3), // 41, 42, 43
237
119k
        }
238
119k
    }
_RNvXs_NtCs2J0Yj5ID6sO_10primeorder16point_arithmeticNtB4_21EquationAIsMinusThreeINtNtB4_6sealed15PointArithmeticNtCsaHRNXv1Y9Bq_4p2568NistP256E3addCs4RkbDk9WRL5_5clvmr
Line
Count
Source
209
119k
    fn add(lhs: &ProjectivePoint<C>, rhs: &ProjectivePoint<C>) -> ProjectivePoint<C> {
210
119k
        debug_assert_eq!(
211
119k
            C::EQUATION_A,
212
119k
            -C::FieldElement::from(3),
213
0
            "this implementation is only valid for C::EQUATION_A = -3"
214
        );
215
216
119k
        let xx = lhs.x * rhs.x; // 1
217
119k
        let yy = lhs.y * rhs.y; // 2
218
119k
        let zz = lhs.z * rhs.z; // 3
219
119k
        let xy_pairs = ((lhs.x + lhs.y) * (rhs.x + rhs.y)) - (xx + yy); // 4, 5, 6, 7, 8
220
119k
        let yz_pairs = ((lhs.y + lhs.z) * (rhs.y + rhs.z)) - (yy + zz); // 9, 10, 11, 12, 13
221
119k
        let xz_pairs = ((lhs.x + lhs.z) * (rhs.x + rhs.z)) - (xx + zz); // 14, 15, 16, 17, 18
222
119k
223
119k
        let bzz_part = xz_pairs - (C::EQUATION_B * zz); // 19, 20
224
119k
        let bzz3_part = bzz_part.double() + bzz_part; // 21, 22
225
119k
        let yy_m_bzz3 = yy - bzz3_part; // 23
226
119k
        let yy_p_bzz3 = yy + bzz3_part; // 24
227
119k
228
119k
        let zz3 = zz.double() + zz; // 26, 27
229
119k
        let bxz_part = (C::EQUATION_B * xz_pairs) - (zz3 + xx); // 25, 28, 29
230
119k
        let bxz3_part = bxz_part.double() + bxz_part; // 30, 31
231
119k
        let xx3_m_zz3 = xx.double() + xx - zz3; // 32, 33, 34
232
119k
233
119k
        ProjectivePoint {
234
119k
            x: (yy_p_bzz3 * xy_pairs) - (yz_pairs * bxz3_part), // 35, 39, 40
235
119k
            y: (yy_p_bzz3 * yy_m_bzz3) + (xx3_m_zz3 * bxz3_part), // 36, 37, 38
236
119k
            z: (yy_m_bzz3 * yz_pairs) + (xy_pairs * xx3_m_zz3), // 41, 42, 43
237
119k
        }
238
119k
    }
Unexecuted instantiation: _RNvXs_NtCs2J0Yj5ID6sO_10primeorder16point_arithmeticNtB4_21EquationAIsMinusThreeINtNtB4_6sealed15PointArithmeticNtCsaHRNXv1Y9Bq_4p2568NistP256E3addB1O_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder16point_arithmetics_0pENtB5_21EquationAIsMinusThreeINtNtB5_6sealed15PointArithmeticpE3addB7_
239
240
    /// Implements complete mixed addition for curves with `a = -3`
241
    ///
242
    /// Implements the complete mixed addition formula from [Renes-Costello-Batina 2015]
243
    /// (Algorithm 5). The comments after each line indicate which algorithm
244
    /// steps are being performed.
245
    ///
246
    /// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
247
0
    fn add_mixed(lhs: &ProjectivePoint<C>, rhs: &AffinePoint<C>) -> ProjectivePoint<C> {
248
0
        debug_assert_eq!(
249
0
            C::EQUATION_A,
250
0
            -C::FieldElement::from(3),
251
0
            "this implementation is only valid for C::EQUATION_A = -3"
252
        );
253
254
0
        let xx = lhs.x * rhs.x; // 1
255
0
        let yy = lhs.y * rhs.y; // 2
256
0
        let xy_pairs = ((lhs.x + lhs.y) * (rhs.x + rhs.y)) - (xx + yy); // 3, 4, 5, 6, 7
257
0
        let yz_pairs = (rhs.y * lhs.z) + lhs.y; // 8, 9 (t4)
258
0
        let xz_pairs = (rhs.x * lhs.z) + lhs.x; // 10, 11 (y3)
259
0
260
0
        let bz_part = xz_pairs - (C::EQUATION_B * lhs.z); // 12, 13
261
0
        let bz3_part = bz_part.double() + bz_part; // 14, 15
262
0
        let yy_m_bzz3 = yy - bz3_part; // 16
263
0
        let yy_p_bzz3 = yy + bz3_part; // 17
264
0
265
0
        let z3 = lhs.z.double() + lhs.z; // 19, 20
266
0
        let bxz_part = (C::EQUATION_B * xz_pairs) - (z3 + xx); // 18, 21, 22
267
0
        let bxz3_part = bxz_part.double() + bxz_part; // 23, 24
268
0
        let xx3_m_zz3 = xx.double() + xx - z3; // 25, 26, 27
269
0
270
0
        let mut ret = ProjectivePoint {
271
0
            x: (yy_p_bzz3 * xy_pairs) - (yz_pairs * bxz3_part), // 28, 32, 33
272
0
            y: (yy_p_bzz3 * yy_m_bzz3) + (xx3_m_zz3 * bxz3_part), // 29, 30, 31
273
0
            z: (yy_m_bzz3 * yz_pairs) + (xy_pairs * xx3_m_zz3), // 34, 35, 36
274
0
        };
275
0
        ret.conditional_assign(lhs, rhs.is_identity());
276
0
        ret
277
0
    }
278
279
    /// Implements point doubling for curves with `a = -3`
280
    ///
281
    /// Implements the exception-free point doubling formula from [Renes-Costello-Batina 2015]
282
    /// (Algorithm 6). The comments after each line indicate which algorithm
283
    /// steps are being performed.
284
    ///
285
    /// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
286
434k
    fn double(point: &ProjectivePoint<C>) -> ProjectivePoint<C> {
287
434k
        debug_assert_eq!(
288
434k
            C::EQUATION_A,
289
434k
            -C::FieldElement::from(3),
290
0
            "this implementation is only valid for C::EQUATION_A = -3"
291
        );
292
293
434k
        let xx = point.x.square(); // 1
294
434k
        let yy = point.y.square(); // 2
295
434k
        let zz = point.z.square(); // 3
296
434k
        let xy2 = (point.x * point.y).double(); // 4, 5
297
434k
        let xz2 = (point.x * point.z).double(); // 6, 7
298
434k
299
434k
        let bzz_part = (C::EQUATION_B * zz) - xz2; // 8, 9
300
434k
        let bzz3_part = bzz_part.double() + bzz_part; // 10, 11
301
434k
        let yy_m_bzz3 = yy - bzz3_part; // 12
302
434k
        let yy_p_bzz3 = yy + bzz3_part; // 13
303
434k
        let y_frag = yy_p_bzz3 * yy_m_bzz3; // 14
304
434k
        let x_frag = yy_m_bzz3 * xy2; // 15
305
434k
306
434k
        let zz3 = zz.double() + zz; // 16, 17
307
434k
        let bxz2_part = (C::EQUATION_B * xz2) - (zz3 + xx); // 18, 19, 20
308
434k
        let bxz6_part = bxz2_part.double() + bxz2_part; // 21, 22
309
434k
        let xx3_m_zz3 = xx.double() + xx - zz3; // 23, 24, 25
310
434k
311
434k
        let y = y_frag + (xx3_m_zz3 * bxz6_part); // 26, 27
312
434k
        let yz2 = (point.y * point.z).double(); // 28, 29
313
434k
        let x = x_frag - (bxz6_part * yz2); // 30, 31
314
434k
        let z = (yz2 * yy).double().double(); // 32, 33, 34
315
434k
316
434k
        ProjectivePoint { x, y, z }
317
434k
    }
_RNvXs_NtCs2J0Yj5ID6sO_10primeorder16point_arithmeticNtB4_21EquationAIsMinusThreeINtNtB4_6sealed15PointArithmeticNtCsaHRNXv1Y9Bq_4p2568NistP256E6doubleCs4RkbDk9WRL5_5clvmr
Line
Count
Source
286
434k
    fn double(point: &ProjectivePoint<C>) -> ProjectivePoint<C> {
287
434k
        debug_assert_eq!(
288
434k
            C::EQUATION_A,
289
434k
            -C::FieldElement::from(3),
290
0
            "this implementation is only valid for C::EQUATION_A = -3"
291
        );
292
293
434k
        let xx = point.x.square(); // 1
294
434k
        let yy = point.y.square(); // 2
295
434k
        let zz = point.z.square(); // 3
296
434k
        let xy2 = (point.x * point.y).double(); // 4, 5
297
434k
        let xz2 = (point.x * point.z).double(); // 6, 7
298
434k
299
434k
        let bzz_part = (C::EQUATION_B * zz) - xz2; // 8, 9
300
434k
        let bzz3_part = bzz_part.double() + bzz_part; // 10, 11
301
434k
        let yy_m_bzz3 = yy - bzz3_part; // 12
302
434k
        let yy_p_bzz3 = yy + bzz3_part; // 13
303
434k
        let y_frag = yy_p_bzz3 * yy_m_bzz3; // 14
304
434k
        let x_frag = yy_m_bzz3 * xy2; // 15
305
434k
306
434k
        let zz3 = zz.double() + zz; // 16, 17
307
434k
        let bxz2_part = (C::EQUATION_B * xz2) - (zz3 + xx); // 18, 19, 20
308
434k
        let bxz6_part = bxz2_part.double() + bxz2_part; // 21, 22
309
434k
        let xx3_m_zz3 = xx.double() + xx - zz3; // 23, 24, 25
310
434k
311
434k
        let y = y_frag + (xx3_m_zz3 * bxz6_part); // 26, 27
312
434k
        let yz2 = (point.y * point.z).double(); // 28, 29
313
434k
        let x = x_frag - (bxz6_part * yz2); // 30, 31
314
434k
        let z = (yz2 * yy).double().double(); // 32, 33, 34
315
434k
316
434k
        ProjectivePoint { x, y, z }
317
434k
    }
Unexecuted instantiation: _RNvXs_NtCs2J0Yj5ID6sO_10primeorder16point_arithmeticNtB4_21EquationAIsMinusThreeINtNtB4_6sealed15PointArithmeticNtCsaHRNXv1Y9Bq_4p2568NistP256E6doubleB1O_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder16point_arithmetics_0pENtB5_21EquationAIsMinusThreeINtNtB5_6sealed15PointArithmeticpE6doubleB7_
318
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/primeorder-0.13.6/src/projective.rs
Line
Count
Source
1
//! Projective curve points.
2
3
#![allow(clippy::needless_range_loop, clippy::op_ref)]
4
5
use crate::{point_arithmetic::PointArithmetic, AffinePoint, Field, PrimeCurveParams};
6
use core::{
7
    borrow::Borrow,
8
    iter::Sum,
9
    ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
10
};
11
use elliptic_curve::{
12
    bigint::{ArrayEncoding, Integer},
13
    generic_array::ArrayLength,
14
    group::{
15
        self,
16
        cofactor::CofactorGroup,
17
        prime::{PrimeCurve, PrimeGroup},
18
        Group, GroupEncoding,
19
    },
20
    ops::{BatchInvert, Invert, LinearCombination, MulByGenerator},
21
    point::Double,
22
    rand_core::RngCore,
23
    sec1::{
24
        CompressedPoint, EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint,
25
        UncompressedPointSize,
26
    },
27
    subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
28
    zeroize::DefaultIsZeroes,
29
    BatchNormalize, Error, FieldBytes, FieldBytesSize, PublicKey, Result, Scalar,
30
};
31
32
#[cfg(feature = "alloc")]
33
use alloc::vec::Vec;
34
35
/// Point on a Weierstrass curve in projective coordinates.
36
#[derive(Clone, Copy, Debug)]
37
pub struct ProjectivePoint<C: PrimeCurveParams> {
38
    pub(crate) x: C::FieldElement,
39
    pub(crate) y: C::FieldElement,
40
    pub(crate) z: C::FieldElement,
41
}
42
43
impl<C> ProjectivePoint<C>
44
where
45
    C: PrimeCurveParams,
46
{
47
    /// Additive identity of the group a.k.a. the point at infinity.
48
    pub const IDENTITY: Self = Self {
49
        x: C::FieldElement::ZERO,
50
        y: C::FieldElement::ONE,
51
        z: C::FieldElement::ZERO,
52
    };
53
54
    /// Base point of the curve.
55
    pub const GENERATOR: Self = Self {
56
        x: C::GENERATOR.0,
57
        y: C::GENERATOR.1,
58
        z: C::FieldElement::ONE,
59
    };
60
61
    /// Returns the affine representation of this point, or `None` if it is the identity.
62
838
    pub fn to_affine(&self) -> AffinePoint<C> {
63
838
        <C::FieldElement as Field>::invert(&self.z)
64
838
            .map(|zinv| self.to_affine_internal(zinv))
_RNCNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB4_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256E9to_affine0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
64
838
            .map(|zinv| self.to_affine_internal(zinv))
Unexecuted instantiation: _RNCNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB4_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256E9to_affine0B17_
Unexecuted instantiation: _RNCNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB4_15ProjectivePointpE9to_affine0B6_
65
838
            .unwrap_or(AffinePoint::IDENTITY)
66
838
    }
_RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256E9to_affineCs4RkbDk9WRL5_5clvmr
Line
Count
Source
62
838
    pub fn to_affine(&self) -> AffinePoint<C> {
63
838
        <C::FieldElement as Field>::invert(&self.z)
64
838
            .map(|zinv| self.to_affine_internal(zinv))
65
838
            .unwrap_or(AffinePoint::IDENTITY)
66
838
    }
Unexecuted instantiation: _RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256E9to_affineB15_
Unexecuted instantiation: _RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointpE9to_affineB4_
67
68
838
    pub(super) fn to_affine_internal(self, zinv: C::FieldElement) -> AffinePoint<C> {
69
838
        AffinePoint {
70
838
            x: self.x * &zinv,
71
838
            y: self.y * &zinv,
72
838
            infinity: 0,
73
838
        }
74
838
    }
_RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256E18to_affine_internalCs4RkbDk9WRL5_5clvmr
Line
Count
Source
68
838
    pub(super) fn to_affine_internal(self, zinv: C::FieldElement) -> AffinePoint<C> {
69
838
        AffinePoint {
70
838
            x: self.x * &zinv,
71
838
            y: self.y * &zinv,
72
838
            infinity: 0,
73
838
        }
74
838
    }
Unexecuted instantiation: _RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256E18to_affine_internalB15_
Unexecuted instantiation: _RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointpE18to_affine_internalB4_
75
76
    /// Returns `-self`.
77
0
    pub fn neg(&self) -> Self {
78
0
        Self {
79
0
            x: self.x,
80
0
            y: -self.y,
81
0
            z: self.z,
82
0
        }
83
0
    }
84
85
    /// Returns `self + other`.
86
119k
    pub fn add(&self, other: &Self) -> Self {
87
119k
        C::PointArithmetic::add(self, other)
88
119k
    }
_RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256E3addCs4RkbDk9WRL5_5clvmr
Line
Count
Source
86
119k
    pub fn add(&self, other: &Self) -> Self {
87
119k
        C::PointArithmetic::add(self, other)
88
119k
    }
Unexecuted instantiation: _RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256E3addB15_
Unexecuted instantiation: _RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointpE3addB4_
89
90
    /// Returns `self + other`.
91
0
    fn add_mixed(&self, other: &AffinePoint<C>) -> Self {
92
0
        C::PointArithmetic::add_mixed(self, other)
93
0
    }
94
95
    /// Returns `self - other`.
96
0
    pub fn sub(&self, other: &Self) -> Self {
97
0
        self.add(&other.neg())
98
0
    }
99
100
    /// Returns `self - other`.
101
0
    fn sub_mixed(&self, other: &AffinePoint<C>) -> Self {
102
0
        self.add_mixed(&other.neg())
103
0
    }
104
105
    /// Returns `[k] self`.
106
1.67k
    fn mul(&self, k: &Scalar<C>) -> Self
107
1.67k
    where
108
1.67k
        Self: Double,
109
1.67k
    {
110
1.67k
        let k = Into::<C::Uint>::into(*k).to_le_byte_array();
111
1.67k
112
1.67k
        let mut pc = [Self::default(); 16];
113
1.67k
        pc[0] = Self::IDENTITY;
114
1.67k
        pc[1] = *self;
115
116
25.1k
        for i in 2..16 {
117
23.4k
            pc[i] = if i % 2 == 0 {
118
11.7k
                Double::double(&pc[i / 2])
119
            } else {
120
11.7k
                pc[i - 1].add(self)
121
            };
122
        }
123
124
1.67k
        let mut q = Self::IDENTITY;
125
1.67k
        let mut pos = C::Uint::BITS - 4;
126
127
        loop {
128
107k
            let slot = (k[pos >> 3] >> (pos & 7)) & 0xf;
129
107k
130
107k
            let mut t = ProjectivePoint::IDENTITY;
131
132
1.71M
            for i in 1..16 {
133
1.60M
                t.conditional_assign(
134
1.60M
                    &pc[i],
135
1.60M
                    Choice::from(((slot as usize ^ i).wrapping_sub(1) >> 8) as u8 & 1),
136
1.60M
                );
137
1.60M
            }
138
139
107k
            q = q.add(&t);
140
107k
141
107k
            if pos == 0 {
142
1.67k
                break;
143
105k
            }
144
105k
145
105k
            q = Double::double(&Double::double(&Double::double(&Double::double(&q))));
146
105k
            pos -= 4;
147
        }
148
149
1.67k
        q
150
1.67k
    }
_RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256E3mulCs4RkbDk9WRL5_5clvmr
Line
Count
Source
106
1.67k
    fn mul(&self, k: &Scalar<C>) -> Self
107
1.67k
    where
108
1.67k
        Self: Double,
109
1.67k
    {
110
1.67k
        let k = Into::<C::Uint>::into(*k).to_le_byte_array();
111
1.67k
112
1.67k
        let mut pc = [Self::default(); 16];
113
1.67k
        pc[0] = Self::IDENTITY;
114
1.67k
        pc[1] = *self;
115
116
25.1k
        for i in 2..16 {
117
23.4k
            pc[i] = if i % 2 == 0 {
118
11.7k
                Double::double(&pc[i / 2])
119
            } else {
120
11.7k
                pc[i - 1].add(self)
121
            };
122
        }
123
124
1.67k
        let mut q = Self::IDENTITY;
125
1.67k
        let mut pos = C::Uint::BITS - 4;
126
127
        loop {
128
107k
            let slot = (k[pos >> 3] >> (pos & 7)) & 0xf;
129
107k
130
107k
            let mut t = ProjectivePoint::IDENTITY;
131
132
1.71M
            for i in 1..16 {
133
1.60M
                t.conditional_assign(
134
1.60M
                    &pc[i],
135
1.60M
                    Choice::from(((slot as usize ^ i).wrapping_sub(1) >> 8) as u8 & 1),
136
1.60M
                );
137
1.60M
            }
138
139
107k
            q = q.add(&t);
140
107k
141
107k
            if pos == 0 {
142
1.67k
                break;
143
105k
            }
144
105k
145
105k
            q = Double::double(&Double::double(&Double::double(&Double::double(&q))));
146
105k
            pos -= 4;
147
        }
148
149
1.67k
        q
150
1.67k
    }
Unexecuted instantiation: _RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256E3mulB15_
Unexecuted instantiation: _RNvMNtCs2J0Yj5ID6sO_10primeorder10projectiveINtB2_15ProjectivePointpE3mulB4_
151
}
152
153
impl<C> CofactorGroup for ProjectivePoint<C>
154
where
155
    Self: Double,
156
    C: PrimeCurveParams,
157
    FieldBytes<C>: Copy,
158
    FieldBytesSize<C>: ModulusSize,
159
    CompressedPoint<C>: Copy,
160
    <UncompressedPointSize<C> as ArrayLength<u8>>::ArrayType: Copy,
161
{
162
    type Subgroup = Self;
163
164
0
    fn clear_cofactor(&self) -> Self::Subgroup {
165
0
        *self
166
0
    }
167
168
0
    fn into_subgroup(self) -> CtOption<Self> {
169
0
        CtOption::new(self, 1.into())
170
0
    }
171
172
0
    fn is_torsion_free(&self) -> Choice {
173
0
        1.into()
174
0
    }
175
}
176
177
impl<C> ConditionallySelectable for ProjectivePoint<C>
178
where
179
    C: PrimeCurveParams,
180
{
181
    #[inline(always)]
182
1.60M
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
183
1.60M
        Self {
184
1.60M
            x: C::FieldElement::conditional_select(&a.x, &b.x, choice),
185
1.60M
            y: C::FieldElement::conditional_select(&a.y, &b.y, choice),
186
1.60M
            z: C::FieldElement::conditional_select(&a.z, &b.z, choice),
187
1.60M
        }
188
1.60M
    }
_RNvXs0_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectCs4RkbDk9WRL5_5clvmr
Line
Count
Source
182
1.60M
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
183
1.60M
        Self {
184
1.60M
            x: C::FieldElement::conditional_select(&a.x, &b.x, choice),
185
1.60M
            y: C::FieldElement::conditional_select(&a.y, &b.y, choice),
186
1.60M
            z: C::FieldElement::conditional_select(&a.z, &b.z, choice),
187
1.60M
        }
188
1.60M
    }
Unexecuted instantiation: _RNvXs0_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectB18_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder10projectives0_0pEINtB5_15ProjectivePointpENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectB7_
189
}
190
191
impl<C> ConstantTimeEq for ProjectivePoint<C>
192
where
193
    C: PrimeCurveParams,
194
{
195
0
    fn ct_eq(&self, other: &Self) -> Choice {
196
0
        self.to_affine().ct_eq(&other.to_affine())
197
0
    }
198
}
199
200
impl<C> Default for ProjectivePoint<C>
201
where
202
    C: PrimeCurveParams,
203
{
204
1.67k
    fn default() -> Self {
205
1.67k
        Self::IDENTITY
206
1.67k
    }
_RNvXs2_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultCs4RkbDk9WRL5_5clvmr
Line
Count
Source
204
1.67k
    fn default() -> Self {
205
1.67k
        Self::IDENTITY
206
1.67k
    }
Unexecuted instantiation: _RNvXs2_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultB18_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder10projectives2_0pEINtB5_15ProjectivePointpENtNtCsbQ8arDwx5Xq_4core7default7Default7defaultB7_
207
}
208
209
impl<C> DefaultIsZeroes for ProjectivePoint<C> where C: PrimeCurveParams {}
210
211
impl<C: PrimeCurveParams> Double for ProjectivePoint<C> {
212
434k
    fn double(&self) -> Self {
213
434k
        C::PointArithmetic::double(self)
214
434k
    }
_RNvXs4_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtCs8yVsO3EKNkV_14elliptic_curve5point6Double6doubleCs4RkbDk9WRL5_5clvmr
Line
Count
Source
212
434k
    fn double(&self) -> Self {
213
434k
        C::PointArithmetic::double(self)
214
434k
    }
Unexecuted instantiation: _RNvXs4_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtCs8yVsO3EKNkV_14elliptic_curve5point6Double6doubleB18_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder10projectives4_0pEINtB5_15ProjectivePointpENtNtCs8yVsO3EKNkV_14elliptic_curve5point6Double6doubleB7_
215
}
216
217
impl<C> Eq for ProjectivePoint<C> where C: PrimeCurveParams {}
218
219
impl<C> From<AffinePoint<C>> for ProjectivePoint<C>
220
where
221
    C: PrimeCurveParams,
222
{
223
838
    fn from(p: AffinePoint<C>) -> Self {
224
838
        let projective = ProjectivePoint {
225
838
            x: p.x,
226
838
            y: p.y,
227
838
            z: C::FieldElement::ONE,
228
838
        };
229
838
        Self::conditional_select(&projective, &Self::IDENTITY, p.is_identity())
230
838
    }
_RNvXs6_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCsbQ8arDwx5Xq_4core7convert4FromINtNtB7_6affine11AffinePointB16_EE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
223
838
    fn from(p: AffinePoint<C>) -> Self {
224
838
        let projective = ProjectivePoint {
225
838
            x: p.x,
226
838
            y: p.y,
227
838
            z: C::FieldElement::ONE,
228
838
        };
229
838
        Self::conditional_select(&projective, &Self::IDENTITY, p.is_identity())
230
838
    }
Unexecuted instantiation: _RNvXs6_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtCsbQ8arDwx5Xq_4core7convert4FromINtNtB7_6affine11AffinePointB16_EE4fromB18_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder10projectives6_0pEINtB5_15ProjectivePointpEINtNtCsbQ8arDwx5Xq_4core7convert4FromINtNtB7_6affine11AffinePointpEE4fromB7_
231
}
232
233
impl<C> From<&AffinePoint<C>> for ProjectivePoint<C>
234
where
235
    C: PrimeCurveParams,
236
{
237
0
    fn from(p: &AffinePoint<C>) -> Self {
238
0
        Self::from(*p)
239
0
    }
240
}
241
242
impl<C> From<PublicKey<C>> for ProjectivePoint<C>
243
where
244
    C: PrimeCurveParams,
245
{
246
0
    fn from(public_key: PublicKey<C>) -> ProjectivePoint<C> {
247
0
        AffinePoint::from(public_key).into()
248
0
    }
249
}
250
251
impl<C> From<&PublicKey<C>> for ProjectivePoint<C>
252
where
253
    C: PrimeCurveParams,
254
{
255
0
    fn from(public_key: &PublicKey<C>) -> ProjectivePoint<C> {
256
0
        AffinePoint::<C>::from(public_key).into()
257
0
    }
258
}
259
260
impl<C> FromEncodedPoint<C> for ProjectivePoint<C>
261
where
262
    C: PrimeCurveParams,
263
    FieldBytes<C>: Copy,
264
    FieldBytesSize<C>: ModulusSize,
265
    CompressedPoint<C>: Copy,
266
{
267
0
    fn from_encoded_point(p: &EncodedPoint<C>) -> CtOption<Self> {
268
0
        AffinePoint::<C>::from_encoded_point(p).map(Self::from)
269
0
    }
270
}
271
272
impl<C> Group for ProjectivePoint<C>
273
where
274
    Self: Double,
275
    C: PrimeCurveParams,
276
{
277
    type Scalar = Scalar<C>;
278
279
0
    fn random(mut rng: impl RngCore) -> Self {
280
0
        Self::GENERATOR * <Scalar<C> as Field>::random(&mut rng)
281
0
    }
282
283
0
    fn identity() -> Self {
284
0
        Self::IDENTITY
285
0
    }
286
287
838
    fn generator() -> Self {
288
838
        Self::GENERATOR
289
838
    }
_RNvXsb_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtCsfkBiU6A8cFc_5group5Group9generatorCs4RkbDk9WRL5_5clvmr
Line
Count
Source
287
838
    fn generator() -> Self {
288
838
        Self::GENERATOR
289
838
    }
Unexecuted instantiation: _RNvXsb_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtCsfkBiU6A8cFc_5group5Group9generatorB18_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder10projectivesb_0pEINtB5_15ProjectivePointpENtCsfkBiU6A8cFc_5group5Group9generatorB7_
290
291
0
    fn is_identity(&self) -> Choice {
292
0
        self.ct_eq(&Self::IDENTITY)
293
0
    }
294
295
    #[must_use]
296
0
    fn double(&self) -> Self {
297
0
        Double::double(self)
298
0
    }
299
}
300
301
impl<C> GroupEncoding for ProjectivePoint<C>
302
where
303
    C: PrimeCurveParams,
304
    FieldBytes<C>: Copy,
305
    FieldBytesSize<C>: ModulusSize,
306
    CompressedPoint<C>: Copy,
307
    <UncompressedPointSize<C> as ArrayLength<u8>>::ArrayType: Copy,
308
{
309
    type Repr = CompressedPoint<C>;
310
311
0
    fn from_bytes(bytes: &Self::Repr) -> CtOption<Self> {
312
0
        <AffinePoint<C> as GroupEncoding>::from_bytes(bytes).map(Into::into)
313
0
    }
314
315
0
    fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption<Self> {
316
0
        // No unchecked conversion possible for compressed points
317
0
        Self::from_bytes(bytes)
318
0
    }
319
320
0
    fn to_bytes(&self) -> Self::Repr {
321
0
        self.to_affine().to_bytes()
322
0
    }
323
}
324
325
impl<C> group::Curve for ProjectivePoint<C>
326
where
327
    Self: Double,
328
    C: PrimeCurveParams,
329
{
330
    type AffineRepr = AffinePoint<C>;
331
332
838
    fn to_affine(&self) -> AffinePoint<C> {
333
838
        ProjectivePoint::to_affine(self)
334
838
    }
_RNvXsd_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtCsfkBiU6A8cFc_5group5Curve9to_affineCs4RkbDk9WRL5_5clvmr
Line
Count
Source
332
838
    fn to_affine(&self) -> AffinePoint<C> {
333
838
        ProjectivePoint::to_affine(self)
334
838
    }
Unexecuted instantiation: _RNvXsd_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtCsfkBiU6A8cFc_5group5Curve9to_affineB18_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder10projectivesd_0pEINtB5_15ProjectivePointpENtCsfkBiU6A8cFc_5group5Curve9to_affineB7_
335
336
    // TODO(tarcieri): re-enable when we can add `Invert` bounds on `FieldElement`
337
    // #[cfg(feature = "alloc")]
338
    // #[inline]
339
    // fn batch_normalize(projective: &[Self], affine: &mut [Self::AffineRepr]) {
340
    //     assert_eq!(projective.len(), affine.len());
341
    //     let mut zs = vec![C::FieldElement::ONE; projective.len()];
342
    //     batch_normalize_generic(projective, zs.as_mut_slice(), affine);
343
    // }
344
}
345
346
impl<const N: usize, C> BatchNormalize<[ProjectivePoint<C>; N]> for ProjectivePoint<C>
347
where
348
    Self: Double,
349
    C: PrimeCurveParams,
350
    C::FieldElement: Invert<Output = CtOption<C::FieldElement>>,
351
{
352
    type Output = [Self::AffineRepr; N];
353
354
    #[inline]
355
0
    fn batch_normalize(points: &[Self; N]) -> [Self::AffineRepr; N] {
356
0
        let mut zs = [C::FieldElement::ONE; N];
357
0
        let mut affine_points = [C::AffinePoint::IDENTITY; N];
358
0
        batch_normalize_generic(points, &mut zs, &mut affine_points);
359
0
        affine_points
360
0
    }
361
}
362
363
#[cfg(feature = "alloc")]
364
impl<C> BatchNormalize<[ProjectivePoint<C>]> for ProjectivePoint<C>
365
where
366
    Self: Double,
367
    C: PrimeCurveParams,
368
    C::FieldElement: Invert<Output = CtOption<C::FieldElement>>,
369
{
370
    type Output = Vec<Self::AffineRepr>;
371
372
    #[inline]
373
    fn batch_normalize(points: &[Self]) -> Vec<Self::AffineRepr> {
374
        let mut zs = vec![C::FieldElement::ONE; points.len()];
375
        let mut affine_points = vec![AffinePoint::IDENTITY; points.len()];
376
        batch_normalize_generic(points, zs.as_mut_slice(), &mut affine_points);
377
        affine_points
378
    }
379
}
380
381
/// Generic implementation of batch normalization.
382
0
fn batch_normalize_generic<C, P, Z, O>(points: &P, zs: &mut Z, out: &mut O)
383
0
where
384
0
    C: PrimeCurveParams,
385
0
    C::FieldElement: BatchInvert<Z>,
386
0
    C::ProjectivePoint: Double,
387
0
    P: AsRef<[ProjectivePoint<C>]> + ?Sized,
388
0
    Z: AsMut<[C::FieldElement]> + ?Sized,
389
0
    O: AsMut<[AffinePoint<C>]> + ?Sized,
390
0
{
391
0
    let points = points.as_ref();
392
0
    let out = out.as_mut();
393
394
0
    for i in 0..points.len() {
395
0
        // Even a single zero value will fail inversion for the entire batch.
396
0
        // Put a dummy value (above `FieldElement::ONE`) so inversion succeeds
397
0
        // and treat that case specially later-on.
398
0
        zs.as_mut()[i].conditional_assign(&points[i].z, !points[i].z.ct_eq(&C::FieldElement::ZERO));
399
0
    }
400
401
    // This is safe to unwrap since we assured that all elements are non-zero
402
0
    let zs_inverses = <C::FieldElement as BatchInvert<Z>>::batch_invert(zs).unwrap();
403
404
0
    for i in 0..out.len() {
405
0
        // If the `z` coordinate is non-zero, we can use it to invert;
406
0
        // otherwise it defaults to the `IDENTITY` value.
407
0
        out[i] = C::AffinePoint::conditional_select(
408
0
            &points[i].to_affine_internal(zs_inverses.as_ref()[i]),
409
0
            &C::AffinePoint::IDENTITY,
410
0
            points[i].z.ct_eq(&C::FieldElement::ZERO),
411
0
        );
412
0
    }
413
0
}
414
415
impl<C> LinearCombination for ProjectivePoint<C>
416
where
417
    Self: Double,
418
    C: PrimeCurveParams,
419
{
420
}
421
422
impl<C> MulByGenerator for ProjectivePoint<C>
423
where
424
    Self: Double,
425
    C: PrimeCurveParams,
426
{
427
0
    fn mul_by_generator(scalar: &Self::Scalar) -> Self {
428
0
        // TODO(tarcieri): precomputed basepoint tables
429
0
        Self::generator() * scalar
430
0
    }
431
}
432
433
impl<C> PrimeGroup for ProjectivePoint<C>
434
where
435
    Self: Double,
436
    C: PrimeCurveParams,
437
    FieldBytes<C>: Copy,
438
    FieldBytesSize<C>: ModulusSize,
439
    CompressedPoint<C>: Copy,
440
    <UncompressedPointSize<C> as ArrayLength<u8>>::ArrayType: Copy,
441
{
442
}
443
444
impl<C> PrimeCurve for ProjectivePoint<C>
445
where
446
    Self: Double,
447
    C: PrimeCurveParams,
448
    FieldBytes<C>: Copy,
449
    FieldBytesSize<C>: ModulusSize,
450
    CompressedPoint<C>: Copy,
451
    <UncompressedPointSize<C> as ArrayLength<u8>>::ArrayType: Copy,
452
{
453
    type Affine = AffinePoint<C>;
454
}
455
456
impl<C> PartialEq for ProjectivePoint<C>
457
where
458
    C: PrimeCurveParams,
459
{
460
0
    fn eq(&self, other: &Self) -> bool {
461
0
        self.ct_eq(other).into()
462
0
    }
463
}
464
465
impl<C> ToEncodedPoint<C> for ProjectivePoint<C>
466
where
467
    C: PrimeCurveParams,
468
    FieldBytesSize<C>: ModulusSize,
469
    CompressedPoint<C>: Copy,
470
    <UncompressedPointSize<C> as ArrayLength<u8>>::ArrayType: Copy,
471
{
472
0
    fn to_encoded_point(&self, compress: bool) -> EncodedPoint<C> {
473
0
        self.to_affine().to_encoded_point(compress)
474
0
    }
475
}
476
477
impl<C> TryFrom<ProjectivePoint<C>> for PublicKey<C>
478
where
479
    C: PrimeCurveParams,
480
{
481
    type Error = Error;
482
483
0
    fn try_from(point: ProjectivePoint<C>) -> Result<PublicKey<C>> {
484
0
        AffinePoint::<C>::from(point).try_into()
485
0
    }
486
}
487
488
impl<C> TryFrom<&ProjectivePoint<C>> for PublicKey<C>
489
where
490
    C: PrimeCurveParams,
491
{
492
    type Error = Error;
493
494
0
    fn try_from(point: &ProjectivePoint<C>) -> Result<PublicKey<C>> {
495
0
        AffinePoint::<C>::from(point).try_into()
496
0
    }
497
}
498
499
//
500
// Arithmetic trait impls
501
//
502
503
impl<C> Add<ProjectivePoint<C>> for ProjectivePoint<C>
504
where
505
    C: PrimeCurveParams,
506
{
507
    type Output = ProjectivePoint<C>;
508
509
838
    fn add(self, other: ProjectivePoint<C>) -> ProjectivePoint<C> {
510
838
        ProjectivePoint::add(&self, &other)
511
838
    }
_RNvXsn_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3addCs4RkbDk9WRL5_5clvmr
Line
Count
Source
509
838
    fn add(self, other: ProjectivePoint<C>) -> ProjectivePoint<C> {
510
838
        ProjectivePoint::add(&self, &other)
511
838
    }
Unexecuted instantiation: _RNvXsn_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3addB18_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder10projectivesn_0pEINtB5_15ProjectivePointpENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3addB7_
512
}
513
514
impl<C> Add<&ProjectivePoint<C>> for &ProjectivePoint<C>
515
where
516
    C: PrimeCurveParams,
517
{
518
    type Output = ProjectivePoint<C>;
519
520
0
    fn add(self, other: &ProjectivePoint<C>) -> ProjectivePoint<C> {
521
0
        ProjectivePoint::add(self, other)
522
0
    }
523
}
524
525
impl<C> Add<&ProjectivePoint<C>> for ProjectivePoint<C>
526
where
527
    C: PrimeCurveParams,
528
{
529
    type Output = ProjectivePoint<C>;
530
531
118k
    fn add(self, other: &ProjectivePoint<C>) -> ProjectivePoint<C> {
532
118k
        ProjectivePoint::add(&self, other)
533
118k
    }
_RNvXsp_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRBJ_E3addCs4RkbDk9WRL5_5clvmr
Line
Count
Source
531
118k
    fn add(self, other: &ProjectivePoint<C>) -> ProjectivePoint<C> {
532
118k
        ProjectivePoint::add(&self, other)
533
118k
    }
Unexecuted instantiation: _RNvXsp_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRBJ_E3addB18_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder10projectivesp_0pEINtB5_15ProjectivePointpEINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRBP_E3addB7_
534
}
535
536
impl<C> AddAssign<ProjectivePoint<C>> for ProjectivePoint<C>
537
where
538
    C: PrimeCurveParams,
539
{
540
0
    fn add_assign(&mut self, rhs: ProjectivePoint<C>) {
541
0
        *self = ProjectivePoint::add(self, &rhs);
542
0
    }
543
}
544
545
impl<C> AddAssign<&ProjectivePoint<C>> for ProjectivePoint<C>
546
where
547
    C: PrimeCurveParams,
548
{
549
0
    fn add_assign(&mut self, rhs: &ProjectivePoint<C>) {
550
0
        *self = ProjectivePoint::add(self, rhs);
551
0
    }
552
}
553
554
impl<C> Add<AffinePoint<C>> for ProjectivePoint<C>
555
where
556
    C: PrimeCurveParams,
557
{
558
    type Output = ProjectivePoint<C>;
559
560
0
    fn add(self, other: AffinePoint<C>) -> ProjectivePoint<C> {
561
0
        ProjectivePoint::add_mixed(&self, &other)
562
0
    }
563
}
564
565
impl<C> Add<&AffinePoint<C>> for &ProjectivePoint<C>
566
where
567
    C: PrimeCurveParams,
568
{
569
    type Output = ProjectivePoint<C>;
570
571
0
    fn add(self, other: &AffinePoint<C>) -> ProjectivePoint<C> {
572
0
        ProjectivePoint::add_mixed(self, other)
573
0
    }
574
}
575
576
impl<C> Add<&AffinePoint<C>> for ProjectivePoint<C>
577
where
578
    C: PrimeCurveParams,
579
{
580
    type Output = ProjectivePoint<C>;
581
582
0
    fn add(self, other: &AffinePoint<C>) -> ProjectivePoint<C> {
583
0
        ProjectivePoint::add_mixed(&self, other)
584
0
    }
585
}
586
587
impl<C> AddAssign<AffinePoint<C>> for ProjectivePoint<C>
588
where
589
    C: PrimeCurveParams,
590
{
591
0
    fn add_assign(&mut self, rhs: AffinePoint<C>) {
592
0
        *self = ProjectivePoint::add_mixed(self, &rhs);
593
0
    }
594
}
595
596
impl<C> AddAssign<&AffinePoint<C>> for ProjectivePoint<C>
597
where
598
    C: PrimeCurveParams,
599
{
600
0
    fn add_assign(&mut self, rhs: &AffinePoint<C>) {
601
0
        *self = ProjectivePoint::add_mixed(self, rhs);
602
0
    }
603
}
604
605
impl<C> Sum for ProjectivePoint<C>
606
where
607
    C: PrimeCurveParams,
608
{
609
0
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
610
0
        iter.fold(ProjectivePoint::IDENTITY, |a, b| a + b)
611
0
    }
612
}
613
614
impl<'a, C> Sum<&'a ProjectivePoint<C>> for ProjectivePoint<C>
615
where
616
    C: PrimeCurveParams,
617
{
618
0
    fn sum<I: Iterator<Item = &'a ProjectivePoint<C>>>(iter: I) -> Self {
619
0
        iter.cloned().sum()
620
0
    }
621
}
622
623
impl<C> Sub<ProjectivePoint<C>> for ProjectivePoint<C>
624
where
625
    C: PrimeCurveParams,
626
{
627
    type Output = ProjectivePoint<C>;
628
629
0
    fn sub(self, other: ProjectivePoint<C>) -> ProjectivePoint<C> {
630
0
        ProjectivePoint::sub(&self, &other)
631
0
    }
632
}
633
634
impl<C> Sub<&ProjectivePoint<C>> for &ProjectivePoint<C>
635
where
636
    C: PrimeCurveParams,
637
{
638
    type Output = ProjectivePoint<C>;
639
640
0
    fn sub(self, other: &ProjectivePoint<C>) -> ProjectivePoint<C> {
641
0
        ProjectivePoint::sub(self, other)
642
0
    }
643
}
644
645
impl<C> Sub<&ProjectivePoint<C>> for ProjectivePoint<C>
646
where
647
    C: PrimeCurveParams,
648
{
649
    type Output = ProjectivePoint<C>;
650
651
0
    fn sub(self, other: &ProjectivePoint<C>) -> ProjectivePoint<C> {
652
0
        ProjectivePoint::sub(&self, other)
653
0
    }
654
}
655
656
impl<C> SubAssign<ProjectivePoint<C>> for ProjectivePoint<C>
657
where
658
    C: PrimeCurveParams,
659
{
660
0
    fn sub_assign(&mut self, rhs: ProjectivePoint<C>) {
661
0
        *self = ProjectivePoint::sub(self, &rhs);
662
0
    }
663
}
664
665
impl<C> SubAssign<&ProjectivePoint<C>> for ProjectivePoint<C>
666
where
667
    C: PrimeCurveParams,
668
{
669
0
    fn sub_assign(&mut self, rhs: &ProjectivePoint<C>) {
670
0
        *self = ProjectivePoint::sub(self, rhs);
671
0
    }
672
}
673
674
impl<C> Sub<AffinePoint<C>> for ProjectivePoint<C>
675
where
676
    C: PrimeCurveParams,
677
{
678
    type Output = ProjectivePoint<C>;
679
680
0
    fn sub(self, other: AffinePoint<C>) -> ProjectivePoint<C> {
681
0
        ProjectivePoint::sub_mixed(&self, &other)
682
0
    }
683
}
684
685
impl<C> Sub<&AffinePoint<C>> for &ProjectivePoint<C>
686
where
687
    C: PrimeCurveParams,
688
{
689
    type Output = ProjectivePoint<C>;
690
691
0
    fn sub(self, other: &AffinePoint<C>) -> ProjectivePoint<C> {
692
0
        ProjectivePoint::sub_mixed(self, other)
693
0
    }
694
}
695
696
impl<C> Sub<&AffinePoint<C>> for ProjectivePoint<C>
697
where
698
    C: PrimeCurveParams,
699
{
700
    type Output = ProjectivePoint<C>;
701
702
0
    fn sub(self, other: &AffinePoint<C>) -> ProjectivePoint<C> {
703
0
        ProjectivePoint::sub_mixed(&self, other)
704
0
    }
705
}
706
707
impl<C> SubAssign<AffinePoint<C>> for ProjectivePoint<C>
708
where
709
    C: PrimeCurveParams,
710
{
711
0
    fn sub_assign(&mut self, rhs: AffinePoint<C>) {
712
0
        *self = ProjectivePoint::sub_mixed(self, &rhs);
713
0
    }
714
}
715
716
impl<C> SubAssign<&AffinePoint<C>> for ProjectivePoint<C>
717
where
718
    C: PrimeCurveParams,
719
{
720
0
    fn sub_assign(&mut self, rhs: &AffinePoint<C>) {
721
0
        *self = ProjectivePoint::sub_mixed(self, rhs);
722
0
    }
723
}
724
725
impl<C, S> Mul<S> for ProjectivePoint<C>
726
where
727
    Self: Double,
728
    C: PrimeCurveParams,
729
    S: Borrow<Scalar<C>>,
730
{
731
    type Output = Self;
732
733
1.67k
    fn mul(self, scalar: S) -> Self {
734
1.67k
        ProjectivePoint::mul(&self, scalar.borrow())
735
1.67k
    }
_RNvXsJ_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtNtNtB18_10arithmetic6scalar6ScalarE3mulCs4RkbDk9WRL5_5clvmr
Line
Count
Source
733
1.67k
    fn mul(self, scalar: S) -> Self {
734
1.67k
        ProjectivePoint::mul(&self, scalar.borrow())
735
1.67k
    }
Unexecuted instantiation: _RNvXsJ_NtCs2J0Yj5ID6sO_10primeorder10projectiveINtB5_15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRNtNtNtB18_10arithmetic6scalar6ScalarE3mulB18_
Unexecuted instantiation: _RNvXININtCs2J0Yj5ID6sO_10primeorder10projectivesJ_0ppEINtB5_15ProjectivePointpEINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulpE3mulB7_
736
}
737
738
impl<C> Mul<&Scalar<C>> for &ProjectivePoint<C>
739
where
740
    C: PrimeCurveParams,
741
    ProjectivePoint<C>: Double,
742
{
743
    type Output = ProjectivePoint<C>;
744
745
0
    fn mul(self, scalar: &Scalar<C>) -> ProjectivePoint<C> {
746
0
        ProjectivePoint::mul(self, scalar)
747
0
    }
748
}
749
750
impl<C, S> MulAssign<S> for ProjectivePoint<C>
751
where
752
    Self: Double,
753
    C: PrimeCurveParams,
754
    S: Borrow<Scalar<C>>,
755
{
756
0
    fn mul_assign(&mut self, scalar: S) {
757
0
        *self = ProjectivePoint::mul(self, scalar.borrow());
758
0
    }
759
}
760
761
impl<C> Neg for ProjectivePoint<C>
762
where
763
    C: PrimeCurveParams,
764
{
765
    type Output = ProjectivePoint<C>;
766
767
0
    fn neg(self) -> ProjectivePoint<C> {
768
0
        ProjectivePoint::neg(&self)
769
0
    }
770
}
771
772
impl<'a, C> Neg for &'a ProjectivePoint<C>
773
where
774
    C: PrimeCurveParams,
775
{
776
    type Output = ProjectivePoint<C>;
777
778
0
    fn neg(self) -> ProjectivePoint<C> {
779
0
        ProjectivePoint::neg(self)
780
0
    }
781
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rand_core-0.6.4/src/block.rs
Line
Count
Source
1
// Copyright 2018 Developers of the Rand project.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
//! The `BlockRngCore` trait and implementation helpers
10
//!
11
//! The [`BlockRngCore`] trait exists to assist in the implementation of RNGs
12
//! which generate a block of data in a cache instead of returning generated
13
//! values directly.
14
//!
15
//! Usage of this trait is optional, but provides two advantages:
16
//! implementations only need to concern themselves with generation of the
17
//! block, not the various [`RngCore`] methods (especially [`fill_bytes`], where
18
//! the optimal implementations are not trivial), and this allows
19
//! `ReseedingRng` (see [`rand`](https://docs.rs/rand) crate) perform periodic
20
//! reseeding with very low overhead.
21
//!
22
//! # Example
23
//!
24
//! ```no_run
25
//! use rand_core::{RngCore, SeedableRng};
26
//! use rand_core::block::{BlockRngCore, BlockRng};
27
//!
28
//! struct MyRngCore;
29
//!
30
//! impl BlockRngCore for MyRngCore {
31
//!     type Item = u32;
32
//!     type Results = [u32; 16];
33
//!
34
//!     fn generate(&mut self, results: &mut Self::Results) {
35
//!         unimplemented!()
36
//!     }
37
//! }
38
//!
39
//! impl SeedableRng for MyRngCore {
40
//!     type Seed = [u8; 32];
41
//!     fn from_seed(seed: Self::Seed) -> Self {
42
//!         unimplemented!()
43
//!     }
44
//! }
45
//!
46
//! // optionally, also implement CryptoRng for MyRngCore
47
//!
48
//! // Final RNG.
49
//! let mut rng = BlockRng::<MyRngCore>::seed_from_u64(0);
50
//! println!("First value: {}", rng.next_u32());
51
//! ```
52
//!
53
//! [`BlockRngCore`]: crate::block::BlockRngCore
54
//! [`fill_bytes`]: RngCore::fill_bytes
55
56
use crate::impls::{fill_via_u32_chunks, fill_via_u64_chunks};
57
use crate::{CryptoRng, Error, RngCore, SeedableRng};
58
use core::convert::AsRef;
59
use core::fmt;
60
#[cfg(feature = "serde1")]
61
use serde::{Deserialize, Serialize};
62
63
/// A trait for RNGs which do not generate random numbers individually, but in
64
/// blocks (typically `[u32; N]`). This technique is commonly used by
65
/// cryptographic RNGs to improve performance.
66
///
67
/// See the [module][crate::block] documentation for details.
68
pub trait BlockRngCore {
69
    /// Results element type, e.g. `u32`.
70
    type Item;
71
72
    /// Results type. This is the 'block' an RNG implementing `BlockRngCore`
73
    /// generates, which will usually be an array like `[u32; 16]`.
74
    type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default;
75
76
    /// Generate a new block of results.
77
    fn generate(&mut self, results: &mut Self::Results);
78
}
79
80
/// A wrapper type implementing [`RngCore`] for some type implementing
81
/// [`BlockRngCore`] with `u32` array buffer; i.e. this can be used to implement
82
/// a full RNG from just a `generate` function.
83
///
84
/// The `core` field may be accessed directly but the results buffer may not.
85
/// PRNG implementations can simply use a type alias
86
/// (`pub type MyRng = BlockRng<MyRngCore>;`) but might prefer to use a
87
/// wrapper type (`pub struct MyRng(BlockRng<MyRngCore>);`); the latter must
88
/// re-implement `RngCore` but hides the implementation details and allows
89
/// extra functionality to be defined on the RNG
90
/// (e.g. `impl MyRng { fn set_stream(...){...} }`).
91
///
92
/// `BlockRng` has heavily optimized implementations of the [`RngCore`] methods
93
/// reading values from the results buffer, as well as
94
/// calling [`BlockRngCore::generate`] directly on the output array when
95
/// [`fill_bytes`] / [`try_fill_bytes`] is called on a large array. These methods
96
/// also handle the bookkeeping of when to generate a new batch of values.
97
///
98
/// No whole generated `u32` values are thrown away and all values are consumed
99
/// in-order. [`next_u32`] simply takes the next available `u32` value.
100
/// [`next_u64`] is implemented by combining two `u32` values, least
101
/// significant first. [`fill_bytes`] and [`try_fill_bytes`] consume a whole
102
/// number of `u32` values, converting each `u32` to a byte slice in
103
/// little-endian order. If the requested byte length is not a multiple of 4,
104
/// some bytes will be discarded.
105
///
106
/// See also [`BlockRng64`] which uses `u64` array buffers. Currently there is
107
/// no direct support for other buffer types.
108
///
109
/// For easy initialization `BlockRng` also implements [`SeedableRng`].
110
///
111
/// [`next_u32`]: RngCore::next_u32
112
/// [`next_u64`]: RngCore::next_u64
113
/// [`fill_bytes`]: RngCore::fill_bytes
114
/// [`try_fill_bytes`]: RngCore::try_fill_bytes
115
#[derive(Clone)]
116
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
117
#[cfg_attr(
118
    feature = "serde1",
119
    serde(
120
        bound = "for<'x> R: Serialize + Deserialize<'x> + Sized, for<'x> R::Results: Serialize + Deserialize<'x>"
121
    )
122
)]
123
pub struct BlockRng<R: BlockRngCore + ?Sized> {
124
    results: R::Results,
125
    index: usize,
126
    /// The *core* part of the RNG, implementing the `generate` function.
127
    pub core: R,
128
}
129
130
// Custom Debug implementation that does not expose the contents of `results`.
131
impl<R: BlockRngCore + fmt::Debug> fmt::Debug for BlockRng<R> {
132
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
133
0
        fmt.debug_struct("BlockRng")
134
0
            .field("core", &self.core)
135
0
            .field("result_len", &self.results.as_ref().len())
136
0
            .field("index", &self.index)
137
0
            .finish()
138
0
    }
139
}
140
141
impl<R: BlockRngCore> BlockRng<R> {
142
    /// Create a new `BlockRng` from an existing RNG implementing
143
    /// `BlockRngCore`. Results will be generated on first use.
144
    #[inline]
145
0
    pub fn new(core: R) -> BlockRng<R> {
146
0
        let results_empty = R::Results::default();
147
0
        BlockRng {
148
0
            core,
149
0
            index: results_empty.as_ref().len(),
150
0
            results: results_empty,
151
0
        }
152
0
    }
153
154
    /// Get the index into the result buffer.
155
    ///
156
    /// If this is equal to or larger than the size of the result buffer then
157
    /// the buffer is "empty" and `generate()` must be called to produce new
158
    /// results.
159
    #[inline(always)]
160
0
    pub fn index(&self) -> usize {
161
0
        self.index
162
0
    }
163
164
    /// Reset the number of available results.
165
    /// This will force a new set of results to be generated on next use.
166
    #[inline]
167
0
    pub fn reset(&mut self) {
168
0
        self.index = self.results.as_ref().len();
169
0
    }
170
171
    /// Generate a new set of results immediately, setting the index to the
172
    /// given value.
173
    #[inline]
174
0
    pub fn generate_and_set(&mut self, index: usize) {
175
0
        assert!(index < self.results.as_ref().len());
176
0
        self.core.generate(&mut self.results);
177
0
        self.index = index;
178
0
    }
179
}
180
181
impl<R: BlockRngCore<Item = u32>> RngCore for BlockRng<R>
182
where
183
    <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>,
184
{
185
    #[inline]
186
0
    fn next_u32(&mut self) -> u32 {
187
0
        if self.index >= self.results.as_ref().len() {
188
0
            self.generate_and_set(0);
189
0
        }
190
191
0
        let value = self.results.as_ref()[self.index];
192
0
        self.index += 1;
193
0
        value
194
0
    }
195
196
    #[inline]
197
0
    fn next_u64(&mut self) -> u64 {
198
0
        let read_u64 = |results: &[u32], index| {
199
0
            let data = &results[index..=index + 1];
200
0
            u64::from(data[1]) << 32 | u64::from(data[0])
201
0
        };
202
203
0
        let len = self.results.as_ref().len();
204
0
205
0
        let index = self.index;
206
0
        if index < len - 1 {
207
0
            self.index += 2;
208
0
            // Read an u64 from the current index
209
0
            read_u64(self.results.as_ref(), index)
210
0
        } else if index >= len {
211
0
            self.generate_and_set(2);
212
0
            read_u64(self.results.as_ref(), 0)
213
        } else {
214
0
            let x = u64::from(self.results.as_ref()[len - 1]);
215
0
            self.generate_and_set(1);
216
0
            let y = u64::from(self.results.as_ref()[0]);
217
0
            (y << 32) | x
218
        }
219
0
    }
220
221
    #[inline]
222
0
    fn fill_bytes(&mut self, dest: &mut [u8]) {
223
0
        let mut read_len = 0;
224
0
        while read_len < dest.len() {
225
0
            if self.index >= self.results.as_ref().len() {
226
0
                self.generate_and_set(0);
227
0
            }
228
0
            let (consumed_u32, filled_u8) =
229
0
                fill_via_u32_chunks(&self.results.as_ref()[self.index..], &mut dest[read_len..]);
230
0
231
0
            self.index += consumed_u32;
232
0
            read_len += filled_u8;
233
        }
234
0
    }
235
236
    #[inline(always)]
237
0
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
238
0
        self.fill_bytes(dest);
239
0
        Ok(())
240
0
    }
241
}
242
243
impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R> {
244
    type Seed = R::Seed;
245
246
    #[inline(always)]
247
0
    fn from_seed(seed: Self::Seed) -> Self {
248
0
        Self::new(R::from_seed(seed))
249
0
    }
250
251
    #[inline(always)]
252
0
    fn seed_from_u64(seed: u64) -> Self {
253
0
        Self::new(R::seed_from_u64(seed))
254
0
    }
255
256
    #[inline(always)]
257
0
    fn from_rng<S: RngCore>(rng: S) -> Result<Self, Error> {
258
0
        Ok(Self::new(R::from_rng(rng)?))
259
0
    }
260
}
261
262
/// A wrapper type implementing [`RngCore`] for some type implementing
263
/// [`BlockRngCore`] with `u64` array buffer; i.e. this can be used to implement
264
/// a full RNG from just a `generate` function.
265
///
266
/// This is similar to [`BlockRng`], but specialized for algorithms that operate
267
/// on `u64` values.
268
///
269
/// No whole generated `u64` values are thrown away and all values are consumed
270
/// in-order. [`next_u64`] simply takes the next available `u64` value.
271
/// [`next_u32`] is however a bit special: half of a `u64` is consumed, leaving
272
/// the other half in the buffer. If the next function called is [`next_u32`]
273
/// then the other half is then consumed, however both [`next_u64`] and
274
/// [`fill_bytes`] discard the rest of any half-consumed `u64`s when called.
275
///
276
/// [`fill_bytes`] and [`try_fill_bytes`] consume a whole number of `u64`
277
/// values. If the requested length is not a multiple of 8, some bytes will be
278
/// discarded.
279
///
280
/// [`next_u32`]: RngCore::next_u32
281
/// [`next_u64`]: RngCore::next_u64
282
/// [`fill_bytes`]: RngCore::fill_bytes
283
/// [`try_fill_bytes`]: RngCore::try_fill_bytes
284
#[derive(Clone)]
285
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
286
pub struct BlockRng64<R: BlockRngCore + ?Sized> {
287
    results: R::Results,
288
    index: usize,
289
    half_used: bool, // true if only half of the previous result is used
290
    /// The *core* part of the RNG, implementing the `generate` function.
291
    pub core: R,
292
}
293
294
// Custom Debug implementation that does not expose the contents of `results`.
295
impl<R: BlockRngCore + fmt::Debug> fmt::Debug for BlockRng64<R> {
296
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
297
0
        fmt.debug_struct("BlockRng64")
298
0
            .field("core", &self.core)
299
0
            .field("result_len", &self.results.as_ref().len())
300
0
            .field("index", &self.index)
301
0
            .field("half_used", &self.half_used)
302
0
            .finish()
303
0
    }
304
}
305
306
impl<R: BlockRngCore> BlockRng64<R> {
307
    /// Create a new `BlockRng` from an existing RNG implementing
308
    /// `BlockRngCore`. Results will be generated on first use.
309
    #[inline]
310
0
    pub fn new(core: R) -> BlockRng64<R> {
311
0
        let results_empty = R::Results::default();
312
0
        BlockRng64 {
313
0
            core,
314
0
            index: results_empty.as_ref().len(),
315
0
            half_used: false,
316
0
            results: results_empty,
317
0
        }
318
0
    }
319
320
    /// Get the index into the result buffer.
321
    ///
322
    /// If this is equal to or larger than the size of the result buffer then
323
    /// the buffer is "empty" and `generate()` must be called to produce new
324
    /// results.
325
    #[inline(always)]
326
0
    pub fn index(&self) -> usize {
327
0
        self.index
328
0
    }
329
330
    /// Reset the number of available results.
331
    /// This will force a new set of results to be generated on next use.
332
    #[inline]
333
0
    pub fn reset(&mut self) {
334
0
        self.index = self.results.as_ref().len();
335
0
        self.half_used = false;
336
0
    }
337
338
    /// Generate a new set of results immediately, setting the index to the
339
    /// given value.
340
    #[inline]
341
0
    pub fn generate_and_set(&mut self, index: usize) {
342
0
        assert!(index < self.results.as_ref().len());
343
0
        self.core.generate(&mut self.results);
344
0
        self.index = index;
345
0
        self.half_used = false;
346
0
    }
347
}
348
349
impl<R: BlockRngCore<Item = u64>> RngCore for BlockRng64<R>
350
where
351
    <R as BlockRngCore>::Results: AsRef<[u64]> + AsMut<[u64]>,
352
{
353
    #[inline]
354
0
    fn next_u32(&mut self) -> u32 {
355
0
        let mut index = self.index - self.half_used as usize;
356
0
        if index >= self.results.as_ref().len() {
357
0
            self.core.generate(&mut self.results);
358
0
            self.index = 0;
359
0
            index = 0;
360
0
            // `self.half_used` is by definition `false`
361
0
            self.half_used = false;
362
0
        }
363
364
0
        let shift = 32 * (self.half_used as usize);
365
0
366
0
        self.half_used = !self.half_used;
367
0
        self.index += self.half_used as usize;
368
0
369
0
        (self.results.as_ref()[index] >> shift) as u32
370
0
    }
371
372
    #[inline]
373
0
    fn next_u64(&mut self) -> u64 {
374
0
        if self.index >= self.results.as_ref().len() {
375
0
            self.core.generate(&mut self.results);
376
0
            self.index = 0;
377
0
        }
378
379
0
        let value = self.results.as_ref()[self.index];
380
0
        self.index += 1;
381
0
        self.half_used = false;
382
0
        value
383
0
    }
384
385
    #[inline]
386
0
    fn fill_bytes(&mut self, dest: &mut [u8]) {
387
0
        let mut read_len = 0;
388
0
        self.half_used = false;
389
0
        while read_len < dest.len() {
390
0
            if self.index as usize >= self.results.as_ref().len() {
391
0
                self.core.generate(&mut self.results);
392
0
                self.index = 0;
393
0
            }
394
395
0
            let (consumed_u64, filled_u8) = fill_via_u64_chunks(
396
0
                &self.results.as_ref()[self.index as usize..],
397
0
                &mut dest[read_len..],
398
0
            );
399
0
400
0
            self.index += consumed_u64;
401
0
            read_len += filled_u8;
402
        }
403
0
    }
404
405
    #[inline(always)]
406
0
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
407
0
        self.fill_bytes(dest);
408
0
        Ok(())
409
0
    }
410
}
411
412
impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng64<R> {
413
    type Seed = R::Seed;
414
415
    #[inline(always)]
416
0
    fn from_seed(seed: Self::Seed) -> Self {
417
0
        Self::new(R::from_seed(seed))
418
0
    }
419
420
    #[inline(always)]
421
0
    fn seed_from_u64(seed: u64) -> Self {
422
0
        Self::new(R::seed_from_u64(seed))
423
0
    }
424
425
    #[inline(always)]
426
0
    fn from_rng<S: RngCore>(rng: S) -> Result<Self, Error> {
427
0
        Ok(Self::new(R::from_rng(rng)?))
428
0
    }
429
}
430
431
impl<R: BlockRngCore + CryptoRng> CryptoRng for BlockRng<R> {}
432
433
#[cfg(test)]
434
mod test {
435
    use crate::{SeedableRng, RngCore};
436
    use crate::block::{BlockRng, BlockRng64, BlockRngCore};
437
438
    #[derive(Debug, Clone)]
439
    struct DummyRng {
440
        counter: u32,
441
    }
442
443
    impl BlockRngCore for DummyRng {
444
        type Item = u32;
445
446
        type Results = [u32; 16];
447
448
        fn generate(&mut self, results: &mut Self::Results) {
449
            for r in results {
450
                *r = self.counter;
451
                self.counter = self.counter.wrapping_add(3511615421);
452
            }
453
        }
454
    }
455
456
    impl SeedableRng for DummyRng {
457
        type Seed = [u8; 4];
458
459
        fn from_seed(seed: Self::Seed) -> Self {
460
            DummyRng { counter: u32::from_le_bytes(seed) }
461
        }
462
    }
463
464
    #[test]
465
    fn blockrng_next_u32_vs_next_u64() {
466
        let mut rng1 = BlockRng::<DummyRng>::from_seed([1, 2, 3, 4]);
467
        let mut rng2 = rng1.clone();
468
        let mut rng3 = rng1.clone();
469
470
        let mut a = [0; 16];
471
        (&mut a[..4]).copy_from_slice(&rng1.next_u32().to_le_bytes());
472
        (&mut a[4..12]).copy_from_slice(&rng1.next_u64().to_le_bytes());
473
        (&mut a[12..]).copy_from_slice(&rng1.next_u32().to_le_bytes());
474
475
        let mut b = [0; 16];
476
        (&mut b[..4]).copy_from_slice(&rng2.next_u32().to_le_bytes());
477
        (&mut b[4..8]).copy_from_slice(&rng2.next_u32().to_le_bytes());
478
        (&mut b[8..]).copy_from_slice(&rng2.next_u64().to_le_bytes());
479
        assert_eq!(a, b);
480
481
        let mut c = [0; 16];
482
        (&mut c[..8]).copy_from_slice(&rng3.next_u64().to_le_bytes());
483
        (&mut c[8..12]).copy_from_slice(&rng3.next_u32().to_le_bytes());
484
        (&mut c[12..]).copy_from_slice(&rng3.next_u32().to_le_bytes());
485
        assert_eq!(a, c);
486
    }
487
488
    #[derive(Debug, Clone)]
489
    struct DummyRng64 {
490
        counter: u64,
491
    }
492
493
    impl BlockRngCore for DummyRng64 {
494
        type Item = u64;
495
496
        type Results = [u64; 8];
497
498
        fn generate(&mut self, results: &mut Self::Results) {
499
            for r in results {
500
                *r = self.counter;
501
                self.counter = self.counter.wrapping_add(2781463553396133981);
502
            }
503
        }
504
    }
505
506
    impl SeedableRng for DummyRng64 {
507
        type Seed = [u8; 8];
508
509
        fn from_seed(seed: Self::Seed) -> Self {
510
            DummyRng64 { counter: u64::from_le_bytes(seed) }
511
        }
512
    }
513
514
    #[test]
515
    fn blockrng64_next_u32_vs_next_u64() {
516
        let mut rng1 = BlockRng64::<DummyRng64>::from_seed([1, 2, 3, 4, 5, 6, 7, 8]);
517
        let mut rng2 = rng1.clone();
518
        let mut rng3 = rng1.clone();
519
520
        let mut a = [0; 16];
521
        (&mut a[..4]).copy_from_slice(&rng1.next_u32().to_le_bytes());
522
        (&mut a[4..12]).copy_from_slice(&rng1.next_u64().to_le_bytes());
523
        (&mut a[12..]).copy_from_slice(&rng1.next_u32().to_le_bytes());
524
525
        let mut b = [0; 16];
526
        (&mut b[..4]).copy_from_slice(&rng2.next_u32().to_le_bytes());
527
        (&mut b[4..8]).copy_from_slice(&rng2.next_u32().to_le_bytes());
528
        (&mut b[8..]).copy_from_slice(&rng2.next_u64().to_le_bytes());
529
        assert_ne!(a, b);
530
        assert_eq!(&a[..4], &b[..4]);
531
        assert_eq!(&a[4..12], &b[8..]);
532
533
        let mut c = [0; 16];
534
        (&mut c[..8]).copy_from_slice(&rng3.next_u64().to_le_bytes());
535
        (&mut c[8..12]).copy_from_slice(&rng3.next_u32().to_le_bytes());
536
        (&mut c[12..]).copy_from_slice(&rng3.next_u32().to_le_bytes());
537
        assert_eq!(b, c);
538
    }
539
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rand_core-0.6.4/src/error.rs
Line
Count
Source
1
// Copyright 2018 Developers of the Rand project.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
//! Error types
10
11
use core::fmt;
12
use core::num::NonZeroU32;
13
14
#[cfg(feature = "std")] use std::boxed::Box;
15
16
/// Error type of random number generators
17
///
18
/// In order to be compatible with `std` and `no_std`, this type has two
19
/// possible implementations: with `std` a boxed `Error` trait object is stored,
20
/// while with `no_std` we merely store an error code.
21
pub struct Error {
22
    #[cfg(feature = "std")]
23
    inner: Box<dyn std::error::Error + Send + Sync + 'static>,
24
    #[cfg(not(feature = "std"))]
25
    code: NonZeroU32,
26
}
27
28
impl Error {
29
    /// Codes at or above this point can be used by users to define their own
30
    /// custom errors.
31
    ///
32
    /// This has a fixed value of `(1 << 31) + (1 << 30) = 0xC000_0000`,
33
    /// therefore the number of values available for custom codes is `1 << 30`.
34
    ///
35
    /// This is identical to [`getrandom::Error::CUSTOM_START`](https://docs.rs/getrandom/latest/getrandom/struct.Error.html#associatedconstant.CUSTOM_START).
36
    pub const CUSTOM_START: u32 = (1 << 31) + (1 << 30);
37
    /// Codes below this point represent OS Errors (i.e. positive i32 values).
38
    /// Codes at or above this point, but below [`Error::CUSTOM_START`] are
39
    /// reserved for use by the `rand` and `getrandom` crates.
40
    ///
41
    /// This is identical to [`getrandom::Error::INTERNAL_START`](https://docs.rs/getrandom/latest/getrandom/struct.Error.html#associatedconstant.INTERNAL_START).
42
    pub const INTERNAL_START: u32 = 1 << 31;
43
44
    /// Construct from any type supporting `std::error::Error`
45
    ///
46
    /// Available only when configured with `std`.
47
    ///
48
    /// See also `From<NonZeroU32>`, which is available with and without `std`.
49
    #[cfg(feature = "std")]
50
    #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
51
    #[inline]
52
0
    pub fn new<E>(err: E) -> Self
53
0
    where
54
0
        E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
55
0
    {
56
0
        Error { inner: err.into() }
57
0
    }
58
59
    /// Reference the inner error (`std` only)
60
    ///
61
    /// When configured with `std`, this is a trivial operation and never
62
    /// panics. Without `std`, this method is simply unavailable.
63
    #[cfg(feature = "std")]
64
    #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
65
    #[inline]
66
0
    pub fn inner(&self) -> &(dyn std::error::Error + Send + Sync + 'static) {
67
0
        &*self.inner
68
0
    }
69
70
    /// Unwrap the inner error (`std` only)
71
    ///
72
    /// When configured with `std`, this is a trivial operation and never
73
    /// panics. Without `std`, this method is simply unavailable.
74
    #[cfg(feature = "std")]
75
    #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
76
    #[inline]
77
0
    pub fn take_inner(self) -> Box<dyn std::error::Error + Send + Sync + 'static> {
78
0
        self.inner
79
0
    }
80
81
    /// Extract the raw OS error code (if this error came from the OS)
82
    ///
83
    /// This method is identical to `std::io::Error::raw_os_error()`, except
84
    /// that it works in `no_std` contexts. If this method returns `None`, the
85
    /// error value can still be formatted via the `Display` implementation.
86
    #[inline]
87
0
    pub fn raw_os_error(&self) -> Option<i32> {
88
        #[cfg(feature = "std")]
89
        {
90
0
            if let Some(e) = self.inner.downcast_ref::<std::io::Error>() {
91
0
                return e.raw_os_error();
92
0
            }
93
0
        }
94
0
        match self.code() {
95
0
            Some(code) if u32::from(code) < Self::INTERNAL_START => Some(u32::from(code) as i32),
96
0
            _ => None,
97
        }
98
0
    }
99
100
    /// Retrieve the error code, if any.
101
    ///
102
    /// If this `Error` was constructed via `From<NonZeroU32>`, then this method
103
    /// will return this `NonZeroU32` code (for `no_std` this is always the
104
    /// case). Otherwise, this method will return `None`.
105
    #[inline]
106
0
    pub fn code(&self) -> Option<NonZeroU32> {
107
0
        #[cfg(feature = "std")]
108
0
        {
109
0
            self.inner.downcast_ref::<ErrorCode>().map(|c| c.0)
110
0
        }
111
0
        #[cfg(not(feature = "std"))]
112
0
        {
113
0
            Some(self.code)
114
0
        }
115
0
    }
116
}
117
118
impl fmt::Debug for Error {
119
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
120
0
        #[cfg(feature = "std")]
121
0
        {
122
0
            write!(f, "Error {{ inner: {:?} }}", self.inner)
123
0
        }
124
0
        #[cfg(all(feature = "getrandom", not(feature = "std")))]
125
0
        {
126
0
            getrandom::Error::from(self.code).fmt(f)
127
0
        }
128
0
        #[cfg(not(feature = "getrandom"))]
129
0
        {
130
0
            write!(f, "Error {{ code: {} }}", self.code)
131
0
        }
132
0
    }
133
}
134
135
impl fmt::Display for Error {
136
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
137
0
        #[cfg(feature = "std")]
138
0
        {
139
0
            write!(f, "{}", self.inner)
140
0
        }
141
0
        #[cfg(all(feature = "getrandom", not(feature = "std")))]
142
0
        {
143
0
            getrandom::Error::from(self.code).fmt(f)
144
0
        }
145
0
        #[cfg(not(feature = "getrandom"))]
146
0
        {
147
0
            write!(f, "error code {}", self.code)
148
0
        }
149
0
    }
150
}
151
152
impl From<NonZeroU32> for Error {
153
    #[inline]
154
0
    fn from(code: NonZeroU32) -> Self {
155
0
        #[cfg(feature = "std")]
156
0
        {
157
0
            Error {
158
0
                inner: Box::new(ErrorCode(code)),
159
0
            }
160
0
        }
161
0
        #[cfg(not(feature = "std"))]
162
0
        {
163
0
            Error { code }
164
0
        }
165
0
    }
166
}
167
168
#[cfg(feature = "getrandom")]
169
impl From<getrandom::Error> for Error {
170
    #[inline]
171
0
    fn from(error: getrandom::Error) -> Self {
172
0
        #[cfg(feature = "std")]
173
0
        {
174
0
            Error {
175
0
                inner: Box::new(error),
176
0
            }
177
0
        }
178
0
        #[cfg(not(feature = "std"))]
179
0
        {
180
0
            Error { code: error.code() }
181
0
        }
182
0
    }
183
}
184
185
#[cfg(feature = "std")]
186
impl std::error::Error for Error {
187
    #[inline]
188
0
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
189
0
        self.inner.source()
190
0
    }
Unexecuted instantiation: _RNvXs3_NtCs7cRyI6h3MOh_9rand_core5errorNtB5_5ErrorNtNtCsbQ8arDwx5Xq_4core5error5Error6sourceB7_
Unexecuted instantiation: _RNvXs3_NtCs7cRyI6h3MOh_9rand_core5errorNtB5_5ErrorNtNtCsbQ8arDwx5Xq_4core5error5Error6sourceCs9XGzgUPXFy2_9signature
191
}
192
193
#[cfg(feature = "std")]
194
impl From<Error> for std::io::Error {
195
    #[inline]
196
0
    fn from(error: Error) -> Self {
197
0
        if let Some(code) = error.raw_os_error() {
198
0
            std::io::Error::from_raw_os_error(code)
199
        } else {
200
0
            std::io::Error::new(std::io::ErrorKind::Other, error)
201
        }
202
0
    }
203
}
204
205
#[cfg(feature = "std")]
206
#[derive(Debug, Copy, Clone)]
207
struct ErrorCode(NonZeroU32);
208
209
#[cfg(feature = "std")]
210
impl fmt::Display for ErrorCode {
211
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
212
0
        write!(f, "error code {}", self.0)
213
0
    }
214
}
215
216
#[cfg(feature = "std")]
217
impl std::error::Error for ErrorCode {}
218
219
#[cfg(test)]
220
mod test {
221
    #[cfg(feature = "getrandom")]
222
    #[test]
223
    fn test_error_codes() {
224
        // Make sure the values are the same as in `getrandom`.
225
        assert_eq!(super::Error::CUSTOM_START, getrandom::Error::CUSTOM_START);
226
        assert_eq!(super::Error::INTERNAL_START, getrandom::Error::INTERNAL_START);
227
    }
228
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rand_core-0.6.4/src/impls.rs
Line
Count
Source
1
// Copyright 2018 Developers of the Rand project.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
//! Helper functions for implementing `RngCore` functions.
10
//!
11
//! For cross-platform reproducibility, these functions all use Little Endian:
12
//! least-significant part first. For example, `next_u64_via_u32` takes `u32`
13
//! values `x, y`, then outputs `(y << 32) | x`. To implement `next_u32`
14
//! from `next_u64` in little-endian order, one should use `next_u64() as u32`.
15
//!
16
//! Byte-swapping (like the std `to_le` functions) is only needed to convert
17
//! to/from byte sequences, and since its purpose is reproducibility,
18
//! non-reproducible sources (e.g. `OsRng`) need not bother with it.
19
20
use crate::RngCore;
21
use core::cmp::min;
22
23
/// Implement `next_u64` via `next_u32`, little-endian order.
24
0
pub fn next_u64_via_u32<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
25
0
    // Use LE; we explicitly generate one value before the next.
26
0
    let x = u64::from(rng.next_u32());
27
0
    let y = u64::from(rng.next_u32());
28
0
    (y << 32) | x
29
0
}
30
31
/// Implement `fill_bytes` via `next_u64` and `next_u32`, little-endian order.
32
///
33
/// The fastest way to fill a slice is usually to work as long as possible with
34
/// integers. That is why this method mostly uses `next_u64`, and only when
35
/// there are 4 or less bytes remaining at the end of the slice it uses
36
/// `next_u32` once.
37
0
pub fn fill_bytes_via_next<R: RngCore + ?Sized>(rng: &mut R, dest: &mut [u8]) {
38
0
    let mut left = dest;
39
0
    while left.len() >= 8 {
40
0
        let (l, r) = { left }.split_at_mut(8);
41
0
        left = r;
42
0
        let chunk: [u8; 8] = rng.next_u64().to_le_bytes();
43
0
        l.copy_from_slice(&chunk);
44
0
    }
45
0
    let n = left.len();
46
0
    if n > 4 {
47
0
        let chunk: [u8; 8] = rng.next_u64().to_le_bytes();
48
0
        left.copy_from_slice(&chunk[..n]);
49
0
    } else if n > 0 {
50
0
        let chunk: [u8; 4] = rng.next_u32().to_le_bytes();
51
0
        left.copy_from_slice(&chunk[..n]);
52
0
    }
53
0
}
54
55
trait Observable: Copy {
56
    type Bytes: AsRef<[u8]>;
57
    fn to_le_bytes(self) -> Self::Bytes;
58
59
    // Contract: observing self is memory-safe (implies no uninitialised padding)
60
    fn as_byte_slice(x: &[Self]) -> &[u8];
61
}
62
impl Observable for u32 {
63
    type Bytes = [u8; 4];
64
0
    fn to_le_bytes(self) -> Self::Bytes {
65
0
        self.to_le_bytes()
66
0
    }
67
0
    fn as_byte_slice(x: &[Self]) -> &[u8] {
68
0
        let ptr = x.as_ptr() as *const u8;
69
0
        let len = x.len() * core::mem::size_of::<Self>();
70
0
        unsafe { core::slice::from_raw_parts(ptr, len) }
71
0
    }
72
}
73
impl Observable for u64 {
74
    type Bytes = [u8; 8];
75
0
    fn to_le_bytes(self) -> Self::Bytes {
76
0
        self.to_le_bytes()
77
0
    }
78
0
    fn as_byte_slice(x: &[Self]) -> &[u8] {
79
0
        let ptr = x.as_ptr() as *const u8;
80
0
        let len = x.len() * core::mem::size_of::<Self>();
81
0
        unsafe { core::slice::from_raw_parts(ptr, len) }
82
0
    }
83
}
84
85
0
fn fill_via_chunks<T: Observable>(src: &[T], dest: &mut [u8]) -> (usize, usize) {
86
0
    let size = core::mem::size_of::<T>();
87
0
    let byte_len = min(src.len() * size, dest.len());
88
0
    let num_chunks = (byte_len + size - 1) / size;
89
0
90
0
    if cfg!(target_endian = "little") {
91
0
        // On LE we can do a simple copy, which is 25-50% faster:
92
0
        dest[..byte_len].copy_from_slice(&T::as_byte_slice(&src[..num_chunks])[..byte_len]);
93
0
    } else {
94
        // This code is valid on all arches, but slower than the above:
95
0
        let mut i = 0;
96
0
        let mut iter = dest[..byte_len].chunks_exact_mut(size);
97
0
        for chunk in &mut iter {
98
0
            chunk.copy_from_slice(src[i].to_le_bytes().as_ref());
99
0
            i += 1;
100
0
        }
101
0
        let chunk = iter.into_remainder();
102
0
        if !chunk.is_empty() {
103
0
            chunk.copy_from_slice(&src[i].to_le_bytes().as_ref()[..chunk.len()]);
104
0
        }
105
    }
106
107
0
    (num_chunks, byte_len)
108
0
}
Unexecuted instantiation: _RINvNtCs7cRyI6h3MOh_9rand_core5impls15fill_via_chunksmEB4_
Unexecuted instantiation: _RINvNtCs7cRyI6h3MOh_9rand_core5impls15fill_via_chunksyEB4_
109
110
/// Implement `fill_bytes` by reading chunks from the output buffer of a block
111
/// based RNG.
112
///
113
/// The return values are `(consumed_u32, filled_u8)`.
114
///
115
/// `filled_u8` is the number of filled bytes in `dest`, which may be less than
116
/// the length of `dest`.
117
/// `consumed_u32` is the number of words consumed from `src`, which is the same
118
/// as `filled_u8 / 4` rounded up.
119
///
120
/// # Example
121
/// (from `IsaacRng`)
122
///
123
/// ```ignore
124
/// fn fill_bytes(&mut self, dest: &mut [u8]) {
125
///     let mut read_len = 0;
126
///     while read_len < dest.len() {
127
///         if self.index >= self.rsl.len() {
128
///             self.isaac();
129
///         }
130
///
131
///         let (consumed_u32, filled_u8) =
132
///             impls::fill_via_u32_chunks(&mut self.rsl[self.index..],
133
///                                        &mut dest[read_len..]);
134
///
135
///         self.index += consumed_u32;
136
///         read_len += filled_u8;
137
///     }
138
/// }
139
/// ```
140
0
pub fn fill_via_u32_chunks(src: &[u32], dest: &mut [u8]) -> (usize, usize) {
141
0
    fill_via_chunks(src, dest)
142
0
}
143
144
/// Implement `fill_bytes` by reading chunks from the output buffer of a block
145
/// based RNG.
146
///
147
/// The return values are `(consumed_u64, filled_u8)`.
148
/// `filled_u8` is the number of filled bytes in `dest`, which may be less than
149
/// the length of `dest`.
150
/// `consumed_u64` is the number of words consumed from `src`, which is the same
151
/// as `filled_u8 / 8` rounded up.
152
///
153
/// See `fill_via_u32_chunks` for an example.
154
0
pub fn fill_via_u64_chunks(src: &[u64], dest: &mut [u8]) -> (usize, usize) {
155
0
    fill_via_chunks(src, dest)
156
0
}
157
158
/// Implement `next_u32` via `fill_bytes`, little-endian order.
159
0
pub fn next_u32_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u32 {
160
0
    let mut buf = [0; 4];
161
0
    rng.fill_bytes(&mut buf);
162
0
    u32::from_le_bytes(buf)
163
0
}
164
165
/// Implement `next_u64` via `fill_bytes`, little-endian order.
166
0
pub fn next_u64_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
167
0
    let mut buf = [0; 8];
168
0
    rng.fill_bytes(&mut buf);
169
0
    u64::from_le_bytes(buf)
170
0
}
171
172
#[cfg(test)]
173
mod test {
174
    use super::*;
175
176
    #[test]
177
    fn test_fill_via_u32_chunks() {
178
        let src = [1, 2, 3];
179
        let mut dst = [0u8; 11];
180
        assert_eq!(fill_via_u32_chunks(&src, &mut dst), (3, 11));
181
        assert_eq!(dst, [1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0]);
182
183
        let mut dst = [0u8; 13];
184
        assert_eq!(fill_via_u32_chunks(&src, &mut dst), (3, 12));
185
        assert_eq!(dst, [1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0]);
186
187
        let mut dst = [0u8; 5];
188
        assert_eq!(fill_via_u32_chunks(&src, &mut dst), (2, 5));
189
        assert_eq!(dst, [1, 0, 0, 0, 2]);
190
    }
191
192
    #[test]
193
    fn test_fill_via_u64_chunks() {
194
        let src = [1, 2];
195
        let mut dst = [0u8; 11];
196
        assert_eq!(fill_via_u64_chunks(&src, &mut dst), (2, 11));
197
        assert_eq!(dst, [1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0]);
198
199
        let mut dst = [0u8; 17];
200
        assert_eq!(fill_via_u64_chunks(&src, &mut dst), (2, 16));
201
        assert_eq!(dst, [1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0]);
202
203
        let mut dst = [0u8; 5];
204
        assert_eq!(fill_via_u64_chunks(&src, &mut dst), (1, 5));
205
        assert_eq!(dst, [1, 0, 0, 0, 0]);
206
    }
207
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rand_core-0.6.4/src/le.rs
Line
Count
Source
1
// Copyright 2018 Developers of the Rand project.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
//! Little-Endian utilities
10
//!
11
//! Little-Endian order has been chosen for internal usage; this makes some
12
//! useful functions available.
13
14
use core::convert::TryInto;
15
16
/// Reads unsigned 32 bit integers from `src` into `dst`.
17
#[inline]
18
0
pub fn read_u32_into(src: &[u8], dst: &mut [u32]) {
19
0
    assert!(src.len() >= 4 * dst.len());
20
0
    for (out, chunk) in dst.iter_mut().zip(src.chunks_exact(4)) {
21
0
        *out = u32::from_le_bytes(chunk.try_into().unwrap());
22
0
    }
23
0
}
24
25
/// Reads unsigned 64 bit integers from `src` into `dst`.
26
#[inline]
27
0
pub fn read_u64_into(src: &[u8], dst: &mut [u64]) {
28
0
    assert!(src.len() >= 8 * dst.len());
29
0
    for (out, chunk) in dst.iter_mut().zip(src.chunks_exact(8)) {
30
0
        *out = u64::from_le_bytes(chunk.try_into().unwrap());
31
0
    }
32
0
}
33
34
#[test]
35
fn test_read() {
36
    let bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
37
38
    let mut buf = [0u32; 4];
39
    read_u32_into(&bytes, &mut buf);
40
    assert_eq!(buf[0], 0x04030201);
41
    assert_eq!(buf[3], 0x100F0E0D);
42
43
    let mut buf = [0u32; 3];
44
    read_u32_into(&bytes[1..13], &mut buf); // unaligned
45
    assert_eq!(buf[0], 0x05040302);
46
    assert_eq!(buf[2], 0x0D0C0B0A);
47
48
    let mut buf = [0u64; 2];
49
    read_u64_into(&bytes, &mut buf);
50
    assert_eq!(buf[0], 0x0807060504030201);
51
    assert_eq!(buf[1], 0x100F0E0D0C0B0A09);
52
53
    let mut buf = [0u64; 1];
54
    read_u64_into(&bytes[7..15], &mut buf); // unaligned
55
    assert_eq!(buf[0], 0x0F0E0D0C0B0A0908);
56
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rand_core-0.6.4/src/lib.rs
Line
Count
Source
1
// Copyright 2018 Developers of the Rand project.
2
// Copyright 2017-2018 The Rust Project Developers.
3
//
4
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7
// option. This file may not be copied, modified, or distributed
8
// except according to those terms.
9
10
//! Random number generation traits
11
//!
12
//! This crate is mainly of interest to crates publishing implementations of
13
//! [`RngCore`]. Other users are encouraged to use the [`rand`] crate instead
14
//! which re-exports the main traits and error types.
15
//!
16
//! [`RngCore`] is the core trait implemented by algorithmic pseudo-random number
17
//! generators and external random-number sources.
18
//!
19
//! [`SeedableRng`] is an extension trait for construction from fixed seeds and
20
//! other random number generators.
21
//!
22
//! [`Error`] is provided for error-handling. It is safe to use in `no_std`
23
//! environments.
24
//!
25
//! The [`impls`] and [`le`] sub-modules include a few small functions to assist
26
//! implementation of [`RngCore`].
27
//!
28
//! [`rand`]: https://docs.rs/rand
29
30
#![doc(
31
    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
32
    html_favicon_url = "https://www.rust-lang.org/favicon.ico",
33
    html_root_url = "https://rust-random.github.io/rand/"
34
)]
35
#![deny(missing_docs)]
36
#![deny(missing_debug_implementations)]
37
#![doc(test(attr(allow(unused_variables), deny(warnings))))]
38
#![cfg_attr(doc_cfg, feature(doc_cfg))]
39
#![no_std]
40
41
use core::convert::AsMut;
42
use core::default::Default;
43
44
#[cfg(feature = "std")] extern crate std;
45
#[cfg(feature = "alloc")] extern crate alloc;
46
#[cfg(feature = "alloc")] use alloc::boxed::Box;
47
48
pub use error::Error;
49
#[cfg(feature = "getrandom")] pub use os::OsRng;
50
51
52
pub mod block;
53
mod error;
54
pub mod impls;
55
pub mod le;
56
#[cfg(feature = "getrandom")] mod os;
57
58
59
/// The core of a random number generator.
60
///
61
/// This trait encapsulates the low-level functionality common to all
62
/// generators, and is the "back end", to be implemented by generators.
63
/// End users should normally use the `Rng` trait from the [`rand`] crate,
64
/// which is automatically implemented for every type implementing `RngCore`.
65
///
66
/// Three different methods for generating random data are provided since the
67
/// optimal implementation of each is dependent on the type of generator. There
68
/// is no required relationship between the output of each; e.g. many
69
/// implementations of [`fill_bytes`] consume a whole number of `u32` or `u64`
70
/// values and drop any remaining unused bytes. The same can happen with the
71
/// [`next_u32`] and [`next_u64`] methods, implementations may discard some
72
/// random bits for efficiency.
73
///
74
/// The [`try_fill_bytes`] method is a variant of [`fill_bytes`] allowing error
75
/// handling; it is not deemed sufficiently useful to add equivalents for
76
/// [`next_u32`] or [`next_u64`] since the latter methods are almost always used
77
/// with algorithmic generators (PRNGs), which are normally infallible.
78
///
79
/// Implementers should produce bits uniformly. Pathological RNGs (e.g. always
80
/// returning the same value, or never setting certain bits) can break rejection
81
/// sampling used by random distributions, and also break other RNGs when
82
/// seeding them via [`SeedableRng::from_rng`].
83
///
84
/// Algorithmic generators implementing [`SeedableRng`] should normally have
85
/// *portable, reproducible* output, i.e. fix Endianness when converting values
86
/// to avoid platform differences, and avoid making any changes which affect
87
/// output (except by communicating that the release has breaking changes).
88
///
89
/// Typically an RNG will implement only one of the methods available
90
/// in this trait directly, then use the helper functions from the
91
/// [`impls`] module to implement the other methods.
92
///
93
/// It is recommended that implementations also implement:
94
///
95
/// - `Debug` with a custom implementation which *does not* print any internal
96
///   state (at least, [`CryptoRng`]s should not risk leaking state through
97
///   `Debug`).
98
/// - `Serialize` and `Deserialize` (from Serde), preferably making Serde
99
///   support optional at the crate level in PRNG libs.
100
/// - `Clone`, if possible.
101
/// - *never* implement `Copy` (accidental copies may cause repeated values).
102
/// - *do not* implement `Default` for pseudorandom generators, but instead
103
///   implement [`SeedableRng`], to guide users towards proper seeding.
104
///   External / hardware RNGs can choose to implement `Default`.
105
/// - `Eq` and `PartialEq` could be implemented, but are probably not useful.
106
///
107
/// # Example
108
///
109
/// A simple example, obviously not generating very *random* output:
110
///
111
/// ```
112
/// #![allow(dead_code)]
113
/// use rand_core::{RngCore, Error, impls};
114
///
115
/// struct CountingRng(u64);
116
///
117
/// impl RngCore for CountingRng {
118
///     fn next_u32(&mut self) -> u32 {
119
///         self.next_u64() as u32
120
///     }
121
///
122
///     fn next_u64(&mut self) -> u64 {
123
///         self.0 += 1;
124
///         self.0
125
///     }
126
///
127
///     fn fill_bytes(&mut self, dest: &mut [u8]) {
128
///         impls::fill_bytes_via_next(self, dest)
129
///     }
130
///
131
///     fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
132
///         Ok(self.fill_bytes(dest))
133
///     }
134
/// }
135
/// ```
136
///
137
/// [`rand`]: https://docs.rs/rand
138
/// [`try_fill_bytes`]: RngCore::try_fill_bytes
139
/// [`fill_bytes`]: RngCore::fill_bytes
140
/// [`next_u32`]: RngCore::next_u32
141
/// [`next_u64`]: RngCore::next_u64
142
pub trait RngCore {
143
    /// Return the next random `u32`.
144
    ///
145
    /// RNGs must implement at least one method from this trait directly. In
146
    /// the case this method is not implemented directly, it can be implemented
147
    /// using `self.next_u64() as u32` or via [`impls::next_u32_via_fill`].
148
    fn next_u32(&mut self) -> u32;
149
150
    /// Return the next random `u64`.
151
    ///
152
    /// RNGs must implement at least one method from this trait directly. In
153
    /// the case this method is not implemented directly, it can be implemented
154
    /// via [`impls::next_u64_via_u32`] or via [`impls::next_u64_via_fill`].
155
    fn next_u64(&mut self) -> u64;
156
157
    /// Fill `dest` with random data.
158
    ///
159
    /// RNGs must implement at least one method from this trait directly. In
160
    /// the case this method is not implemented directly, it can be implemented
161
    /// via [`impls::fill_bytes_via_next`] or
162
    /// via [`RngCore::try_fill_bytes`]; if this generator can
163
    /// fail the implementation must choose how best to handle errors here
164
    /// (e.g. panic with a descriptive message or log a warning and retry a few
165
    /// times).
166
    ///
167
    /// This method should guarantee that `dest` is entirely filled
168
    /// with new data, and may panic if this is impossible
169
    /// (e.g. reading past the end of a file that is being used as the
170
    /// source of randomness).
171
    fn fill_bytes(&mut self, dest: &mut [u8]);
172
173
    /// Fill `dest` entirely with random data.
174
    ///
175
    /// This is the only method which allows an RNG to report errors while
176
    /// generating random data thus making this the primary method implemented
177
    /// by external (true) RNGs (e.g. `OsRng`) which can fail. It may be used
178
    /// directly to generate keys and to seed (infallible) PRNGs.
179
    ///
180
    /// Other than error handling, this method is identical to [`RngCore::fill_bytes`];
181
    /// thus this may be implemented using `Ok(self.fill_bytes(dest))` or
182
    /// `fill_bytes` may be implemented with
183
    /// `self.try_fill_bytes(dest).unwrap()` or more specific error handling.
184
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>;
185
}
186
187
/// A marker trait used to indicate that an [`RngCore`] or [`BlockRngCore`]
188
/// implementation is supposed to be cryptographically secure.
189
///
190
/// *Cryptographically secure generators*, also known as *CSPRNGs*, should
191
/// satisfy an additional properties over other generators: given the first
192
/// *k* bits of an algorithm's output
193
/// sequence, it should not be possible using polynomial-time algorithms to
194
/// predict the next bit with probability significantly greater than 50%.
195
///
196
/// Some generators may satisfy an additional property, however this is not
197
/// required by this trait: if the CSPRNG's state is revealed, it should not be
198
/// computationally-feasible to reconstruct output prior to this. Some other
199
/// generators allow backwards-computation and are considered *reversible*.
200
///
201
/// Note that this trait is provided for guidance only and cannot guarantee
202
/// suitability for cryptographic applications. In general it should only be
203
/// implemented for well-reviewed code implementing well-regarded algorithms.
204
///
205
/// Note also that use of a `CryptoRng` does not protect against other
206
/// weaknesses such as seeding from a weak entropy source or leaking state.
207
///
208
/// [`BlockRngCore`]: block::BlockRngCore
209
pub trait CryptoRng {}
210
211
/// An extension trait that is automatically implemented for any type
212
/// implementing [`RngCore`] and [`CryptoRng`].
213
///
214
/// It may be used as a trait object, and supports upcasting to [`RngCore`] via
215
/// the [`CryptoRngCore::as_rngcore`] method.
216
///
217
/// # Example
218
///
219
/// ```
220
/// use rand_core::CryptoRngCore;
221
///
222
/// #[allow(unused)]
223
/// fn make_token(rng: &mut dyn CryptoRngCore) -> [u8; 32] {
224
///     let mut buf = [0u8; 32];
225
///     rng.fill_bytes(&mut buf);
226
///     buf
227
/// }
228
/// ```
229
pub trait CryptoRngCore: CryptoRng + RngCore {
230
    /// Upcast to an [`RngCore`] trait object.
231
    fn as_rngcore(&mut self) -> &mut dyn RngCore;
232
}
233
234
impl<T: CryptoRng + RngCore> CryptoRngCore for T {
235
0
    fn as_rngcore(&mut self) -> &mut dyn RngCore {
236
0
        self
237
0
    }
238
}
239
240
/// A random number generator that can be explicitly seeded.
241
///
242
/// This trait encapsulates the low-level functionality common to all
243
/// pseudo-random number generators (PRNGs, or algorithmic generators).
244
///
245
/// [`rand`]: https://docs.rs/rand
246
pub trait SeedableRng: Sized {
247
    /// Seed type, which is restricted to types mutably-dereferenceable as `u8`
248
    /// arrays (we recommend `[u8; N]` for some `N`).
249
    ///
250
    /// It is recommended to seed PRNGs with a seed of at least circa 100 bits,
251
    /// which means an array of `[u8; 12]` or greater to avoid picking RNGs with
252
    /// partially overlapping periods.
253
    ///
254
    /// For cryptographic RNG's a seed of 256 bits is recommended, `[u8; 32]`.
255
    ///
256
    ///
257
    /// # Implementing `SeedableRng` for RNGs with large seeds
258
    ///
259
    /// Note that the required traits `core::default::Default` and
260
    /// `core::convert::AsMut<u8>` are not implemented for large arrays
261
    /// `[u8; N]` with `N` > 32. To be able to implement the traits required by
262
    /// `SeedableRng` for RNGs with such large seeds, the newtype pattern can be
263
    /// used:
264
    ///
265
    /// ```
266
    /// use rand_core::SeedableRng;
267
    ///
268
    /// const N: usize = 64;
269
    /// pub struct MyRngSeed(pub [u8; N]);
270
    /// pub struct MyRng(MyRngSeed);
271
    ///
272
    /// impl Default for MyRngSeed {
273
    ///     fn default() -> MyRngSeed {
274
    ///         MyRngSeed([0; N])
275
    ///     }
276
    /// }
277
    ///
278
    /// impl AsMut<[u8]> for MyRngSeed {
279
    ///     fn as_mut(&mut self) -> &mut [u8] {
280
    ///         &mut self.0
281
    ///     }
282
    /// }
283
    ///
284
    /// impl SeedableRng for MyRng {
285
    ///     type Seed = MyRngSeed;
286
    ///
287
    ///     fn from_seed(seed: MyRngSeed) -> MyRng {
288
    ///         MyRng(seed)
289
    ///     }
290
    /// }
291
    /// ```
292
    type Seed: Sized + Default + AsMut<[u8]>;
293
294
    /// Create a new PRNG using the given seed.
295
    ///
296
    /// PRNG implementations are allowed to assume that bits in the seed are
297
    /// well distributed. That means usually that the number of one and zero
298
    /// bits are roughly equal, and values like 0, 1 and (size - 1) are unlikely.
299
    /// Note that many non-cryptographic PRNGs will show poor quality output
300
    /// if this is not adhered to. If you wish to seed from simple numbers, use
301
    /// `seed_from_u64` instead.
302
    ///
303
    /// All PRNG implementations should be reproducible unless otherwise noted:
304
    /// given a fixed `seed`, the same sequence of output should be produced
305
    /// on all runs, library versions and architectures (e.g. check endianness).
306
    /// Any "value-breaking" changes to the generator should require bumping at
307
    /// least the minor version and documentation of the change.
308
    ///
309
    /// It is not required that this function yield the same state as a
310
    /// reference implementation of the PRNG given equivalent seed; if necessary
311
    /// another constructor replicating behaviour from a reference
312
    /// implementation can be added.
313
    ///
314
    /// PRNG implementations should make sure `from_seed` never panics. In the
315
    /// case that some special values (like an all zero seed) are not viable
316
    /// seeds it is preferable to map these to alternative constant value(s),
317
    /// for example `0xBAD5EEDu32` or `0x0DDB1A5E5BAD5EEDu64` ("odd biases? bad
318
    /// seed"). This is assuming only a small number of values must be rejected.
319
    fn from_seed(seed: Self::Seed) -> Self;
320
321
    /// Create a new PRNG using a `u64` seed.
322
    ///
323
    /// This is a convenience-wrapper around `from_seed` to allow construction
324
    /// of any `SeedableRng` from a simple `u64` value. It is designed such that
325
    /// low Hamming Weight numbers like 0 and 1 can be used and should still
326
    /// result in good, independent seeds to the PRNG which is returned.
327
    ///
328
    /// This **is not suitable for cryptography**, as should be clear given that
329
    /// the input size is only 64 bits.
330
    ///
331
    /// Implementations for PRNGs *may* provide their own implementations of
332
    /// this function, but the default implementation should be good enough for
333
    /// all purposes. *Changing* the implementation of this function should be
334
    /// considered a value-breaking change.
335
0
    fn seed_from_u64(mut state: u64) -> Self {
336
        // We use PCG32 to generate a u32 sequence, and copy to the seed
337
0
        fn pcg32(state: &mut u64) -> [u8; 4] {
338
            const MUL: u64 = 6364136223846793005;
339
            const INC: u64 = 11634580027462260723;
340
341
            // We advance the state first (to get away from the input value,
342
            // in case it has low Hamming Weight).
343
0
            *state = state.wrapping_mul(MUL).wrapping_add(INC);
344
0
            let state = *state;
345
0
346
0
            // Use PCG output function with to_le to generate x:
347
0
            let xorshifted = (((state >> 18) ^ state) >> 27) as u32;
348
0
            let rot = (state >> 59) as u32;
349
0
            let x = xorshifted.rotate_right(rot);
350
0
            x.to_le_bytes()
351
0
        }
352
353
0
        let mut seed = Self::Seed::default();
354
0
        let mut iter = seed.as_mut().chunks_exact_mut(4);
355
0
        for chunk in &mut iter {
356
0
            chunk.copy_from_slice(&pcg32(&mut state));
357
0
        }
358
0
        let rem = iter.into_remainder();
359
0
        if !rem.is_empty() {
360
0
            rem.copy_from_slice(&pcg32(&mut state)[..rem.len()]);
361
0
        }
362
363
0
        Self::from_seed(seed)
364
0
    }
365
366
    /// Create a new PRNG seeded from another `Rng`.
367
    ///
368
    /// This may be useful when needing to rapidly seed many PRNGs from a master
369
    /// PRNG, and to allow forking of PRNGs. It may be considered deterministic.
370
    ///
371
    /// The master PRNG should be at least as high quality as the child PRNGs.
372
    /// When seeding non-cryptographic child PRNGs, we recommend using a
373
    /// different algorithm for the master PRNG (ideally a CSPRNG) to avoid
374
    /// correlations between the child PRNGs. If this is not possible (e.g.
375
    /// forking using small non-crypto PRNGs) ensure that your PRNG has a good
376
    /// mixing function on the output or consider use of a hash function with
377
    /// `from_seed`.
378
    ///
379
    /// Note that seeding `XorShiftRng` from another `XorShiftRng` provides an
380
    /// extreme example of what can go wrong: the new PRNG will be a clone
381
    /// of the parent.
382
    ///
383
    /// PRNG implementations are allowed to assume that a good RNG is provided
384
    /// for seeding, and that it is cryptographically secure when appropriate.
385
    /// As of `rand` 0.7 / `rand_core` 0.5, implementations overriding this
386
    /// method should ensure the implementation satisfies reproducibility
387
    /// (in prior versions this was not required).
388
    ///
389
    /// [`rand`]: https://docs.rs/rand
390
0
    fn from_rng<R: RngCore>(mut rng: R) -> Result<Self, Error> {
391
0
        let mut seed = Self::Seed::default();
392
0
        rng.try_fill_bytes(seed.as_mut())?;
393
0
        Ok(Self::from_seed(seed))
394
0
    }
395
396
    /// Creates a new instance of the RNG seeded via [`getrandom`].
397
    ///
398
    /// This method is the recommended way to construct non-deterministic PRNGs
399
    /// since it is convenient and secure.
400
    ///
401
    /// In case the overhead of using [`getrandom`] to seed *many* PRNGs is an
402
    /// issue, one may prefer to seed from a local PRNG, e.g.
403
    /// `from_rng(thread_rng()).unwrap()`.
404
    ///
405
    /// # Panics
406
    ///
407
    /// If [`getrandom`] is unable to provide secure entropy this method will panic.
408
    ///
409
    /// [`getrandom`]: https://docs.rs/getrandom
410
    #[cfg(feature = "getrandom")]
411
    #[cfg_attr(doc_cfg, doc(cfg(feature = "getrandom")))]
412
0
    fn from_entropy() -> Self {
413
0
        let mut seed = Self::Seed::default();
414
0
        if let Err(err) = getrandom::getrandom(seed.as_mut()) {
415
0
            panic!("from_entropy failed: {}", err);
416
0
        }
417
0
        Self::from_seed(seed)
418
0
    }
419
}
420
421
// Implement `RngCore` for references to an `RngCore`.
422
// Force inlining all functions, so that it is up to the `RngCore`
423
// implementation and the optimizer to decide on inlining.
424
impl<'a, R: RngCore + ?Sized> RngCore for &'a mut R {
425
    #[inline(always)]
426
0
    fn next_u32(&mut self) -> u32 {
427
0
        (**self).next_u32()
428
0
    }
429
430
    #[inline(always)]
431
0
    fn next_u64(&mut self) -> u64 {
432
0
        (**self).next_u64()
433
0
    }
434
435
    #[inline(always)]
436
0
    fn fill_bytes(&mut self, dest: &mut [u8]) {
437
0
        (**self).fill_bytes(dest)
438
0
    }
439
440
    #[inline(always)]
441
0
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
442
0
        (**self).try_fill_bytes(dest)
443
0
    }
444
}
445
446
// Implement `RngCore` for boxed references to an `RngCore`.
447
// Force inlining all functions, so that it is up to the `RngCore`
448
// implementation and the optimizer to decide on inlining.
449
#[cfg(feature = "alloc")]
450
impl<R: RngCore + ?Sized> RngCore for Box<R> {
451
    #[inline(always)]
452
0
    fn next_u32(&mut self) -> u32 {
453
0
        (**self).next_u32()
454
0
    }
455
456
    #[inline(always)]
457
0
    fn next_u64(&mut self) -> u64 {
458
0
        (**self).next_u64()
459
0
    }
460
461
    #[inline(always)]
462
0
    fn fill_bytes(&mut self, dest: &mut [u8]) {
463
0
        (**self).fill_bytes(dest)
464
0
    }
465
466
    #[inline(always)]
467
0
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
468
0
        (**self).try_fill_bytes(dest)
469
0
    }
470
}
471
472
#[cfg(feature = "std")]
473
impl std::io::Read for dyn RngCore {
474
0
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
475
0
        self.try_fill_bytes(buf)?;
476
0
        Ok(buf.len())
477
0
    }
478
}
479
480
// Implement `CryptoRng` for references to a `CryptoRng`.
481
impl<'a, R: CryptoRng + ?Sized> CryptoRng for &'a mut R {}
482
483
// Implement `CryptoRng` for boxed references to a `CryptoRng`.
484
#[cfg(feature = "alloc")]
485
impl<R: CryptoRng + ?Sized> CryptoRng for Box<R> {}
486
487
#[cfg(test)]
488
mod test {
489
    use super::*;
490
491
    #[test]
492
    fn test_seed_from_u64() {
493
        struct SeedableNum(u64);
494
        impl SeedableRng for SeedableNum {
495
            type Seed = [u8; 8];
496
497
            fn from_seed(seed: Self::Seed) -> Self {
498
                let mut x = [0u64; 1];
499
                le::read_u64_into(&seed, &mut x);
500
                SeedableNum(x[0])
501
            }
502
        }
503
504
        const N: usize = 8;
505
        const SEEDS: [u64; N] = [0u64, 1, 2, 3, 4, 8, 16, -1i64 as u64];
506
        let mut results = [0u64; N];
507
        for (i, seed) in SEEDS.iter().enumerate() {
508
            let SeedableNum(x) = SeedableNum::seed_from_u64(*seed);
509
            results[i] = x;
510
        }
511
512
        for (i1, r1) in results.iter().enumerate() {
513
            let weight = r1.count_ones();
514
            // This is the binomial distribution B(64, 0.5), so chance of
515
            // weight < 20 is binocdf(19, 64, 0.5) = 7.8e-4, and same for
516
            // weight > 44.
517
            assert!((20..=44).contains(&weight));
518
519
            for (i2, r2) in results.iter().enumerate() {
520
                if i1 == i2 {
521
                    continue;
522
                }
523
                let diff_weight = (r1 ^ r2).count_ones();
524
                assert!(diff_weight >= 20);
525
            }
526
        }
527
528
        // value-breakage test:
529
        assert_eq!(results[0], 5029875928683246316);
530
    }
531
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rand_core-0.6.4/src/os.rs
Line
Count
Source
1
// Copyright 2019 Developers of the Rand project.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
//! Interface to the random number generator of the operating system.
10
11
use crate::{impls, CryptoRng, Error, RngCore};
12
use getrandom::getrandom;
13
14
/// A random number generator that retrieves randomness from the
15
/// operating system.
16
///
17
/// This is a zero-sized struct. It can be freely constructed with `OsRng`.
18
///
19
/// The implementation is provided by the [getrandom] crate. Refer to
20
/// [getrandom] documentation for details.
21
///
22
/// This struct is only available when specifying the crate feature `getrandom`
23
/// or `std`. When using the `rand` lib, it is also available as `rand::rngs::OsRng`.
24
///
25
/// # Blocking and error handling
26
///
27
/// It is possible that when used during early boot the first call to `OsRng`
28
/// will block until the system's RNG is initialised. It is also possible
29
/// (though highly unlikely) for `OsRng` to fail on some platforms, most
30
/// likely due to system mis-configuration.
31
///
32
/// After the first successful call, it is highly unlikely that failures or
33
/// significant delays will occur (although performance should be expected to
34
/// be much slower than a user-space PRNG).
35
///
36
/// # Usage example
37
/// ```
38
/// use rand_core::{RngCore, OsRng};
39
///
40
/// let mut key = [0u8; 16];
41
/// OsRng.fill_bytes(&mut key);
42
/// let random_u64 = OsRng.next_u64();
43
/// ```
44
///
45
/// [getrandom]: https://crates.io/crates/getrandom
46
#[cfg_attr(doc_cfg, doc(cfg(feature = "getrandom")))]
47
#[derive(Clone, Copy, Debug, Default)]
48
pub struct OsRng;
49
50
impl CryptoRng for OsRng {}
51
52
impl RngCore for OsRng {
53
0
    fn next_u32(&mut self) -> u32 {
54
0
        impls::next_u32_via_fill(self)
55
0
    }
56
57
0
    fn next_u64(&mut self) -> u64 {
58
0
        impls::next_u64_via_fill(self)
59
0
    }
60
61
0
    fn fill_bytes(&mut self, dest: &mut [u8]) {
62
0
        if let Err(e) = self.try_fill_bytes(dest) {
63
0
            panic!("Error: {}", e);
64
0
        }
65
0
    }
66
67
0
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
68
0
        getrandom(dest)?;
69
0
        Ok(())
70
0
    }
71
}
72
73
#[test]
74
fn test_os_rng() {
75
    let x = OsRng.next_u64();
76
    let y = OsRng.next_u64();
77
    assert!(x != 0);
78
    assert!(x != y);
79
}
80
81
#[test]
82
fn test_construction() {
83
    let mut rng = OsRng::default();
84
    assert!(rng.next_u64() != 0);
85
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rfc6979-0.4.0/src/ct_cmp.rs
Line
Count
Source
1
//! Constant-time comparison helpers for [`ByteArray`].
2
3
use crate::{ArrayLength, ByteArray};
4
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
5
6
/// Constant-time equals.
7
0
pub(crate) fn ct_eq<N: ArrayLength<u8>>(a: &ByteArray<N>, b: &ByteArray<N>) -> Choice {
8
0
    let mut ret = Choice::from(1);
9
10
0
    for (a, b) in a.iter().zip(b.iter()) {
11
0
        ret.conditional_assign(&Choice::from(0), !a.ct_eq(b));
12
0
    }
13
14
0
    ret
15
0
}
16
17
/// Constant-time less than.
18
///
19
/// Inputs are interpreted as big endian integers.
20
0
pub(crate) fn ct_lt<N: ArrayLength<u8>>(a: &ByteArray<N>, b: &ByteArray<N>) -> Choice {
21
0
    let mut borrow = 0;
22
23
    // Perform subtraction with borrow a byte-at-a-time, interpreting a
24
    // no-borrow condition as the less-than case
25
0
    for (&a, &b) in a.iter().zip(b.iter()).rev() {
26
0
        let c = (b as u16).wrapping_add(borrow >> (u8::BITS - 1));
27
0
        borrow = (a as u16).wrapping_sub(c) >> u8::BITS as u8;
28
0
    }
29
30
0
    !borrow.ct_eq(&0)
31
0
}
32
33
#[cfg(test)]
34
mod tests {
35
    const A: [u8; 4] = [0, 0, 0, 0];
36
    const B: [u8; 4] = [0, 0, 0, 1];
37
    const C: [u8; 4] = [0xFF, 0, 0, 0];
38
    const D: [u8; 4] = [0xFF, 0, 0, 1];
39
    const E: [u8; 4] = [0xFF, 0xFF, 0xFF, 0xFE];
40
    const F: [u8; 4] = [0xFF, 0xFF, 0xFF, 0xFF];
41
42
    #[test]
43
    fn ct_eq() {
44
        use super::ct_eq;
45
46
        assert_eq!(ct_eq(&A.into(), &A.into()).unwrap_u8(), 1);
47
        assert_eq!(ct_eq(&B.into(), &B.into()).unwrap_u8(), 1);
48
        assert_eq!(ct_eq(&C.into(), &C.into()).unwrap_u8(), 1);
49
        assert_eq!(ct_eq(&D.into(), &D.into()).unwrap_u8(), 1);
50
        assert_eq!(ct_eq(&E.into(), &E.into()).unwrap_u8(), 1);
51
        assert_eq!(ct_eq(&F.into(), &F.into()).unwrap_u8(), 1);
52
53
        assert_eq!(ct_eq(&A.into(), &B.into()).unwrap_u8(), 0);
54
        assert_eq!(ct_eq(&C.into(), &D.into()).unwrap_u8(), 0);
55
        assert_eq!(ct_eq(&E.into(), &F.into()).unwrap_u8(), 0);
56
    }
57
58
    #[test]
59
    fn ct_lt() {
60
        use super::ct_lt;
61
62
        assert_eq!(ct_lt(&A.into(), &A.into()).unwrap_u8(), 0);
63
        assert_eq!(ct_lt(&B.into(), &B.into()).unwrap_u8(), 0);
64
        assert_eq!(ct_lt(&C.into(), &C.into()).unwrap_u8(), 0);
65
        assert_eq!(ct_lt(&D.into(), &D.into()).unwrap_u8(), 0);
66
        assert_eq!(ct_lt(&E.into(), &E.into()).unwrap_u8(), 0);
67
        assert_eq!(ct_lt(&F.into(), &F.into()).unwrap_u8(), 0);
68
69
        assert_eq!(ct_lt(&A.into(), &B.into()).unwrap_u8(), 1);
70
        assert_eq!(ct_lt(&A.into(), &C.into()).unwrap_u8(), 1);
71
        assert_eq!(ct_lt(&B.into(), &A.into()).unwrap_u8(), 0);
72
        assert_eq!(ct_lt(&C.into(), &A.into()).unwrap_u8(), 0);
73
74
        assert_eq!(ct_lt(&B.into(), &C.into()).unwrap_u8(), 1);
75
        assert_eq!(ct_lt(&B.into(), &D.into()).unwrap_u8(), 1);
76
        assert_eq!(ct_lt(&C.into(), &B.into()).unwrap_u8(), 0);
77
        assert_eq!(ct_lt(&D.into(), &B.into()).unwrap_u8(), 0);
78
79
        assert_eq!(ct_lt(&C.into(), &D.into()).unwrap_u8(), 1);
80
        assert_eq!(ct_lt(&C.into(), &E.into()).unwrap_u8(), 1);
81
        assert_eq!(ct_lt(&D.into(), &C.into()).unwrap_u8(), 0);
82
        assert_eq!(ct_lt(&E.into(), &C.into()).unwrap_u8(), 0);
83
84
        assert_eq!(ct_lt(&E.into(), &F.into()).unwrap_u8(), 1);
85
        assert_eq!(ct_lt(&F.into(), &E.into()).unwrap_u8(), 0);
86
    }
87
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rfc6979-0.4.0/src/lib.rs
Line
Count
Source
1
#![no_std]
2
#![doc = include_str!("../README.md")]
3
#![forbid(unsafe_code, clippy::unwrap_used)]
4
#![warn(missing_docs, rust_2018_idioms)]
5
#![doc(
6
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
7
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
8
)]
9
10
//! ## Usage
11
//!
12
//! See also: the documentation for the [`generate_k`] function.
13
//!
14
//! ```
15
//! use hex_literal::hex;
16
//! use rfc6979::consts::U32;
17
//! use sha2::{Digest, Sha256};
18
//!
19
//! // NIST P-256 field modulus
20
//! const NIST_P256_MODULUS: [u8; 32] =
21
//!     hex!("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
22
//!
23
//! // Public key for RFC6979 NIST P256/SHA256 test case
24
//! const RFC6979_KEY: [u8; 32] =
25
//!     hex!("C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721");
26
//!
27
//! // Test message for RFC6979 NIST P256/SHA256 test case
28
//! const RFC6979_MSG: &[u8; 6] = b"sample";
29
//!
30
//! // Expected K for RFC6979 NIST P256/SHA256 test case
31
//! const RFC6979_EXPECTED_K: [u8; 32] =
32
//!     hex!("A6E3C57DD01ABE90086538398355DD4C3B17AA873382B0F24D6129493D8AAD60");
33
//!
34
//! let h = Sha256::digest(RFC6979_MSG);
35
//! let aad = b"";
36
//! let k = rfc6979::generate_k::<Sha256, U32>(&RFC6979_KEY.into(), &NIST_P256_MODULUS.into(), &h, aad);
37
//! assert_eq!(k.as_slice(), &RFC6979_EXPECTED_K);
38
//! ```
39
40
mod ct_cmp;
41
42
pub use hmac::digest::generic_array::typenum::consts;
43
44
use hmac::{
45
    digest::{
46
        core_api::BlockSizeUser,
47
        generic_array::{ArrayLength, GenericArray},
48
        Digest, FixedOutput, FixedOutputReset, Mac,
49
    },
50
    SimpleHmac,
51
};
52
53
/// Array of bytes representing a scalar serialized as a big endian integer.
54
pub type ByteArray<Size> = GenericArray<u8, Size>;
55
56
/// Deterministically generate ephemeral scalar `k`.
57
///
58
/// Accepts the following parameters and inputs:
59
///
60
/// - `x`: secret key
61
/// - `n`: field modulus
62
/// - `h`: hash/digest of input message: must be reduced modulo `n` in advance
63
/// - `data`: additional associated data, e.g. CSRNG output used as added entropy
64
#[inline]
65
0
pub fn generate_k<D, N>(
66
0
    x: &ByteArray<N>,
67
0
    n: &ByteArray<N>,
68
0
    h: &ByteArray<N>,
69
0
    data: &[u8],
70
0
) -> ByteArray<N>
71
0
where
72
0
    D: Digest + BlockSizeUser + FixedOutput<OutputSize = N> + FixedOutputReset,
73
0
    N: ArrayLength<u8>,
74
0
{
75
0
    let mut hmac_drbg = HmacDrbg::<D>::new(x, h, data);
76
77
    loop {
78
0
        let mut k = ByteArray::<N>::default();
79
0
        hmac_drbg.fill_bytes(&mut k);
80
0
81
0
        let k_is_zero = ct_cmp::ct_eq(&k, &ByteArray::default());
82
0
        if (!k_is_zero & ct_cmp::ct_lt(&k, n)).into() {
83
0
            return k;
84
0
        }
85
    }
86
0
}
87
88
/// Internal implementation of `HMAC_DRBG` as described in NIST SP800-90A.
89
///
90
/// <https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final>
91
///
92
/// This is a HMAC-based deterministic random bit generator used compute a
93
/// deterministic ephemeral scalar `k`.
94
pub struct HmacDrbg<D>
95
where
96
    D: Digest + BlockSizeUser + FixedOutputReset,
97
{
98
    /// HMAC key `K` (see RFC 6979 Section 3.2.c)
99
    k: SimpleHmac<D>,
100
101
    /// Chaining value `V` (see RFC 6979 Section 3.2.c)
102
    v: GenericArray<u8, D::OutputSize>,
103
}
104
105
impl<D> HmacDrbg<D>
106
where
107
    D: Digest + BlockSizeUser + FixedOutputReset,
108
{
109
    /// Initialize `HMAC_DRBG`
110
0
    pub fn new(entropy_input: &[u8], nonce: &[u8], additional_data: &[u8]) -> Self {
111
0
        let mut k = SimpleHmac::new(&Default::default());
112
0
        let mut v = GenericArray::default();
113
114
0
        for b in &mut v {
115
0
            *b = 0x01;
116
0
        }
117
118
0
        for i in 0..=1 {
119
0
            k.update(&v);
120
0
            k.update(&[i]);
121
0
            k.update(entropy_input);
122
0
            k.update(nonce);
123
0
            k.update(additional_data);
124
0
            k = SimpleHmac::new_from_slice(&k.finalize().into_bytes()).expect("HMAC error");
125
0
126
0
            // Steps 3.2.e,g: v = HMAC_k(v)
127
0
            k.update(&v);
128
0
            v = k.finalize_reset().into_bytes();
129
0
        }
130
131
0
        Self { k, v }
132
0
    }
133
134
    /// Write the next `HMAC_DRBG` output to the given byte slice.
135
0
    pub fn fill_bytes(&mut self, out: &mut [u8]) {
136
0
        for out_chunk in out.chunks_mut(self.v.len()) {
137
0
            self.k.update(&self.v);
138
0
            self.v = self.k.finalize_reset().into_bytes();
139
0
            out_chunk.copy_from_slice(&self.v[..out_chunk.len()]);
140
0
        }
141
142
0
        self.k.update(&self.v);
143
0
        self.k.update(&[0x00]);
144
0
        self.k =
145
0
            SimpleHmac::new_from_slice(&self.k.finalize_reset().into_bytes()).expect("HMAC error");
146
0
        self.k.update(&self.v);
147
0
        self.v = self.k.finalize_reset().into_bytes();
148
0
    }
149
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sec1-0.7.3/src/error.rs
Line
Count
Source
1
//! Error types
2
3
use core::fmt;
4
5
#[cfg(feature = "pem")]
6
use der::pem;
7
8
/// Result type with `sec1` crate's [`Error`] type.
9
pub type Result<T> = core::result::Result<T, Error>;
10
11
/// Error type
12
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
13
#[non_exhaustive]
14
pub enum Error {
15
    /// ASN.1 DER-related errors.
16
    #[cfg(feature = "der")]
17
    Asn1(der::Error),
18
19
    /// Cryptographic errors.
20
    ///
21
    /// These can be used by EC implementations to signal that a key is
22
    /// invalid for cryptographic reasons. This means the document parsed
23
    /// correctly, but one of the values contained within was invalid, e.g.
24
    /// a number expected to be a prime was not a prime.
25
    Crypto,
26
27
    /// PKCS#8 errors.
28
    #[cfg(feature = "pkcs8")]
29
    Pkcs8(pkcs8::Error),
30
31
    /// Errors relating to the `Elliptic-Curve-Point-to-Octet-String` or
32
    /// `Octet-String-to-Elliptic-Curve-Point` encodings.
33
    PointEncoding,
34
35
    /// Version errors
36
    Version,
37
}
38
39
impl fmt::Display for Error {
40
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41
0
        match self {
42
            #[cfg(feature = "der")]
43
0
            Error::Asn1(err) => write!(f, "SEC1 ASN.1 error: {}", err),
44
0
            Error::Crypto => f.write_str("SEC1 cryptographic error"),
45
            #[cfg(feature = "pkcs8")]
46
0
            Error::Pkcs8(err) => write!(f, "{}", err),
47
0
            Error::PointEncoding => f.write_str("elliptic curve point encoding error"),
48
0
            Error::Version => f.write_str("SEC1 version error"),
49
        }
50
0
    }
51
}
52
53
#[cfg(feature = "der")]
54
impl From<der::Error> for Error {
55
0
    fn from(err: der::Error) -> Error {
56
0
        Error::Asn1(err)
57
0
    }
58
}
59
60
#[cfg(feature = "pem")]
61
impl From<pem::Error> for Error {
62
0
    fn from(err: pem::Error) -> Error {
63
0
        der::Error::from(err).into()
64
0
    }
65
}
66
67
#[cfg(feature = "pkcs8")]
68
impl From<pkcs8::Error> for Error {
69
0
    fn from(err: pkcs8::Error) -> Error {
70
0
        Error::Pkcs8(err)
71
0
    }
72
}
73
74
#[cfg(feature = "pkcs8")]
75
impl From<pkcs8::spki::Error> for Error {
76
0
    fn from(err: pkcs8::spki::Error) -> Error {
77
0
        Error::Pkcs8(pkcs8::Error::PublicKey(err))
78
0
    }
79
}
80
81
#[cfg(feature = "std")]
82
impl std::error::Error for Error {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sec1-0.7.3/src/parameters.rs
Line
Count
Source
1
use der::{
2
    asn1::{AnyRef, ObjectIdentifier},
3
    DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Tag, Writer,
4
};
5
6
/// Elliptic curve parameters as described in
7
/// [RFC5480 Section 2.1.1](https://datatracker.ietf.org/doc/html/rfc5480#section-2.1.1):
8
///
9
/// ```text
10
/// ECParameters ::= CHOICE {
11
///   namedCurve         OBJECT IDENTIFIER
12
///   -- implicitCurve   NULL
13
///   -- specifiedCurve  SpecifiedECDomain
14
/// }
15
///   -- implicitCurve and specifiedCurve MUST NOT be used in PKIX.
16
///   -- Details for SpecifiedECDomain can be found in [X9.62].
17
///   -- Any future additions to this CHOICE should be coordinated
18
///   -- with ANSI X9.
19
/// ```
20
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
21
pub enum EcParameters {
22
    /// Elliptic curve named by a particular OID.
23
    ///
24
    /// > namedCurve identifies all the required values for a particular
25
    /// > set of elliptic curve domain parameters to be represented by an
26
    /// > object identifier.
27
    NamedCurve(ObjectIdentifier),
28
}
29
30
impl<'a> DecodeValue<'a> for EcParameters {
31
0
    fn decode_value<R: Reader<'a>>(decoder: &mut R, header: Header) -> der::Result<Self> {
32
0
        ObjectIdentifier::decode_value(decoder, header).map(Self::NamedCurve)
33
0
    }
Unexecuted instantiation: _RINvXNtCsj9qtwLkMHqH_4sec110parametersNtB3_12EcParametersNtNtCscrZQdumITES_3der6decode11DecodeValue12decode_valueINtNtNtBX_6reader6nested12NestedReaderIB1O_NtNtB1S_5slice11SliceReaderEEEB5_
Unexecuted instantiation: _RINvXNtCsj9qtwLkMHqH_4sec110parametersNtB3_12EcParametersNtNtCscrZQdumITES_3der6decode11DecodeValue12decode_valueINtNtNtBX_6reader6nested12NestedReaderNtNtB1S_5slice11SliceReaderEEB5_
34
}
35
36
impl EncodeValue for EcParameters {
37
0
    fn value_len(&self) -> der::Result<Length> {
38
0
        match self {
39
0
            Self::NamedCurve(oid) => oid.value_len(),
40
0
        }
41
0
    }
42
43
0
    fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
44
0
        match self {
45
0
            Self::NamedCurve(oid) => oid.encode_value(writer),
46
0
        }
47
0
    }
48
}
49
50
impl EcParameters {
51
    /// Obtain the `namedCurve` OID.
52
0
    pub fn named_curve(self) -> Option<ObjectIdentifier> {
53
0
        match self {
54
0
            Self::NamedCurve(oid) => Some(oid),
55
0
        }
56
0
    }
57
}
58
59
impl<'a> From<&'a EcParameters> for AnyRef<'a> {
60
0
    fn from(params: &'a EcParameters) -> AnyRef<'a> {
61
0
        match params {
62
0
            EcParameters::NamedCurve(oid) => oid.into(),
63
0
        }
64
0
    }
65
}
66
67
impl From<ObjectIdentifier> for EcParameters {
68
0
    fn from(oid: ObjectIdentifier) -> EcParameters {
69
0
        EcParameters::NamedCurve(oid)
70
0
    }
71
}
72
73
impl FixedTag for EcParameters {
74
    const TAG: Tag = Tag::ObjectIdentifier;
75
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sec1-0.7.3/src/point.rs
Line
Count
Source
1
//! Support for the SEC1 `Elliptic-Curve-Point-to-Octet-String` and
2
//! `Octet-String-to-Elliptic-Curve-Point` encoding algorithms.
3
//!
4
//! Described in [SEC1: Elliptic Curve Cryptography] (Version 2.0) section 2.3.3 (p.10).
5
//!
6
//! [SEC1: Elliptic Curve Cryptography]: https://www.secg.org/sec1-v2.pdf
7
8
use crate::{Error, Result};
9
use base16ct::HexDisplay;
10
use core::{
11
    cmp::Ordering,
12
    fmt::{self, Debug},
13
    hash::{Hash, Hasher},
14
    ops::Add,
15
    str,
16
};
17
use generic_array::{
18
    typenum::{U1, U24, U28, U32, U48, U66},
19
    ArrayLength, GenericArray,
20
};
21
22
#[cfg(feature = "alloc")]
23
use alloc::boxed::Box;
24
25
#[cfg(feature = "serde")]
26
use serdect::serde::{de, ser, Deserialize, Serialize};
27
28
#[cfg(feature = "subtle")]
29
use subtle::{Choice, ConditionallySelectable};
30
31
#[cfg(feature = "zeroize")]
32
use zeroize::Zeroize;
33
34
/// Trait for supported modulus sizes which precomputes the typenums for
35
/// various point encodings so they don't need to be included as bounds.
36
// TODO(tarcieri): replace this all with const generic expressions.
37
pub trait ModulusSize: 'static + ArrayLength<u8> + Copy + Debug {
38
    /// Size of a compressed point for the given elliptic curve when encoded
39
    /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm
40
    /// (including leading `0x02` or `0x03` tag byte).
41
    type CompressedPointSize: 'static + ArrayLength<u8> + Copy + Debug;
42
43
    /// Size of an uncompressed point for the given elliptic curve when encoded
44
    /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm
45
    /// (including leading `0x04` tag byte).
46
    type UncompressedPointSize: 'static + ArrayLength<u8> + Copy + Debug;
47
48
    /// Size of an untagged point for given elliptic curve, i.e. size of two
49
    /// serialized base field elements.
50
    type UntaggedPointSize: 'static + ArrayLength<u8> + Copy + Debug;
51
}
52
53
macro_rules! impl_modulus_size {
54
    ($($size:ty),+) => {
55
        $(impl ModulusSize for $size {
56
            type CompressedPointSize = <$size as Add<U1>>::Output;
57
            type UncompressedPointSize = <Self::UntaggedPointSize as Add<U1>>::Output;
58
            type UntaggedPointSize = <$size as Add>::Output;
59
        })+
60
    }
61
}
62
63
impl_modulus_size!(U24, U28, U32, U48, U66);
64
65
/// SEC1 encoded curve point.
66
///
67
/// This type is an enum over the compressed and uncompressed encodings,
68
/// useful for cases where either encoding can be supported, or conversions
69
/// between the two forms.
70
#[derive(Clone, Default)]
71
pub struct EncodedPoint<Size>
72
where
73
    Size: ModulusSize,
74
{
75
    bytes: GenericArray<u8, Size::UncompressedPointSize>,
76
}
77
78
#[allow(clippy::len_without_is_empty)]
79
impl<Size> EncodedPoint<Size>
80
where
81
    Size: ModulusSize,
82
{
83
    /// Decode elliptic curve point (compressed or uncompressed) from the
84
    /// `Elliptic-Curve-Point-to-Octet-String` encoding described in
85
    /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section
86
    /// 2.3.3 (page 10).
87
    ///
88
    /// <http://www.secg.org/sec1-v2.pdf>
89
2.51k
    pub fn from_bytes(input: impl AsRef<[u8]>) -> Result<Self> {
90
2.51k
        let input = input.as_ref();
91
92
        // Validate tag
93
2.51k
        let tag = input
94
2.51k
            .first()
95
2.51k
            .cloned()
96
2.51k
            .ok_or(Error::PointEncoding)
97
2.51k
            .and_then(Tag::from_u8)?;
98
99
        // Validate length
100
2.47k
        let expected_len = tag.message_len(Size::to_usize());
101
2.47k
102
2.47k
        if input.len() != expected_len {
103
23
            return Err(Error::PointEncoding);
104
2.45k
        }
105
2.45k
106
2.45k
        let mut bytes = GenericArray::default();
107
2.45k
        bytes[..expected_len].copy_from_slice(input);
108
2.45k
        Ok(Self { bytes })
109
2.51k
    }
_RINvMNtCsj9qtwLkMHqH_4sec15pointINtB3_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBP_IBP_IBP_IBP_IBP_NtBR_5UTermNtNtBT_3bit2B1ENtB1W_2B0EB29_EB29_EB29_EB29_EE10from_bytesRShECs4RkbDk9WRL5_5clvmr
Line
Count
Source
89
2.51k
    pub fn from_bytes(input: impl AsRef<[u8]>) -> Result<Self> {
90
2.51k
        let input = input.as_ref();
91
92
        // Validate tag
93
2.51k
        let tag = input
94
2.51k
            .first()
95
2.51k
            .cloned()
96
2.51k
            .ok_or(Error::PointEncoding)
97
2.51k
            .and_then(Tag::from_u8)?;
98
99
        // Validate length
100
2.47k
        let expected_len = tag.message_len(Size::to_usize());
101
2.47k
102
2.47k
        if input.len() != expected_len {
103
23
            return Err(Error::PointEncoding);
104
2.45k
        }
105
2.45k
106
2.45k
        let mut bytes = GenericArray::default();
107
2.45k
        bytes[..expected_len].copy_from_slice(input);
108
2.45k
        Ok(Self { bytes })
109
2.51k
    }
Unexecuted instantiation: _RINvMNtCsj9qtwLkMHqH_4sec15pointINtB3_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBP_IBP_IBP_IBP_IBP_NtBR_5UTermNtNtBT_3bit2B1ENtB1W_2B0EB29_EB29_EB29_EB29_EE10from_bytesRINtCskVr04X3DebC_13generic_array12GenericArrayhIBP_B1p_B1U_EEECsjewTDwKBbyD_4k256
Unexecuted instantiation: _RINvMNtCsj9qtwLkMHqH_4sec15pointINtB3_12EncodedPointpE10from_bytespEB5_
110
111
    /// Decode elliptic curve point from raw uncompressed coordinates, i.e.
112
    /// encoded as the concatenated `x || y` coordinates with no leading SEC1
113
    /// tag byte (which would otherwise be `0x04` for an uncompressed point).
114
0
    pub fn from_untagged_bytes(bytes: &GenericArray<u8, Size::UntaggedPointSize>) -> Self {
115
0
        let (x, y) = bytes.split_at(Size::to_usize());
116
0
        Self::from_affine_coordinates(x.into(), y.into(), false)
117
0
    }
118
119
    /// Encode an elliptic curve point from big endian serialized coordinates
120
    /// (with optional point compression)
121
0
    pub fn from_affine_coordinates(
122
0
        x: &GenericArray<u8, Size>,
123
0
        y: &GenericArray<u8, Size>,
124
0
        compress: bool,
125
0
    ) -> Self {
126
0
        let tag = if compress {
127
0
            Tag::compress_y(y.as_slice())
128
        } else {
129
0
            Tag::Uncompressed
130
        };
131
132
0
        let mut bytes = GenericArray::default();
133
0
        bytes[0] = tag.into();
134
0
        bytes[1..(Size::to_usize() + 1)].copy_from_slice(x);
135
0
136
0
        if !compress {
137
0
            bytes[(Size::to_usize() + 1)..].copy_from_slice(y);
138
0
        }
139
140
0
        Self { bytes }
141
0
    }
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE23from_affine_coordinatesCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointpE23from_affine_coordinatesB4_
142
143
    /// Return [`EncodedPoint`] representing the additive identity
144
    /// (a.k.a. point at infinity)
145
0
    pub fn identity() -> Self {
146
0
        Self::default()
147
0
    }
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE8identityCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointpE8identityB4_
148
149
    /// Get the length of the encoded point in bytes
150
0
    pub fn len(&self) -> usize {
151
0
        self.tag().message_len(Size::to_usize())
152
0
    }
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE3lenCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointpE3lenB4_
153
154
    /// Get byte slice containing the serialized [`EncodedPoint`].
155
0
    pub fn as_bytes(&self) -> &[u8] {
156
0
        &self.bytes[..self.len()]
157
0
    }
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE8as_bytesCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointpE8as_bytesB4_
158
159
    /// Get boxed byte slice containing the serialized [`EncodedPoint`]
160
    #[cfg(feature = "alloc")]
161
0
    pub fn to_bytes(&self) -> Box<[u8]> {
162
0
        self.as_bytes().to_vec().into_boxed_slice()
163
0
    }
164
165
    /// Is this [`EncodedPoint`] compact?
166
1.11k
    pub fn is_compact(&self) -> bool {
167
1.11k
        self.tag().is_compact()
168
1.11k
    }
_RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE10is_compactCs4RkbDk9WRL5_5clvmr
Line
Count
Source
166
573
    pub fn is_compact(&self) -> bool {
167
573
        self.tag().is_compact()
168
573
    }
_RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE10is_compactCsjewTDwKBbyD_4k256
Line
Count
Source
166
538
    pub fn is_compact(&self) -> bool {
167
538
        self.tag().is_compact()
168
538
    }
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointpE10is_compactB4_
169
170
    /// Is this [`EncodedPoint`] compressed?
171
2.43k
    pub fn is_compressed(&self) -> bool {
172
2.43k
        self.tag().is_compressed()
173
2.43k
    }
_RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE13is_compressedCs4RkbDk9WRL5_5clvmr
Line
Count
Source
171
1.17k
    pub fn is_compressed(&self) -> bool {
172
1.17k
        self.tag().is_compressed()
173
1.17k
    }
_RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE13is_compressedCsjewTDwKBbyD_4k256
Line
Count
Source
171
1.26k
    pub fn is_compressed(&self) -> bool {
172
1.26k
        self.tag().is_compressed()
173
1.26k
    }
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointpE13is_compressedB4_
174
175
    /// Is this [`EncodedPoint`] the additive identity? (a.k.a. point at infinity)
176
4.90k
    pub fn is_identity(&self) -> bool {
177
4.90k
        self.tag().is_identity()
178
4.90k
    }
_RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE11is_identityCs4RkbDk9WRL5_5clvmr
Line
Count
Source
176
3.63k
    pub fn is_identity(&self) -> bool {
177
3.63k
        self.tag().is_identity()
178
3.63k
    }
_RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE11is_identityCsjewTDwKBbyD_4k256
Line
Count
Source
176
1.27k
    pub fn is_identity(&self) -> bool {
177
1.27k
        self.tag().is_identity()
178
1.27k
    }
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointpE11is_identityB4_
179
180
    /// Compress this [`EncodedPoint`], returning a new [`EncodedPoint`].
181
0
    pub fn compress(&self) -> Self {
182
0
        match self.coordinates() {
183
            Coordinates::Compressed { .. }
184
            | Coordinates::Compact { .. }
185
0
            | Coordinates::Identity => self.clone(),
186
0
            Coordinates::Uncompressed { x, y } => Self::from_affine_coordinates(x, y, true),
187
        }
188
0
    }
189
190
    /// Get the SEC1 tag for this [`EncodedPoint`]
191
9.77k
    pub fn tag(&self) -> Tag {
192
9.77k
        // Tag is ensured valid by the constructor
193
9.77k
        Tag::from_u8(self.bytes[0]).expect("invalid tag")
194
9.77k
    }
_RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE3tagCs4RkbDk9WRL5_5clvmr
Line
Count
Source
191
5.97k
    pub fn tag(&self) -> Tag {
192
5.97k
        // Tag is ensured valid by the constructor
193
5.97k
        Tag::from_u8(self.bytes[0]).expect("invalid tag")
194
5.97k
    }
_RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE3tagCsjewTDwKBbyD_4k256
Line
Count
Source
191
3.79k
    pub fn tag(&self) -> Tag {
192
3.79k
        // Tag is ensured valid by the constructor
193
3.79k
        Tag::from_u8(self.bytes[0]).expect("invalid tag")
194
3.79k
    }
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointpE3tagB4_
195
196
    /// Get the [`Coordinates`] for this [`EncodedPoint`].
197
    #[inline]
198
2.45k
    pub fn coordinates(&self) -> Coordinates<'_, Size> {
199
2.45k
        if self.is_identity() {
200
20
            return Coordinates::Identity;
201
2.43k
        }
202
2.43k
203
2.43k
        let (x, y) = self.bytes[1..].split_at(Size::to_usize());
204
2.43k
205
2.43k
        if self.is_compressed() {
206
1.32k
            Coordinates::Compressed {
207
1.32k
                x: x.into(),
208
1.32k
                y_is_odd: self.tag() as u8 & 1 == 1,
209
1.32k
            }
210
1.11k
        } else if self.is_compact() {
211
24
            Coordinates::Compact { x: x.into() }
212
        } else {
213
1.08k
            Coordinates::Uncompressed {
214
1.08k
                x: x.into(),
215
1.08k
                y: y.into(),
216
1.08k
            }
217
        }
218
2.45k
    }
_RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE11coordinatesCs4RkbDk9WRL5_5clvmr
Line
Count
Source
198
1.18k
    pub fn coordinates(&self) -> Coordinates<'_, Size> {
199
1.18k
        if self.is_identity() {
200
10
            return Coordinates::Identity;
201
1.17k
        }
202
1.17k
203
1.17k
        let (x, y) = self.bytes[1..].split_at(Size::to_usize());
204
1.17k
205
1.17k
        if self.is_compressed() {
206
597
            Coordinates::Compressed {
207
597
                x: x.into(),
208
597
                y_is_odd: self.tag() as u8 & 1 == 1,
209
597
            }
210
573
        } else if self.is_compact() {
211
14
            Coordinates::Compact { x: x.into() }
212
        } else {
213
559
            Coordinates::Uncompressed {
214
559
                x: x.into(),
215
559
                y: y.into(),
216
559
            }
217
        }
218
1.18k
    }
_RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBO_IBO_IBO_IBO_IBO_NtBQ_5UTermNtNtBS_3bit2B1ENtB1V_2B0EB28_EB28_EB28_EB28_EE11coordinatesCsjewTDwKBbyD_4k256
Line
Count
Source
198
1.27k
    pub fn coordinates(&self) -> Coordinates<'_, Size> {
199
1.27k
        if self.is_identity() {
200
10
            return Coordinates::Identity;
201
1.26k
        }
202
1.26k
203
1.26k
        let (x, y) = self.bytes[1..].split_at(Size::to_usize());
204
1.26k
205
1.26k
        if self.is_compressed() {
206
725
            Coordinates::Compressed {
207
725
                x: x.into(),
208
725
                y_is_odd: self.tag() as u8 & 1 == 1,
209
725
            }
210
538
        } else if self.is_compact() {
211
10
            Coordinates::Compact { x: x.into() }
212
        } else {
213
528
            Coordinates::Uncompressed {
214
528
                x: x.into(),
215
528
                y: y.into(),
216
528
            }
217
        }
218
1.27k
    }
Unexecuted instantiation: _RNvMNtCsj9qtwLkMHqH_4sec15pointINtB2_12EncodedPointpE11coordinatesB4_
219
220
    /// Get the x-coordinate for this [`EncodedPoint`].
221
    ///
222
    /// Returns `None` if this point is the identity point.
223
0
    pub fn x(&self) -> Option<&GenericArray<u8, Size>> {
224
0
        match self.coordinates() {
225
0
            Coordinates::Identity => None,
226
0
            Coordinates::Compressed { x, .. } => Some(x),
227
0
            Coordinates::Uncompressed { x, .. } => Some(x),
228
0
            Coordinates::Compact { x } => Some(x),
229
        }
230
0
    }
231
232
    /// Get the y-coordinate for this [`EncodedPoint`].
233
    ///
234
    /// Returns `None` if this point is compressed or the identity point.
235
0
    pub fn y(&self) -> Option<&GenericArray<u8, Size>> {
236
0
        match self.coordinates() {
237
0
            Coordinates::Compressed { .. } | Coordinates::Identity => None,
238
0
            Coordinates::Uncompressed { y, .. } => Some(y),
239
0
            Coordinates::Compact { .. } => None,
240
        }
241
0
    }
242
}
243
244
impl<Size> AsRef<[u8]> for EncodedPoint<Size>
245
where
246
    Size: ModulusSize,
247
{
248
    #[inline]
249
0
    fn as_ref(&self) -> &[u8] {
250
0
        self.as_bytes()
251
0
    }
252
}
253
254
#[cfg(feature = "subtle")]
255
impl<Size> ConditionallySelectable for EncodedPoint<Size>
256
where
257
    Size: ModulusSize,
258
    <Size::UncompressedPointSize as ArrayLength<u8>>::ArrayType: Copy,
259
{
260
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
261
0
        let mut bytes = GenericArray::default();
262
263
0
        for (i, byte) in bytes.iter_mut().enumerate() {
264
0
            *byte = u8::conditional_select(&a.bytes[i], &b.bytes[i], choice);
265
0
        }
266
267
0
        Self { bytes }
268
0
    }
Unexecuted instantiation: _RNvXs0_NtCsj9qtwLkMHqH_4sec15pointINtB5_12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIBR_IBR_IBR_IBR_IBR_NtBT_5UTermNtNtBV_3bit2B1ENtB1Y_2B0EB2b_EB2b_EB2b_EB2b_EENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXININtCsj9qtwLkMHqH_4sec15points0_0pEINtB5_12EncodedPointpENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_selectB7_
269
}
270
271
impl<Size> Copy for EncodedPoint<Size>
272
where
273
    Size: ModulusSize,
274
    <Size::UncompressedPointSize as ArrayLength<u8>>::ArrayType: Copy,
275
{
276
}
277
278
impl<Size> Debug for EncodedPoint<Size>
279
where
280
    Size: ModulusSize,
281
{
282
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
283
0
        write!(f, "EncodedPoint({:?})", self.coordinates())
284
0
    }
285
}
286
287
impl<Size: ModulusSize> Eq for EncodedPoint<Size> {}
288
289
impl<Size> PartialEq for EncodedPoint<Size>
290
where
291
    Size: ModulusSize,
292
{
293
0
    fn eq(&self, other: &Self) -> bool {
294
0
        self.as_bytes() == other.as_bytes()
295
0
    }
296
}
297
298
impl<Size> Hash for EncodedPoint<Size>
299
where
300
    Size: ModulusSize,
301
{
302
0
    fn hash<H: Hasher>(&self, state: &mut H) {
303
0
        self.as_bytes().hash(state)
304
0
    }
305
}
306
307
impl<Size: ModulusSize> PartialOrd for EncodedPoint<Size>
308
where
309
    Size: ModulusSize,
310
{
311
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
312
0
        Some(self.cmp(other))
313
0
    }
314
}
315
316
impl<Size: ModulusSize> Ord for EncodedPoint<Size>
317
where
318
    Size: ModulusSize,
319
{
320
0
    fn cmp(&self, other: &Self) -> Ordering {
321
0
        self.as_bytes().cmp(other.as_bytes())
322
0
    }
323
}
324
325
impl<Size: ModulusSize> TryFrom<&[u8]> for EncodedPoint<Size>
326
where
327
    Size: ModulusSize,
328
{
329
    type Error = Error;
330
331
0
    fn try_from(bytes: &[u8]) -> Result<Self> {
332
0
        Self::from_bytes(bytes)
333
0
    }
334
}
335
336
#[cfg(feature = "zeroize")]
337
impl<Size> Zeroize for EncodedPoint<Size>
338
where
339
    Size: ModulusSize,
340
{
341
0
    fn zeroize(&mut self) {
342
0
        self.bytes.zeroize();
343
0
        *self = Self::identity();
344
0
    }
345
}
346
347
impl<Size> fmt::Display for EncodedPoint<Size>
348
where
349
    Size: ModulusSize,
350
{
351
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352
0
        write!(f, "{:X}", self)
353
0
    }
354
}
355
356
impl<Size> fmt::LowerHex for EncodedPoint<Size>
357
where
358
    Size: ModulusSize,
359
{
360
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361
0
        write!(f, "{:x}", HexDisplay(self.as_bytes()))
362
0
    }
363
}
364
365
impl<Size> fmt::UpperHex for EncodedPoint<Size>
366
where
367
    Size: ModulusSize,
368
{
369
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
370
0
        write!(f, "{:X}", HexDisplay(self.as_bytes()))
371
0
    }
372
}
373
374
/// Decode a SEC1-encoded point from hexadecimal.
375
///
376
/// Upper and lower case hexadecimal are both accepted, however mixed case is
377
/// rejected.
378
impl<Size> str::FromStr for EncodedPoint<Size>
379
where
380
    Size: ModulusSize,
381
{
382
    type Err = Error;
383
384
0
    fn from_str(hex: &str) -> Result<Self> {
385
0
        let mut buf = GenericArray::<u8, Size::UncompressedPointSize>::default();
386
0
        base16ct::mixed::decode(hex, &mut buf)
387
0
            .map_err(|_| Error::PointEncoding)
388
0
            .and_then(Self::from_bytes)
389
0
    }
390
}
391
392
#[cfg(feature = "serde")]
393
impl<Size> Serialize for EncodedPoint<Size>
394
where
395
    Size: ModulusSize,
396
{
397
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
398
    where
399
        S: ser::Serializer,
400
    {
401
        serdect::slice::serialize_hex_upper_or_bin(&self.as_bytes(), serializer)
402
    }
403
}
404
405
#[cfg(feature = "serde")]
406
impl<'de, Size> Deserialize<'de> for EncodedPoint<Size>
407
where
408
    Size: ModulusSize,
409
{
410
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
411
    where
412
        D: de::Deserializer<'de>,
413
    {
414
        let bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?;
415
        Self::from_bytes(bytes).map_err(de::Error::custom)
416
    }
417
}
418
419
/// Enum representing the coordinates of either compressed or uncompressed
420
/// SEC1-encoded elliptic curve points.
421
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
422
pub enum Coordinates<'a, Size: ModulusSize> {
423
    /// Identity point (a.k.a. point at infinity)
424
    Identity,
425
426
    /// Compact curve point
427
    Compact {
428
        /// x-coordinate
429
        x: &'a GenericArray<u8, Size>,
430
    },
431
432
    /// Compressed curve point
433
    Compressed {
434
        /// x-coordinate
435
        x: &'a GenericArray<u8, Size>,
436
437
        /// Is the y-coordinate odd?
438
        y_is_odd: bool,
439
    },
440
441
    /// Uncompressed curve point
442
    Uncompressed {
443
        /// x-coordinate
444
        x: &'a GenericArray<u8, Size>,
445
446
        /// y-coordinate
447
        y: &'a GenericArray<u8, Size>,
448
    },
449
}
450
451
impl<'a, Size: ModulusSize> Coordinates<'a, Size> {
452
    /// Get the tag octet needed to encode this set of [`Coordinates`]
453
0
    pub fn tag(&self) -> Tag {
454
0
        match self {
455
0
            Coordinates::Compact { .. } => Tag::Compact,
456
0
            Coordinates::Compressed { y_is_odd, .. } => {
457
0
                if *y_is_odd {
458
0
                    Tag::CompressedOddY
459
                } else {
460
0
                    Tag::CompressedEvenY
461
                }
462
            }
463
0
            Coordinates::Identity => Tag::Identity,
464
0
            Coordinates::Uncompressed { .. } => Tag::Uncompressed,
465
        }
466
0
    }
467
}
468
469
/// Tag byte used by the `Elliptic-Curve-Point-to-Octet-String` encoding.
470
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
471
#[repr(u8)]
472
pub enum Tag {
473
    /// Identity point (`0x00`)
474
    Identity = 0,
475
476
    /// Compressed point with even y-coordinate (`0x02`)
477
    CompressedEvenY = 2,
478
479
    /// Compressed point with odd y-coordinate (`0x03`)
480
    CompressedOddY = 3,
481
482
    /// Uncompressed point (`0x04`)
483
    Uncompressed = 4,
484
485
    /// Compact point (`0x05`)
486
    Compact = 5,
487
}
488
489
impl Tag {
490
    /// Parse a tag value from a byte
491
12.2k
    pub fn from_u8(byte: u8) -> Result<Self> {
492
12.2k
        match byte {
493
80
            0 => Ok(Tag::Identity),
494
6.49k
            2 => Ok(Tag::CompressedEvenY),
495
115
            3 => Ok(Tag::CompressedOddY),
496
5.43k
            4 => Ok(Tag::Uncompressed),
497
123
            5 => Ok(Tag::Compact),
498
21
            _ => Err(Error::PointEncoding),
499
        }
500
12.2k
    }
_RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag7from_u8Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
491
8.47k
    pub fn from_u8(byte: u8) -> Result<Self> {
492
8.47k
        match byte {
493
70
            0 => Ok(Tag::Identity),
494
4.35k
            2 => Ok(Tag::CompressedEvenY),
495
76
            3 => Ok(Tag::CompressedOddY),
496
3.85k
            4 => Ok(Tag::Uncompressed),
497
93
            5 => Ok(Tag::Compact),
498
21
            _ => Err(Error::PointEncoding),
499
        }
500
8.47k
    }
_RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag7from_u8CsjewTDwKBbyD_4k256
Line
Count
Source
491
3.79k
    pub fn from_u8(byte: u8) -> Result<Self> {
492
3.79k
        match byte {
493
10
            0 => Ok(Tag::Identity),
494
2.13k
            2 => Ok(Tag::CompressedEvenY),
495
39
            3 => Ok(Tag::CompressedOddY),
496
1.58k
            4 => Ok(Tag::Uncompressed),
497
30
            5 => Ok(Tag::Compact),
498
0
            _ => Err(Error::PointEncoding),
499
        }
500
3.79k
    }
Unexecuted instantiation: _RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag7from_u8B7_
501
502
    /// Is this point compact?
503
1.11k
    pub fn is_compact(self) -> bool {
504
1.11k
        matches!(self, Tag::Compact)
505
1.11k
    }
_RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag10is_compactCs4RkbDk9WRL5_5clvmr
Line
Count
Source
503
573
    pub fn is_compact(self) -> bool {
504
573
        matches!(self, Tag::Compact)
505
573
    }
_RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag10is_compactCsjewTDwKBbyD_4k256
Line
Count
Source
503
538
    pub fn is_compact(self) -> bool {
504
538
        matches!(self, Tag::Compact)
505
538
    }
Unexecuted instantiation: _RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag10is_compactB7_
506
507
    /// Is this point compressed?
508
2.43k
    pub fn is_compressed(self) -> bool {
509
2.43k
        matches!(self, Tag::CompressedEvenY | Tag::CompressedOddY)
510
2.43k
    }
_RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag13is_compressedCs4RkbDk9WRL5_5clvmr
Line
Count
Source
508
1.17k
    pub fn is_compressed(self) -> bool {
509
1.17k
        matches!(self, Tag::CompressedEvenY | Tag::CompressedOddY)
510
1.17k
    }
_RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag13is_compressedCsjewTDwKBbyD_4k256
Line
Count
Source
508
1.26k
    pub fn is_compressed(self) -> bool {
509
1.26k
        matches!(self, Tag::CompressedEvenY | Tag::CompressedOddY)
510
1.26k
    }
Unexecuted instantiation: _RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag13is_compressedB7_
511
512
    /// Is this point the identity point?
513
4.90k
    pub fn is_identity(self) -> bool {
514
4.90k
        self == Tag::Identity
515
4.90k
    }
_RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag11is_identityCs4RkbDk9WRL5_5clvmr
Line
Count
Source
513
3.63k
    pub fn is_identity(self) -> bool {
514
3.63k
        self == Tag::Identity
515
3.63k
    }
_RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag11is_identityCsjewTDwKBbyD_4k256
Line
Count
Source
513
1.27k
    pub fn is_identity(self) -> bool {
514
1.27k
        self == Tag::Identity
515
1.27k
    }
Unexecuted instantiation: _RNvMsf_NtCsj9qtwLkMHqH_4sec15pointNtB5_3Tag11is_identityB7_
516
517
    /// Compute the expected total message length for a message prefixed
518
    /// with this tag (including the tag byte), given the field element size
519
    /// (in bytes) for a particular elliptic curve.
520
2.47k
    pub fn message_len(self, field_element_size: usize) -> usize {
521
2.47k
        1 + match self {
522
40
            Tag::Identity => 0,
523
1.32k
            Tag::CompressedEvenY | Tag::CompressedOddY => field_element_size,
524
1.08k
            Tag::Uncompressed => field_element_size * 2,
525
27
            Tag::Compact => field_element_size,
526
        }
527
2.47k
    }
528
529
    /// Compress the given y-coordinate, returning a `Tag::Compressed*` value
530
0
    fn compress_y(y: &[u8]) -> Self {
531
0
        // Is the y-coordinate odd in the SEC1 sense: `self mod 2 == 1`?
532
0
        if y.as_ref().last().expect("empty y-coordinate") & 1 == 1 {
533
0
            Tag::CompressedOddY
534
        } else {
535
0
            Tag::CompressedEvenY
536
        }
537
0
    }
538
}
539
540
impl TryFrom<u8> for Tag {
541
    type Error = Error;
542
543
0
    fn try_from(byte: u8) -> Result<Self> {
544
0
        Self::from_u8(byte)
545
0
    }
546
}
547
548
impl From<Tag> for u8 {
549
0
    fn from(tag: Tag) -> u8 {
550
0
        tag as u8
551
0
    }
Unexecuted instantiation: _RNvXsh_NtCsj9qtwLkMHqH_4sec15pointhINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_3TagE4fromCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXsh_NtCsj9qtwLkMHqH_4sec15pointhINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB5_3TagE4fromB7_
552
}
553
554
#[cfg(test)]
555
mod tests {
556
    use super::{Coordinates, Tag};
557
    use core::str::FromStr;
558
    use generic_array::{typenum::U32, GenericArray};
559
    use hex_literal::hex;
560
561
    #[cfg(feature = "alloc")]
562
    use alloc::string::ToString;
563
564
    #[cfg(feature = "subtle")]
565
    use subtle::ConditionallySelectable;
566
567
    type EncodedPoint = super::EncodedPoint<U32>;
568
569
    /// Identity point
570
    const IDENTITY_BYTES: [u8; 1] = [0];
571
572
    /// Example uncompressed point
573
    const UNCOMPRESSED_BYTES: [u8; 65] = hex!("0411111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222");
574
575
    /// Example compressed point: `UNCOMPRESSED_BYTES` after point compression
576
    const COMPRESSED_BYTES: [u8; 33] =
577
        hex!("021111111111111111111111111111111111111111111111111111111111111111");
578
579
    #[test]
580
    fn decode_compressed_point() {
581
        // Even y-coordinate
582
        let compressed_even_y_bytes =
583
            hex!("020100000000000000000000000000000000000000000000000000000000000000");
584
585
        let compressed_even_y = EncodedPoint::from_bytes(&compressed_even_y_bytes[..]).unwrap();
586
587
        assert!(compressed_even_y.is_compressed());
588
        assert_eq!(compressed_even_y.tag(), Tag::CompressedEvenY);
589
        assert_eq!(compressed_even_y.len(), 33);
590
        assert_eq!(compressed_even_y.as_bytes(), &compressed_even_y_bytes[..]);
591
592
        assert_eq!(
593
            compressed_even_y.coordinates(),
594
            Coordinates::Compressed {
595
                x: &hex!("0100000000000000000000000000000000000000000000000000000000000000").into(),
596
                y_is_odd: false
597
            }
598
        );
599
600
        assert_eq!(
601
            compressed_even_y.x().unwrap(),
602
            &hex!("0100000000000000000000000000000000000000000000000000000000000000").into()
603
        );
604
        assert_eq!(compressed_even_y.y(), None);
605
606
        // Odd y-coordinate
607
        let compressed_odd_y_bytes =
608
            hex!("030200000000000000000000000000000000000000000000000000000000000000");
609
610
        let compressed_odd_y = EncodedPoint::from_bytes(&compressed_odd_y_bytes[..]).unwrap();
611
612
        assert!(compressed_odd_y.is_compressed());
613
        assert_eq!(compressed_odd_y.tag(), Tag::CompressedOddY);
614
        assert_eq!(compressed_odd_y.len(), 33);
615
        assert_eq!(compressed_odd_y.as_bytes(), &compressed_odd_y_bytes[..]);
616
617
        assert_eq!(
618
            compressed_odd_y.coordinates(),
619
            Coordinates::Compressed {
620
                x: &hex!("0200000000000000000000000000000000000000000000000000000000000000").into(),
621
                y_is_odd: true
622
            }
623
        );
624
625
        assert_eq!(
626
            compressed_odd_y.x().unwrap(),
627
            &hex!("0200000000000000000000000000000000000000000000000000000000000000").into()
628
        );
629
        assert_eq!(compressed_odd_y.y(), None);
630
    }
631
632
    #[test]
633
    fn decode_uncompressed_point() {
634
        let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap();
635
636
        assert!(!uncompressed_point.is_compressed());
637
        assert_eq!(uncompressed_point.tag(), Tag::Uncompressed);
638
        assert_eq!(uncompressed_point.len(), 65);
639
        assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]);
640
641
        assert_eq!(
642
            uncompressed_point.coordinates(),
643
            Coordinates::Uncompressed {
644
                x: &hex!("1111111111111111111111111111111111111111111111111111111111111111").into(),
645
                y: &hex!("2222222222222222222222222222222222222222222222222222222222222222").into()
646
            }
647
        );
648
649
        assert_eq!(
650
            uncompressed_point.x().unwrap(),
651
            &hex!("1111111111111111111111111111111111111111111111111111111111111111").into()
652
        );
653
        assert_eq!(
654
            uncompressed_point.y().unwrap(),
655
            &hex!("2222222222222222222222222222222222222222222222222222222222222222").into()
656
        );
657
    }
658
659
    #[test]
660
    fn decode_identity() {
661
        let identity_point = EncodedPoint::from_bytes(&IDENTITY_BYTES[..]).unwrap();
662
        assert!(identity_point.is_identity());
663
        assert_eq!(identity_point.tag(), Tag::Identity);
664
        assert_eq!(identity_point.len(), 1);
665
        assert_eq!(identity_point.as_bytes(), &IDENTITY_BYTES[..]);
666
        assert_eq!(identity_point.coordinates(), Coordinates::Identity);
667
        assert_eq!(identity_point.x(), None);
668
        assert_eq!(identity_point.y(), None);
669
    }
670
671
    #[test]
672
    fn decode_invalid_tag() {
673
        let mut compressed_bytes = COMPRESSED_BYTES;
674
        let mut uncompressed_bytes = UNCOMPRESSED_BYTES;
675
676
        for bytes in &mut [&mut compressed_bytes[..], &mut uncompressed_bytes[..]] {
677
            for tag in 0..=0xFF {
678
                // valid tags
679
                if tag == 2 || tag == 3 || tag == 4 || tag == 5 {
680
                    continue;
681
                }
682
683
                (*bytes)[0] = tag;
684
                let decode_result = EncodedPoint::from_bytes(&*bytes);
685
                assert!(decode_result.is_err());
686
            }
687
        }
688
    }
689
690
    #[test]
691
    fn decode_truncated_point() {
692
        for bytes in &[&COMPRESSED_BYTES[..], &UNCOMPRESSED_BYTES[..]] {
693
            for len in 0..bytes.len() {
694
                let decode_result = EncodedPoint::from_bytes(&bytes[..len]);
695
                assert!(decode_result.is_err());
696
            }
697
        }
698
    }
699
700
    #[test]
701
    fn from_untagged_point() {
702
        let untagged_bytes = hex!("11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222");
703
        let uncompressed_point =
704
            EncodedPoint::from_untagged_bytes(GenericArray::from_slice(&untagged_bytes[..]));
705
        assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]);
706
    }
707
708
    #[test]
709
    fn from_affine_coordinates() {
710
        let x = hex!("1111111111111111111111111111111111111111111111111111111111111111");
711
        let y = hex!("2222222222222222222222222222222222222222222222222222222222222222");
712
713
        let uncompressed_point = EncodedPoint::from_affine_coordinates(&x.into(), &y.into(), false);
714
        assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]);
715
716
        let compressed_point = EncodedPoint::from_affine_coordinates(&x.into(), &y.into(), true);
717
        assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]);
718
    }
719
720
    #[test]
721
    fn compress() {
722
        let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap();
723
        let compressed_point = uncompressed_point.compress();
724
        assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]);
725
    }
726
727
    #[cfg(feature = "subtle")]
728
    #[test]
729
    fn conditional_select() {
730
        let a = EncodedPoint::from_bytes(&COMPRESSED_BYTES[..]).unwrap();
731
        let b = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap();
732
733
        let a_selected = EncodedPoint::conditional_select(&a, &b, 0.into());
734
        assert_eq!(a, a_selected);
735
736
        let b_selected = EncodedPoint::conditional_select(&a, &b, 1.into());
737
        assert_eq!(b, b_selected);
738
    }
739
740
    #[test]
741
    fn identity() {
742
        let identity_point = EncodedPoint::identity();
743
        assert_eq!(identity_point.tag(), Tag::Identity);
744
        assert_eq!(identity_point.len(), 1);
745
        assert_eq!(identity_point.as_bytes(), &IDENTITY_BYTES[..]);
746
747
        // identity is default
748
        assert_eq!(identity_point, EncodedPoint::default());
749
    }
750
751
    #[test]
752
    fn decode_hex() {
753
        let point = EncodedPoint::from_str(
754
            "021111111111111111111111111111111111111111111111111111111111111111",
755
        )
756
        .unwrap();
757
        assert_eq!(point.as_bytes(), COMPRESSED_BYTES);
758
    }
759
760
    #[cfg(feature = "alloc")]
761
    #[test]
762
    fn to_bytes() {
763
        let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap();
764
        assert_eq!(&*uncompressed_point.to_bytes(), &UNCOMPRESSED_BYTES[..]);
765
    }
766
767
    #[cfg(feature = "alloc")]
768
    #[test]
769
    fn to_string() {
770
        let point = EncodedPoint::from_bytes(&COMPRESSED_BYTES[..]).unwrap();
771
        assert_eq!(
772
            point.to_string(),
773
            "021111111111111111111111111111111111111111111111111111111111111111"
774
        );
775
    }
776
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sec1-0.7.3/src/private_key.rs
Line
Count
Source
1
//! SEC1 elliptic curve private key support.
2
//!
3
//! Support for ASN.1 DER-encoded elliptic curve private keys as described in
4
//! SEC1: Elliptic Curve Cryptography (Version 2.0) Appendix C.4 (p.108):
5
//!
6
//! <https://www.secg.org/sec1-v2.pdf>
7
8
use crate::{EcParameters, Error, Result};
9
use core::fmt;
10
use der::{
11
    asn1::{BitStringRef, ContextSpecific, ContextSpecificRef, OctetStringRef},
12
    Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Tag, TagMode,
13
    TagNumber, Writer,
14
};
15
16
#[cfg(all(feature = "alloc", feature = "zeroize"))]
17
use der::SecretDocument;
18
19
#[cfg(feature = "pem")]
20
use der::pem::PemLabel;
21
22
/// `ECPrivateKey` version.
23
///
24
/// From [RFC5913 Section 3]:
25
/// > version specifies the syntax version number of the elliptic curve
26
/// > private key structure.  For this version of the document, it SHALL
27
/// > be set to ecPrivkeyVer1, which is of type INTEGER and whose value
28
/// > is one (1).
29
///
30
/// [RFC5915 Section 3]: https://datatracker.ietf.org/doc/html/rfc5915#section-3
31
const VERSION: u8 = 1;
32
33
/// Context-specific tag number for the elliptic curve parameters.
34
const EC_PARAMETERS_TAG: TagNumber = TagNumber::new(0);
35
36
/// Context-specific tag number for the public key.
37
const PUBLIC_KEY_TAG: TagNumber = TagNumber::new(1);
38
39
/// SEC1 elliptic curve private key.
40
///
41
/// Described in [SEC1: Elliptic Curve Cryptography (Version 2.0)]
42
/// Appendix C.4 (p.108) and also [RFC5915 Section 3]:
43
///
44
/// ```text
45
/// ECPrivateKey ::= SEQUENCE {
46
///   version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
47
///   privateKey     OCTET STRING,
48
///   parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
49
///   publicKey  [1] BIT STRING OPTIONAL
50
/// }
51
/// ```
52
///
53
/// When encoded as PEM (text), keys in this format begin with the following:
54
///
55
/// ```text
56
/// -----BEGIN EC PRIVATE KEY-----
57
/// ```
58
///
59
/// [SEC1: Elliptic Curve Cryptography (Version 2.0)]: https://www.secg.org/sec1-v2.pdf
60
/// [RFC5915 Section 3]: https://datatracker.ietf.org/doc/html/rfc5915#section-3
61
#[derive(Clone)]
62
pub struct EcPrivateKey<'a> {
63
    /// Private key data.
64
    pub private_key: &'a [u8],
65
66
    /// Elliptic curve parameters.
67
    pub parameters: Option<EcParameters>,
68
69
    /// Public key data, optionally available if version is V2.
70
    pub public_key: Option<&'a [u8]>,
71
}
72
73
impl<'a> EcPrivateKey<'a> {
74
0
    fn context_specific_parameters(&self) -> Option<ContextSpecificRef<'_, EcParameters>> {
75
0
        self.parameters.as_ref().map(|params| ContextSpecificRef {
76
0
            tag_number: EC_PARAMETERS_TAG,
77
0
            tag_mode: TagMode::Explicit,
78
0
            value: params,
79
0
        })
80
0
    }
81
82
0
    fn context_specific_public_key(
83
0
        &self,
84
0
    ) -> der::Result<Option<ContextSpecific<BitStringRef<'a>>>> {
85
0
        self.public_key
86
0
            .map(|pk| {
87
0
                BitStringRef::from_bytes(pk).map(|value| ContextSpecific {
88
0
                    tag_number: PUBLIC_KEY_TAG,
89
0
                    tag_mode: TagMode::Explicit,
90
0
                    value,
91
0
                })
92
0
            })
93
0
            .transpose()
94
0
    }
95
}
96
97
impl<'a> DecodeValue<'a> for EcPrivateKey<'a> {
98
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
99
0
        reader.read_nested(header.length, |reader| {
100
0
            if u8::decode(reader)? != VERSION {
101
0
                return Err(der::Tag::Integer.value_error());
102
0
            }
103
104
0
            let private_key = OctetStringRef::decode(reader)?.as_bytes();
105
0
            let parameters = reader.context_specific(EC_PARAMETERS_TAG, TagMode::Explicit)?;
106
0
            let public_key = reader
107
0
                .context_specific::<BitStringRef<'_>>(PUBLIC_KEY_TAG, TagMode::Explicit)?
108
0
                .map(|bs| bs.as_bytes().ok_or_else(|| Tag::BitString.value_error()))
109
0
                .transpose()?;
110
111
0
            Ok(EcPrivateKey {
112
0
                private_key,
113
0
                parameters,
114
0
                public_key,
115
0
            })
116
0
        })
117
0
    }
118
}
119
120
impl EncodeValue for EcPrivateKey<'_> {
121
0
    fn value_len(&self) -> der::Result<Length> {
122
0
        VERSION.encoded_len()?
123
0
            + OctetStringRef::new(self.private_key)?.encoded_len()?
124
0
            + self.context_specific_parameters().encoded_len()?
125
0
            + self.context_specific_public_key()?.encoded_len()?
126
0
    }
127
128
0
    fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
129
0
        VERSION.encode(writer)?;
130
0
        OctetStringRef::new(self.private_key)?.encode(writer)?;
131
0
        self.context_specific_parameters().encode(writer)?;
132
0
        self.context_specific_public_key()?.encode(writer)?;
133
0
        Ok(())
134
0
    }
135
}
136
137
impl<'a> Sequence<'a> for EcPrivateKey<'a> {}
138
139
impl<'a> TryFrom<&'a [u8]> for EcPrivateKey<'a> {
140
    type Error = Error;
141
142
0
    fn try_from(bytes: &'a [u8]) -> Result<EcPrivateKey<'a>> {
143
0
        Ok(Self::from_der(bytes)?)
144
0
    }
145
}
146
147
impl<'a> fmt::Debug for EcPrivateKey<'a> {
148
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149
0
        f.debug_struct("EcPrivateKey")
150
0
            .field("parameters", &self.parameters)
151
0
            .field("public_key", &self.public_key)
152
0
            .finish_non_exhaustive()
153
0
    }
154
}
155
156
#[cfg(feature = "alloc")]
157
impl TryFrom<EcPrivateKey<'_>> for SecretDocument {
158
    type Error = Error;
159
160
0
    fn try_from(private_key: EcPrivateKey<'_>) -> Result<Self> {
161
0
        SecretDocument::try_from(&private_key)
162
0
    }
163
}
164
165
#[cfg(feature = "alloc")]
166
impl TryFrom<&EcPrivateKey<'_>> for SecretDocument {
167
    type Error = Error;
168
169
0
    fn try_from(private_key: &EcPrivateKey<'_>) -> Result<Self> {
170
0
        Ok(Self::encode_msg(private_key)?)
171
0
    }
172
}
173
174
#[cfg(feature = "pem")]
175
impl PemLabel for EcPrivateKey<'_> {
176
    const PEM_LABEL: &'static str = "EC PRIVATE KEY";
177
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sec1-0.7.3/src/traits.rs
Line
Count
Source
1
//! Traits for parsing objects from SEC1 encoded documents
2
3
use crate::Result;
4
5
#[cfg(feature = "alloc")]
6
use der::SecretDocument;
7
8
#[cfg(feature = "pem")]
9
use {crate::LineEnding, alloc::string::String, der::pem::PemLabel};
10
11
#[cfg(feature = "pkcs8")]
12
use {
13
    crate::{EcPrivateKey, ALGORITHM_OID},
14
    der::Decode,
15
};
16
17
#[cfg(feature = "std")]
18
use std::path::Path;
19
20
#[cfg(feature = "pem")]
21
use zeroize::Zeroizing;
22
23
/// Parse an [`EcPrivateKey`] from a SEC1-encoded document.
24
pub trait DecodeEcPrivateKey: Sized {
25
    /// Deserialize SEC1 private key from ASN.1 DER-encoded data
26
    /// (binary format).
27
    fn from_sec1_der(bytes: &[u8]) -> Result<Self>;
28
29
    /// Deserialize SEC1-encoded private key from PEM.
30
    ///
31
    /// Keys in this format begin with the following:
32
    ///
33
    /// ```text
34
    /// -----BEGIN EC PRIVATE KEY-----
35
    /// ```
36
    #[cfg(feature = "pem")]
37
0
    fn from_sec1_pem(s: &str) -> Result<Self> {
38
0
        let (label, doc) = SecretDocument::from_pem(s)?;
39
0
        EcPrivateKey::validate_pem_label(label)?;
40
0
        Self::from_sec1_der(doc.as_bytes())
41
0
    }
42
43
    /// Load SEC1 private key from an ASN.1 DER-encoded file on the local
44
    /// filesystem (binary format).
45
    #[cfg(feature = "std")]
46
0
    fn read_sec1_der_file(path: impl AsRef<Path>) -> Result<Self> {
47
0
        Self::from_sec1_der(SecretDocument::read_der_file(path)?.as_bytes())
48
0
    }
49
50
    /// Load SEC1 private key from a PEM-encoded file on the local filesystem.
51
    #[cfg(all(feature = "pem", feature = "std"))]
52
0
    fn read_sec1_pem_file(path: impl AsRef<Path>) -> Result<Self> {
53
0
        let (label, doc) = SecretDocument::read_pem_file(path)?;
54
0
        EcPrivateKey::validate_pem_label(&label)?;
55
0
        Self::from_sec1_der(doc.as_bytes())
56
0
    }
57
}
58
59
/// Serialize a [`EcPrivateKey`] to a SEC1 encoded document.
60
#[cfg(feature = "alloc")]
61
pub trait EncodeEcPrivateKey {
62
    /// Serialize a [`SecretDocument`] containing a SEC1-encoded private key.
63
    fn to_sec1_der(&self) -> Result<SecretDocument>;
64
65
    /// Serialize this private key as PEM-encoded SEC1 with the given [`LineEnding`].
66
    ///
67
    /// To use the OS's native line endings, pass `Default::default()`.
68
    #[cfg(feature = "pem")]
69
0
    fn to_sec1_pem(&self, line_ending: LineEnding) -> Result<Zeroizing<String>> {
70
0
        let doc = self.to_sec1_der()?;
71
0
        Ok(doc.to_pem(EcPrivateKey::PEM_LABEL, line_ending)?)
72
0
    }
73
74
    /// Write ASN.1 DER-encoded SEC1 private key to the given path.
75
    #[cfg(feature = "std")]
76
0
    fn write_sec1_der_file(&self, path: impl AsRef<Path>) -> Result<()> {
77
0
        Ok(self.to_sec1_der()?.write_der_file(path)?)
78
0
    }
79
80
    /// Write ASN.1 DER-encoded SEC1 private key to the given path.
81
    #[cfg(all(feature = "pem", feature = "std"))]
82
0
    fn write_sec1_pem_file(&self, path: impl AsRef<Path>, line_ending: LineEnding) -> Result<()> {
83
0
        let doc = self.to_sec1_der()?;
84
0
        Ok(doc.write_pem_file(path, EcPrivateKey::PEM_LABEL, line_ending)?)
85
0
    }
86
}
87
88
#[cfg(feature = "pkcs8")]
89
impl<T> DecodeEcPrivateKey for T
90
where
91
    T: for<'a> TryFrom<pkcs8::PrivateKeyInfo<'a>, Error = pkcs8::Error>,
92
{
93
0
    fn from_sec1_der(private_key: &[u8]) -> Result<Self> {
94
0
        let params_oid = EcPrivateKey::from_der(private_key)?
95
            .parameters
96
0
            .and_then(|params| params.named_curve());
97
0
98
0
        let algorithm = pkcs8::AlgorithmIdentifierRef {
99
0
            oid: ALGORITHM_OID,
100
0
            parameters: params_oid.as_ref().map(Into::into),
101
0
        };
102
0
103
0
        Ok(Self::try_from(pkcs8::PrivateKeyInfo {
104
0
            algorithm,
105
0
            private_key,
106
0
            public_key: None,
107
0
        })?)
108
0
    }
109
}
110
111
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
112
impl<T: pkcs8::EncodePrivateKey> EncodeEcPrivateKey for T {
113
0
    fn to_sec1_der(&self) -> Result<SecretDocument> {
114
0
        let doc = self.to_pkcs8_der()?;
115
0
        let pkcs8_key = pkcs8::PrivateKeyInfo::from_der(doc.as_bytes())?;
116
0
        pkcs8_key.algorithm.assert_algorithm_oid(ALGORITHM_OID)?;
117
118
0
        let mut pkcs1_key = EcPrivateKey::from_der(pkcs8_key.private_key)?;
119
0
        pkcs1_key.parameters = Some(pkcs8_key.algorithm.parameters_oid()?.into());
120
0
        pkcs1_key.try_into()
121
0
    }
122
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sha2-0.10.8/src/core_api.rs
Line
Count
Source
1
use crate::{consts, sha256::compress256, sha512::compress512};
2
use core::{fmt, slice::from_ref};
3
use digest::{
4
    block_buffer::Eager,
5
    core_api::{
6
        AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, OutputSizeUser, TruncSide,
7
        UpdateCore, VariableOutputCore,
8
    },
9
    typenum::{Unsigned, U128, U32, U64},
10
    HashMarker, InvalidOutputSize, Output,
11
};
12
13
/// Core block-level SHA-256 hasher with variable output size.
14
///
15
/// Supports initialization only for 28 and 32 byte output sizes,
16
/// i.e. 224 and 256 bits respectively.
17
#[derive(Clone)]
18
pub struct Sha256VarCore {
19
    state: consts::State256,
20
    block_len: u64,
21
}
22
23
impl HashMarker for Sha256VarCore {}
24
25
impl BlockSizeUser for Sha256VarCore {
26
    type BlockSize = U64;
27
}
28
29
impl BufferKindUser for Sha256VarCore {
30
    type BufferKind = Eager;
31
}
32
33
impl UpdateCore for Sha256VarCore {
34
    #[inline]
35
10.2k
    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
36
10.2k
        self.block_len += blocks.len() as u64;
37
10.2k
        compress256(&mut self.state, blocks);
38
10.2k
    }
Unexecuted instantiation: _RNvXs1_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api10UpdateCore13update_blocksCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs1_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api10UpdateCore13update_blocksCs2IvCg5PL8uK_11chia_traits
_RNvXs1_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api10UpdateCore13update_blocksCs4RkbDk9WRL5_5clvmr
Line
Count
Source
35
10.2k
    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
36
10.2k
        self.block_len += blocks.len() as u64;
37
10.2k
        compress256(&mut self.state, blocks);
38
10.2k
    }
Unexecuted instantiation: _RNvXs1_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api10UpdateCore13update_blocksCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs1_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api10UpdateCore13update_blocksB7_
39
}
40
41
impl OutputSizeUser for Sha256VarCore {
42
    type OutputSize = U32;
43
}
44
45
impl VariableOutputCore for Sha256VarCore {
46
    const TRUNC_SIDE: TruncSide = TruncSide::Left;
47
48
    #[inline]
49
9.63k
    fn new(output_size: usize) -> Result<Self, InvalidOutputSize> {
50
9.63k
        let state = match output_size {
51
0
            28 => consts::H256_224,
52
9.63k
            32 => consts::H256_256,
53
0
            _ => return Err(InvalidOutputSize),
54
        };
55
9.63k
        let block_len = 0;
56
9.63k
        Ok(Self { state, block_len })
57
9.63k
    }
Unexecuted instantiation: _RNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore3newCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore3newCs2IvCg5PL8uK_11chia_traits
_RNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
49
9.63k
    fn new(output_size: usize) -> Result<Self, InvalidOutputSize> {
50
9.63k
        let state = match output_size {
51
0
            28 => consts::H256_224,
52
9.63k
            32 => consts::H256_256,
53
0
            _ => return Err(InvalidOutputSize),
54
        };
55
9.63k
        let block_len = 0;
56
9.63k
        Ok(Self { state, block_len })
57
9.63k
    }
Unexecuted instantiation: _RNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore3newCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore3newB7_
58
59
    #[inline]
60
9.60k
    fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
61
9.60k
        let bs = Self::BlockSize::U64;
62
9.60k
        let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len);
63
9.94k
        buffer.len64_padding_be(bit_len, |b| compress256(&mut self.state, from_ref(b)));
Unexecuted instantiation: _RNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB7_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0Cs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB7_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0Cs2IvCg5PL8uK_11chia_traits
_RNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB7_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
63
9.94k
        buffer.len64_padding_be(bit_len, |b| compress256(&mut self.state, from_ref(b)));
Unexecuted instantiation: _RNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB7_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0CsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNCNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB7_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_core0B9_
64
65
76.8k
        for (chunk, v) in out.chunks_exact_mut(4).zip(self.state.iter()) {
66
76.8k
            chunk.copy_from_slice(&v.to_be_bytes());
67
76.8k
        }
68
9.60k
    }
Unexecuted instantiation: _RNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_coreCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_coreCs2IvCg5PL8uK_11chia_traits
_RNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_coreCs4RkbDk9WRL5_5clvmr
Line
Count
Source
60
9.60k
    fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
61
9.60k
        let bs = Self::BlockSize::U64;
62
9.60k
        let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len);
63
9.60k
        buffer.len64_padding_be(bit_len, |b| compress256(&mut self.state, from_ref(b)));
64
65
76.8k
        for (chunk, v) in out.chunks_exact_mut(4).zip(self.state.iter()) {
66
76.8k
            chunk.copy_from_slice(&v.to_be_bytes());
67
76.8k
        }
68
9.60k
    }
Unexecuted instantiation: _RNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_coreCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs3_NtCs23lnNM1woOA_4sha28core_apiNtB5_13Sha256VarCoreNtNtCsfSiVvAzsu9K_6digest8core_api18VariableOutputCore22finalize_variable_coreB7_
69
}
70
71
impl AlgorithmName for Sha256VarCore {
72
    #[inline]
73
0
    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
74
0
        f.write_str("Sha256")
75
0
    }
76
}
77
78
impl fmt::Debug for Sha256VarCore {
79
    #[inline]
80
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81
0
        f.write_str("Sha256VarCore { ... }")
82
0
    }
83
}
84
85
/// Core block-level SHA-512 hasher with variable output size.
86
///
87
/// Supports initialization only for 28, 32, 48, and 64 byte output sizes,
88
/// i.e. 224, 256, 384, and 512 bits respectively.
89
#[derive(Clone)]
90
pub struct Sha512VarCore {
91
    state: consts::State512,
92
    block_len: u128,
93
}
94
95
impl HashMarker for Sha512VarCore {}
96
97
impl BlockSizeUser for Sha512VarCore {
98
    type BlockSize = U128;
99
}
100
101
impl BufferKindUser for Sha512VarCore {
102
    type BufferKind = Eager;
103
}
104
105
impl UpdateCore for Sha512VarCore {
106
    #[inline]
107
0
    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
108
0
        self.block_len += blocks.len() as u128;
109
0
        compress512(&mut self.state, blocks);
110
0
    }
111
}
112
113
impl OutputSizeUser for Sha512VarCore {
114
    type OutputSize = U64;
115
}
116
117
impl VariableOutputCore for Sha512VarCore {
118
    const TRUNC_SIDE: TruncSide = TruncSide::Left;
119
120
    #[inline]
121
0
    fn new(output_size: usize) -> Result<Self, InvalidOutputSize> {
122
0
        let state = match output_size {
123
0
            28 => consts::H512_224,
124
0
            32 => consts::H512_256,
125
0
            48 => consts::H512_384,
126
0
            64 => consts::H512_512,
127
0
            _ => return Err(InvalidOutputSize),
128
        };
129
0
        let block_len = 0;
130
0
        Ok(Self { state, block_len })
131
0
    }
132
133
    #[inline]
134
0
    fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
135
0
        let bs = Self::BlockSize::U64 as u128;
136
0
        let bit_len = 8 * (buffer.get_pos() as u128 + bs * self.block_len);
137
0
        buffer.len128_padding_be(bit_len, |b| compress512(&mut self.state, from_ref(b)));
138
139
0
        for (chunk, v) in out.chunks_exact_mut(8).zip(self.state.iter()) {
140
0
            chunk.copy_from_slice(&v.to_be_bytes());
141
0
        }
142
0
    }
143
}
144
145
impl AlgorithmName for Sha512VarCore {
146
    #[inline]
147
0
    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
148
0
        f.write_str("Sha512")
149
0
    }
150
}
151
152
impl fmt::Debug for Sha512VarCore {
153
    #[inline]
154
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155
0
        f.write_str("Sha512VarCore { ... }")
156
0
    }
157
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sha2-0.10.8/src/sha256.rs
Line
Count
Source
1
use digest::{generic_array::GenericArray, typenum::U64};
2
3
cfg_if::cfg_if! {
4
    if #[cfg(feature = "force-soft")] {
5
        mod soft;
6
        use soft::compress;
7
    } else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
8
        #[cfg(not(feature = "asm"))]
9
        mod soft;
10
        #[cfg(feature = "asm")]
11
        mod soft {
12
            pub(crate) use sha2_asm::compress256 as compress;
13
        }
14
        mod x86;
15
        use x86::compress;
16
    } else if #[cfg(all(feature = "asm", target_arch = "aarch64"))] {
17
        mod soft;
18
        mod aarch64;
19
        use aarch64::compress;
20
    } else if #[cfg(all(feature = "loongarch64_asm", target_arch = "loongarch64"))] {
21
        mod loongarch64_asm;
22
        use loongarch64_asm::compress;
23
    } else {
24
        mod soft;
25
        use soft::compress;
26
    }
27
}
28
29
/// Raw SHA-256 compression function.
30
///
31
/// This is a low-level "hazmat" API which provides direct access to the core
32
/// functionality of SHA-256.
33
#[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
34
20.2k
pub fn compress256(state: &mut [u32; 8], blocks: &[GenericArray<u8, U64>]) {
35
20.2k
    // SAFETY: GenericArray<u8, U64> and [u8; 64] have
36
20.2k
    // exactly the same memory layout
37
20.2k
    let p = blocks.as_ptr() as *const [u8; 64];
38
20.2k
    let blocks = unsafe { core::slice::from_raw_parts(p, blocks.len()) };
39
20.2k
    compress(state, blocks)
40
20.2k
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sha2-0.10.8/src/sha256/soft.rs
Line
Count
Source
1
#![allow(clippy::many_single_char_names)]
2
use crate::consts::BLOCK_LEN;
3
use core::convert::TryInto;
4
5
#[inline(always)]
6
876k
fn shl(v: [u32; 4], o: u32) -> [u32; 4] {
7
876k
    [v[0] >> o, v[1] >> o, v[2] >> o, v[3] >> o]
8
876k
}
9
10
#[inline(always)]
11
584k
fn shr(v: [u32; 4], o: u32) -> [u32; 4] {
12
584k
    [v[0] << o, v[1] << o, v[2] << o, v[3] << o]
13
584k
}
14
15
#[inline(always)]
16
584k
fn or(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
17
584k
    [a[0] | b[0], a[1] | b[1], a[2] | b[2], a[3] | b[3]]
18
584k
}
19
20
#[inline(always)]
21
584k
fn xor(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
22
584k
    [a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]]
23
584k
}
24
25
#[inline(always)]
26
973k
fn add(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
27
973k
    [
28
973k
        a[0].wrapping_add(b[0]),
29
973k
        a[1].wrapping_add(b[1]),
30
973k
        a[2].wrapping_add(b[2]),
31
973k
        a[3].wrapping_add(b[3]),
32
973k
    ]
33
973k
}
34
35
584k
fn sha256load(v2: [u32; 4], v3: [u32; 4]) -> [u32; 4] {
36
584k
    [v3[3], v2[0], v2[1], v2[2]]
37
584k
}
38
39
389k
fn sha256swap(v0: [u32; 4]) -> [u32; 4] {
40
389k
    [v0[2], v0[3], v0[0], v0[1]]
41
389k
}
42
43
292k
fn sha256msg1(v0: [u32; 4], v1: [u32; 4]) -> [u32; 4] {
44
    // sigma 0 on vectors
45
    #[inline]
46
292k
    fn sigma0x4(x: [u32; 4]) -> [u32; 4] {
47
292k
        let t1 = or(shl(x, 7), shr(x, 25));
48
292k
        let t2 = or(shl(x, 18), shr(x, 14));
49
292k
        let t3 = shl(x, 3);
50
292k
        xor(xor(t1, t2), t3)
51
292k
    }
52
53
292k
    add(v0, sigma0x4(sha256load(v0, v1)))
54
292k
}
55
56
292k
fn sha256msg2(v4: [u32; 4], v3: [u32; 4]) -> [u32; 4] {
57
    macro_rules! sigma1 {
58
        ($a:expr) => {
59
            $a.rotate_right(17) ^ $a.rotate_right(19) ^ ($a >> 10)
60
        };
61
    }
62
63
292k
    let [x3, x2, x1, x0] = v4;
64
292k
    let [w15, w14, _, _] = v3;
65
292k
66
292k
    let w16 = x0.wrapping_add(sigma1!(w14));
67
292k
    let w17 = x1.wrapping_add(sigma1!(w15));
68
292k
    let w18 = x2.wrapping_add(sigma1!(w16));
69
292k
    let w19 = x3.wrapping_add(sigma1!(w17));
70
292k
71
292k
    [w19, w18, w17, w16]
72
292k
}
73
74
778k
fn sha256_digest_round_x2(cdgh: [u32; 4], abef: [u32; 4], wk: [u32; 4]) -> [u32; 4] {
75
    macro_rules! big_sigma0 {
76
        ($a:expr) => {
77
            ($a.rotate_right(2) ^ $a.rotate_right(13) ^ $a.rotate_right(22))
78
        };
79
    }
80
    macro_rules! big_sigma1 {
81
        ($a:expr) => {
82
            ($a.rotate_right(6) ^ $a.rotate_right(11) ^ $a.rotate_right(25))
83
        };
84
    }
85
    macro_rules! bool3ary_202 {
86
        ($a:expr, $b:expr, $c:expr) => {
87
            $c ^ ($a & ($b ^ $c))
88
        };
89
    } // Choose, MD5F, SHA1C
90
    macro_rules! bool3ary_232 {
91
        ($a:expr, $b:expr, $c:expr) => {
92
            ($a & $b) ^ ($a & $c) ^ ($b & $c)
93
        };
94
    } // Majority, SHA1M
95
96
778k
    let [_, _, wk1, wk0] = wk;
97
778k
    let [a0, b0, e0, f0] = abef;
98
778k
    let [c0, d0, g0, h0] = cdgh;
99
778k
100
778k
    // a round
101
778k
    let x0 = big_sigma1!(e0)
102
778k
        .wrapping_add(bool3ary_202!(e0, f0, g0))
103
778k
        .wrapping_add(wk0)
104
778k
        .wrapping_add(h0);
105
778k
    let y0 = big_sigma0!(a0).wrapping_add(bool3ary_232!(a0, b0, c0));
106
778k
    let (a1, b1, c1, d1, e1, f1, g1, h1) = (
107
778k
        x0.wrapping_add(y0),
108
778k
        a0,
109
778k
        b0,
110
778k
        c0,
111
778k
        x0.wrapping_add(d0),
112
778k
        e0,
113
778k
        f0,
114
778k
        g0,
115
778k
    );
116
778k
117
778k
    // a round
118
778k
    let x1 = big_sigma1!(e1)
119
778k
        .wrapping_add(bool3ary_202!(e1, f1, g1))
120
778k
        .wrapping_add(wk1)
121
778k
        .wrapping_add(h1);
122
778k
    let y1 = big_sigma0!(a1).wrapping_add(bool3ary_232!(a1, b1, c1));
123
778k
    let (a2, b2, _, _, e2, f2, _, _) = (
124
778k
        x1.wrapping_add(y1),
125
778k
        a1,
126
778k
        b1,
127
778k
        c1,
128
778k
        x1.wrapping_add(d1),
129
778k
        e1,
130
778k
        f1,
131
778k
        g1,
132
778k
    );
133
778k
134
778k
    [a2, b2, e2, f2]
135
778k
}
136
137
292k
fn schedule(v0: [u32; 4], v1: [u32; 4], v2: [u32; 4], v3: [u32; 4]) -> [u32; 4] {
138
292k
    let t1 = sha256msg1(v0, v1);
139
292k
    let t2 = sha256load(v2, v3);
140
292k
    let t3 = add(t1, t2);
141
292k
    sha256msg2(t3, v3)
142
292k
}
143
144
macro_rules! rounds4 {
145
    ($abef:ident, $cdgh:ident, $rest:expr, $i:expr) => {{
146
        let t1 = add($rest, crate::consts::K32X4[$i]);
147
        $cdgh = sha256_digest_round_x2($cdgh, $abef, t1);
148
        let t2 = sha256swap(t1);
149
        $abef = sha256_digest_round_x2($abef, $cdgh, t2);
150
    }};
151
}
152
153
macro_rules! schedule_rounds4 {
154
    (
155
        $abef:ident, $cdgh:ident,
156
        $w0:expr, $w1:expr, $w2:expr, $w3:expr, $w4:expr,
157
        $i: expr
158
    ) => {{
159
        $w4 = schedule($w0, $w1, $w2, $w3);
160
        rounds4!($abef, $cdgh, $w4, $i);
161
    }};
162
}
163
164
/// Process a block with the SHA-256 algorithm.
165
24.3k
fn sha256_digest_block_u32(state: &mut [u32; 8], block: &[u32; 16]) {
166
24.3k
    let mut abef = [state[0], state[1], state[4], state[5]];
167
24.3k
    let mut cdgh = [state[2], state[3], state[6], state[7]];
168
24.3k
169
24.3k
    // Rounds 0..64
170
24.3k
    let mut w0 = [block[3], block[2], block[1], block[0]];
171
24.3k
    let mut w1 = [block[7], block[6], block[5], block[4]];
172
24.3k
    let mut w2 = [block[11], block[10], block[9], block[8]];
173
24.3k
    let mut w3 = [block[15], block[14], block[13], block[12]];
174
24.3k
    let mut w4;
175
24.3k
176
24.3k
    rounds4!(abef, cdgh, w0, 0);
177
24.3k
    rounds4!(abef, cdgh, w1, 1);
178
24.3k
    rounds4!(abef, cdgh, w2, 2);
179
24.3k
    rounds4!(abef, cdgh, w3, 3);
180
24.3k
    schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 4);
181
24.3k
    schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 5);
182
24.3k
    schedule_rounds4!(abef, cdgh, w2, w3, w4, w0, w1, 6);
183
24.3k
    schedule_rounds4!(abef, cdgh, w3, w4, w0, w1, w2, 7);
184
24.3k
    schedule_rounds4!(abef, cdgh, w4, w0, w1, w2, w3, 8);
185
24.3k
    schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 9);
186
24.3k
    schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 10);
187
24.3k
    schedule_rounds4!(abef, cdgh, w2, w3, w4, w0, w1, 11);
188
24.3k
    schedule_rounds4!(abef, cdgh, w3, w4, w0, w1, w2, 12);
189
24.3k
    schedule_rounds4!(abef, cdgh, w4, w0, w1, w2, w3, 13);
190
24.3k
    schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 14);
191
24.3k
    schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 15);
192
24.3k
193
24.3k
    let [a, b, e, f] = abef;
194
24.3k
    let [c, d, g, h] = cdgh;
195
24.3k
196
24.3k
    state[0] = state[0].wrapping_add(a);
197
24.3k
    state[1] = state[1].wrapping_add(b);
198
24.3k
    state[2] = state[2].wrapping_add(c);
199
24.3k
    state[3] = state[3].wrapping_add(d);
200
24.3k
    state[4] = state[4].wrapping_add(e);
201
24.3k
    state[5] = state[5].wrapping_add(f);
202
24.3k
    state[6] = state[6].wrapping_add(g);
203
24.3k
    state[7] = state[7].wrapping_add(h);
204
24.3k
}
205
206
20.2k
pub fn compress(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
207
20.2k
    let mut block_u32 = [0u32; BLOCK_LEN];
208
20.2k
    // since LLVM can't properly use aliasing yet it will make
209
20.2k
    // unnecessary state stores without this copy
210
20.2k
    let mut state_cpy = *state;
211
44.5k
    for block in blocks {
212
389k
        for (o, chunk) in block_u32.iter_mut().zip(block.chunks_exact(4)) {
213
389k
            *o = u32::from_be_bytes(chunk.try_into().unwrap());
214
389k
        }
215
24.3k
        sha256_digest_block_u32(&mut state_cpy, &block_u32);
216
    }
217
20.2k
    *state = state_cpy;
218
20.2k
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sha2-0.10.8/src/sha256/x86.rs
Line
Count
Source
1
//! SHA-256 `x86`/`x86_64` backend
2
3
#![allow(clippy::many_single_char_names)]
4
5
#[cfg(target_arch = "x86")]
6
use core::arch::x86::*;
7
#[cfg(target_arch = "x86_64")]
8
use core::arch::x86_64::*;
9
10
0
unsafe fn schedule(v0: __m128i, v1: __m128i, v2: __m128i, v3: __m128i) -> __m128i {
11
0
    let t1 = _mm_sha256msg1_epu32(v0, v1);
12
0
    let t2 = _mm_alignr_epi8(v3, v2, 4);
13
0
    let t3 = _mm_add_epi32(t1, t2);
14
0
    _mm_sha256msg2_epu32(t3, v3)
15
0
}
16
17
macro_rules! rounds4 {
18
    ($abef:ident, $cdgh:ident, $rest:expr, $i:expr) => {{
19
        let k = crate::consts::K32X4[$i];
20
        let kv = _mm_set_epi32(k[0] as i32, k[1] as i32, k[2] as i32, k[3] as i32);
21
        let t1 = _mm_add_epi32($rest, kv);
22
        $cdgh = _mm_sha256rnds2_epu32($cdgh, $abef, t1);
23
        let t2 = _mm_shuffle_epi32(t1, 0x0E);
24
        $abef = _mm_sha256rnds2_epu32($abef, $cdgh, t2);
25
    }};
26
}
27
28
macro_rules! schedule_rounds4 {
29
    (
30
        $abef:ident, $cdgh:ident,
31
        $w0:expr, $w1:expr, $w2:expr, $w3:expr, $w4:expr,
32
        $i: expr
33
    ) => {{
34
        $w4 = schedule($w0, $w1, $w2, $w3);
35
        rounds4!($abef, $cdgh, $w4, $i);
36
    }};
37
}
38
39
// we use unaligned loads with `__m128i` pointers
40
#[allow(clippy::cast_ptr_alignment)]
41
#[target_feature(enable = "sha,sse2,ssse3,sse4.1")]
42
0
unsafe fn digest_blocks(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
43
0
    #[allow(non_snake_case)]
44
0
    let MASK: __m128i = _mm_set_epi64x(
45
0
        0x0C0D_0E0F_0809_0A0Bu64 as i64,
46
0
        0x0405_0607_0001_0203u64 as i64,
47
0
    );
48
0
49
0
    let state_ptr = state.as_ptr() as *const __m128i;
50
0
    let dcba = _mm_loadu_si128(state_ptr.add(0));
51
0
    let efgh = _mm_loadu_si128(state_ptr.add(1));
52
0
53
0
    let cdab = _mm_shuffle_epi32(dcba, 0xB1);
54
0
    let efgh = _mm_shuffle_epi32(efgh, 0x1B);
55
0
    let mut abef = _mm_alignr_epi8(cdab, efgh, 8);
56
0
    let mut cdgh = _mm_blend_epi16(efgh, cdab, 0xF0);
57
58
0
    for block in blocks {
59
0
        let abef_save = abef;
60
0
        let cdgh_save = cdgh;
61
0
62
0
        let data_ptr = block.as_ptr() as *const __m128i;
63
0
        let mut w0 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(0)), MASK);
64
0
        let mut w1 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(1)), MASK);
65
0
        let mut w2 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(2)), MASK);
66
0
        let mut w3 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(3)), MASK);
67
0
        let mut w4;
68
0
69
0
        rounds4!(abef, cdgh, w0, 0);
70
0
        rounds4!(abef, cdgh, w1, 1);
71
0
        rounds4!(abef, cdgh, w2, 2);
72
0
        rounds4!(abef, cdgh, w3, 3);
73
0
        schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 4);
74
0
        schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 5);
75
0
        schedule_rounds4!(abef, cdgh, w2, w3, w4, w0, w1, 6);
76
0
        schedule_rounds4!(abef, cdgh, w3, w4, w0, w1, w2, 7);
77
0
        schedule_rounds4!(abef, cdgh, w4, w0, w1, w2, w3, 8);
78
0
        schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 9);
79
0
        schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 10);
80
0
        schedule_rounds4!(abef, cdgh, w2, w3, w4, w0, w1, 11);
81
0
        schedule_rounds4!(abef, cdgh, w3, w4, w0, w1, w2, 12);
82
0
        schedule_rounds4!(abef, cdgh, w4, w0, w1, w2, w3, 13);
83
0
        schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 14);
84
0
        schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 15);
85
0
86
0
        abef = _mm_add_epi32(abef, abef_save);
87
0
        cdgh = _mm_add_epi32(cdgh, cdgh_save);
88
0
    }
89
90
0
    let feba = _mm_shuffle_epi32(abef, 0x1B);
91
0
    let dchg = _mm_shuffle_epi32(cdgh, 0xB1);
92
0
    let dcba = _mm_blend_epi16(feba, dchg, 0xF0);
93
0
    let hgef = _mm_alignr_epi8(dchg, feba, 8);
94
0
95
0
    let state_ptr_mut = state.as_mut_ptr() as *mut __m128i;
96
0
    _mm_storeu_si128(state_ptr_mut.add(0), dcba);
97
0
    _mm_storeu_si128(state_ptr_mut.add(1), hgef);
98
0
}
99
100
cpufeatures::new!(shani_cpuid, "sha", "sse2", "ssse3", "sse4.1");
101
102
20.2k
pub fn compress(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
103
20.2k
    // TODO: Replace with https://github.com/rust-lang/rfcs/pull/2725
104
20.2k
    // after stabilization
105
20.2k
    if shani_cpuid::get() {
106
0
        unsafe {
107
0
            digest_blocks(state, blocks);
108
0
        }
109
20.2k
    } else {
110
20.2k
        super::soft::compress(state, blocks);
111
20.2k
    }
112
20.2k
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sha2-0.10.8/src/sha512.rs
Line
Count
Source
1
use digest::{generic_array::GenericArray, typenum::U128};
2
3
cfg_if::cfg_if! {
4
    if #[cfg(feature = "force-soft")] {
5
        mod soft;
6
        use soft::compress;
7
    } else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
8
        #[cfg(not(feature = "asm"))]
9
        mod soft;
10
        #[cfg(feature = "asm")]
11
        mod soft {
12
            pub(crate) fn compress(state: &mut [u64; 8], blocks: &[[u8; 128]]) {
13
                sha2_asm::compress512(state, blocks);
14
            }
15
        }
16
        mod x86;
17
        use x86::compress;
18
    } else if #[cfg(all(feature = "asm", target_arch = "aarch64"))] {
19
        mod soft;
20
        mod aarch64;
21
        use aarch64::compress;
22
    } else if #[cfg(all(feature = "loongarch64_asm", target_arch = "loongarch64"))] {
23
        mod loongarch64_asm;
24
        use loongarch64_asm::compress;
25
    } else {
26
        mod soft;
27
        use soft::compress;
28
    }
29
}
30
31
/// Raw SHA-512 compression function.
32
///
33
/// This is a low-level "hazmat" API which provides direct access to the core
34
/// functionality of SHA-512.
35
#[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
36
0
pub fn compress512(state: &mut [u64; 8], blocks: &[GenericArray<u8, U128>]) {
37
0
    // SAFETY: GenericArray<u8, U64> and [u8; 64] have
38
0
    // exactly the same memory layout
39
0
    let p = blocks.as_ptr() as *const [u8; 128];
40
0
    let blocks = unsafe { core::slice::from_raw_parts(p, blocks.len()) };
41
0
    compress(state, blocks)
42
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sha2-0.10.8/src/sha512/soft.rs
Line
Count
Source
1
#![allow(clippy::many_single_char_names)]
2
use crate::consts::{BLOCK_LEN, K64X2};
3
use core::convert::TryInto;
4
5
0
fn add(a: [u64; 2], b: [u64; 2]) -> [u64; 2] {
6
0
    [a[0].wrapping_add(b[0]), a[1].wrapping_add(b[1])]
7
0
}
8
9
/// Not an intrinsic, but works like an unaligned load.
10
0
fn sha512load(v0: [u64; 2], v1: [u64; 2]) -> [u64; 2] {
11
0
    [v1[1], v0[0]]
12
0
}
13
14
/// Performs 2 rounds of the SHA-512 message schedule update.
15
0
pub fn sha512_schedule_x2(v0: [u64; 2], v1: [u64; 2], v4to5: [u64; 2], v7: [u64; 2]) -> [u64; 2] {
16
    // sigma 0
17
0
    fn sigma0(x: u64) -> u64 {
18
0
        ((x << 63) | (x >> 1)) ^ ((x << 56) | (x >> 8)) ^ (x >> 7)
19
0
    }
20
21
    // sigma 1
22
0
    fn sigma1(x: u64) -> u64 {
23
0
        ((x << 45) | (x >> 19)) ^ ((x << 3) | (x >> 61)) ^ (x >> 6)
24
0
    }
25
26
0
    let [w1, w0] = v0;
27
0
    let [_, w2] = v1;
28
0
    let [w10, w9] = v4to5;
29
0
    let [w15, w14] = v7;
30
0
31
0
    let w16 = sigma1(w14)
32
0
        .wrapping_add(w9)
33
0
        .wrapping_add(sigma0(w1))
34
0
        .wrapping_add(w0);
35
0
    let w17 = sigma1(w15)
36
0
        .wrapping_add(w10)
37
0
        .wrapping_add(sigma0(w2))
38
0
        .wrapping_add(w1);
39
0
40
0
    [w17, w16]
41
0
}
42
43
/// Performs one round of the SHA-512 message block digest.
44
0
pub fn sha512_digest_round(
45
0
    ae: [u64; 2],
46
0
    bf: [u64; 2],
47
0
    cg: [u64; 2],
48
0
    dh: [u64; 2],
49
0
    wk0: u64,
50
0
) -> [u64; 2] {
51
    macro_rules! big_sigma0 {
52
        ($a:expr) => {
53
            ($a.rotate_right(28) ^ $a.rotate_right(34) ^ $a.rotate_right(39))
54
        };
55
    }
56
    macro_rules! big_sigma1 {
57
        ($a:expr) => {
58
            ($a.rotate_right(14) ^ $a.rotate_right(18) ^ $a.rotate_right(41))
59
        };
60
    }
61
    macro_rules! bool3ary_202 {
62
        ($a:expr, $b:expr, $c:expr) => {
63
            $c ^ ($a & ($b ^ $c))
64
        };
65
    } // Choose, MD5F, SHA1C
66
    macro_rules! bool3ary_232 {
67
        ($a:expr, $b:expr, $c:expr) => {
68
            ($a & $b) ^ ($a & $c) ^ ($b & $c)
69
        };
70
    } // Majority, SHA1M
71
72
0
    let [a0, e0] = ae;
73
0
    let [b0, f0] = bf;
74
0
    let [c0, g0] = cg;
75
0
    let [d0, h0] = dh;
76
0
77
0
    // a round
78
0
    let x0 = big_sigma1!(e0)
79
0
        .wrapping_add(bool3ary_202!(e0, f0, g0))
80
0
        .wrapping_add(wk0)
81
0
        .wrapping_add(h0);
82
0
    let y0 = big_sigma0!(a0).wrapping_add(bool3ary_232!(a0, b0, c0));
83
0
    let (a1, _, _, _, e1, _, _, _) = (
84
0
        x0.wrapping_add(y0),
85
0
        a0,
86
0
        b0,
87
0
        c0,
88
0
        x0.wrapping_add(d0),
89
0
        e0,
90
0
        f0,
91
0
        g0,
92
0
    );
93
0
94
0
    [a1, e1]
95
0
}
96
97
/// Process a block with the SHA-512 algorithm.
98
0
pub fn sha512_digest_block_u64(state: &mut [u64; 8], block: &[u64; 16]) {
99
0
    let k = &K64X2;
100
101
    macro_rules! schedule {
102
        ($v0:expr, $v1:expr, $v4:expr, $v5:expr, $v7:expr) => {
103
            sha512_schedule_x2($v0, $v1, sha512load($v4, $v5), $v7)
104
        };
105
    }
106
107
    macro_rules! rounds4 {
108
        ($ae:ident, $bf:ident, $cg:ident, $dh:ident, $wk0:expr, $wk1:expr) => {{
109
            let [u, t] = $wk0;
110
            let [w, v] = $wk1;
111
112
            $dh = sha512_digest_round($ae, $bf, $cg, $dh, t);
113
            $cg = sha512_digest_round($dh, $ae, $bf, $cg, u);
114
            $bf = sha512_digest_round($cg, $dh, $ae, $bf, v);
115
            $ae = sha512_digest_round($bf, $cg, $dh, $ae, w);
116
        }};
117
    }
118
119
0
    let mut ae = [state[0], state[4]];
120
0
    let mut bf = [state[1], state[5]];
121
0
    let mut cg = [state[2], state[6]];
122
0
    let mut dh = [state[3], state[7]];
123
0
124
0
    // Rounds 0..20
125
0
    let (mut w1, mut w0) = ([block[3], block[2]], [block[1], block[0]]);
126
0
    rounds4!(ae, bf, cg, dh, add(k[0], w0), add(k[1], w1));
127
0
    let (mut w3, mut w2) = ([block[7], block[6]], [block[5], block[4]]);
128
0
    rounds4!(ae, bf, cg, dh, add(k[2], w2), add(k[3], w3));
129
0
    let (mut w5, mut w4) = ([block[11], block[10]], [block[9], block[8]]);
130
0
    rounds4!(ae, bf, cg, dh, add(k[4], w4), add(k[5], w5));
131
0
    let (mut w7, mut w6) = ([block[15], block[14]], [block[13], block[12]]);
132
0
    rounds4!(ae, bf, cg, dh, add(k[6], w6), add(k[7], w7));
133
0
    let mut w8 = schedule!(w0, w1, w4, w5, w7);
134
0
    let mut w9 = schedule!(w1, w2, w5, w6, w8);
135
0
    rounds4!(ae, bf, cg, dh, add(k[8], w8), add(k[9], w9));
136
0
137
0
    // Rounds 20..40
138
0
    w0 = schedule!(w2, w3, w6, w7, w9);
139
0
    w1 = schedule!(w3, w4, w7, w8, w0);
140
0
    rounds4!(ae, bf, cg, dh, add(k[10], w0), add(k[11], w1));
141
0
    w2 = schedule!(w4, w5, w8, w9, w1);
142
0
    w3 = schedule!(w5, w6, w9, w0, w2);
143
0
    rounds4!(ae, bf, cg, dh, add(k[12], w2), add(k[13], w3));
144
0
    w4 = schedule!(w6, w7, w0, w1, w3);
145
0
    w5 = schedule!(w7, w8, w1, w2, w4);
146
0
    rounds4!(ae, bf, cg, dh, add(k[14], w4), add(k[15], w5));
147
0
    w6 = schedule!(w8, w9, w2, w3, w5);
148
0
    w7 = schedule!(w9, w0, w3, w4, w6);
149
0
    rounds4!(ae, bf, cg, dh, add(k[16], w6), add(k[17], w7));
150
0
    w8 = schedule!(w0, w1, w4, w5, w7);
151
0
    w9 = schedule!(w1, w2, w5, w6, w8);
152
0
    rounds4!(ae, bf, cg, dh, add(k[18], w8), add(k[19], w9));
153
0
154
0
    // Rounds 40..60
155
0
    w0 = schedule!(w2, w3, w6, w7, w9);
156
0
    w1 = schedule!(w3, w4, w7, w8, w0);
157
0
    rounds4!(ae, bf, cg, dh, add(k[20], w0), add(k[21], w1));
158
0
    w2 = schedule!(w4, w5, w8, w9, w1);
159
0
    w3 = schedule!(w5, w6, w9, w0, w2);
160
0
    rounds4!(ae, bf, cg, dh, add(k[22], w2), add(k[23], w3));
161
0
    w4 = schedule!(w6, w7, w0, w1, w3);
162
0
    w5 = schedule!(w7, w8, w1, w2, w4);
163
0
    rounds4!(ae, bf, cg, dh, add(k[24], w4), add(k[25], w5));
164
0
    w6 = schedule!(w8, w9, w2, w3, w5);
165
0
    w7 = schedule!(w9, w0, w3, w4, w6);
166
0
    rounds4!(ae, bf, cg, dh, add(k[26], w6), add(k[27], w7));
167
0
    w8 = schedule!(w0, w1, w4, w5, w7);
168
0
    w9 = schedule!(w1, w2, w5, w6, w8);
169
0
    rounds4!(ae, bf, cg, dh, add(k[28], w8), add(k[29], w9));
170
0
171
0
    // Rounds 60..80
172
0
    w0 = schedule!(w2, w3, w6, w7, w9);
173
0
    w1 = schedule!(w3, w4, w7, w8, w0);
174
0
    rounds4!(ae, bf, cg, dh, add(k[30], w0), add(k[31], w1));
175
0
    w2 = schedule!(w4, w5, w8, w9, w1);
176
0
    w3 = schedule!(w5, w6, w9, w0, w2);
177
0
    rounds4!(ae, bf, cg, dh, add(k[32], w2), add(k[33], w3));
178
0
    w4 = schedule!(w6, w7, w0, w1, w3);
179
0
    w5 = schedule!(w7, w8, w1, w2, w4);
180
0
    rounds4!(ae, bf, cg, dh, add(k[34], w4), add(k[35], w5));
181
0
    w6 = schedule!(w8, w9, w2, w3, w5);
182
0
    w7 = schedule!(w9, w0, w3, w4, w6);
183
0
    rounds4!(ae, bf, cg, dh, add(k[36], w6), add(k[37], w7));
184
0
    w8 = schedule!(w0, w1, w4, w5, w7);
185
0
    w9 = schedule!(w1, w2, w5, w6, w8);
186
0
    rounds4!(ae, bf, cg, dh, add(k[38], w8), add(k[39], w9));
187
0
188
0
    let [a, e] = ae;
189
0
    let [b, f] = bf;
190
0
    let [c, g] = cg;
191
0
    let [d, h] = dh;
192
0
193
0
    state[0] = state[0].wrapping_add(a);
194
0
    state[1] = state[1].wrapping_add(b);
195
0
    state[2] = state[2].wrapping_add(c);
196
0
    state[3] = state[3].wrapping_add(d);
197
0
    state[4] = state[4].wrapping_add(e);
198
0
    state[5] = state[5].wrapping_add(f);
199
0
    state[6] = state[6].wrapping_add(g);
200
0
    state[7] = state[7].wrapping_add(h);
201
0
}
202
203
0
pub fn compress(state: &mut [u64; 8], blocks: &[[u8; 128]]) {
204
0
    let mut block_u32 = [0u64; BLOCK_LEN];
205
0
    // since LLVM can't properly use aliasing yet it will make
206
0
    // unnecessary state stores without this copy
207
0
    let mut state_cpy = *state;
208
0
    for block in blocks {
209
0
        for (o, chunk) in block_u32.iter_mut().zip(block.chunks_exact(8)) {
210
0
            *o = u64::from_be_bytes(chunk.try_into().unwrap());
211
0
        }
212
0
        sha512_digest_block_u64(&mut state_cpy, &block_u32);
213
    }
214
0
    *state = state_cpy;
215
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sha2-0.10.8/src/sha512/x86.rs
Line
Count
Source
1
//! SHA-512 `x86`/`x86_64` backend
2
3
#![allow(clippy::many_single_char_names)]
4
5
use core::mem::size_of;
6
7
#[cfg(target_arch = "x86")]
8
use core::arch::x86::*;
9
#[cfg(target_arch = "x86_64")]
10
use core::arch::x86_64::*;
11
12
use crate::consts::K64;
13
14
cpufeatures::new!(avx2_cpuid, "avx2");
15
16
0
pub fn compress(state: &mut [u64; 8], blocks: &[[u8; 128]]) {
17
0
    // TODO: Replace with https://github.com/rust-lang/rfcs/pull/2725
18
0
    // after stabilization
19
0
    if avx2_cpuid::get() {
20
0
        unsafe {
21
0
            sha512_compress_x86_64_avx2(state, blocks);
22
0
        }
23
0
    } else {
24
0
        super::soft::compress(state, blocks);
25
0
    }
26
0
}
27
28
#[target_feature(enable = "avx2")]
29
0
unsafe fn sha512_compress_x86_64_avx2(state: &mut [u64; 8], blocks: &[[u8; 128]]) {
30
0
    let mut start_block = 0;
31
0
32
0
    if blocks.len() & 0b1 != 0 {
33
0
        sha512_compress_x86_64_avx(state, &blocks[0]);
34
0
        start_block += 1;
35
0
    }
36
37
0
    let mut ms: MsgSchedule = [_mm_setzero_si128(); 8];
38
0
    let mut t2: RoundStates = [_mm_setzero_si128(); 40];
39
0
    let mut x = [_mm256_setzero_si256(); 8];
40
41
0
    for i in (start_block..blocks.len()).step_by(2) {
42
0
        load_data_avx2(&mut x, &mut ms, &mut t2, blocks.as_ptr().add(i) as *const _);
43
0
44
0
        // First block
45
0
        let mut current_state = *state;
46
0
        rounds_0_63_avx2(&mut current_state, &mut x, &mut ms, &mut t2);
47
0
        rounds_64_79(&mut current_state, &ms);
48
0
        accumulate_state(state, &current_state);
49
0
50
0
        // Second block
51
0
        current_state = *state;
52
0
        process_second_block(&mut current_state, &t2);
53
0
        accumulate_state(state, &current_state);
54
0
    }
55
0
}
56
57
#[inline(always)]
58
0
unsafe fn sha512_compress_x86_64_avx(state: &mut [u64; 8], block: &[u8; 128]) {
59
0
    let mut ms = [_mm_setzero_si128(); 8];
60
0
    let mut x = [_mm_setzero_si128(); 8];
61
0
62
0
    // Reduced to single iteration
63
0
    let mut current_state = *state;
64
0
    load_data_avx(&mut x, &mut ms, block.as_ptr() as *const _);
65
0
    rounds_0_63_avx(&mut current_state, &mut x, &mut ms);
66
0
    rounds_64_79(&mut current_state, &ms);
67
0
    accumulate_state(state, &current_state);
68
0
}
69
70
#[inline(always)]
71
0
unsafe fn load_data_avx(x: &mut [__m128i; 8], ms: &mut MsgSchedule, data: *const __m128i) {
72
0
    #[allow(non_snake_case)]
73
0
    let MASK = _mm_setr_epi32(0x04050607, 0x00010203, 0x0c0d0e0f, 0x08090a0b);
74
75
    macro_rules! unrolled_iterations {
76
        ($($i:literal),*) => {$(
77
            x[$i] = _mm_loadu_si128(data.add($i) as *const _);
78
            x[$i] = _mm_shuffle_epi8(x[$i], MASK);
79
80
            let y = _mm_add_epi64(
81
                x[$i],
82
                _mm_loadu_si128(&K64[2 * $i] as *const u64 as *const _),
83
            );
84
85
            ms[$i] = y;
86
        )*};
87
    }
88
89
0
    unrolled_iterations!(0, 1, 2, 3, 4, 5, 6, 7);
90
0
}
91
92
#[inline(always)]
93
0
unsafe fn load_data_avx2(
94
0
    x: &mut [__m256i; 8],
95
0
    ms: &mut MsgSchedule,
96
0
    t2: &mut RoundStates,
97
0
    data: *const __m128i,
98
0
) {
99
0
    #[allow(non_snake_case)]
100
0
    let MASK = _mm256_set_epi64x(
101
0
        0x0809_0A0B_0C0D_0E0F_i64,
102
0
        0x0001_0203_0405_0607_i64,
103
0
        0x0809_0A0B_0C0D_0E0F_i64,
104
0
        0x0001_0203_0405_0607_i64,
105
0
    );
106
107
    macro_rules! unrolled_iterations {
108
        ($($i:literal),*) => {$(
109
            x[$i] = _mm256_insertf128_si256(x[$i], _mm_loadu_si128(data.add(8 + $i) as *const _), 1);
110
            x[$i] = _mm256_insertf128_si256(x[$i], _mm_loadu_si128(data.add($i) as *const _), 0);
111
112
            x[$i] = _mm256_shuffle_epi8(x[$i], MASK);
113
114
            let t = _mm_loadu_si128(K64.as_ptr().add($i * 2) as *const u64 as *const _);
115
            let y = _mm256_add_epi64(x[$i], _mm256_set_m128i(t, t));
116
117
            ms[$i] = _mm256_extracti128_si256(y, 0);
118
            t2[$i] = _mm256_extracti128_si256(y, 1);
119
        )*};
120
    }
121
122
0
    unrolled_iterations!(0, 1, 2, 3, 4, 5, 6, 7);
123
0
}
124
125
#[inline(always)]
126
0
unsafe fn rounds_0_63_avx(current_state: &mut State, x: &mut [__m128i; 8], ms: &mut MsgSchedule) {
127
0
    let mut k64_idx: usize = SHA512_BLOCK_WORDS_NUM;
128
129
0
    for _ in 0..4 {
130
0
        for j in 0..8 {
131
0
            let k64 = _mm_loadu_si128(&K64[k64_idx] as *const u64 as *const _);
132
0
            let y = sha512_update_x_avx(x, k64);
133
0
134
0
            {
135
0
                let ms = cast_ms(ms);
136
0
                sha_round(current_state, ms[2 * j]);
137
0
                sha_round(current_state, ms[2 * j + 1]);
138
0
            }
139
0
140
0
            ms[j] = y;
141
0
            k64_idx += 2;
142
0
        }
143
    }
144
0
}
145
146
#[inline(always)]
147
0
unsafe fn rounds_0_63_avx2(
148
0
    current_state: &mut State,
149
0
    x: &mut [__m256i; 8],
150
0
    ms: &mut MsgSchedule,
151
0
    t2: &mut RoundStates,
152
0
) {
153
0
    let mut k64x4_idx: usize = SHA512_BLOCK_WORDS_NUM;
154
155
0
    for i in 1..5 {
156
0
        for j in 0..8 {
157
0
            let t = _mm_loadu_si128(K64.as_ptr().add(k64x4_idx) as *const u64 as *const _);
158
0
            let y = sha512_update_x_avx2(x, _mm256_set_m128i(t, t));
159
0
160
0
            {
161
0
                let ms = cast_ms(ms);
162
0
                sha_round(current_state, ms[2 * j]);
163
0
                sha_round(current_state, ms[2 * j + 1]);
164
0
            }
165
0
166
0
            ms[j] = _mm256_extracti128_si256(y, 0);
167
0
            t2[8 * i + j] = _mm256_extracti128_si256(y, 1);
168
0
169
0
            k64x4_idx += 2;
170
0
        }
171
    }
172
0
}
173
174
#[inline(always)]
175
0
fn rounds_64_79(current_state: &mut State, ms: &MsgSchedule) {
176
0
    let ms = cast_ms(ms);
177
0
    for i in 64..80 {
178
0
        sha_round(current_state, ms[i & 0xf]);
179
0
    }
180
0
}
181
182
#[inline(always)]
183
0
fn process_second_block(current_state: &mut State, t2: &RoundStates) {
184
0
    for t2 in cast_rs(t2).iter() {
185
0
        sha_round(current_state, *t2);
186
0
    }
187
0
}
188
189
#[inline(always)]
190
0
fn sha_round(s: &mut State, x: u64) {
191
    macro_rules! big_sigma0 {
192
        ($a:expr) => {
193
            $a.rotate_right(28) ^ $a.rotate_right(34) ^ $a.rotate_right(39)
194
        };
195
    }
196
    macro_rules! big_sigma1 {
197
        ($a:expr) => {
198
            $a.rotate_right(14) ^ $a.rotate_right(18) ^ $a.rotate_right(41)
199
        };
200
    }
201
    macro_rules! bool3ary_202 {
202
        ($a:expr, $b:expr, $c:expr) => {
203
            $c ^ ($a & ($b ^ $c))
204
        };
205
    } // Choose, MD5F, SHA1C
206
    macro_rules! bool3ary_232 {
207
        ($a:expr, $b:expr, $c:expr) => {
208
            ($a & $b) ^ ($a & $c) ^ ($b & $c)
209
        };
210
    } // Majority, SHA1M
211
212
    macro_rules! rotate_state {
213
        ($s:ident) => {{
214
            let tmp = $s[7];
215
            $s[7] = $s[6];
216
            $s[6] = $s[5];
217
            $s[5] = $s[4];
218
            $s[4] = $s[3];
219
            $s[3] = $s[2];
220
            $s[2] = $s[1];
221
            $s[1] = $s[0];
222
            $s[0] = tmp;
223
        }};
224
    }
225
226
0
    let t = x
227
0
        .wrapping_add(s[7])
228
0
        .wrapping_add(big_sigma1!(s[4]))
229
0
        .wrapping_add(bool3ary_202!(s[4], s[5], s[6]));
230
0
231
0
    s[7] = t
232
0
        .wrapping_add(big_sigma0!(s[0]))
233
0
        .wrapping_add(bool3ary_232!(s[0], s[1], s[2]));
234
0
    s[3] = s[3].wrapping_add(t);
235
0
236
0
    rotate_state!(s);
237
0
}
238
239
#[inline(always)]
240
0
fn accumulate_state(dst: &mut State, src: &State) {
241
0
    for i in 0..SHA512_HASH_WORDS_NUM {
242
0
        dst[i] = dst[i].wrapping_add(src[i]);
243
0
    }
244
0
}
245
246
macro_rules! fn_sha512_update_x {
247
    ($name:ident, $ty:ident, {
248
        ADD64 = $ADD64:ident,
249
        ALIGNR8 = $ALIGNR8:ident,
250
        SRL64 = $SRL64:ident,
251
        SLL64 = $SLL64:ident,
252
        XOR = $XOR:ident,
253
    }) => {
254
0
        unsafe fn $name(x: &mut [$ty; 8], k64: $ty) -> $ty {
255
0
            // q[2:1]
256
0
            let mut t0 = $ALIGNR8(x[1], x[0], 8);
257
0
            // q[10:9]
258
0
            let mut t3 = $ALIGNR8(x[5], x[4], 8);
259
0
            // q[2:1] >> s0[0]
260
0
            let mut t2 = $SRL64(t0, 1);
261
0
            // q[1:0] + q[10:9]
262
0
            x[0] = $ADD64(x[0], t3);
263
0
            // q[2:1] >> s0[2]
264
0
            t3 = $SRL64(t0, 7);
265
0
            // q[2:1] << (64 - s0[1])
266
0
            let mut t1 = $SLL64(t0, 64 - 8);
267
0
            // (q[2:1] >> s0[2]) ^
268
0
            // (q[2:1] >> s0[0])
269
0
            t0 = $XOR(t3, t2);
270
0
            // q[2:1] >> s0[1]
271
0
            t2 = $SRL64(t2, 8 - 1);
272
0
            // (q[2:1] >> s0[2]) ^
273
0
            // (q[2:1] >> s0[0]) ^
274
0
            // q[2:1] << (64 - s0[1])
275
0
            t0 = $XOR(t0, t1);
276
0
            // q[2:1] << (64 - s0[0])
277
0
            t1 = $SLL64(t1, 8 - 1);
278
0
            // sigma1(q[2:1])
279
0
            t0 = $XOR(t0, t2);
280
0
            t0 = $XOR(t0, t1);
281
0
            // q[15:14] >> s1[2]
282
0
            t3 = $SRL64(x[7], 6);
283
0
            // q[15:14] >> (64 - s1[1])
284
0
            t2 = $SLL64(x[7], 64 - 61);
285
0
            // q[1:0] + sigma0(q[2:1])
286
0
            x[0] = $ADD64(x[0], t0);
287
0
            // q[15:14] >> s1[0]
288
0
            t1 = $SRL64(x[7], 19);
289
0
            // q[15:14] >> s1[2] ^
290
0
            // q[15:14] >> (64 - s1[1])
291
0
            t3 = $XOR(t3, t2);
292
0
            // q[15:14] >> (64 - s1[0])
293
0
            t2 = $SLL64(t2, 61 - 19);
294
0
            // q[15:14] >> s1[2] ^
295
0
            // q[15:14] >> (64 - s1[1] ^
296
0
            // q[15:14] >> s1[0]
297
0
            t3 = $XOR(t3, t1);
298
0
            // q[15:14] >> s1[1]
299
0
            t1 = $SRL64(t1, 61 - 19);
300
0
            // sigma1(q[15:14])
301
0
            t3 = $XOR(t3, t2);
302
0
            t3 = $XOR(t3, t1);
303
0
304
0
            // q[1:0] + q[10:9] + sigma1(q[15:14]) + sigma0(q[2:1])
305
0
            x[0] = $ADD64(x[0], t3);
306
0
307
0
            // rotate
308
0
            let temp = x[0];
309
0
            x[0] = x[1];
310
0
            x[1] = x[2];
311
0
            x[2] = x[3];
312
0
            x[3] = x[4];
313
0
            x[4] = x[5];
314
0
            x[5] = x[6];
315
0
            x[6] = x[7];
316
0
            x[7] = temp;
317
0
318
0
            $ADD64(x[7], k64)
319
0
        }
Unexecuted instantiation: _RNvNtNtCs23lnNM1woOA_4sha26sha5123x8619sha512_update_x_avx
Unexecuted instantiation: _RNvNtNtCs23lnNM1woOA_4sha26sha5123x8620sha512_update_x_avx2
320
    };
321
}
322
323
fn_sha512_update_x!(sha512_update_x_avx, __m128i, {
324
        ADD64 = _mm_add_epi64,
325
        ALIGNR8 = _mm_alignr_epi8,
326
        SRL64 = _mm_srli_epi64,
327
        SLL64 = _mm_slli_epi64,
328
        XOR = _mm_xor_si128,
329
});
330
331
fn_sha512_update_x!(sha512_update_x_avx2, __m256i, {
332
        ADD64 = _mm256_add_epi64,
333
        ALIGNR8 = _mm256_alignr_epi8,
334
        SRL64 = _mm256_srli_epi64,
335
        SLL64 = _mm256_slli_epi64,
336
        XOR = _mm256_xor_si256,
337
});
338
339
#[inline(always)]
340
0
fn cast_ms(ms: &MsgSchedule) -> &[u64; SHA512_BLOCK_WORDS_NUM] {
341
0
    unsafe { &*(ms as *const MsgSchedule as *const _) }
342
0
}
343
344
#[inline(always)]
345
0
fn cast_rs(rs: &RoundStates) -> &[u64; SHA512_ROUNDS_NUM] {
346
0
    unsafe { &*(rs as *const RoundStates as *const _) }
347
0
}
348
349
type State = [u64; SHA512_HASH_WORDS_NUM];
350
type MsgSchedule = [__m128i; SHA512_BLOCK_WORDS_NUM / 2];
351
type RoundStates = [__m128i; SHA512_ROUNDS_NUM / 2];
352
353
const SHA512_BLOCK_BYTE_LEN: usize = 128;
354
const SHA512_ROUNDS_NUM: usize = 80;
355
const SHA512_HASH_BYTE_LEN: usize = 64;
356
const SHA512_HASH_WORDS_NUM: usize = SHA512_HASH_BYTE_LEN / size_of::<u64>();
357
const SHA512_BLOCK_WORDS_NUM: usize = SHA512_BLOCK_BYTE_LEN / size_of::<u64>();
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/signature-2.2.0/src/encoding.rs
Line
Count
Source
1
//! Encoding support.
2
3
#[cfg(feature = "alloc")]
4
use alloc::vec::Vec;
5
6
/// Support for decoding/encoding signatures as bytes.
7
pub trait SignatureEncoding:
8
    Clone + Sized + for<'a> TryFrom<&'a [u8]> + TryInto<Self::Repr>
9
{
10
    /// Byte representation of a signature.
11
    type Repr: 'static + AsRef<[u8]> + Clone + Send + Sync;
12
13
    /// Encode signature as its byte representation.
14
0
    fn to_bytes(&self) -> Self::Repr {
15
0
        self.clone()
16
0
            .try_into()
17
0
            .ok()
18
0
            .expect("signature encoding error")
19
0
    }
20
21
    /// Encode signature as a byte vector.
22
    #[cfg(feature = "alloc")]
23
0
    fn to_vec(&self) -> Vec<u8> {
24
0
        self.to_bytes().as_ref().to_vec()
25
0
    }
Unexecuted instantiation: _RNvYNtNtCsjewTDwKBbyD_4k2567schnorr9SignatureNtNtCs9XGzgUPXFy2_9signature8encoding17SignatureEncoding6to_vecB6_
Unexecuted instantiation: _RNvYpNtNtCs9XGzgUPXFy2_9signature8encoding17SignatureEncoding6to_vecB7_
26
27
    /// Get the length of this signature when encoded.
28
0
    fn encoded_len(&self) -> usize {
29
0
        self.to_bytes().as_ref().len()
30
0
    }
Unexecuted instantiation: _RNvYNtNtCsjewTDwKBbyD_4k2567schnorr9SignatureNtNtCs9XGzgUPXFy2_9signature8encoding17SignatureEncoding11encoded_lenB6_
Unexecuted instantiation: _RNvYpNtNtCs9XGzgUPXFy2_9signature8encoding17SignatureEncoding11encoded_lenB7_
31
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/signature-2.2.0/src/error.rs
Line
Count
Source
1
//! Signature error types
2
3
use core::fmt::{self, Debug, Display};
4
5
#[cfg(feature = "std")]
6
use std::boxed::Box;
7
8
/// Result type.
9
///
10
/// A result with the `signature` crate's [`Error`] type.
11
pub type Result<T> = core::result::Result<T, Error>;
12
13
/// Signature errors.
14
///
15
/// This type is deliberately opaque as to avoid sidechannel leakage which
16
/// could potentially be used recover signing private keys or forge signatures
17
/// (e.g. [BB'06]).
18
///
19
/// When the `std` feature is enabled, it impls [`std::error::Error`] and
20
/// supports an optional [`std::error::Error::source`], which can be used by
21
/// things like remote signers (e.g. HSM, KMS) to report I/O or auth errors.
22
///
23
/// [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher
24
#[derive(Default)]
25
#[non_exhaustive]
26
pub struct Error {
27
    /// Source of the error (if applicable).
28
    #[cfg(feature = "std")]
29
    source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
30
}
31
32
impl Error {
33
    /// Create a new error with no associated source
34
1.95k
    pub fn new() -> Self {
35
1.95k
        Self::default()
36
1.95k
    }
_RNvMNtCs9XGzgUPXFy2_9signature5errorNtB2_5Error3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
34
1.52k
    pub fn new() -> Self {
35
1.52k
        Self::default()
36
1.52k
    }
Unexecuted instantiation: _RNvMNtCs9XGzgUPXFy2_9signature5errorNtB2_5Error3newCs56dDIOPvtI3_5ecdsa
_RNvMNtCs9XGzgUPXFy2_9signature5errorNtB2_5Error3newCsjewTDwKBbyD_4k256
Line
Count
Source
34
425
    pub fn new() -> Self {
35
425
        Self::default()
36
425
    }
Unexecuted instantiation: _RNvMNtCs9XGzgUPXFy2_9signature5errorNtB2_5Error3newCsaHRNXv1Y9Bq_4p256
Unexecuted instantiation: _RNvMNtCs9XGzgUPXFy2_9signature5errorNtB2_5Error3newB4_
37
38
    /// Create a new error with an associated source.
39
    ///
40
    /// **NOTE:** The "source" should **NOT** be used to propagate cryptographic
41
    /// errors e.g. signature parsing or verification errors. The intended use
42
    /// cases are for propagating errors related to external signers, e.g.
43
    /// communication/authentication errors with HSMs, KMS, etc.
44
    #[cfg(feature = "std")]
45
0
    pub fn from_source(
46
0
        source: impl Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
47
0
    ) -> Self {
48
0
        Self {
49
0
            source: Some(source.into()),
50
0
        }
51
0
    }
Unexecuted instantiation: _RINvMNtCs9XGzgUPXFy2_9signature5errorNtB3_5Error11from_sourceINtNtCsiBl6Lc3cFal_5alloc5boxed3BoxDNtNtCsbQ8arDwx5Xq_4core5error5ErrorNtNtB1B_6marker4SendNtB28_4SyncEL_EEB5_
Unexecuted instantiation: _RINvMNtCs9XGzgUPXFy2_9signature5errorNtB3_5Error11from_sourceNtNtCs7cRyI6h3MOh_9rand_core5error5ErrorEB5_
52
}
53
54
impl Debug for Error {
55
    #[cfg(not(feature = "std"))]
56
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57
        f.write_str("signature::Error {}")
58
    }
59
60
    #[cfg(feature = "std")]
61
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62
0
        f.write_str("signature::Error { source: ")?;
63
64
0
        if let Some(source) = &self.source {
65
0
            write!(f, "Some({})", source)?;
66
        } else {
67
0
            f.write_str("None")?;
68
        }
69
70
0
        f.write_str(" }")
71
0
    }
72
}
73
74
impl Display for Error {
75
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76
0
        f.write_str("signature error")?;
77
78
        #[cfg(feature = "std")]
79
        {
80
0
            if let Some(source) = &self.source {
81
0
                write!(f, ": {}", source)?;
82
0
            }
83
        }
84
85
0
        Ok(())
86
0
    }
87
}
88
89
#[cfg(feature = "std")]
90
impl From<Box<dyn std::error::Error + Send + Sync + 'static>> for Error {
91
0
    fn from(source: Box<dyn std::error::Error + Send + Sync + 'static>) -> Error {
92
0
        Self::from_source(source)
93
0
    }
94
}
95
96
#[cfg(feature = "rand_core")]
97
impl From<rand_core::Error> for Error {
98
    #[cfg(not(feature = "std"))]
99
    fn from(_source: rand_core::Error) -> Error {
100
        Error::new()
101
    }
102
103
    #[cfg(feature = "std")]
104
0
    fn from(source: rand_core::Error) -> Error {
105
0
        Error::from_source(source)
106
0
    }
107
}
108
109
#[cfg(feature = "std")]
110
impl std::error::Error for Error {
111
0
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
112
0
        self.source
113
0
            .as_ref()
114
0
            .map(|source| source.as_ref() as &(dyn std::error::Error + 'static))
115
0
    }
116
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/signature-2.2.0/src/keypair.rs
Line
Count
Source
1
//! Signing keypairs.
2
3
/// Signing keypair with an associated verifying key.
4
///
5
/// This represents a type which holds both a signing key and a verifying key.
6
pub trait Keypair {
7
    /// Verifying key type for this keypair.
8
    type VerifyingKey: Clone;
9
10
    /// Get the verifying key which can verify signatures produced by the
11
    /// signing key portion of this keypair.
12
    fn verifying_key(&self) -> Self::VerifyingKey;
13
}
14
15
/// Signing keypair with an associated verifying key.
16
///
17
/// This represents a type which holds both a signing key and a verifying key.
18
pub trait KeypairRef: AsRef<Self::VerifyingKey> {
19
    /// Verifying key type for this keypair.
20
    type VerifyingKey: Clone;
21
}
22
23
impl<K: KeypairRef> Keypair for K {
24
    type VerifyingKey = <Self as KeypairRef>::VerifyingKey;
25
26
0
    fn verifying_key(&self) -> Self::VerifyingKey {
27
0
        self.as_ref().clone()
28
0
    }
29
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/signature-2.2.0/src/signer.rs
Line
Count
Source
1
//! Traits for generating digital signatures
2
3
use crate::error::Error;
4
5
#[cfg(feature = "digest")]
6
use crate::digest::Digest;
7
8
#[cfg(feature = "rand_core")]
9
use crate::rand_core::CryptoRngCore;
10
11
/// Sign the provided message bytestring using `Self` (e.g. a cryptographic key
12
/// or connection to an HSM), returning a digital signature.
13
pub trait Signer<S> {
14
    /// Sign the given message and return a digital signature
15
0
    fn sign(&self, msg: &[u8]) -> S {
16
0
        self.try_sign(msg).expect("signature operation failed")
17
0
    }
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k2567schnorr7signing10SigningKeyINtNtCs9XGzgUPXFy2_9signature6signer6SignerNtB6_9SignatureE4signB8_
Unexecuted instantiation: _RNvYpINtNtCs9XGzgUPXFy2_9signature6signer6SignerpE4signB8_
18
19
    /// Attempt to sign the given message, returning a digital signature on
20
    /// success, or an error if something went wrong.
21
    ///
22
    /// The main intended use case for signing errors is when communicating
23
    /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens.
24
    fn try_sign(&self, msg: &[u8]) -> Result<S, Error>;
25
}
26
27
/// Sign the provided message bytestring using `&mut Self` (e.g. an evolving
28
/// cryptographic key such as a stateful hash-based signature), returning a
29
/// digital signature.
30
pub trait SignerMut<S> {
31
    /// Sign the given message, update the state, and return a digital signature.
32
0
    fn sign(&mut self, msg: &[u8]) -> S {
33
0
        self.try_sign(msg).expect("signature operation failed")
34
0
    }
35
36
    /// Attempt to sign the given message, updating the state, and returning a
37
    /// digital signature on success, or an error if something went wrong.
38
    ///
39
    /// Signing can fail, e.g., if the number of time periods allowed by the
40
    /// current key is exceeded.
41
    fn try_sign(&mut self, msg: &[u8]) -> Result<S, Error>;
42
}
43
44
/// Blanket impl of [`SignerMut`] for all [`Signer`] types.
45
impl<S, T: Signer<S>> SignerMut<S> for T {
46
0
    fn try_sign(&mut self, msg: &[u8]) -> Result<S, Error> {
47
0
        T::try_sign(self, msg)
48
0
    }
49
}
50
51
/// Sign the given prehashed message [`Digest`] using `Self`.
52
///
53
/// ## Notes
54
///
55
/// This trait is primarily intended for signature algorithms based on the
56
/// [Fiat-Shamir heuristic], a method for converting an interactive
57
/// challenge/response-based proof-of-knowledge protocol into an offline
58
/// digital signature through the use of a random oracle, i.e. a digest
59
/// function.
60
///
61
/// The security of such protocols critically rests upon the inability of
62
/// an attacker to solve for the output of the random oracle, as generally
63
/// otherwise such signature algorithms are a system of linear equations and
64
/// therefore doing so would allow the attacker to trivially forge signatures.
65
///
66
/// To prevent misuse which would potentially allow this to be possible, this
67
/// API accepts a [`Digest`] instance, rather than a raw digest value.
68
///
69
/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic
70
#[cfg(feature = "digest")]
71
pub trait DigestSigner<D: Digest, S> {
72
    /// Sign the given prehashed message [`Digest`], returning a signature.
73
    ///
74
    /// Panics in the event of a signing error.
75
0
    fn sign_digest(&self, digest: D) -> S {
76
0
        self.try_sign_digest(digest)
77
0
            .expect("signature operation failed")
78
0
    }
79
80
    /// Attempt to sign the given prehashed message [`Digest`], returning a
81
    /// digital signature on success, or an error if something went wrong.
82
    fn try_sign_digest(&self, digest: D) -> Result<S, Error>;
83
}
84
85
/// Sign the given message using the provided external randomness source.
86
#[cfg(feature = "rand_core")]
87
pub trait RandomizedSigner<S> {
88
    /// Sign the given message and return a digital signature
89
0
    fn sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S {
90
0
        self.try_sign_with_rng(rng, msg)
91
0
            .expect("signature operation failed")
92
0
    }
93
94
    /// Attempt to sign the given message, returning a digital signature on
95
    /// success, or an error if something went wrong.
96
    ///
97
    /// The main intended use case for signing errors is when communicating
98
    /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens.
99
    fn try_sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result<S, Error>;
100
}
101
102
/// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for
103
/// computing a signature over a digest which requires entropy from an RNG.
104
#[cfg(all(feature = "digest", feature = "rand_core"))]
105
pub trait RandomizedDigestSigner<D: Digest, S> {
106
    /// Sign the given prehashed message `Digest`, returning a signature.
107
    ///
108
    /// Panics in the event of a signing error.
109
0
    fn sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) -> S {
110
0
        self.try_sign_digest_with_rng(rng, digest)
111
0
            .expect("signature operation failed")
112
0
    }
113
114
    /// Attempt to sign the given prehashed message `Digest`, returning a
115
    /// digital signature on success, or an error if something went wrong.
116
    fn try_sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D)
117
        -> Result<S, Error>;
118
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/spki-0.7.3/src/algorithm.rs
Line
Count
Source
1
//! X.509 `AlgorithmIdentifier`
2
3
use crate::{Error, Result};
4
use core::cmp::Ordering;
5
use der::{
6
    asn1::{AnyRef, Choice, ObjectIdentifier},
7
    Decode, DecodeValue, DerOrd, Encode, EncodeValue, Header, Length, Reader, Sequence, ValueOrd,
8
    Writer,
9
};
10
11
#[cfg(feature = "alloc")]
12
use der::asn1::Any;
13
14
/// X.509 `AlgorithmIdentifier` as defined in [RFC 5280 Section 4.1.1.2].
15
///
16
/// ```text
17
/// AlgorithmIdentifier  ::=  SEQUENCE  {
18
///      algorithm               OBJECT IDENTIFIER,
19
///      parameters              ANY DEFINED BY algorithm OPTIONAL  }
20
/// ```
21
///
22
/// [RFC 5280 Section 4.1.1.2]: https://tools.ietf.org/html/rfc5280#section-4.1.1.2
23
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
24
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
25
pub struct AlgorithmIdentifier<Params> {
26
    /// Algorithm OID, i.e. the `algorithm` field in the `AlgorithmIdentifier`
27
    /// ASN.1 schema.
28
    pub oid: ObjectIdentifier,
29
30
    /// Algorithm `parameters`.
31
    pub parameters: Option<Params>,
32
}
33
34
impl<'a, Params> DecodeValue<'a> for AlgorithmIdentifier<Params>
35
where
36
    Params: Choice<'a>,
37
{
38
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
39
0
        reader.read_nested(header.length, |reader| {
40
0
            Ok(Self {
41
0
                oid: reader.decode()?,
42
0
                parameters: reader.decode()?,
43
            })
44
0
        })
Unexecuted instantiation: _RNCINvXNtCskctcMqaO4X4_4spki9algorithmINtB5_19AlgorithmIdentifierNtNtNtCscrZQdumITES_3der4asn13any6AnyRefENtNtB17_6decode11DecodeValue12decode_valueINtNtNtB17_6reader6nested12NestedReaderNtNtB2r_5slice11SliceReaderEE0Cssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNCINvXININtCskctcMqaO4X4_4spki9algorithm0pEINtB8_19AlgorithmIdentifierpENtNtCscrZQdumITES_3der6decode11DecodeValue12decode_valuepE0Ba_
45
0
    }
Unexecuted instantiation: _RINvXNtCskctcMqaO4X4_4spki9algorithmINtB3_19AlgorithmIdentifierNtNtNtCscrZQdumITES_3der4asn13any6AnyRefENtNtB15_6decode11DecodeValue12decode_valueINtNtNtB15_6reader6nested12NestedReaderNtNtB2p_5slice11SliceReaderEECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXININtCskctcMqaO4X4_4spki9algorithm0pEINtB6_19AlgorithmIdentifierpENtNtCscrZQdumITES_3der6decode11DecodeValue12decode_valuepEB8_
46
}
47
48
impl<Params> EncodeValue for AlgorithmIdentifier<Params>
49
where
50
    Params: Encode,
51
{
52
0
    fn value_len(&self) -> der::Result<Length> {
53
0
        self.oid.encoded_len()? + self.parameters.encoded_len()?
54
0
    }
Unexecuted instantiation: _RNvXs_NtCskctcMqaO4X4_4spki9algorithmINtB4_19AlgorithmIdentifierNtNtNtCscrZQdumITES_3der4asn13any6AnyRefENtNtB16_6encode11EncodeValue9value_lenCssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RNvXININtCskctcMqaO4X4_4spki9algorithms_0pEINtB5_19AlgorithmIdentifierpENtNtCscrZQdumITES_3der6encode11EncodeValue9value_lenB7_
55
56
0
    fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
57
0
        self.oid.encode(writer)?;
58
0
        self.parameters.encode(writer)?;
59
0
        Ok(())
60
0
    }
Unexecuted instantiation: _RINvXs_NtCskctcMqaO4X4_4spki9algorithmINtB5_19AlgorithmIdentifierNtNtNtCscrZQdumITES_3der4asn13any6AnyRefENtNtB17_6encode11EncodeValue12encode_valueNtNtNtB17_6writer5slice11SliceWriterECssr1zNgi7Nt_5pkcs8
Unexecuted instantiation: _RINvXININtCskctcMqaO4X4_4spki9algorithms_0pEINtB6_19AlgorithmIdentifierpENtNtCscrZQdumITES_3der6encode11EncodeValue12encode_valuepEB8_
61
}
62
63
impl<'a, Params> Sequence<'a> for AlgorithmIdentifier<Params> where Params: Choice<'a> + Encode {}
64
65
impl<'a, Params> TryFrom<&'a [u8]> for AlgorithmIdentifier<Params>
66
where
67
    Params: Choice<'a> + Encode,
68
{
69
    type Error = Error;
70
71
0
    fn try_from(bytes: &'a [u8]) -> Result<Self> {
72
0
        Ok(Self::from_der(bytes)?)
73
0
    }
74
}
75
76
impl<Params> ValueOrd for AlgorithmIdentifier<Params>
77
where
78
    Params: DerOrd,
79
{
80
0
    fn value_cmp(&self, other: &Self) -> der::Result<Ordering> {
81
0
        match self.oid.der_cmp(&other.oid)? {
82
0
            Ordering::Equal => self.parameters.der_cmp(&other.parameters),
83
0
            other => Ok(other),
84
        }
85
0
    }
86
}
87
88
/// `AlgorithmIdentifier` reference which has `AnyRef` parameters.
89
pub type AlgorithmIdentifierRef<'a> = AlgorithmIdentifier<AnyRef<'a>>;
90
91
/// `AlgorithmIdentifier` with `ObjectIdentifier` parameters.
92
pub type AlgorithmIdentifierWithOid = AlgorithmIdentifier<ObjectIdentifier>;
93
94
/// `AlgorithmIdentifier` reference which has `Any` parameters.
95
#[cfg(feature = "alloc")]
96
pub type AlgorithmIdentifierOwned = AlgorithmIdentifier<Any>;
97
98
impl<Params> AlgorithmIdentifier<Params> {
99
    /// Assert the `algorithm` OID is an expected value.
100
0
    pub fn assert_algorithm_oid(&self, expected_oid: ObjectIdentifier) -> Result<ObjectIdentifier> {
101
0
        if self.oid == expected_oid {
102
0
            Ok(expected_oid)
103
        } else {
104
0
            Err(Error::OidUnknown { oid: expected_oid })
105
        }
106
0
    }
107
}
108
109
impl<'a> AlgorithmIdentifierRef<'a> {
110
    /// Assert `parameters` is an OID and has the expected value.
111
0
    pub fn assert_parameters_oid(
112
0
        &self,
113
0
        expected_oid: ObjectIdentifier,
114
0
    ) -> Result<ObjectIdentifier> {
115
0
        let actual_oid = self.parameters_oid()?;
116
117
0
        if actual_oid == expected_oid {
118
0
            Ok(actual_oid)
119
        } else {
120
0
            Err(Error::OidUnknown { oid: expected_oid })
121
        }
122
0
    }
123
124
    /// Assert the values of the `algorithm` and `parameters` OIDs.
125
0
    pub fn assert_oids(
126
0
        &self,
127
0
        algorithm: ObjectIdentifier,
128
0
        parameters: ObjectIdentifier,
129
0
    ) -> Result<()> {
130
0
        self.assert_algorithm_oid(algorithm)?;
131
0
        self.assert_parameters_oid(parameters)?;
132
0
        Ok(())
133
0
    }
134
135
    /// Get the `parameters` field as an [`AnyRef`].
136
    ///
137
    /// Returns an error if `parameters` are `None`.
138
0
    pub fn parameters_any(&self) -> Result<AnyRef<'a>> {
139
0
        self.parameters.ok_or(Error::AlgorithmParametersMissing)
140
0
    }
141
142
    /// Get the `parameters` field as an [`ObjectIdentifier`].
143
    ///
144
    /// Returns an error if it is absent or not an OID.
145
0
    pub fn parameters_oid(&self) -> Result<ObjectIdentifier> {
146
0
        Ok(ObjectIdentifier::try_from(self.parameters_any()?)?)
147
0
    }
148
149
    /// Convert to a pair of [`ObjectIdentifier`]s.
150
    ///
151
    /// This method is helpful for decomposing in match statements. Note in
152
    /// particular that `NULL` parameters are treated the same as missing
153
    /// parameters.
154
    ///
155
    /// Returns an error if parameters are present but not an OID.
156
0
    pub fn oids(&self) -> der::Result<(ObjectIdentifier, Option<ObjectIdentifier>)> {
157
0
        Ok((
158
0
            self.oid,
159
0
            match self.parameters {
160
0
                None => None,
161
0
                Some(p) => match p {
162
0
                    AnyRef::NULL => None,
163
0
                    _ => Some(p.decode_as::<ObjectIdentifier>()?),
164
                },
165
            },
166
        ))
167
0
    }
168
}
169
170
#[cfg(feature = "alloc")]
171
mod allocating {
172
    use super::*;
173
    use der::referenced::*;
174
175
    impl<'a> RefToOwned<'a> for AlgorithmIdentifierRef<'a> {
176
        type Owned = AlgorithmIdentifierOwned;
177
0
        fn ref_to_owned(&self) -> Self::Owned {
178
0
            AlgorithmIdentifier {
179
0
                oid: self.oid,
180
0
                parameters: self.parameters.ref_to_owned(),
181
0
            }
182
0
        }
183
    }
184
185
    impl OwnedToRef for AlgorithmIdentifierOwned {
186
        type Borrowed<'a> = AlgorithmIdentifierRef<'a>;
187
0
        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
188
0
            AlgorithmIdentifier {
189
0
                oid: self.oid,
190
0
                parameters: self.parameters.owned_to_ref(),
191
0
            }
192
0
        }
193
    }
194
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/spki-0.7.3/src/error.rs
Line
Count
Source
1
//! Error types
2
3
use core::fmt;
4
use der::asn1::ObjectIdentifier;
5
6
/// Result type with `spki` crate's [`Error`] type.
7
pub type Result<T> = core::result::Result<T, Error>;
8
9
#[cfg(feature = "pem")]
10
use der::pem;
11
12
/// Error type
13
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
14
#[non_exhaustive]
15
pub enum Error {
16
    /// Algorithm parameters are missing.
17
    AlgorithmParametersMissing,
18
19
    /// ASN.1 DER-related errors.
20
    Asn1(der::Error),
21
22
    /// Malformed cryptographic key contained in a SPKI document.
23
    ///
24
    /// This is intended for relaying errors related to the raw data contained
25
    /// in [`SubjectPublicKeyInfo::subject_public_key`][`crate::SubjectPublicKeyInfo::subject_public_key`].
26
    KeyMalformed,
27
28
    /// Unknown algorithm OID.
29
    OidUnknown {
30
        /// Unrecognized OID value found in e.g. a SPKI `AlgorithmIdentifier`.
31
        oid: ObjectIdentifier,
32
    },
33
}
34
35
impl fmt::Display for Error {
36
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37
0
        match self {
38
            Error::AlgorithmParametersMissing => {
39
0
                f.write_str("AlgorithmIdentifier parameters missing")
40
            }
41
0
            Error::Asn1(err) => write!(f, "ASN.1 error: {}", err),
42
0
            Error::KeyMalformed => f.write_str("SPKI cryptographic key data malformed"),
43
0
            Error::OidUnknown { oid } => {
44
0
                write!(f, "unknown/unsupported algorithm OID: {}", oid)
45
            }
46
        }
47
0
    }
48
}
49
50
impl From<der::Error> for Error {
51
0
    fn from(err: der::Error) -> Error {
52
0
        if let der::ErrorKind::OidUnknown { oid } = err.kind() {
53
0
            Error::OidUnknown { oid }
54
        } else {
55
0
            Error::Asn1(err)
56
        }
57
0
    }
58
}
59
60
#[cfg(feature = "pem")]
61
impl From<pem::Error> for Error {
62
0
    fn from(err: pem::Error) -> Error {
63
0
        der::Error::from(err).into()
64
0
    }
65
}
66
67
#[cfg(feature = "std")]
68
impl std::error::Error for Error {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/spki-0.7.3/src/spki.rs
Line
Count
Source
1
//! X.509 `SubjectPublicKeyInfo`
2
3
use crate::{AlgorithmIdentifier, Error, Result};
4
use core::cmp::Ordering;
5
use der::{
6
    asn1::{AnyRef, BitStringRef},
7
    Choice, Decode, DecodeValue, DerOrd, Encode, EncodeValue, FixedTag, Header, Length, Reader,
8
    Sequence, ValueOrd, Writer,
9
};
10
11
#[cfg(feature = "alloc")]
12
use der::{
13
    asn1::{Any, BitString},
14
    Document,
15
};
16
17
#[cfg(feature = "fingerprint")]
18
use crate::{fingerprint, FingerprintBytes};
19
20
#[cfg(feature = "pem")]
21
use der::pem::PemLabel;
22
23
/// [`SubjectPublicKeyInfo`] with [`AnyRef`] algorithm parameters, and [`BitStringRef`] params.
24
pub type SubjectPublicKeyInfoRef<'a> = SubjectPublicKeyInfo<AnyRef<'a>, BitStringRef<'a>>;
25
26
/// [`SubjectPublicKeyInfo`] with [`Any`] algorithm parameters, and [`BitString`] params.
27
#[cfg(feature = "alloc")]
28
pub type SubjectPublicKeyInfoOwned = SubjectPublicKeyInfo<Any, BitString>;
29
30
/// X.509 `SubjectPublicKeyInfo` (SPKI) as defined in [RFC 5280 § 4.1.2.7].
31
///
32
/// ASN.1 structure containing an [`AlgorithmIdentifier`] and public key
33
/// data in an algorithm specific format.
34
///
35
/// ```text
36
///    SubjectPublicKeyInfo  ::=  SEQUENCE  {
37
///         algorithm            AlgorithmIdentifier,
38
///         subjectPublicKey     BIT STRING  }
39
/// ```
40
///
41
/// [RFC 5280 § 4.1.2.7]: https://tools.ietf.org/html/rfc5280#section-4.1.2.7
42
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
43
#[derive(Clone, Debug, Eq, PartialEq)]
44
pub struct SubjectPublicKeyInfo<Params, Key> {
45
    /// X.509 [`AlgorithmIdentifier`] for the public key type
46
    pub algorithm: AlgorithmIdentifier<Params>,
47
48
    /// Public key data
49
    pub subject_public_key: Key,
50
}
51
52
impl<'a, Params, Key> SubjectPublicKeyInfo<Params, Key>
53
where
54
    Params: Choice<'a> + Encode,
55
    // TODO: replace FixedTag with FixedTag<TAG = { Tag::BitString }> once
56
    // https://github.com/rust-lang/rust/issues/92827 is fixed
57
    Key: Decode<'a> + Encode + FixedTag,
58
{
59
    /// Calculate the SHA-256 fingerprint of this [`SubjectPublicKeyInfo`] and
60
    /// encode it as a Base64 string.
61
    ///
62
    /// See [RFC7469 § 2.1.1] for more information.
63
    ///
64
    /// [RFC7469 § 2.1.1]: https://datatracker.ietf.org/doc/html/rfc7469#section-2.1.1
65
    #[cfg(all(feature = "fingerprint", feature = "alloc", feature = "base64"))]
66
    pub fn fingerprint_base64(&self) -> Result<alloc::string::String> {
67
        use base64ct::{Base64, Encoding};
68
        Ok(Base64::encode_string(&self.fingerprint_bytes()?))
69
    }
70
71
    /// Calculate the SHA-256 fingerprint of this [`SubjectPublicKeyInfo`] as
72
    /// a raw byte array.
73
    ///
74
    /// See [RFC7469 § 2.1.1] for more information.
75
    ///
76
    /// [RFC7469 § 2.1.1]: https://datatracker.ietf.org/doc/html/rfc7469#section-2.1.1
77
    #[cfg(feature = "fingerprint")]
78
    pub fn fingerprint_bytes(&self) -> Result<FingerprintBytes> {
79
        let mut builder = fingerprint::Builder::new();
80
        self.encode(&mut builder)?;
81
        Ok(builder.finish())
82
    }
83
}
84
85
impl<'a: 'k, 'k, Params, Key: 'k> DecodeValue<'a> for SubjectPublicKeyInfo<Params, Key>
86
where
87
    Params: Choice<'a> + Encode,
88
    Key: Decode<'a>,
89
{
90
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
91
0
        reader.read_nested(header.length, |reader| {
92
0
            Ok(Self {
93
0
                algorithm: reader.decode()?,
94
0
                subject_public_key: Key::decode(reader)?,
95
            })
96
0
        })
97
0
    }
98
}
99
100
impl<'a, Params, Key> EncodeValue for SubjectPublicKeyInfo<Params, Key>
101
where
102
    Params: Choice<'a> + Encode,
103
    Key: Encode,
104
{
105
0
    fn value_len(&self) -> der::Result<Length> {
106
0
        self.algorithm.encoded_len()? + self.subject_public_key.encoded_len()?
107
0
    }
108
109
0
    fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
110
0
        self.algorithm.encode(writer)?;
111
0
        self.subject_public_key.encode(writer)?;
112
0
        Ok(())
113
0
    }
114
}
115
116
impl<'a, Params, Key> Sequence<'a> for SubjectPublicKeyInfo<Params, Key>
117
where
118
    Params: Choice<'a> + Encode,
119
    Key: Decode<'a> + Encode + FixedTag,
120
{
121
}
122
123
impl<'a, Params, Key> TryFrom<&'a [u8]> for SubjectPublicKeyInfo<Params, Key>
124
where
125
    Params: Choice<'a> + Encode,
126
    Key: Decode<'a> + Encode + FixedTag,
127
{
128
    type Error = Error;
129
130
0
    fn try_from(bytes: &'a [u8]) -> Result<Self> {
131
0
        Ok(Self::from_der(bytes)?)
132
0
    }
133
}
134
135
impl<'a, Params, Key> ValueOrd for SubjectPublicKeyInfo<Params, Key>
136
where
137
    Params: Choice<'a> + DerOrd + Encode,
138
    Key: ValueOrd,
139
{
140
0
    fn value_cmp(&self, other: &Self) -> der::Result<Ordering> {
141
0
        match self.algorithm.der_cmp(&other.algorithm)? {
142
0
            Ordering::Equal => self.subject_public_key.value_cmp(&other.subject_public_key),
143
0
            other => Ok(other),
144
        }
145
0
    }
146
}
147
148
#[cfg(feature = "alloc")]
149
impl<'a: 'k, 'k, Params, Key: 'k> TryFrom<SubjectPublicKeyInfo<Params, Key>> for Document
150
where
151
    Params: Choice<'a> + Encode,
152
    Key: Decode<'a> + Encode + FixedTag,
153
    BitStringRef<'a>: From<&'k Key>,
154
{
155
    type Error = Error;
156
157
0
    fn try_from(spki: SubjectPublicKeyInfo<Params, Key>) -> Result<Document> {
158
0
        Self::try_from(&spki)
159
0
    }
160
}
161
162
#[cfg(feature = "alloc")]
163
impl<'a: 'k, 'k, Params, Key: 'k> TryFrom<&SubjectPublicKeyInfo<Params, Key>> for Document
164
where
165
    Params: Choice<'a> + Encode,
166
    Key: Decode<'a> + Encode + FixedTag,
167
    BitStringRef<'a>: From<&'k Key>,
168
{
169
    type Error = Error;
170
171
0
    fn try_from(spki: &SubjectPublicKeyInfo<Params, Key>) -> Result<Document> {
172
0
        Ok(Self::encode_msg(spki)?)
173
0
    }
174
}
175
176
#[cfg(feature = "pem")]
177
impl<Params, Key> PemLabel for SubjectPublicKeyInfo<Params, Key> {
178
    const PEM_LABEL: &'static str = "PUBLIC KEY";
179
}
180
181
#[cfg(feature = "alloc")]
182
mod allocating {
183
    use super::*;
184
    use crate::EncodePublicKey;
185
    use der::referenced::*;
186
187
    impl<'a> RefToOwned<'a> for SubjectPublicKeyInfoRef<'a> {
188
        type Owned = SubjectPublicKeyInfoOwned;
189
0
        fn ref_to_owned(&self) -> Self::Owned {
190
0
            SubjectPublicKeyInfo {
191
0
                algorithm: self.algorithm.ref_to_owned(),
192
0
                subject_public_key: self.subject_public_key.ref_to_owned(),
193
0
            }
194
0
        }
195
    }
196
197
    impl OwnedToRef for SubjectPublicKeyInfoOwned {
198
        type Borrowed<'a> = SubjectPublicKeyInfoRef<'a>;
199
0
        fn owned_to_ref(&self) -> Self::Borrowed<'_> {
200
0
            SubjectPublicKeyInfo {
201
0
                algorithm: self.algorithm.owned_to_ref(),
202
0
                subject_public_key: self.subject_public_key.owned_to_ref(),
203
0
            }
204
0
        }
205
    }
206
207
    impl SubjectPublicKeyInfoOwned {
208
        /// Create a [`SubjectPublicKeyInfoOwned`] from any object that implements
209
        /// [`EncodePublicKey`].
210
0
        pub fn from_key<T>(source: T) -> Result<Self>
211
0
        where
212
0
            T: EncodePublicKey,
213
0
        {
214
0
            Ok(source.to_public_key_der()?.decode_msg::<Self>()?)
215
0
        }
216
    }
217
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/spki-0.7.3/src/traits.rs
Line
Count
Source
1
//! Traits for encoding/decoding SPKI public keys.
2
3
use crate::{AlgorithmIdentifier, Error, Result, SubjectPublicKeyInfoRef};
4
use der::{EncodeValue, Tagged};
5
6
#[cfg(feature = "alloc")]
7
use {
8
    crate::AlgorithmIdentifierOwned,
9
    der::{asn1::BitString, Any, Document},
10
};
11
12
#[cfg(feature = "pem")]
13
use {
14
    alloc::string::String,
15
    der::pem::{LineEnding, PemLabel},
16
};
17
18
#[cfg(feature = "std")]
19
use std::path::Path;
20
21
#[cfg(doc)]
22
use crate::SubjectPublicKeyInfo;
23
24
/// Parse a public key object from an encoded SPKI document.
25
pub trait DecodePublicKey: Sized {
26
    /// Deserialize object from ASN.1 DER-encoded [`SubjectPublicKeyInfo`]
27
    /// (binary format).
28
    fn from_public_key_der(bytes: &[u8]) -> Result<Self>;
29
30
    /// Deserialize PEM-encoded [`SubjectPublicKeyInfo`].
31
    ///
32
    /// Keys in this format begin with the following delimiter:
33
    ///
34
    /// ```text
35
    /// -----BEGIN PUBLIC KEY-----
36
    /// ```
37
    #[cfg(feature = "pem")]
38
0
    fn from_public_key_pem(s: &str) -> Result<Self> {
39
0
        let (label, doc) = Document::from_pem(s)?;
40
0
        SubjectPublicKeyInfoRef::validate_pem_label(label)?;
41
0
        Self::from_public_key_der(doc.as_bytes())
42
0
    }
43
44
    /// Load public key object from an ASN.1 DER-encoded file on the local
45
    /// filesystem (binary format).
46
    #[cfg(feature = "std")]
47
0
    fn read_public_key_der_file(path: impl AsRef<Path>) -> Result<Self> {
48
0
        let doc = Document::read_der_file(path)?;
49
0
        Self::from_public_key_der(doc.as_bytes())
50
0
    }
51
52
    /// Load public key object from a PEM-encoded file on the local filesystem.
53
    #[cfg(all(feature = "pem", feature = "std"))]
54
0
    fn read_public_key_pem_file(path: impl AsRef<Path>) -> Result<Self> {
55
0
        let (label, doc) = Document::read_pem_file(path)?;
56
0
        SubjectPublicKeyInfoRef::validate_pem_label(&label)?;
57
0
        Self::from_public_key_der(doc.as_bytes())
58
0
    }
59
}
60
61
impl<T> DecodePublicKey for T
62
where
63
    T: for<'a> TryFrom<SubjectPublicKeyInfoRef<'a>, Error = Error>,
64
{
65
0
    fn from_public_key_der(bytes: &[u8]) -> Result<Self> {
66
0
        Self::try_from(SubjectPublicKeyInfoRef::try_from(bytes)?)
67
0
    }
68
}
69
70
/// Serialize a public key object to a SPKI-encoded document.
71
#[cfg(feature = "alloc")]
72
pub trait EncodePublicKey {
73
    /// Serialize a [`Document`] containing a SPKI-encoded public key.
74
    fn to_public_key_der(&self) -> Result<Document>;
75
76
    /// Serialize this public key as PEM-encoded SPKI with the given [`LineEnding`].
77
    #[cfg(feature = "pem")]
78
0
    fn to_public_key_pem(&self, line_ending: LineEnding) -> Result<String> {
79
0
        let doc = self.to_public_key_der()?;
80
0
        Ok(doc.to_pem(SubjectPublicKeyInfoRef::PEM_LABEL, line_ending)?)
81
0
    }
82
83
    /// Write ASN.1 DER-encoded public key to the given path
84
    #[cfg(feature = "std")]
85
0
    fn write_public_key_der_file(&self, path: impl AsRef<Path>) -> Result<()> {
86
0
        Ok(self.to_public_key_der()?.write_der_file(path)?)
87
0
    }
88
89
    /// Write ASN.1 DER-encoded public key to the given path
90
    #[cfg(all(feature = "pem", feature = "std"))]
91
0
    fn write_public_key_pem_file(
92
0
        &self,
93
0
        path: impl AsRef<Path>,
94
0
        line_ending: LineEnding,
95
0
    ) -> Result<()> {
96
0
        let doc = self.to_public_key_der()?;
97
0
        Ok(doc.write_pem_file(path, SubjectPublicKeyInfoRef::PEM_LABEL, line_ending)?)
98
0
    }
99
}
100
101
/// Returns `AlgorithmIdentifier` associated with the structure.
102
///
103
/// This is useful for e.g. keys for digital signature algorithms.
104
pub trait AssociatedAlgorithmIdentifier {
105
    /// Algorithm parameters.
106
    type Params: Tagged + EncodeValue;
107
108
    /// `AlgorithmIdentifier` for this structure.
109
    const ALGORITHM_IDENTIFIER: AlgorithmIdentifier<Self::Params>;
110
}
111
112
/// Returns `AlgorithmIdentifier` associated with the structure.
113
///
114
/// This is useful for e.g. keys for digital signature algorithms.
115
#[cfg(feature = "alloc")]
116
pub trait DynAssociatedAlgorithmIdentifier {
117
    /// `AlgorithmIdentifier` for this structure.
118
    fn algorithm_identifier(&self) -> Result<AlgorithmIdentifierOwned>;
119
}
120
121
#[cfg(feature = "alloc")]
122
impl<T> DynAssociatedAlgorithmIdentifier for T
123
where
124
    T: AssociatedAlgorithmIdentifier,
125
{
126
0
    fn algorithm_identifier(&self) -> Result<AlgorithmIdentifierOwned> {
127
0
        Ok(AlgorithmIdentifierOwned {
128
0
            oid: T::ALGORITHM_IDENTIFIER.oid,
129
0
            parameters: T::ALGORITHM_IDENTIFIER
130
0
                .parameters
131
0
                .as_ref()
132
0
                .map(Any::encode_from)
133
0
                .transpose()?,
134
        })
135
0
    }
136
}
137
138
/// Returns `AlgorithmIdentifier` associated with the signature system.
139
///
140
/// Unlike AssociatedAlgorithmIdentifier this is intended to be implemented for public and/or
141
/// private keys.
142
pub trait SignatureAlgorithmIdentifier {
143
    /// Algorithm parameters.
144
    type Params: Tagged + EncodeValue;
145
146
    /// `AlgorithmIdentifier` for the corresponding singature system.
147
    const SIGNATURE_ALGORITHM_IDENTIFIER: AlgorithmIdentifier<Self::Params>;
148
}
149
150
/// Returns `AlgorithmIdentifier` associated with the signature system.
151
///
152
/// Unlike AssociatedAlgorithmIdentifier this is intended to be implemented for public and/or
153
/// private keys.
154
#[cfg(feature = "alloc")]
155
pub trait DynSignatureAlgorithmIdentifier {
156
    /// `AlgorithmIdentifier` for the corresponding singature system.
157
    fn signature_algorithm_identifier(&self) -> Result<AlgorithmIdentifierOwned>;
158
}
159
160
#[cfg(feature = "alloc")]
161
impl<T> DynSignatureAlgorithmIdentifier for T
162
where
163
    T: SignatureAlgorithmIdentifier,
164
{
165
0
    fn signature_algorithm_identifier(&self) -> Result<AlgorithmIdentifierOwned> {
166
0
        Ok(AlgorithmIdentifierOwned {
167
0
            oid: T::SIGNATURE_ALGORITHM_IDENTIFIER.oid,
168
0
            parameters: T::SIGNATURE_ALGORITHM_IDENTIFIER
169
0
                .parameters
170
0
                .as_ref()
171
0
                .map(Any::encode_from)
172
0
                .transpose()?,
173
        })
174
0
    }
175
}
176
177
/// Returns the `BitString` encoding of the signature.
178
///
179
/// X.509 and CSR structures require signatures to be BitString encoded.
180
#[cfg(feature = "alloc")]
181
pub trait SignatureBitStringEncoding {
182
    /// `BitString` encoding for this signature.
183
    fn to_bitstring(&self) -> der::Result<BitString>;
184
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/subtle-2.6.1/src/lib.rs
Line
Count
Source
1
// -*- mode: rust; -*-
2
//
3
// This file is part of subtle, part of the dalek cryptography project.
4
// Copyright (c) 2016-2018 isis lovecruft, Henry de Valence
5
// See LICENSE for licensing information.
6
//
7
// Authors:
8
// - isis agora lovecruft <isis@patternsinthevoid.net>
9
// - Henry de Valence <hdevalence@hdevalence.ca>
10
11
#![no_std]
12
#![deny(missing_docs)]
13
#![doc(html_logo_url = "https://doc.dalek.rs/assets/dalek-logo-clear.png")]
14
#![doc(html_root_url = "https://docs.rs/subtle/2.6.0")]
15
16
//! # subtle [![](https://img.shields.io/crates/v/subtle.svg)](https://crates.io/crates/subtle) [![](https://img.shields.io/badge/dynamic/json.svg?label=docs&uri=https%3A%2F%2Fcrates.io%2Fapi%2Fv1%2Fcrates%2Fsubtle%2Fversions&query=%24.versions%5B0%5D.num&colorB=4F74A6)](https://doc.dalek.rs/subtle) [![](https://travis-ci.org/dalek-cryptography/subtle.svg?branch=master)](https://travis-ci.org/dalek-cryptography/subtle)
17
//!
18
//! **Pure-Rust traits and utilities for constant-time cryptographic implementations.**
19
//!
20
//! It consists of a `Choice` type, and a collection of traits using `Choice`
21
//! instead of `bool` which are intended to execute in constant-time.  The `Choice`
22
//! type is a wrapper around a `u8` that holds a `0` or `1`.
23
//!
24
//! ```toml
25
//! subtle = "2.6"
26
//! ```
27
//!
28
//! This crate represents a “best-effort” attempt, since side-channels
29
//! are ultimately a property of a deployed cryptographic system
30
//! including the hardware it runs on, not just of software.
31
//!
32
//! The traits are implemented using bitwise operations, and should execute in
33
//! constant time provided that a) the bitwise operations are constant-time and
34
//! b) the bitwise operations are not recognized as a conditional assignment and
35
//! optimized back into a branch.
36
//!
37
//! For a compiler to recognize that bitwise operations represent a conditional
38
//! assignment, it needs to know that the value used to generate the bitmasks is
39
//! really a boolean `i1` rather than an `i8` byte value. In an attempt to
40
//! prevent this refinement, the crate tries to hide the value of a `Choice`'s
41
//! inner `u8` by passing it through a volatile read. For more information, see
42
//! the _About_ section below.
43
//!
44
//! Rust versions from 1.51 or higher have const generics support. You may enable
45
//! `const-generics` feautre to have `subtle` traits implemented for arrays `[T; N]`.
46
//!
47
//! Versions prior to `2.2` recommended use of the `nightly` feature to enable an
48
//! optimization barrier; this is not required in versions `2.2` and above.
49
//!
50
//! Note: the `subtle` crate contains `debug_assert`s to check invariants during
51
//! debug builds. These invariant checks involve secret-dependent branches, and
52
//! are not present when compiled in release mode. This crate is intended to be
53
//! used in release mode.
54
//!
55
//! ## Documentation
56
//!
57
//! Documentation is available [here][docs].
58
//!
59
//! ## Minimum Supported Rust Version
60
//!
61
//! Rust **1.41** or higher.
62
//!
63
//! Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump.
64
//!
65
//! ## About
66
//!
67
//! This library aims to be the Rust equivalent of Go’s `crypto/subtle` module.
68
//!
69
//! Old versions of the optimization barrier in `impl From<u8> for Choice` were
70
//! based on Tim Maclean's [work on `rust-timing-shield`][rust-timing-shield],
71
//! which attempts to provide a more comprehensive approach for preventing
72
//! software side-channels in Rust code.
73
//! From version `2.2`, it was based on Diane Hosfelt and Amber Sprenkels' work on
74
//! "Secret Types in Rust".
75
//!
76
//! `subtle` is authored by isis agora lovecruft and Henry de Valence.
77
//!
78
//! ## Warning
79
//!
80
//! This code is a low-level library, intended for specific use-cases implementing
81
//! cryptographic protocols.  It represents a best-effort attempt to protect
82
//! against some software side-channels.  Because side-channel resistance is not a
83
//! property of software alone, but of software together with hardware, any such
84
//! effort is fundamentally limited.
85
//!
86
//! **USE AT YOUR OWN RISK**
87
//!
88
//! [docs]: https://docs.rs/subtle
89
//! [rust-timing-shield]: https://www.chosenplaintext.ca/open-source/rust-timing-shield/security
90
91
#[cfg(feature = "std")]
92
#[macro_use]
93
extern crate std;
94
95
use core::cmp;
96
use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Neg, Not};
97
use core::option::Option;
98
99
#[cfg(feature = "core_hint_black_box")]
100
use core::hint::black_box;
101
102
/// The `Choice` struct represents a choice for use in conditional assignment.
103
///
104
/// It is a wrapper around a `u8`, which should have the value either `1` (true)
105
/// or `0` (false).
106
///
107
/// The conversion from `u8` to `Choice` passes the value through an optimization
108
/// barrier, as a best-effort attempt to prevent the compiler from inferring that
109
/// the `Choice` value is a boolean. This strategy is based on Tim Maclean's
110
/// [work on `rust-timing-shield`][rust-timing-shield], which attempts to provide
111
/// a more comprehensive approach for preventing software side-channels in Rust
112
/// code.
113
///
114
/// The `Choice` struct implements operators for AND, OR, XOR, and NOT, to allow
115
/// combining `Choice` values. These operations do not short-circuit.
116
///
117
/// [rust-timing-shield]:
118
/// https://www.chosenplaintext.ca/open-source/rust-timing-shield/security
119
#[derive(Copy, Clone, Debug)]
120
pub struct Choice(u8);
121
122
impl Choice {
123
    /// Unwrap the `Choice` wrapper to reveal the underlying `u8`.
124
    ///
125
    /// # Note
126
    ///
127
    /// This function only exists as an **escape hatch** for the rare case
128
    /// where it's not possible to use one of the `subtle`-provided
129
    /// trait impls.
130
    ///
131
    /// **To convert a `Choice` to a `bool`, use the `From` implementation instead.**
132
    #[inline]
133
30.7M
    pub fn unwrap_u8(&self) -> u8 {
134
30.7M
        self.0
135
30.7M
    }
_RNvMCs3v1T4Vw6hEJ_6subtleNtB2_6Choice9unwrap_u8Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
133
9.84k
    pub fn unwrap_u8(&self) -> u8 {
134
9.84k
        self.0
135
9.84k
    }
Unexecuted instantiation: _RNvMCs3v1T4Vw6hEJ_6subtleNtB2_6Choice9unwrap_u8CshRehcWQJ0wE_13crypto_bigint
_RNvMCs3v1T4Vw6hEJ_6subtleNtB2_6Choice9unwrap_u8CsjewTDwKBbyD_4k256
Line
Count
Source
133
11.3M
    pub fn unwrap_u8(&self) -> u8 {
134
11.3M
        self.0
135
11.3M
    }
_RNvMCs3v1T4Vw6hEJ_6subtleNtB2_6Choice9unwrap_u8CsaHRNXv1Y9Bq_4p256
Line
Count
Source
133
19.3M
    pub fn unwrap_u8(&self) -> u8 {
134
19.3M
        self.0
135
19.3M
    }
Unexecuted instantiation: _RNvMCs3v1T4Vw6hEJ_6subtleNtB2_6Choice9unwrap_u8B2_
136
}
137
138
impl From<Choice> for bool {
139
    /// Convert the `Choice` wrapper into a `bool`, depending on whether
140
    /// the underlying `u8` was a `0` or a `1`.
141
    ///
142
    /// # Note
143
    ///
144
    /// This function exists to avoid having higher-level cryptographic protocol
145
    /// implementations duplicating this pattern.
146
    ///
147
    /// The intended use case for this conversion is at the _end_ of a
148
    /// higher-level primitive implementation: for example, in checking a keyed
149
    /// MAC, where the verification should happen in constant-time (and thus use
150
    /// a `Choice`) but it is safe to return a `bool` at the end of the
151
    /// verification.
152
    #[inline]
153
4.15M
    fn from(source: Choice) -> bool {
154
4.15M
        debug_assert!((source.0 == 0u8) | (source.0 == 1u8));
155
4.15M
        source.0 != 0
156
4.15M
    }
_RNvXs_Cs3v1T4Vw6hEJ_6subtlebINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB4_6ChoiceE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
153
2.77k
    fn from(source: Choice) -> bool {
154
2.77k
        debug_assert!((source.0 == 0u8) | (source.0 == 1u8));
155
2.77k
        source.0 != 0
156
2.77k
    }
Unexecuted instantiation: _RNvXs_Cs3v1T4Vw6hEJ_6subtlebINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB4_6ChoiceE4fromCshRehcWQJ0wE_13crypto_bigint
_RNvXs_Cs3v1T4Vw6hEJ_6subtlebINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB4_6ChoiceE4fromCsjewTDwKBbyD_4k256
Line
Count
Source
153
2.53M
    fn from(source: Choice) -> bool {
154
2.53M
        debug_assert!((source.0 == 0u8) | (source.0 == 1u8));
155
2.53M
        source.0 != 0
156
2.53M
    }
_RNvXs_Cs3v1T4Vw6hEJ_6subtlebINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB4_6ChoiceE4fromCsaHRNXv1Y9Bq_4p256
Line
Count
Source
153
1.61M
    fn from(source: Choice) -> bool {
154
1.61M
        debug_assert!((source.0 == 0u8) | (source.0 == 1u8));
155
1.61M
        source.0 != 0
156
1.61M
    }
Unexecuted instantiation: _RNvXs_Cs3v1T4Vw6hEJ_6subtlebINtNtCsbQ8arDwx5Xq_4core7convert4FromNtB4_6ChoiceE4fromB4_
157
}
158
159
impl BitAnd for Choice {
160
    type Output = Choice;
161
    #[inline]
162
5.97k
    fn bitand(self, rhs: Choice) -> Choice {
163
5.97k
        (self.0 & rhs.0).into()
164
5.97k
    }
_RNvXs0_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitAnd6bitandCs4RkbDk9WRL5_5clvmr
Line
Count
Source
162
4.18k
    fn bitand(self, rhs: Choice) -> Choice {
163
4.18k
        (self.0 & rhs.0).into()
164
4.18k
    }
Unexecuted instantiation: _RNvXs0_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitAnd6bitandCshRehcWQJ0wE_13crypto_bigint
_RNvXs0_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitAnd6bitandCsjewTDwKBbyD_4k256
Line
Count
Source
162
1.79k
    fn bitand(self, rhs: Choice) -> Choice {
163
1.79k
        (self.0 & rhs.0).into()
164
1.79k
    }
Unexecuted instantiation: _RNvXs0_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitAnd6bitandCsaHRNXv1Y9Bq_4p256
Unexecuted instantiation: _RNvXs0_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitAnd6bitandB5_
165
}
166
167
impl BitAndAssign for Choice {
168
    #[inline]
169
5.97k
    fn bitand_assign(&mut self, rhs: Choice) {
170
5.97k
        *self = *self & rhs;
171
5.97k
    }
_RNvXs1_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit12BitAndAssign13bitand_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
169
4.18k
    fn bitand_assign(&mut self, rhs: Choice) {
170
4.18k
        *self = *self & rhs;
171
4.18k
    }
Unexecuted instantiation: _RNvXs1_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit12BitAndAssign13bitand_assignCshRehcWQJ0wE_13crypto_bigint
_RNvXs1_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit12BitAndAssign13bitand_assignCsjewTDwKBbyD_4k256
Line
Count
Source
169
1.79k
    fn bitand_assign(&mut self, rhs: Choice) {
170
1.79k
        *self = *self & rhs;
171
1.79k
    }
Unexecuted instantiation: _RNvXs1_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit12BitAndAssign13bitand_assignCsaHRNXv1Y9Bq_4p256
Unexecuted instantiation: _RNvXs1_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit12BitAndAssign13bitand_assignB5_
172
}
173
174
impl BitOr for Choice {
175
    type Output = Choice;
176
    #[inline]
177
4.18k
    fn bitor(self, rhs: Choice) -> Choice {
178
4.18k
        (self.0 | rhs.0).into()
179
4.18k
    }
_RNvXs2_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit5BitOr5bitorCsjewTDwKBbyD_4k256
Line
Count
Source
177
4.18k
    fn bitor(self, rhs: Choice) -> Choice {
178
4.18k
        (self.0 | rhs.0).into()
179
4.18k
    }
Unexecuted instantiation: _RNvXs2_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit5BitOr5bitorCsaHRNXv1Y9Bq_4p256
Unexecuted instantiation: _RNvXs2_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit5BitOr5bitorB5_
180
}
181
182
impl BitOrAssign for Choice {
183
    #[inline]
184
0
    fn bitor_assign(&mut self, rhs: Choice) {
185
0
        *self = *self | rhs;
186
0
    }
187
}
188
189
impl BitXor for Choice {
190
    type Output = Choice;
191
    #[inline]
192
1.34k
    fn bitxor(self, rhs: Choice) -> Choice {
193
1.34k
        (self.0 ^ rhs.0).into()
194
1.34k
    }
_RNvXs4_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitXor6bitxorCs4RkbDk9WRL5_5clvmr
Line
Count
Source
192
611
    fn bitxor(self, rhs: Choice) -> Choice {
193
611
        (self.0 ^ rhs.0).into()
194
611
    }
_RNvXs4_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitXor6bitxorCsjewTDwKBbyD_4k256
Line
Count
Source
192
735
    fn bitxor(self, rhs: Choice) -> Choice {
193
735
        (self.0 ^ rhs.0).into()
194
735
    }
Unexecuted instantiation: _RNvXs4_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitXor6bitxorCsaHRNXv1Y9Bq_4p256
Unexecuted instantiation: _RNvXs4_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit6BitXor6bitxorB5_
195
}
196
197
impl BitXorAssign for Choice {
198
    #[inline]
199
0
    fn bitxor_assign(&mut self, rhs: Choice) {
200
0
        *self = *self ^ rhs;
201
0
    }
202
}
203
204
impl Not for Choice {
205
    type Output = Choice;
206
    #[inline]
207
999k
    fn not(self) -> Choice {
208
999k
        (1u8 & (!self.0)).into()
209
999k
    }
_RNvXs6_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit3Not3notCs4RkbDk9WRL5_5clvmr
Line
Count
Source
207
4.74k
    fn not(self) -> Choice {
208
4.74k
        (1u8 & (!self.0)).into()
209
4.74k
    }
Unexecuted instantiation: _RNvXs6_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit3Not3notCshRehcWQJ0wE_13crypto_bigint
_RNvXs6_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit3Not3notCsjewTDwKBbyD_4k256
Line
Count
Source
207
384k
    fn not(self) -> Choice {
208
384k
        (1u8 & (!self.0)).into()
209
384k
    }
_RNvXs6_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit3Not3notCsaHRNXv1Y9Bq_4p256
Line
Count
Source
207
610k
    fn not(self) -> Choice {
208
610k
        (1u8 & (!self.0)).into()
209
610k
    }
Unexecuted instantiation: _RNvXs6_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtNtNtCsbQ8arDwx5Xq_4core3ops3bit3Not3notB5_
210
}
211
212
/// This function is a best-effort attempt to prevent the compiler from knowing
213
/// anything about the value of the returned `u8`, other than its type.
214
///
215
/// Because we want to support stable Rust, we don't have access to inline
216
/// assembly or test::black_box, so we use the fact that volatile values will
217
/// never be elided to register values.
218
///
219
/// Note: Rust's notion of "volatile" is subject to change over time. While this
220
/// code may break in a non-destructive way in the future, “constant-time” code
221
/// is a continually moving target, and this is better than doing nothing.
222
#[cfg(not(feature = "core_hint_black_box"))]
223
#[inline(never)]
224
5.55M
fn black_box<T: Copy>(input: T) -> T {
225
5.55M
    unsafe {
226
5.55M
        // Optimization barrier
227
5.55M
        //
228
5.55M
        // SAFETY:
229
5.55M
        //   - &input is not NULL because we own input;
230
5.55M
        //   - input is Copy and always live;
231
5.55M
        //   - input is always properly aligned.
232
5.55M
        core::ptr::read_volatile(&input)
233
5.55M
    }
234
5.55M
}
_RINvCs3v1T4Vw6hEJ_6subtle9black_boxhECs4RkbDk9WRL5_5clvmr
Line
Count
Source
224
1.62M
fn black_box<T: Copy>(input: T) -> T {
225
1.62M
    unsafe {
226
1.62M
        // Optimization barrier
227
1.62M
        //
228
1.62M
        // SAFETY:
229
1.62M
        //   - &input is not NULL because we own input;
230
1.62M
        //   - input is Copy and always live;
231
1.62M
        //   - input is always properly aligned.
232
1.62M
        core::ptr::read_volatile(&input)
233
1.62M
    }
234
1.62M
}
_RINvCs3v1T4Vw6hEJ_6subtle9black_boxhECshRehcWQJ0wE_13crypto_bigint
Line
Count
Source
224
823k
fn black_box<T: Copy>(input: T) -> T {
225
823k
    unsafe {
226
823k
        // Optimization barrier
227
823k
        //
228
823k
        // SAFETY:
229
823k
        //   - &input is not NULL because we own input;
230
823k
        //   - input is Copy and always live;
231
823k
        //   - input is always properly aligned.
232
823k
        core::ptr::read_volatile(&input)
233
823k
    }
234
823k
}
_RINvCs3v1T4Vw6hEJ_6subtle9black_boxhECsjewTDwKBbyD_4k256
Line
Count
Source
224
1.59M
fn black_box<T: Copy>(input: T) -> T {
225
1.59M
    unsafe {
226
1.59M
        // Optimization barrier
227
1.59M
        //
228
1.59M
        // SAFETY:
229
1.59M
        //   - &input is not NULL because we own input;
230
1.59M
        //   - input is Copy and always live;
231
1.59M
        //   - input is always properly aligned.
232
1.59M
        core::ptr::read_volatile(&input)
233
1.59M
    }
234
1.59M
}
_RINvCs3v1T4Vw6hEJ_6subtle9black_boxhECsaHRNXv1Y9Bq_4p256
Line
Count
Source
224
1.51M
fn black_box<T: Copy>(input: T) -> T {
225
1.51M
    unsafe {
226
1.51M
        // Optimization barrier
227
1.51M
        //
228
1.51M
        // SAFETY:
229
1.51M
        //   - &input is not NULL because we own input;
230
1.51M
        //   - input is Copy and always live;
231
1.51M
        //   - input is always properly aligned.
232
1.51M
        core::ptr::read_volatile(&input)
233
1.51M
    }
234
1.51M
}
Unexecuted instantiation: _RINvCs3v1T4Vw6hEJ_6subtle9black_boxhEB2_
235
236
impl From<u8> for Choice {
237
    #[inline]
238
5.55M
    fn from(input: u8) -> Choice {
239
5.55M
        debug_assert!((input == 0u8) | (input == 1u8));
240
241
        // Our goal is to prevent the compiler from inferring that the value held inside the
242
        // resulting `Choice` struct is really a `bool` instead of a `u8`.
243
5.55M
        Choice(black_box(input))
244
5.55M
    }
_RNvXs7_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceINtNtCsbQ8arDwx5Xq_4core7convert4FromhE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
238
1.62M
    fn from(input: u8) -> Choice {
239
1.62M
        debug_assert!((input == 0u8) | (input == 1u8));
240
241
        // Our goal is to prevent the compiler from inferring that the value held inside the
242
        // resulting `Choice` struct is really a `bool` instead of a `u8`.
243
1.62M
        Choice(black_box(input))
244
1.62M
    }
_RNvXs7_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceINtNtCsbQ8arDwx5Xq_4core7convert4FromhE4fromCshRehcWQJ0wE_13crypto_bigint
Line
Count
Source
238
823k
    fn from(input: u8) -> Choice {
239
823k
        debug_assert!((input == 0u8) | (input == 1u8));
240
241
        // Our goal is to prevent the compiler from inferring that the value held inside the
242
        // resulting `Choice` struct is really a `bool` instead of a `u8`.
243
823k
        Choice(black_box(input))
244
823k
    }
_RNvXs7_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceINtNtCsbQ8arDwx5Xq_4core7convert4FromhE4fromCsjewTDwKBbyD_4k256
Line
Count
Source
238
1.59M
    fn from(input: u8) -> Choice {
239
1.59M
        debug_assert!((input == 0u8) | (input == 1u8));
240
241
        // Our goal is to prevent the compiler from inferring that the value held inside the
242
        // resulting `Choice` struct is really a `bool` instead of a `u8`.
243
1.59M
        Choice(black_box(input))
244
1.59M
    }
_RNvXs7_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceINtNtCsbQ8arDwx5Xq_4core7convert4FromhE4fromCsaHRNXv1Y9Bq_4p256
Line
Count
Source
238
1.51M
    fn from(input: u8) -> Choice {
239
1.51M
        debug_assert!((input == 0u8) | (input == 1u8));
240
241
        // Our goal is to prevent the compiler from inferring that the value held inside the
242
        // resulting `Choice` struct is really a `bool` instead of a `u8`.
243
1.51M
        Choice(black_box(input))
244
1.51M
    }
Unexecuted instantiation: _RNvXs7_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceINtNtCsbQ8arDwx5Xq_4core7convert4FromhE4fromB5_
245
}
246
247
/// An `Eq`-like trait that produces a `Choice` instead of a `bool`.
248
///
249
/// # Example
250
///
251
/// ```
252
/// use subtle::ConstantTimeEq;
253
/// let x: u8 = 5;
254
/// let y: u8 = 13;
255
///
256
/// assert_eq!(x.ct_eq(&y).unwrap_u8(), 0);
257
/// assert_eq!(x.ct_eq(&x).unwrap_u8(), 1);
258
/// ```
259
//
260
// #[inline] is specified on these function prototypes to signify that they
261
#[allow(unused_attributes)] // should be in the actual implementation
262
pub trait ConstantTimeEq {
263
    /// Determine if two items are equal.
264
    ///
265
    /// The `ct_eq` function should execute in constant time.
266
    ///
267
    /// # Returns
268
    ///
269
    /// * `Choice(1u8)` if `self == other`;
270
    /// * `Choice(0u8)` if `self != other`.
271
    #[inline]
272
    #[allow(unused_attributes)]
273
    fn ct_eq(&self, other: &Self) -> Choice;
274
275
    /// Determine if two items are NOT equal.
276
    ///
277
    /// The `ct_ne` function should execute in constant time.
278
    ///
279
    /// # Returns
280
    ///
281
    /// * `Choice(0u8)` if `self == other`;
282
    /// * `Choice(1u8)` if `self != other`.
283
    #[inline]
284
0
    fn ct_ne(&self, other: &Self) -> Choice {
285
0
        !self.ct_eq(other)
286
0
    }
Unexecuted instantiation: _RNvYNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB6_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic10projective15ProjectivePointNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6affine11AffinePointNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB8_
Unexecuted instantiation: _RNvYNtNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field10field_5x5216FieldElement5x52NtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neBa_
Unexecuted instantiation: _RNvYNtNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field10field_impl16FieldElementImplNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neBa_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB8_
Unexecuted instantiation: _RNvYNtCs3v1T4Vw6hEJ_6subtle6ChoiceNtB4_14ConstantTimeEq5ct_neB4_
Unexecuted instantiation: _RNvYNtNtCsbQ8arDwx5Xq_4core3cmp8OrderingNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neBE_
Unexecuted instantiation: _RNvYaNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
Unexecuted instantiation: _RNvYhNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
Unexecuted instantiation: _RNvYiNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
Unexecuted instantiation: _RNvYjNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
Unexecuted instantiation: _RNvYlNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
Unexecuted instantiation: _RNvYmNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
Unexecuted instantiation: _RNvYnNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
Unexecuted instantiation: _RNvYoNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
Unexecuted instantiation: _RNvYsNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
Unexecuted instantiation: _RNvYtNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
Unexecuted instantiation: _RNvYxNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
Unexecuted instantiation: _RNvYyNtCs3v1T4Vw6hEJ_6subtle14ConstantTimeEq5ct_neB5_
287
}
288
289
impl<T: ConstantTimeEq> ConstantTimeEq for [T] {
290
    /// Check whether two slices of `ConstantTimeEq` types are equal.
291
    ///
292
    /// # Note
293
    ///
294
    /// This function short-circuits if the lengths of the input slices
295
    /// are different.  Otherwise, it should execute in time independent
296
    /// of the slice contents.
297
    ///
298
    /// Since arrays coerce to slices, this function works with fixed-size arrays:
299
    ///
300
    /// ```
301
    /// # use subtle::ConstantTimeEq;
302
    /// #
303
    /// let a: [u8; 8] = [0,1,2,3,4,5,6,7];
304
    /// let b: [u8; 8] = [0,1,2,3,0,1,2,3];
305
    ///
306
    /// let a_eq_a = a.ct_eq(&a);
307
    /// let a_eq_b = a.ct_eq(&b);
308
    ///
309
    /// assert_eq!(a_eq_a.unwrap_u8(), 1);
310
    /// assert_eq!(a_eq_b.unwrap_u8(), 0);
311
    /// ```
312
    #[inline]
313
0
    fn ct_eq(&self, _rhs: &[T]) -> Choice {
314
0
        let len = self.len();
315
0
316
0
        // Short-circuit on the *lengths* of the slices, not their
317
0
        // contents.
318
0
        if len != _rhs.len() {
319
0
            return Choice::from(0);
320
0
        }
321
0
322
0
        // This loop shouldn't be shortcircuitable, since the compiler
323
0
        // shouldn't be able to reason about the value of the `u8`
324
0
        // unwrapped from the `ct_eq` result.
325
0
        let mut x = 1u8;
326
0
        for (ai, bi) in self.iter().zip(_rhs.iter()) {
327
0
            x &= ai.ct_eq(bi).unwrap_u8();
328
0
        }
329
330
0
        x.into()
331
0
    }
Unexecuted instantiation: _RNvXs8_Cs3v1T4Vw6hEJ_6subtleShNtB5_14ConstantTimeEq5ct_eqCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXINICs3v1T4Vw6hEJ_6subtles8_0pESpNtB5_14ConstantTimeEq5ct_eqB5_
332
}
333
334
impl ConstantTimeEq for Choice {
335
    #[inline]
336
1.34k
    fn ct_eq(&self, rhs: &Choice) -> Choice {
337
1.34k
        !(*self ^ *rhs)
338
1.34k
    }
_RNvXs9_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtB5_14ConstantTimeEq5ct_eqCs4RkbDk9WRL5_5clvmr
Line
Count
Source
336
611
    fn ct_eq(&self, rhs: &Choice) -> Choice {
337
611
        !(*self ^ *rhs)
338
611
    }
_RNvXs9_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtB5_14ConstantTimeEq5ct_eqCsjewTDwKBbyD_4k256
Line
Count
Source
336
735
    fn ct_eq(&self, rhs: &Choice) -> Choice {
337
735
        !(*self ^ *rhs)
338
735
    }
Unexecuted instantiation: _RNvXs9_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtB5_14ConstantTimeEq5ct_eqB5_
339
}
340
341
/// Given the bit-width `$bit_width` and the corresponding primitive
342
/// unsigned and signed types `$t_u` and `$t_i` respectively, generate
343
/// an `ConstantTimeEq` implementation.
344
macro_rules! generate_integer_equal {
345
    ($t_u:ty, $t_i:ty, $bit_width:expr) => {
346
        impl ConstantTimeEq for $t_u {
347
            #[inline]
348
552k
            fn ct_eq(&self, other: &$t_u) -> Choice {
349
552k
                // x == 0 if and only if self == other
350
552k
                let x: $t_u = self ^ other;
351
552k
352
552k
                // If x == 0, then x and -x are both equal to zero;
353
552k
                // otherwise, one or both will have its high bit set.
354
552k
                let y: $t_u = (x | x.wrapping_neg()) >> ($bit_width - 1);
355
552k
356
552k
                // Result is the opposite of the high bit (now shifted to low).
357
552k
                ((y ^ (1 as $t_u)) as u8).into()
358
552k
            }
Unexecuted instantiation: _RNvXsz_Cs3v1T4Vw6hEJ_6subtleyNtB5_14ConstantTimeEq5ct_eqCshRehcWQJ0wE_13crypto_bigint
_RNvXst_Cs3v1T4Vw6hEJ_6subtlehNtB5_14ConstantTimeEq5ct_eqCsjewTDwKBbyD_4k256
Line
Count
Source
348
552k
            fn ct_eq(&self, other: &$t_u) -> Choice {
349
552k
                // x == 0 if and only if self == other
350
552k
                let x: $t_u = self ^ other;
351
552k
352
552k
                // If x == 0, then x and -x are both equal to zero;
353
552k
                // otherwise, one or both will have its high bit set.
354
552k
                let y: $t_u = (x | x.wrapping_neg()) >> ($bit_width - 1);
355
552k
356
552k
                // Result is the opposite of the high bit (now shifted to low).
357
552k
                ((y ^ (1 as $t_u)) as u8).into()
358
552k
            }
Unexecuted instantiation: _RNvXsx_Cs3v1T4Vw6hEJ_6subtlemNtB5_14ConstantTimeEq5ct_eqCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXsz_Cs3v1T4Vw6hEJ_6subtleyNtB5_14ConstantTimeEq5ct_eqCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXsx_Cs3v1T4Vw6hEJ_6subtlemNtB5_14ConstantTimeEq5ct_eqCsaHRNXv1Y9Bq_4p256
Unexecuted instantiation: _RNvXst_Cs3v1T4Vw6hEJ_6subtlehNtB5_14ConstantTimeEq5ct_eqB5_
Unexecuted instantiation: _RNvXsv_Cs3v1T4Vw6hEJ_6subtletNtB5_14ConstantTimeEq5ct_eqB5_
Unexecuted instantiation: _RNvXsx_Cs3v1T4Vw6hEJ_6subtlemNtB5_14ConstantTimeEq5ct_eqB5_
Unexecuted instantiation: _RNvXsz_Cs3v1T4Vw6hEJ_6subtleyNtB5_14ConstantTimeEq5ct_eqB5_
Unexecuted instantiation: _RNvXsB_Cs3v1T4Vw6hEJ_6subtleoNtB5_14ConstantTimeEq5ct_eqB5_
Unexecuted instantiation: _RNvXsD_Cs3v1T4Vw6hEJ_6subtlejNtB5_14ConstantTimeEq5ct_eqB5_
359
        }
360
        impl ConstantTimeEq for $t_i {
361
            #[inline]
362
0
            fn ct_eq(&self, other: &$t_i) -> Choice {
363
0
                // Bitcast to unsigned and call that implementation.
364
0
                (*self as $t_u).ct_eq(&(*other as $t_u))
365
0
            }
Unexecuted instantiation: _RNvXsu_Cs3v1T4Vw6hEJ_6subtleaNtB5_14ConstantTimeEq5ct_eqB5_
Unexecuted instantiation: _RNvXsw_Cs3v1T4Vw6hEJ_6subtlesNtB5_14ConstantTimeEq5ct_eqB5_
Unexecuted instantiation: _RNvXsy_Cs3v1T4Vw6hEJ_6subtlelNtB5_14ConstantTimeEq5ct_eqB5_
Unexecuted instantiation: _RNvXsA_Cs3v1T4Vw6hEJ_6subtlexNtB5_14ConstantTimeEq5ct_eqB5_
Unexecuted instantiation: _RNvXsC_Cs3v1T4Vw6hEJ_6subtlenNtB5_14ConstantTimeEq5ct_eqB5_
Unexecuted instantiation: _RNvXsE_Cs3v1T4Vw6hEJ_6subtleiNtB5_14ConstantTimeEq5ct_eqB5_
366
        }
367
    };
368
}
369
370
generate_integer_equal!(u8, i8, 8);
371
generate_integer_equal!(u16, i16, 16);
372
generate_integer_equal!(u32, i32, 32);
373
generate_integer_equal!(u64, i64, 64);
374
#[cfg(feature = "i128")]
375
generate_integer_equal!(u128, i128, 128);
376
generate_integer_equal!(usize, isize, ::core::mem::size_of::<usize>() * 8);
377
378
/// `Ordering` is `#[repr(i8)]` making it possible to leverage `i8::ct_eq`.
379
impl ConstantTimeEq for cmp::Ordering {
380
    #[inline]
381
0
    fn ct_eq(&self, other: &Self) -> Choice {
382
0
        (*self as i8).ct_eq(&(*other as i8))
383
0
    }
384
}
385
386
/// A type which can be conditionally selected in constant time.
387
///
388
/// This trait also provides generic implementations of conditional
389
/// assignment and conditional swaps.
390
//
391
// #[inline] is specified on these function prototypes to signify that they
392
#[allow(unused_attributes)] // should be in the actual implementation
393
pub trait ConditionallySelectable: Copy {
394
    /// Select `a` or `b` according to `choice`.
395
    ///
396
    /// # Returns
397
    ///
398
    /// * `a` if `choice == Choice(0)`;
399
    /// * `b` if `choice == Choice(1)`.
400
    ///
401
    /// This function should execute in constant time.
402
    ///
403
    /// # Example
404
    ///
405
    /// ```
406
    /// use subtle::ConditionallySelectable;
407
    /// #
408
    /// # fn main() {
409
    /// let x: u8 = 13;
410
    /// let y: u8 = 42;
411
    ///
412
    /// let z = u8::conditional_select(&x, &y, 0.into());
413
    /// assert_eq!(z, x);
414
    /// let z = u8::conditional_select(&x, &y, 1.into());
415
    /// assert_eq!(z, y);
416
    /// # }
417
    /// ```
418
    #[inline]
419
    #[allow(unused_attributes)]
420
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self;
421
422
    /// Conditionally assign `other` to `self`, according to `choice`.
423
    ///
424
    /// This function should execute in constant time.
425
    ///
426
    /// # Example
427
    ///
428
    /// ```
429
    /// use subtle::ConditionallySelectable;
430
    /// #
431
    /// # fn main() {
432
    /// let mut x: u8 = 13;
433
    /// let mut y: u8 = 42;
434
    ///
435
    /// x.conditional_assign(&y, 0.into());
436
    /// assert_eq!(x, 13);
437
    /// x.conditional_assign(&y, 1.into());
438
    /// assert_eq!(x, 42);
439
    /// # }
440
    /// ```
441
    #[inline]
442
2.23M
    fn conditional_assign(&mut self, other: &Self, choice: Choice) {
443
2.23M
        *self = Self::conditional_select(self, other, choice);
444
2.23M
    }
_RNvYINtNtCs2J0Yj5ID6sO_10primeorder10projective15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignCs4RkbDk9WRL5_5clvmr
Line
Count
Source
442
1.60M
    fn conditional_assign(&mut self, other: &Self, choice: Choice) {
443
1.60M
        *self = Self::conditional_select(self, other, choice);
444
1.60M
    }
Unexecuted instantiation: _RNvYNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignB6_
Unexecuted instantiation: _RNvYNtNtNtCshRehcWQJ0wE_13crypto_bigint4uint8div_limb10ReciprocalNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignB8_
_RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic10projective15ProjectivePointNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignB8_
Line
Count
Source
442
621k
    fn conditional_assign(&mut self, other: &Self, choice: Choice) {
443
621k
        *self = Self::conditional_select(self, other, choice);
444
621k
    }
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6affine11AffinePointNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignB8_
Unexecuted instantiation: _RNvYNtNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field10field_5x5216FieldElement5x52NtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignBa_
Unexecuted instantiation: _RNvYNtNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field10field_impl16FieldElementImplNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignBa_
Unexecuted instantiation: _RNvYINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzero13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1ENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignB19_
Unexecuted instantiation: _RNvYINtNtCs2J0Yj5ID6sO_10primeorder10projective15ProjectivePointNtCsaHRNXv1Y9Bq_4p2568NistP256ENtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignB12_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignB8_
Unexecuted instantiation: _RNvYNtCs3v1T4Vw6hEJ_6subtle6ChoiceNtB4_23ConditionallySelectable18conditional_assignB4_
Unexecuted instantiation: _RNvYNtNtCsbQ8arDwx5Xq_4core3cmp8OrderingNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable18conditional_assignBE_
445
446
    /// Conditionally swap `self` and `other` if `choice == 1`; otherwise,
447
    /// reassign both unto themselves.
448
    ///
449
    /// This function should execute in constant time.
450
    ///
451
    /// # Example
452
    ///
453
    /// ```
454
    /// use subtle::ConditionallySelectable;
455
    /// #
456
    /// # fn main() {
457
    /// let mut x: u8 = 13;
458
    /// let mut y: u8 = 42;
459
    ///
460
    /// u8::conditional_swap(&mut x, &mut y, 0.into());
461
    /// assert_eq!(x, 13);
462
    /// assert_eq!(y, 42);
463
    /// u8::conditional_swap(&mut x, &mut y, 1.into());
464
    /// assert_eq!(x, 42);
465
    /// assert_eq!(y, 13);
466
    /// # }
467
    /// ```
468
    #[inline]
469
0
    fn conditional_swap(a: &mut Self, b: &mut Self, choice: Choice) {
470
0
        let t: Self = *a;
471
0
        a.conditional_assign(&b, choice);
472
0
        b.conditional_assign(&t, choice);
473
0
    }
Unexecuted instantiation: _RNvYNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable16conditional_swapB6_
Unexecuted instantiation: _RNvYNtNtNtCshRehcWQJ0wE_13crypto_bigint4uint8div_limb10ReciprocalNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable16conditional_swapB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic10projective15ProjectivePointNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable16conditional_swapB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable16conditional_swapB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6affine11AffinePointNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable16conditional_swapB8_
Unexecuted instantiation: _RNvYNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable16conditional_swapB8_
Unexecuted instantiation: _RNvYNtNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field10field_5x5216FieldElement5x52NtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable16conditional_swapBa_
Unexecuted instantiation: _RNvYNtNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field10field_impl16FieldElementImplNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable16conditional_swapBa_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable16conditional_swapB8_
Unexecuted instantiation: _RNvYNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable16conditional_swapB8_
Unexecuted instantiation: _RNvYNtCs3v1T4Vw6hEJ_6subtle6ChoiceNtB4_23ConditionallySelectable16conditional_swapB4_
Unexecuted instantiation: _RNvYNtNtCsbQ8arDwx5Xq_4core3cmp8OrderingNtCs3v1T4Vw6hEJ_6subtle23ConditionallySelectable16conditional_swapBE_
474
}
475
476
macro_rules! to_signed_int {
477
    (u8) => {
478
        i8
479
    };
480
    (u16) => {
481
        i16
482
    };
483
    (u32) => {
484
        i32
485
    };
486
    (u64) => {
487
        i64
488
    };
489
    (u128) => {
490
        i128
491
    };
492
    (i8) => {
493
        i8
494
    };
495
    (i16) => {
496
        i16
497
    };
498
    (i32) => {
499
        i32
500
    };
501
    (i64) => {
502
        i64
503
    };
504
    (i128) => {
505
        i128
506
    };
507
}
508
509
macro_rules! generate_integer_conditional_select {
510
    ($($t:tt)*) => ($(
511
        impl ConditionallySelectable for $t {
512
            #[inline]
513
30.7M
            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
514
30.7M
                // if choice = 0, mask = (-0) = 0000...0000
515
30.7M
                // if choice = 1, mask = (-1) = 1111...1111
516
30.7M
                let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
517
30.7M
                a ^ (mask & (a ^ b))
518
30.7M
            }
_RNvXsF_Cs3v1T4Vw6hEJ_6subtlehNtB5_23ConditionallySelectable18conditional_selectCs4RkbDk9WRL5_5clvmr
Line
Count
Source
513
2.03k
            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
514
2.03k
                // if choice = 0, mask = (-0) = 0000...0000
515
2.03k
                // if choice = 1, mask = (-1) = 1111...1111
516
2.03k
                let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
517
2.03k
                a ^ (mask & (a ^ b))
518
2.03k
            }
Unexecuted instantiation: _RNvXsL_Cs3v1T4Vw6hEJ_6subtleyNtB5_23ConditionallySelectable18conditional_selectCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsJ_Cs3v1T4Vw6hEJ_6subtlemNtB5_23ConditionallySelectable18conditional_selectCshRehcWQJ0wE_13crypto_bigint
_RNvXsF_Cs3v1T4Vw6hEJ_6subtlehNtB5_23ConditionallySelectable18conditional_selectCsjewTDwKBbyD_4k256
Line
Count
Source
513
1.79k
            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
514
1.79k
                // if choice = 0, mask = (-0) = 0000...0000
515
1.79k
                // if choice = 1, mask = (-1) = 1111...1111
516
1.79k
                let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
517
1.79k
                a ^ (mask & (a ^ b))
518
1.79k
            }
_RNvXsL_Cs3v1T4Vw6hEJ_6subtleyNtB5_23ConditionallySelectable18conditional_selectCsjewTDwKBbyD_4k256
Line
Count
Source
513
9.46M
            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
514
9.46M
                // if choice = 0, mask = (-0) = 0000...0000
515
9.46M
                // if choice = 1, mask = (-1) = 1111...1111
516
9.46M
                let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
517
9.46M
                a ^ (mask & (a ^ b))
518
9.46M
            }
_RNvXsJ_Cs3v1T4Vw6hEJ_6subtlemNtB5_23ConditionallySelectable18conditional_selectCsjewTDwKBbyD_4k256
Line
Count
Source
513
1.88M
            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
514
1.88M
                // if choice = 0, mask = (-0) = 0000...0000
515
1.88M
                // if choice = 1, mask = (-1) = 1111...1111
516
1.88M
                let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
517
1.88M
                a ^ (mask & (a ^ b))
518
1.88M
            }
Unexecuted instantiation: _RNvXsF_Cs3v1T4Vw6hEJ_6subtlehNtB5_23ConditionallySelectable18conditional_selectCsaHRNXv1Y9Bq_4p256
_RNvXsL_Cs3v1T4Vw6hEJ_6subtleyNtB5_23ConditionallySelectable18conditional_selectCsaHRNXv1Y9Bq_4p256
Line
Count
Source
513
19.3M
            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
514
19.3M
                // if choice = 0, mask = (-0) = 0000...0000
515
19.3M
                // if choice = 1, mask = (-1) = 1111...1111
516
19.3M
                let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
517
19.3M
                a ^ (mask & (a ^ b))
518
19.3M
            }
Unexecuted instantiation: _RNvXsJ_Cs3v1T4Vw6hEJ_6subtlemNtB5_23ConditionallySelectable18conditional_selectCsaHRNXv1Y9Bq_4p256
Unexecuted instantiation: _RNvXsG_Cs3v1T4Vw6hEJ_6subtleaNtB5_23ConditionallySelectable18conditional_selectB5_
Unexecuted instantiation: _RNvXsF_Cs3v1T4Vw6hEJ_6subtlehNtB5_23ConditionallySelectable18conditional_selectB5_
Unexecuted instantiation: _RNvXsH_Cs3v1T4Vw6hEJ_6subtletNtB5_23ConditionallySelectable18conditional_selectB5_
Unexecuted instantiation: _RNvXsI_Cs3v1T4Vw6hEJ_6subtlesNtB5_23ConditionallySelectable18conditional_selectB5_
Unexecuted instantiation: _RNvXsJ_Cs3v1T4Vw6hEJ_6subtlemNtB5_23ConditionallySelectable18conditional_selectB5_
Unexecuted instantiation: _RNvXsK_Cs3v1T4Vw6hEJ_6subtlelNtB5_23ConditionallySelectable18conditional_selectB5_
Unexecuted instantiation: _RNvXsL_Cs3v1T4Vw6hEJ_6subtleyNtB5_23ConditionallySelectable18conditional_selectB5_
Unexecuted instantiation: _RNvXsM_Cs3v1T4Vw6hEJ_6subtlexNtB5_23ConditionallySelectable18conditional_selectB5_
Unexecuted instantiation: _RNvXsN_Cs3v1T4Vw6hEJ_6subtleoNtB5_23ConditionallySelectable18conditional_selectB5_
Unexecuted instantiation: _RNvXsO_Cs3v1T4Vw6hEJ_6subtlenNtB5_23ConditionallySelectable18conditional_selectB5_
519
520
            #[inline]
521
0
            fn conditional_assign(&mut self, other: &Self, choice: Choice) {
522
0
                // if choice = 0, mask = (-0) = 0000...0000
523
0
                // if choice = 1, mask = (-1) = 1111...1111
524
0
                let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
525
0
                *self ^= mask & (*self ^ *other);
526
0
            }
Unexecuted instantiation: _RNvXsF_Cs3v1T4Vw6hEJ_6subtlehNtB5_23ConditionallySelectable18conditional_assignB5_
Unexecuted instantiation: _RNvXsG_Cs3v1T4Vw6hEJ_6subtleaNtB5_23ConditionallySelectable18conditional_assignB5_
Unexecuted instantiation: _RNvXsH_Cs3v1T4Vw6hEJ_6subtletNtB5_23ConditionallySelectable18conditional_assignB5_
Unexecuted instantiation: _RNvXsI_Cs3v1T4Vw6hEJ_6subtlesNtB5_23ConditionallySelectable18conditional_assignB5_
Unexecuted instantiation: _RNvXsJ_Cs3v1T4Vw6hEJ_6subtlemNtB5_23ConditionallySelectable18conditional_assignB5_
Unexecuted instantiation: _RNvXsK_Cs3v1T4Vw6hEJ_6subtlelNtB5_23ConditionallySelectable18conditional_assignB5_
Unexecuted instantiation: _RNvXsL_Cs3v1T4Vw6hEJ_6subtleyNtB5_23ConditionallySelectable18conditional_assignB5_
Unexecuted instantiation: _RNvXsM_Cs3v1T4Vw6hEJ_6subtlexNtB5_23ConditionallySelectable18conditional_assignB5_
Unexecuted instantiation: _RNvXsN_Cs3v1T4Vw6hEJ_6subtleoNtB5_23ConditionallySelectable18conditional_assignB5_
Unexecuted instantiation: _RNvXsO_Cs3v1T4Vw6hEJ_6subtlenNtB5_23ConditionallySelectable18conditional_assignB5_
527
528
            #[inline]
529
0
            fn conditional_swap(a: &mut Self, b: &mut Self, choice: Choice) {
530
0
                // if choice = 0, mask = (-0) = 0000...0000
531
0
                // if choice = 1, mask = (-1) = 1111...1111
532
0
                let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
533
0
                let t = mask & (*a ^ *b);
534
0
                *a ^= t;
535
0
                *b ^= t;
536
0
            }
Unexecuted instantiation: _RNvXsF_Cs3v1T4Vw6hEJ_6subtlehNtB5_23ConditionallySelectable16conditional_swapB5_
Unexecuted instantiation: _RNvXsG_Cs3v1T4Vw6hEJ_6subtleaNtB5_23ConditionallySelectable16conditional_swapB5_
Unexecuted instantiation: _RNvXsH_Cs3v1T4Vw6hEJ_6subtletNtB5_23ConditionallySelectable16conditional_swapB5_
Unexecuted instantiation: _RNvXsI_Cs3v1T4Vw6hEJ_6subtlesNtB5_23ConditionallySelectable16conditional_swapB5_
Unexecuted instantiation: _RNvXsJ_Cs3v1T4Vw6hEJ_6subtlemNtB5_23ConditionallySelectable16conditional_swapB5_
Unexecuted instantiation: _RNvXsK_Cs3v1T4Vw6hEJ_6subtlelNtB5_23ConditionallySelectable16conditional_swapB5_
Unexecuted instantiation: _RNvXsL_Cs3v1T4Vw6hEJ_6subtleyNtB5_23ConditionallySelectable16conditional_swapB5_
Unexecuted instantiation: _RNvXsM_Cs3v1T4Vw6hEJ_6subtlexNtB5_23ConditionallySelectable16conditional_swapB5_
Unexecuted instantiation: _RNvXsN_Cs3v1T4Vw6hEJ_6subtleoNtB5_23ConditionallySelectable16conditional_swapB5_
Unexecuted instantiation: _RNvXsO_Cs3v1T4Vw6hEJ_6subtlenNtB5_23ConditionallySelectable16conditional_swapB5_
537
         }
538
    )*)
539
}
540
541
generate_integer_conditional_select!(  u8   i8);
542
generate_integer_conditional_select!( u16  i16);
543
generate_integer_conditional_select!( u32  i32);
544
generate_integer_conditional_select!( u64  i64);
545
#[cfg(feature = "i128")]
546
generate_integer_conditional_select!(u128 i128);
547
548
/// `Ordering` is `#[repr(i8)]` where:
549
///
550
/// - `Less` => -1
551
/// - `Equal` => 0
552
/// - `Greater` => 1
553
///
554
/// Given this, it's possible to operate on orderings as if they're integers,
555
/// which allows leveraging conditional masking for predication.
556
impl ConditionallySelectable for cmp::Ordering {
557
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
558
0
        let a = *a as i8;
559
0
        let b = *b as i8;
560
0
        let ret = i8::conditional_select(&a, &b, choice);
561
0
562
0
        // SAFETY: `Ordering` is `#[repr(i8)]` and `ret` has been assigned to
563
0
        // a value which was originally a valid `Ordering` then cast to `i8`
564
0
        unsafe { *((&ret as *const _) as *const cmp::Ordering) }
565
0
    }
566
}
567
568
impl ConditionallySelectable for Choice {
569
    #[inline]
570
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
571
0
        Choice(u8::conditional_select(&a.0, &b.0, choice))
572
0
    }
Unexecuted instantiation: _RNvXsc_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtB5_23ConditionallySelectable18conditional_selectCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXsc_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtB5_23ConditionallySelectable18conditional_selectCsaHRNXv1Y9Bq_4p256
Unexecuted instantiation: _RNvXsc_Cs3v1T4Vw6hEJ_6subtleNtB5_6ChoiceNtB5_23ConditionallySelectable18conditional_selectB5_
573
}
574
575
#[cfg(feature = "const-generics")]
576
impl<T, const N: usize> ConditionallySelectable for [T; N]
577
where
578
    T: ConditionallySelectable,
579
{
580
    #[inline]
581
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
582
        let mut output = *a;
583
        output.conditional_assign(b, choice);
584
        output
585
    }
586
587
    fn conditional_assign(&mut self, other: &Self, choice: Choice) {
588
        for (a_i, b_i) in self.iter_mut().zip(other) {
589
            a_i.conditional_assign(b_i, choice)
590
        }
591
    }
592
}
593
594
/// A type which can be conditionally negated in constant time.
595
///
596
/// # Note
597
///
598
/// A generic implementation of `ConditionallyNegatable` is provided
599
/// for types `T` which are `ConditionallySelectable` and have `Neg`
600
/// implemented on `&T`.
601
//
602
// #[inline] is specified on these function prototypes to signify that they
603
#[allow(unused_attributes)] // should be in the actual implementation
604
pub trait ConditionallyNegatable {
605
    /// Negate `self` if `choice == Choice(1)`; otherwise, leave it
606
    /// unchanged.
607
    ///
608
    /// This function should execute in constant time.
609
    #[inline]
610
    #[allow(unused_attributes)]
611
    fn conditional_negate(&mut self, choice: Choice);
612
}
613
614
impl<T> ConditionallyNegatable for T
615
where
616
    T: ConditionallySelectable,
617
    for<'a> &'a T: Neg<Output = T>,
618
{
619
    #[inline]
620
0
    fn conditional_negate(&mut self, choice: Choice) {
621
0
        // Need to cast to eliminate mutability
622
0
        let self_neg: T = -(self as &T);
623
0
        self.conditional_assign(&self_neg, choice);
624
0
    }
625
}
626
627
/// The `CtOption<T>` type represents an optional value similar to the
628
/// [`Option<T>`](core::option::Option) type but is intended for
629
/// use in constant time APIs.
630
///
631
/// Any given `CtOption<T>` is either `Some` or `None`, but unlike
632
/// `Option<T>` these variants are not exposed. The
633
/// [`is_some()`](CtOption::is_some) method is used to determine if
634
/// the value is `Some`, and [`unwrap_or()`](CtOption::unwrap_or) and
635
/// [`unwrap_or_else()`](CtOption::unwrap_or_else) methods are
636
/// provided to access the underlying value. The value can also be
637
/// obtained with [`unwrap()`](CtOption::unwrap) but this will panic
638
/// if it is `None`.
639
///
640
/// Functions that are intended to be constant time may not produce
641
/// valid results for all inputs, such as square root and inversion
642
/// operations in finite field arithmetic. Returning an `Option<T>`
643
/// from these functions makes it difficult for the caller to reason
644
/// about the result in constant time, and returning an incorrect
645
/// value burdens the caller and increases the chance of bugs.
646
#[derive(Clone, Copy, Debug)]
647
pub struct CtOption<T> {
648
    value: T,
649
    is_some: Choice,
650
}
651
652
impl<T> From<CtOption<T>> for Option<T> {
653
    /// Convert the `CtOption<T>` wrapper into an `Option<T>`, depending on whether
654
    /// the underlying `is_some` `Choice` was a `0` or a `1` once unwrapped.
655
    ///
656
    /// # Note
657
    ///
658
    /// This function exists to avoid ending up with ugly, verbose and/or bad handled
659
    /// conversions from the `CtOption<T>` wraps to an `Option<T>` or `Result<T, E>`.
660
    /// This implementation doesn't intend to be constant-time nor try to protect the
661
    /// leakage of the `T` since the `Option<T>` will do it anyways.
662
5.30k
    fn from(source: CtOption<T>) -> Option<T> {
663
5.30k
        if source.is_some().unwrap_u8() == 1u8 {
664
4.67k
            Option::Some(source.value)
665
        } else {
666
626
            None
667
        }
668
5.30k
    }
_RNvXse_Cs3v1T4Vw6hEJ_6subtleINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtCs8yVsO3EKNkV_14elliptic_curve10public_key9PublicKeyNtCsaHRNXv1Y9Bq_4p2568NistP256EEINtNtBv_7convert4FromINtB5_8CtOptionB12_EE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
662
1.18k
    fn from(source: CtOption<T>) -> Option<T> {
663
1.18k
        if source.is_some().unwrap_u8() == 1u8 {
664
1.14k
            Option::Some(source.value)
665
        } else {
666
35
            None
667
        }
668
1.18k
    }
_RNvXse_Cs3v1T4Vw6hEJ_6subtleINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtCs8yVsO3EKNkV_14elliptic_curve10public_key9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1EEINtNtBv_7convert4FromINtB5_8CtOptionB12_EE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
662
1.27k
    fn from(source: CtOption<T>) -> Option<T> {
663
1.27k
        if source.is_some().unwrap_u8() == 1u8 {
664
712
            Option::Some(source.value)
665
        } else {
666
561
            None
667
        }
668
1.27k
    }
_RNvXse_Cs3v1T4Vw6hEJ_6subtleINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256EEINtNtBv_7convert4FromINtB5_8CtOptionB12_EE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
662
1.73k
    fn from(source: CtOption<T>) -> Option<T> {
663
1.73k
        if source.is_some().unwrap_u8() == 1u8 {
664
1.71k
            Option::Some(source.value)
665
        } else {
666
20
            None
667
        }
668
1.73k
    }
_RNvXse_Cs3v1T4Vw6hEJ_6subtleINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1EEINtNtBv_7convert4FromINtB5_8CtOptionB12_EE4fromCs4RkbDk9WRL5_5clvmr
Line
Count
Source
662
1.11k
    fn from(source: CtOption<T>) -> Option<T> {
663
1.11k
        if source.is_some().unwrap_u8() == 1u8 {
664
1.10k
            Option::Some(source.value)
665
        } else {
666
10
            None
667
        }
668
1.11k
    }
Unexecuted instantiation: _RNvXse_Cs3v1T4Vw6hEJ_6subtleINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzero13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1EEINtNtBv_7convert4FromINtB5_8CtOptionB12_EE4fromB29_
Unexecuted instantiation: _RNvXse_Cs3v1T4Vw6hEJ_6subtleINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementEINtNtBv_7convert4FromINtB5_8CtOptionB12_EE4fromB18_
Unexecuted instantiation: _RNvXse_Cs3v1T4Vw6hEJ_6subtleINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarEINtNtBv_7convert4FromINtB5_8CtOptionB12_EE4fromB18_
Unexecuted instantiation: _RNvXse_Cs3v1T4Vw6hEJ_6subtleINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6affine11AffinePointEINtNtBv_7convert4FromINtB5_8CtOptionB12_EE4fromB18_
Unexecuted instantiation: _RNvXse_Cs3v1T4Vw6hEJ_6subtleINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementEINtNtBv_7convert4FromINtB5_8CtOptionB12_EE4fromB18_
Unexecuted instantiation: _RNvXse_Cs3v1T4Vw6hEJ_6subtleINtNtCsbQ8arDwx5Xq_4core6option6OptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarEINtNtBv_7convert4FromINtB5_8CtOptionB12_EE4fromB18_
Unexecuted instantiation: _RNvXINICs3v1T4Vw6hEJ_6subtlese_0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionpEINtNtBB_7convert4FromINtB5_8CtOptionpEE4fromB5_
669
}
670
671
impl<T> CtOption<T> {
672
    /// This method is used to construct a new `CtOption<T>` and takes
673
    /// a value of type `T`, and a `Choice` that determines whether
674
    /// the optional value should be `Some` or not. If `is_some` is
675
    /// false, the value will still be stored but its value is never
676
    /// exposed.
677
    #[inline]
678
23.5k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
23.5k
        CtOption {
680
23.5k
            value: value,
681
23.5k
            is_some: is_some,
682
23.5k
        }
683
23.5k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EE3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
678
2.03k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
2.03k
        CtOption {
680
2.03k
            value: value,
681
2.03k
            is_some: is_some,
682
2.03k
        }
683
2.03k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtCs8yVsO3EKNkV_14elliptic_curve10public_key9PublicKeyNtCsaHRNXv1Y9Bq_4p2568NistP256EE3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
678
1.18k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
1.18k
        CtOption {
680
1.18k
            value: value,
681
1.18k
            is_some: is_some,
682
1.18k
        }
683
1.18k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtCs8yVsO3EKNkV_14elliptic_curve10public_key9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1EE3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
678
1.27k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
1.27k
        CtOption {
680
1.27k
            value: value,
681
1.27k
            is_some: is_some,
682
1.27k
        }
683
1.27k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzero13NonZeroScalarNtCsaHRNXv1Y9Bq_4p2568NistP256EE3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
678
1.67k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
1.67k
        CtOption {
680
1.67k
            value: value,
681
1.67k
            is_some: is_some,
682
1.67k
        }
683
1.67k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256EE3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
678
1.73k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
1.73k
        CtOption {
680
1.73k
            value: value,
681
1.73k
            is_some: is_some,
682
1.73k
        }
683
1.73k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1EE3newCs4RkbDk9WRL5_5clvmr
Line
Count
Source
678
1.11k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
1.11k
        CtOption {
680
1.11k
            value: value,
681
1.11k
            is_some: is_some,
682
1.11k
        }
683
1.11k
    }
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE3newBJ_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCshRehcWQJ0wE_13crypto_bigint4uint8div_limb10ReciprocalE3newBL_
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6affine11AffinePointE3newBL_
Line
Count
Source
678
1.79k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
1.79k
        CtOption {
680
1.79k
            value: value,
681
1.79k
            is_some: is_some,
682
1.79k
        }
683
1.79k
    }
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionuE3newCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic10projective15ProjectivePointE3newBL_
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field10field_impl16FieldElementImplE3newBN_
Line
Count
Source
678
1.79k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
1.79k
        CtOption {
680
1.79k
            value: value,
681
1.79k
            is_some: is_some,
682
1.79k
        }
683
1.79k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementE3newBL_
Line
Count
Source
678
3.04k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
3.04k
        CtOption {
680
3.04k
            value: value,
681
3.04k
            is_some: is_some,
682
3.04k
        }
683
3.04k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzero13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1EE3newB1M_
Line
Count
Source
678
1.58k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
1.58k
        CtOption {
680
1.58k
            value: value,
681
1.58k
            is_some: is_some,
682
1.58k
        }
683
1.58k
    }
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtCsiBl6Lc3cFal_5alloc3vec3VecNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementEE3newB1i_
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarE3newBL_
Line
Count
Source
678
523
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
523
        CtOption {
680
523
            value: value,
681
523
            is_some: is_some,
682
523
        }
683
523
    }
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtCsj9qtwLkMHqH_4sec15point12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1o_IB1o_IB1o_IB1o_IB1o_NtB1q_5UTermNtNtB1s_3bit2B1ENtB2B_2B0EB2P_EB2P_EB2P_EB2P_EEE3newCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1EE3newB1Q_
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field10field_5x5216FieldElement5x52E3newBN_
Line
Count
Source
678
1.79k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
1.79k
        CtOption {
680
1.79k
            value: value,
681
1.79k
            is_some: is_some,
682
1.79k
        }
683
1.79k
    }
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EE3newB1w_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzero13NonZeroScalarNtCsaHRNXv1Y9Bq_4p2568NistP256EE3newB1M_
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementE3newBL_
Line
Count
Source
678
3.17k
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
3.17k
        CtOption {
680
3.17k
            value: value,
681
3.17k
            is_some: is_some,
682
3.17k
        }
683
3.17k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarE3newBL_
Line
Count
Source
678
838
    pub fn new(value: T, is_some: Choice) -> CtOption<T> {
679
838
        CtOption {
680
838
            value: value,
681
838
            is_some: is_some,
682
838
        }
683
838
    }
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256EE3newB1Q_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionpE3newB5_
684
685
    /// Returns the contained value, consuming the `self` value.
686
    ///
687
    /// # Panics
688
    ///
689
    /// Panics if the value is none with a custom panic message provided by
690
    /// `msg`.
691
0
    pub fn expect(self, msg: &str) -> T {
692
0
        assert_eq!(self.is_some.unwrap_u8(), 1, "{}", msg);
693
694
0
        self.value
695
0
    }
696
697
    /// This returns the underlying value but panics if it
698
    /// is not `Some`.
699
    #[inline]
700
4.61k
    pub fn unwrap(self) -> T {
701
4.61k
        assert_eq!(self.is_some.unwrap_u8(), 1);
702
703
4.61k
        self.value
704
4.61k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzero13NonZeroScalarNtCsaHRNXv1Y9Bq_4p2568NistP256EE6unwrapCs4RkbDk9WRL5_5clvmr
Line
Count
Source
700
1.67k
    pub fn unwrap(self) -> T {
701
1.67k
        assert_eq!(self.is_some.unwrap_u8(), 1);
702
703
1.67k
        self.value
704
1.67k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarE6unwrapCs4RkbDk9WRL5_5clvmr
Line
Count
Source
700
838
    pub fn unwrap(self) -> T {
701
838
        assert_eq!(self.is_some.unwrap_u8(), 1);
702
703
838
        self.value
704
838
    }
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtCsiBl6Lc3cFal_5alloc3vec3VecNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementEE6unwrapB1i_
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzero13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1EE6unwrapB1M_
Line
Count
Source
700
1.58k
    pub fn unwrap(self) -> T {
701
1.58k
        assert_eq!(self.is_some.unwrap_u8(), 1);
702
703
1.58k
        self.value
704
1.58k
    }
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1EE6unwrapB1Q_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementE6unwrapBL_
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarE6unwrapBL_
Line
Count
Source
700
523
    pub fn unwrap(self) -> T {
701
523
        assert_eq!(self.is_some.unwrap_u8(), 1);
702
703
523
        self.value
704
523
    }
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzero13NonZeroScalarNtCsaHRNXv1Y9Bq_4p2568NistP256EE6unwrapB1M_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256EE6unwrapB1Q_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementE6unwrapBL_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarE6unwrapBL_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionpE6unwrapB5_
705
706
    /// This returns the underlying value if it is `Some`
707
    /// or the provided value otherwise.
708
    #[inline]
709
838
    pub fn unwrap_or(self, def: T) -> T
710
838
    where
711
838
        T: ConditionallySelectable,
712
838
    {
713
838
        T::conditional_select(&def, &self.value, self.is_some)
714
838
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EE9unwrap_orCs4RkbDk9WRL5_5clvmr
Line
Count
Source
709
838
    pub fn unwrap_or(self, def: T) -> T
710
838
    where
711
838
        T: ConditionallySelectable,
712
838
    {
713
838
        T::conditional_select(&def, &self.value, self.is_some)
714
838
    }
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementE9unwrap_orBL_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarE9unwrap_orBL_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementE9unwrap_orBL_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarE9unwrap_orBL_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EE9unwrap_orB1w_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionpE9unwrap_orB5_
715
716
    /// This returns the underlying value if it is `Some`
717
    /// or the value produced by the provided closure otherwise.
718
    ///
719
    /// This operates in constant time, because the provided closure
720
    /// is always called.
721
    #[inline]
722
523
    pub fn unwrap_or_else<F>(self, f: F) -> T
723
523
    where
724
523
        T: ConditionallySelectable,
725
523
        F: FnOnce() -> T,
726
523
    {
727
523
        T::conditional_select(&f(), &self.value, self.is_some)
728
523
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6affine11AffinePointE14unwrap_or_elseNCNvMNtBK_10projectiveNtB1X_15ProjectivePoint9to_affines_0EBM_
Line
Count
Source
722
523
    pub fn unwrap_or_else<F>(self, f: F) -> T
723
523
    where
724
523
        T: ConditionallySelectable,
725
523
        F: FnOnce() -> T,
726
523
    {
727
523
        T::conditional_select(&f(), &self.value, self.is_some)
728
523
    }
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionpE14unwrap_or_elsepEB6_
729
730
    /// Returns a true `Choice` if this value is `Some`.
731
    #[inline]
732
5.30k
    pub fn is_some(&self) -> Choice {
733
5.30k
        self.is_some
734
5.30k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtCs8yVsO3EKNkV_14elliptic_curve10public_key9PublicKeyNtCsaHRNXv1Y9Bq_4p2568NistP256EE7is_someCs4RkbDk9WRL5_5clvmr
Line
Count
Source
732
1.18k
    pub fn is_some(&self) -> Choice {
733
1.18k
        self.is_some
734
1.18k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtCs8yVsO3EKNkV_14elliptic_curve10public_key9PublicKeyNtCsjewTDwKBbyD_4k2569Secp256k1EE7is_someCs4RkbDk9WRL5_5clvmr
Line
Count
Source
732
1.27k
    pub fn is_some(&self) -> Choice {
733
1.27k
        self.is_some
734
1.27k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsaHRNXv1Y9Bq_4p2568NistP256EE7is_someCs4RkbDk9WRL5_5clvmr
Line
Count
Source
732
1.73k
    pub fn is_some(&self) -> Choice {
733
1.73k
        self.is_some
734
1.73k
    }
_RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1EE7is_someCs4RkbDk9WRL5_5clvmr
Line
Count
Source
732
1.11k
    pub fn is_some(&self) -> Choice {
733
1.11k
        self.is_some
734
1.11k
    }
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementE7is_someBL_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarE7is_someBL_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionuE7is_someCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzero13NonZeroScalarNtCsjewTDwKBbyD_4k2569Secp256k1EE7is_someB1M_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6affine11AffinePointE7is_someBL_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementE7is_someBL_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarE7is_someBL_
Unexecuted instantiation: _RNvMsf_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionpE7is_someB5_
735
736
    /// Returns a true `Choice` if this value is `None`.
737
    #[inline]
738
0
    pub fn is_none(&self) -> Choice {
739
0
        !self.is_some
740
0
    }
741
742
    /// Returns a `None` value if the option is `None`, otherwise
743
    /// returns a `CtOption` enclosing the value of the provided closure.
744
    /// The closure is given the enclosed value or, if the option is
745
    /// `None`, it is provided a dummy value computed using
746
    /// `Default::default()`.
747
    ///
748
    /// This operates in constant time, because the provided closure
749
    /// is always called.
750
    #[inline]
751
6.30k
    pub fn map<U, F>(self, f: F) -> CtOption<U>
752
6.30k
    where
753
6.30k
        T: Default + ConditionallySelectable,
754
6.30k
        F: FnOnce(T) -> U,
755
6.30k
    {
756
6.30k
        CtOption::new(
757
6.30k
            f(T::conditional_select(
758
6.30k
                &T::default(),
759
6.30k
                &self.value,
760
6.30k
                self.is_some,
761
6.30k
            )),
762
6.30k
            self.is_some,
763
6.30k
        )
764
6.30k
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EE3mapBG_NCNvXs5_BJ_BG_INtNtCs8yVsO3EKNkV_14elliptic_curve5point14DecompactPointB1v_E9decompact0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
751
14
    pub fn map<U, F>(self, f: F) -> CtOption<U>
752
14
    where
753
14
        T: Default + ConditionallySelectable,
754
14
        F: FnOnce(T) -> U,
755
14
    {
756
14
        CtOption::new(
757
14
            f(T::conditional_select(
758
14
                &T::default(),
759
14
                &self.value,
760
14
                self.is_some,
761
14
            )),
762
14
            self.is_some,
763
14
        )
764
14
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementE3mapINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtBM_8NistP256ENCNCNvXs4_B1J_B1G_INtNtCs8yVsO3EKNkV_14elliptic_curve5point15DecompressPointB2v_E10decompress00ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
751
611
    pub fn map<U, F>(self, f: F) -> CtOption<U>
752
611
    where
753
611
        T: Default + ConditionallySelectable,
754
611
        F: FnOnce(T) -> U,
755
611
    {
756
611
        CtOption::new(
757
611
            f(T::conditional_select(
758
611
                &T::default(),
759
611
                &self.value,
760
611
                self.is_some,
761
611
            )),
762
611
            self.is_some,
763
611
        )
764
611
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementE3mapINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtBM_8NistP256ENCNvMNtB1L_10projectiveINtB2P_15ProjectivePointB2v_E9to_affine0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
751
838
    pub fn map<U, F>(self, f: F) -> CtOption<U>
752
838
    where
753
838
        T: Default + ConditionallySelectable,
754
838
        F: FnOnce(T) -> U,
755
838
    {
756
838
        CtOption::new(
757
838
            f(T::conditional_select(
758
838
                &T::default(),
759
838
                &self.value,
760
838
                self.is_some,
761
838
            )),
762
838
            self.is_some,
763
838
        )
764
838
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementE3mapNtNtBK_6affine11AffinePointNCNCNvXsb_B1I_B1G_INtNtCs8yVsO3EKNkV_14elliptic_curve5point15DecompressPointNtBM_9Secp256k1E10decompress00EBM_
Line
Count
Source
751
735
    pub fn map<U, F>(self, f: F) -> CtOption<U>
752
735
    where
753
735
        T: Default + ConditionallySelectable,
754
735
        F: FnOnce(T) -> U,
755
735
    {
756
735
        CtOption::new(
757
735
            f(T::conditional_select(
758
735
                &T::default(),
759
735
                &self.value,
760
735
                self.is_some,
761
735
            )),
762
735
            self.is_some,
763
735
        )
764
735
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementE3mapNtNtBK_6affine11AffinePointNCNvMNtBK_10projectiveNtB2c_15ProjectivePoint9to_affine0EBM_
Line
Count
Source
751
523
    pub fn map<U, F>(self, f: F) -> CtOption<U>
752
523
    where
753
523
        T: Default + ConditionallySelectable,
754
523
        F: FnOnce(T) -> U,
755
523
    {
756
523
        CtOption::new(
757
523
            f(T::conditional_select(
758
523
                &T::default(),
759
523
                &self.value,
760
523
                self.is_some,
761
523
            )),
762
523
            self.is_some,
763
523
        )
764
523
    }
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementE3mapuNCINvNtCs8yVsO3EKNkV_14elliptic_curve3ops21invert_batch_internalBG_E0EBM_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6affine11AffinePointE3mapNtNtBK_10projective15ProjectivePointNvYB1G_INtNtCsbQ8arDwx5Xq_4core7convert4FromBG_E4fromEBM_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6affine11AffinePointE3mapNtNtBK_10projective15ProjectivePointNvYBG_INtNtCsbQ8arDwx5Xq_4core7convert4IntoB1G_E4intoEBM_
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field10field_5x5216FieldElement5x52E3mapNtNtBK_10field_impl16FieldElementImplNCNvMB20_B1Y_10from_bytes0EBO_
Line
Count
Source
751
1.79k
    pub fn map<U, F>(self, f: F) -> CtOption<U>
752
1.79k
    where
753
1.79k
        T: Default + ConditionallySelectable,
754
1.79k
        F: FnOnce(T) -> U,
755
1.79k
    {
756
1.79k
        CtOption::new(
757
1.79k
            f(T::conditional_select(
758
1.79k
                &T::default(),
759
1.79k
                &self.value,
760
1.79k
                self.is_some,
761
1.79k
            )),
762
1.79k
            self.is_some,
763
1.79k
        )
764
1.79k
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field10field_impl16FieldElementImplE3mapNtBK_12FieldElementNcB1Y_0EBO_
Line
Count
Source
751
1.79k
    pub fn map<U, F>(self, f: F) -> CtOption<U>
752
1.79k
    where
753
1.79k
        T: Default + ConditionallySelectable,
754
1.79k
        F: FnOnce(T) -> U,
755
1.79k
    {
756
1.79k
        CtOption::new(
757
1.79k
            f(T::conditional_select(
758
1.79k
                &T::default(),
759
1.79k
                &self.value,
760
1.79k
                self.is_some,
761
1.79k
            )),
762
1.79k
            self.is_some,
763
1.79k
        )
764
1.79k
    }
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementE3mapINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtBM_8NistP256ENCNvMNtB1L_10projectiveINtB2P_15ProjectivePointB2v_E9to_affine0EBM_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionpE3mapppEB6_
765
766
    /// Returns a `None` value if the option is `None`, otherwise
767
    /// returns the result of the provided closure. The closure is
768
    /// given the enclosed value or, if the option is `None`, it
769
    /// is provided a dummy value computed using `Default::default()`.
770
    ///
771
    /// This operates in constant time, because the provided closure
772
    /// is always called.
773
    #[inline]
774
5.97k
    pub fn and_then<U, F>(self, f: F) -> CtOption<U>
775
5.97k
    where
776
5.97k
        T: Default + ConditionallySelectable,
777
5.97k
        F: FnOnce(T) -> CtOption<U>,
778
5.97k
    {
779
5.97k
        let mut tmp = f(T::conditional_select(
780
5.97k
            &T::default(),
781
5.97k
            &self.value,
782
5.97k
            self.is_some,
783
5.97k
        ));
784
5.97k
        tmp.is_some &= self.is_some;
785
5.97k
786
5.97k
        tmp
787
5.97k
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtCsaHRNXv1Y9Bq_4p2568NistP256EE8and_thenINtNtCs8yVsO3EKNkV_14elliptic_curve10public_key9PublicKeyB1v_ENCNvXs1_B2d_B2a_INtNtB2f_4sec116FromEncodedPointB1v_E18from_encoded_point0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
774
1.18k
    pub fn and_then<U, F>(self, f: F) -> CtOption<U>
775
1.18k
    where
776
1.18k
        T: Default + ConditionallySelectable,
777
1.18k
        F: FnOnce(T) -> CtOption<U>,
778
1.18k
    {
779
1.18k
        let mut tmp = f(T::conditional_select(
780
1.18k
            &T::default(),
781
1.18k
            &self.value,
782
1.18k
            self.is_some,
783
1.18k
        ));
784
1.18k
        tmp.is_some &= self.is_some;
785
1.18k
786
1.18k
        tmp
787
1.18k
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementE8and_thenINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtBM_8NistP256ENCNCNvXs7_B1O_B1L_INtNtCs8yVsO3EKNkV_14elliptic_curve4sec116FromEncodedPointB2A_E18from_encoded_point00ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
774
559
    pub fn and_then<U, F>(self, f: F) -> CtOption<U>
775
559
    where
776
559
        T: Default + ConditionallySelectable,
777
559
        F: FnOnce(T) -> CtOption<U>,
778
559
    {
779
559
        let mut tmp = f(T::conditional_select(
780
559
            &T::default(),
781
559
            &self.value,
782
559
            self.is_some,
783
559
        ));
784
559
        tmp.is_some &= self.is_some;
785
559
786
559
        tmp
787
559
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementE8and_thenINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtBM_8NistP256ENCNvXs4_B1O_B1L_INtNtCs8yVsO3EKNkV_14elliptic_curve5point15DecompressPointB2A_E10decompress0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
774
611
    pub fn and_then<U, F>(self, f: F) -> CtOption<U>
775
611
    where
776
611
        T: Default + ConditionallySelectable,
777
611
        F: FnOnce(T) -> CtOption<U>,
778
611
    {
779
611
        let mut tmp = f(T::conditional_select(
780
611
            &T::default(),
781
611
            &self.value,
782
611
            self.is_some,
783
611
        ));
784
611
        tmp.is_some &= self.is_some;
785
611
786
611
        tmp
787
611
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementE8and_thenINtNtCs2J0Yj5ID6sO_10primeorder6affine11AffinePointNtBM_8NistP256ENCNvXs7_B1O_B1L_INtNtCs8yVsO3EKNkV_14elliptic_curve4sec116FromEncodedPointB2A_E18from_encoded_point0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
774
559
    pub fn and_then<U, F>(self, f: F) -> CtOption<U>
775
559
    where
776
559
        T: Default + ConditionallySelectable,
777
559
        F: FnOnce(T) -> CtOption<U>,
778
559
    {
779
559
        let mut tmp = f(T::conditional_select(
780
559
            &T::default(),
781
559
            &self.value,
782
559
            self.is_some,
783
559
        ));
784
559
        tmp.is_some &= self.is_some;
785
559
786
559
        tmp
787
559
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6affine11AffinePointE8and_thenINtNtCs8yVsO3EKNkV_14elliptic_curve10public_key9PublicKeyNtBM_9Secp256k1ENCNvXs1_B1O_B1L_INtNtB1Q_4sec116FromEncodedPointB2G_E18from_encoded_point0ECs4RkbDk9WRL5_5clvmr
Line
Count
Source
774
1.27k
    pub fn and_then<U, F>(self, f: F) -> CtOption<U>
775
1.27k
    where
776
1.27k
        T: Default + ConditionallySelectable,
777
1.27k
        F: FnOnce(T) -> CtOption<U>,
778
1.27k
    {
779
1.27k
        let mut tmp = f(T::conditional_select(
780
1.27k
            &T::default(),
781
1.27k
            &self.value,
782
1.27k
            self.is_some,
783
1.27k
        ));
784
1.27k
        tmp.is_some &= self.is_some;
785
1.27k
786
1.27k
        tmp
787
1.27k
    }
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs6_NtBI_3addINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3add00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs6_NtBI_3mulINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mul00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs6_NtBI_3subINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Sub3sub00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs7_NtBI_3addINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRB1T_E3add00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs7_NtBI_3mulINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRB1T_E3mul00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs7_NtBI_3subINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRB1T_E3sub00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs8_NtBI_3addRINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddB1U_E3add00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs8_NtBI_3mulRINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulB1U_E3mul00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs8_NtBI_3subRINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubB1U_E3sub00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs9_NtBI_3addRINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3add00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs9_NtBI_3mulRINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mul00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNCNvXs9_NtBI_3subRINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Sub3sub00EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs6_NtBI_3addINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3add0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs6_NtBI_3mulINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mul0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs6_NtBI_3subINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Sub3sub0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs7_NtBI_3addINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddRB1R_E3add0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs7_NtBI_3mulINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulRB1R_E3mul0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs7_NtBI_3subINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubRB1R_E3sub0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs8_NtBI_3addRINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3AddB1S_E3add0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs8_NtBI_3mulRINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3MulB1S_E3mul0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs8_NtBI_3subRINtNtBK_7checked7CheckedBG_EINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3SubB1S_E3sub0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs9_NtBI_3addRINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Add3add0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs9_NtBI_3mulRINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Mul3mul0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtCshRehcWQJ0wE_13crypto_bigint4limb4LimbE8and_thenBG_NCNvXs9_NtBI_3subRINtNtBK_7checked7CheckedBG_ENtNtNtCsbQ8arDwx5Xq_4core3ops5arith3Sub3sub0EBK_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionINtNtCsj9qtwLkMHqH_4sec15point12EncodedPointINtNtCs5VhUk8EIQ63_7typenum4uint4UIntIB1p_IB1p_IB1p_IB1p_IB1p_NtB1r_5UTermNtNtB1t_3bit2B1ENtB2C_2B0EB2Q_EB2Q_EB2Q_EB2Q_EEE8and_thenNtNtNtCsjewTDwKBbyD_4k25610arithmetic6affine11AffinePointNCNvXsd_B3x_B3v_NtCsfkBiU6A8cFc_5group13GroupEncoding10from_bytess0_0EB3B_
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementE8and_thenNtNtBK_6affine11AffinePointNCNCNvXse_B1N_B1L_INtNtCs8yVsO3EKNkV_14elliptic_curve4sec116FromEncodedPointNtBM_9Secp256k1E18from_encoded_point00EBM_
Line
Count
Source
774
528
    pub fn and_then<U, F>(self, f: F) -> CtOption<U>
775
528
    where
776
528
        T: Default + ConditionallySelectable,
777
528
        F: FnOnce(T) -> CtOption<U>,
778
528
    {
779
528
        let mut tmp = f(T::conditional_select(
780
528
            &T::default(),
781
528
            &self.value,
782
528
            self.is_some,
783
528
        ));
784
528
        tmp.is_some &= self.is_some;
785
528
786
528
        tmp
787
528
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementE8and_thenNtNtBK_6affine11AffinePointNCNvXsb_B1N_B1L_INtNtCs8yVsO3EKNkV_14elliptic_curve5point15DecompressPointNtBM_9Secp256k1E10decompress0EBM_
Line
Count
Source
774
735
    pub fn and_then<U, F>(self, f: F) -> CtOption<U>
775
735
    where
776
735
        T: Default + ConditionallySelectable,
777
735
        F: FnOnce(T) -> CtOption<U>,
778
735
    {
779
735
        let mut tmp = f(T::conditional_select(
780
735
            &T::default(),
781
735
            &self.value,
782
735
            self.is_some,
783
735
        ));
784
735
        tmp.is_some &= self.is_some;
785
735
786
735
        tmp
787
735
    }
_RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementE8and_thenNtNtBK_6affine11AffinePointNCNvXse_B1N_B1L_INtNtCs8yVsO3EKNkV_14elliptic_curve4sec116FromEncodedPointNtBM_9Secp256k1E18from_encoded_point0EBM_
Line
Count
Source
774
528
    pub fn and_then<U, F>(self, f: F) -> CtOption<U>
775
528
    where
776
528
        T: Default + ConditionallySelectable,
777
528
        F: FnOnce(T) -> CtOption<U>,
778
528
    {
779
528
        let mut tmp = f(T::conditional_select(
780
528
            &T::default(),
781
528
            &self.value,
782
528
            self.is_some,
783
528
        ));
784
528
        tmp.is_some &= self.is_some;
785
528
786
528
        tmp
787
528
    }
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarE8and_thenINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar7nonzero13NonZeroScalarNtBM_9Secp256k1ENvMB1I_B1F_3newEBM_
Unexecuted instantiation: _RINvMsf_Cs3v1T4Vw6hEJ_6subtleINtB6_8CtOptionpE8and_thenppEB6_
788
789
    /// Returns `self` if it contains a value, and otherwise returns the result of
790
    /// calling `f`. The provided function `f` is always called.
791
    #[inline]
792
0
    pub fn or_else<F>(self, f: F) -> CtOption<T>
793
0
    where
794
0
        T: ConditionallySelectable,
795
0
        F: FnOnce() -> CtOption<T>,
796
0
    {
797
0
        let is_none = self.is_none();
798
0
        let f = f();
799
0
800
0
        Self::conditional_select(&self, &f, is_none)
801
0
    }
802
803
    /// Convert the `CtOption<T>` wrapper into an `Option<T>`, depending on whether
804
    /// the underlying `is_some` `Choice` was a `0` or a `1` once unwrapped.
805
    ///
806
    /// # Note
807
    ///
808
    /// This function exists to avoid ending up with ugly, verbose and/or bad handled
809
    /// conversions from the `CtOption<T>` wraps to an `Option<T>` or `Result<T, E>`.
810
    /// This implementation doesn't intend to be constant-time nor try to protect the
811
    /// leakage of the `T` since the `Option<T>` will do it anyways.
812
    ///
813
    /// It's equivalent to the corresponding `From` impl, however this version is
814
    /// friendlier for type inference.
815
0
    pub fn into_option(self) -> Option<T> {
816
0
        self.into()
817
0
    }
818
}
819
820
impl<T: ConditionallySelectable> ConditionallySelectable for CtOption<T> {
821
0
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
822
0
        CtOption::new(
823
0
            T::conditional_select(&a.value, &b.value, choice),
824
0
            Choice::conditional_select(&a.is_some, &b.is_some, choice),
825
0
        )
826
0
    }
Unexecuted instantiation: _RNvXsg_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic5field12FieldElementENtB5_23ConditionallySelectable18conditional_selectBL_
Unexecuted instantiation: _RNvXsg_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarENtB5_23ConditionallySelectable18conditional_selectBL_
Unexecuted instantiation: _RNvXsg_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic5field12FieldElementENtB5_23ConditionallySelectable18conditional_selectBL_
Unexecuted instantiation: _RNvXsg_Cs3v1T4Vw6hEJ_6subtleINtB5_8CtOptionNtNtNtCsaHRNXv1Y9Bq_4p25610arithmetic6scalar6ScalarENtB5_23ConditionallySelectable18conditional_selectBL_
Unexecuted instantiation: _RNvXINICs3v1T4Vw6hEJ_6subtlesg_0pEINtB5_8CtOptionpENtB5_23ConditionallySelectable18conditional_selectB5_
827
}
828
829
impl<T: ConstantTimeEq> ConstantTimeEq for CtOption<T> {
830
    /// Two `CtOption<T>`s are equal if they are both `Some` and
831
    /// their values are equal, or both `None`.
832
    #[inline]
833
0
    fn ct_eq(&self, rhs: &CtOption<T>) -> Choice {
834
0
        let a = self.is_some();
835
0
        let b = rhs.is_some();
836
0
837
0
        (a & b & self.value.ct_eq(&rhs.value)) | (!a & !b)
838
0
    }
839
}
840
841
/// A type which can be compared in some manner and be determined to be greater
842
/// than another of the same type.
843
pub trait ConstantTimeGreater {
844
    /// Determine whether `self > other`.
845
    ///
846
    /// The bitwise-NOT of the return value of this function should be usable to
847
    /// determine if `self <= other`.
848
    ///
849
    /// This function should execute in constant time.
850
    ///
851
    /// # Returns
852
    ///
853
    /// A `Choice` with a set bit if `self > other`, and with no set bits
854
    /// otherwise.
855
    ///
856
    /// # Example
857
    ///
858
    /// ```
859
    /// use subtle::ConstantTimeGreater;
860
    ///
861
    /// let x: u8 = 13;
862
    /// let y: u8 = 42;
863
    ///
864
    /// let x_gt_y = x.ct_gt(&y);
865
    ///
866
    /// assert_eq!(x_gt_y.unwrap_u8(), 0);
867
    ///
868
    /// let y_gt_x = y.ct_gt(&x);
869
    ///
870
    /// assert_eq!(y_gt_x.unwrap_u8(), 1);
871
    ///
872
    /// let x_gt_x = x.ct_gt(&x);
873
    ///
874
    /// assert_eq!(x_gt_x.unwrap_u8(), 0);
875
    /// ```
876
    fn ct_gt(&self, other: &Self) -> Choice;
877
}
878
879
macro_rules! generate_unsigned_integer_greater {
880
    ($t_u: ty, $bit_width: expr) => {
881
        impl ConstantTimeGreater for $t_u {
882
            /// Returns Choice::from(1) iff x > y, and Choice::from(0) iff x <= y.
883
            ///
884
            /// # Note
885
            ///
886
            /// This algoritm would also work for signed integers if we first
887
            /// flip the top bit, e.g. `let x: u8 = x ^ 0x80`, etc.
888
            #[inline]
889
0
            fn ct_gt(&self, other: &$t_u) -> Choice {
890
0
                let gtb = self & !other; // All the bits in self that are greater than their corresponding bits in other.
891
0
                let mut ltb = !self & other; // All the bits in self that are less than their corresponding bits in other.
892
0
                let mut pow = 1;
893
894
                // Less-than operator is okay here because it's dependent on the bit-width.
895
0
                while pow < $bit_width {
896
0
                    ltb |= ltb >> pow; // Bit-smear the highest set bit to the right.
897
0
                    pow += pow;
898
0
                }
899
0
                let mut bit = gtb & !ltb; // Select the highest set bit.
900
0
                let mut pow = 1;
901
902
0
                while pow < $bit_width {
903
0
                    bit |= bit >> pow; // Shift it to the right until we end up with either 0 or 1.
904
0
                    pow += pow;
905
0
                }
906
                // XXX We should possibly do the above flattening to 0 or 1 in the
907
                //     Choice constructor rather than making it a debug error?
908
0
                Choice::from((bit & 1) as u8)
909
0
            }
Unexecuted instantiation: _RNvXsV_Cs3v1T4Vw6hEJ_6subtleyNtB5_19ConstantTimeGreater5ct_gtCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvXsS_Cs3v1T4Vw6hEJ_6subtlehNtB5_19ConstantTimeGreater5ct_gtB5_
Unexecuted instantiation: _RNvXsT_Cs3v1T4Vw6hEJ_6subtletNtB5_19ConstantTimeGreater5ct_gtB5_
Unexecuted instantiation: _RNvXsU_Cs3v1T4Vw6hEJ_6subtlemNtB5_19ConstantTimeGreater5ct_gtB5_
Unexecuted instantiation: _RNvXsV_Cs3v1T4Vw6hEJ_6subtleyNtB5_19ConstantTimeGreater5ct_gtB5_
Unexecuted instantiation: _RNvXsW_Cs3v1T4Vw6hEJ_6subtleoNtB5_19ConstantTimeGreater5ct_gtB5_
910
        }
911
    };
912
}
913
914
generate_unsigned_integer_greater!(u8, 8);
915
generate_unsigned_integer_greater!(u16, 16);
916
generate_unsigned_integer_greater!(u32, 32);
917
generate_unsigned_integer_greater!(u64, 64);
918
#[cfg(feature = "i128")]
919
generate_unsigned_integer_greater!(u128, 128);
920
921
impl ConstantTimeGreater for cmp::Ordering {
922
    #[inline]
923
0
    fn ct_gt(&self, other: &Self) -> Choice {
924
0
        // No impl of `ConstantTimeGreater` for `i8`, so use `u8`
925
0
        let a = (*self as i8) + 1;
926
0
        let b = (*other as i8) + 1;
927
0
        (a as u8).ct_gt(&(b as u8))
928
0
    }
929
}
930
931
/// A type which can be compared in some manner and be determined to be less
932
/// than another of the same type.
933
pub trait ConstantTimeLess: ConstantTimeEq + ConstantTimeGreater {
934
    /// Determine whether `self < other`.
935
    ///
936
    /// The bitwise-NOT of the return value of this function should be usable to
937
    /// determine if `self >= other`.
938
    ///
939
    /// A default implementation is provided and implemented for the unsigned
940
    /// integer types.
941
    ///
942
    /// This function should execute in constant time.
943
    ///
944
    /// # Returns
945
    ///
946
    /// A `Choice` with a set bit if `self < other`, and with no set bits
947
    /// otherwise.
948
    ///
949
    /// # Example
950
    ///
951
    /// ```
952
    /// use subtle::ConstantTimeLess;
953
    ///
954
    /// let x: u8 = 13;
955
    /// let y: u8 = 42;
956
    ///
957
    /// let x_lt_y = x.ct_lt(&y);
958
    ///
959
    /// assert_eq!(x_lt_y.unwrap_u8(), 1);
960
    ///
961
    /// let y_lt_x = y.ct_lt(&x);
962
    ///
963
    /// assert_eq!(y_lt_x.unwrap_u8(), 0);
964
    ///
965
    /// let x_lt_x = x.ct_lt(&x);
966
    ///
967
    /// assert_eq!(x_lt_x.unwrap_u8(), 0);
968
    /// ```
969
    #[inline]
970
0
    fn ct_lt(&self, other: &Self) -> Choice {
971
0
        !self.ct_gt(other) & !self.ct_eq(other)
972
0
    }
Unexecuted instantiation: _RNvYyNtCs3v1T4Vw6hEJ_6subtle16ConstantTimeLess5ct_ltCshRehcWQJ0wE_13crypto_bigint
Unexecuted instantiation: _RNvYhNtCs3v1T4Vw6hEJ_6subtle16ConstantTimeLess5ct_ltB5_
Unexecuted instantiation: _RNvYmNtCs3v1T4Vw6hEJ_6subtle16ConstantTimeLess5ct_ltB5_
Unexecuted instantiation: _RNvYoNtCs3v1T4Vw6hEJ_6subtle16ConstantTimeLess5ct_ltB5_
Unexecuted instantiation: _RNvYtNtCs3v1T4Vw6hEJ_6subtle16ConstantTimeLess5ct_ltB5_
Unexecuted instantiation: _RNvYyNtCs3v1T4Vw6hEJ_6subtle16ConstantTimeLess5ct_ltB5_
973
}
974
975
impl ConstantTimeLess for u8 {}
976
impl ConstantTimeLess for u16 {}
977
impl ConstantTimeLess for u32 {}
978
impl ConstantTimeLess for u64 {}
979
#[cfg(feature = "i128")]
980
impl ConstantTimeLess for u128 {}
981
982
impl ConstantTimeLess for cmp::Ordering {
983
    #[inline]
984
0
    fn ct_lt(&self, other: &Self) -> Choice {
985
0
        // No impl of `ConstantTimeLess` for `i8`, so use `u8`
986
0
        let a = (*self as i8) + 1;
987
0
        let b = (*other as i8) + 1;
988
0
        (a as u8).ct_lt(&(b as u8))
989
0
    }
990
}
991
992
/// Wrapper type which implements an optimization barrier for all accesses.
993
#[derive(Clone, Copy, Debug)]
994
pub struct BlackBox<T: Copy>(T);
995
996
impl<T: Copy> BlackBox<T> {
997
    /// Constructs a new instance of `BlackBox` which will wrap the specified value.
998
    ///
999
    /// All access to the inner value will be mediated by a `black_box` optimization barrier.
1000
0
    pub fn new(value: T) -> Self {
1001
0
        Self(value)
1002
0
    }
1003
1004
    /// Read the inner value, applying an optimization barrier on access.
1005
0
    pub fn get(self) -> T {
1006
0
        black_box(self.0)
1007
0
    }
1008
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/thiserror-1.0.61/src/aserror.rs
Line
Count
Source
1
use core::panic::UnwindSafe;
2
use std::error::Error;
3
4
#[doc(hidden)]
5
pub trait AsDynError<'a>: Sealed {
6
    fn as_dyn_error(&self) -> &(dyn Error + 'a);
7
}
8
9
impl<'a, T: Error + 'a> AsDynError<'a> for T {
10
    #[inline]
11
0
    fn as_dyn_error(&self) -> &(dyn Error + 'a) {
12
0
        self
13
0
    }
14
}
15
16
impl<'a> AsDynError<'a> for dyn Error + 'a {
17
    #[inline]
18
0
    fn as_dyn_error(&self) -> &(dyn Error + 'a) {
19
0
        self
20
0
    }
21
}
22
23
impl<'a> AsDynError<'a> for dyn Error + Send + 'a {
24
    #[inline]
25
0
    fn as_dyn_error(&self) -> &(dyn Error + 'a) {
26
0
        self
27
0
    }
28
}
29
30
impl<'a> AsDynError<'a> for dyn Error + Send + Sync + 'a {
31
    #[inline]
32
0
    fn as_dyn_error(&self) -> &(dyn Error + 'a) {
33
0
        self
34
0
    }
35
}
36
37
impl<'a> AsDynError<'a> for dyn Error + Send + Sync + UnwindSafe + 'a {
38
    #[inline]
39
0
    fn as_dyn_error(&self) -> &(dyn Error + 'a) {
40
0
        self
41
0
    }
42
}
43
44
#[doc(hidden)]
45
pub trait Sealed {}
46
impl<'a, T: Error + 'a> Sealed for T {}
47
impl<'a> Sealed for dyn Error + 'a {}
48
impl<'a> Sealed for dyn Error + Send + 'a {}
49
impl<'a> Sealed for dyn Error + Send + Sync + 'a {}
50
impl<'a> Sealed for dyn Error + Send + Sync + UnwindSafe + 'a {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/thiserror-1.0.61/src/display.rs
Line
Count
Source
1
use core::fmt::Display;
2
use std::path::{self, Path, PathBuf};
3
4
#[doc(hidden)]
5
pub trait AsDisplay<'a> {
6
    // TODO: convert to generic associated type.
7
    // https://github.com/dtolnay/thiserror/pull/253
8
    type Target: Display;
9
10
    fn as_display(&'a self) -> Self::Target;
11
}
12
13
impl<'a, T> AsDisplay<'a> for &T
14
where
15
    T: Display + 'a,
16
{
17
    type Target = &'a T;
18
19
0
    fn as_display(&'a self) -> Self::Target {
20
0
        *self
21
0
    }
Unexecuted instantiation: _RNvXNtCsa36ACAPCLse_9thiserror7displayRNtNtCsiBl6Lc3cFal_5alloc6string6StringNtB2_9AsDisplay10as_displayCs2IvCg5PL8uK_11chia_traits
Unexecuted instantiation: _RNvXININtCsa36ACAPCLse_9thiserror7display0pERpNtB5_9AsDisplay10as_displayB7_
22
}
23
24
impl<'a> AsDisplay<'a> for Path {
25
    type Target = path::Display<'a>;
26
27
    #[inline]
28
0
    fn as_display(&'a self) -> Self::Target {
29
0
        self.display()
30
0
    }
31
}
32
33
impl<'a> AsDisplay<'a> for PathBuf {
34
    type Target = path::Display<'a>;
35
36
    #[inline]
37
0
    fn as_display(&'a self) -> Self::Target {
38
0
        self.display()
39
0
    }
40
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/thiserror-1.0.61/src/provide.rs
Line
Count
Source
1
use std::error::{Error, Request};
2
3
#[doc(hidden)]
4
pub trait ThiserrorProvide: Sealed {
5
    fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>);
6
}
7
8
impl<T> ThiserrorProvide for T
9
where
10
    T: Error + ?Sized,
11
{
12
    #[inline]
13
0
    fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) {
14
0
        self.provide(request);
15
0
    }
16
}
17
18
#[doc(hidden)]
19
pub trait Sealed {}
20
impl<T: Error + ?Sized> Sealed for T {}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/threadpool-1.8.1/src/lib.rs
Line
Count
Source
1
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2
// file at the top-level directory of this distribution and at
3
// http://rust-lang.org/COPYRIGHT.
4
//
5
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8
// option. This file may not be copied, modified, or distributed
9
// except according to those terms.
10
11
//! A thread pool used to execute functions in parallel.
12
//!
13
//! Spawns a specified number of worker threads and replenishes the pool if any worker threads
14
//! panic.
15
//!
16
//! # Examples
17
//!
18
//! ## Synchronized with a channel
19
//!
20
//! Every thread sends one message over the channel, which then is collected with the `take()`.
21
//!
22
//! ```
23
//! use threadpool::ThreadPool;
24
//! use std::sync::mpsc::channel;
25
//!
26
//! let n_workers = 4;
27
//! let n_jobs = 8;
28
//! let pool = ThreadPool::new(n_workers);
29
//!
30
//! let (tx, rx) = channel();
31
//! for _ in 0..n_jobs {
32
//!     let tx = tx.clone();
33
//!     pool.execute(move|| {
34
//!         tx.send(1).expect("channel will be there waiting for the pool");
35
//!     });
36
//! }
37
//!
38
//! assert_eq!(rx.iter().take(n_jobs).fold(0, |a, b| a + b), 8);
39
//! ```
40
//!
41
//! ## Synchronized with a barrier
42
//!
43
//! Keep in mind, if a barrier synchronizes more jobs than you have workers in the pool,
44
//! you will end up with a [deadlock](https://en.wikipedia.org/wiki/Deadlock)
45
//! at the barrier which is [not considered unsafe](
46
//! https://doc.rust-lang.org/reference/behavior-not-considered-unsafe.html).
47
//!
48
//! ```
49
//! use threadpool::ThreadPool;
50
//! use std::sync::{Arc, Barrier};
51
//! use std::sync::atomic::{AtomicUsize, Ordering};
52
//!
53
//! // create at least as many workers as jobs or you will deadlock yourself
54
//! let n_workers = 42;
55
//! let n_jobs = 23;
56
//! let pool = ThreadPool::new(n_workers);
57
//! let an_atomic = Arc::new(AtomicUsize::new(0));
58
//!
59
//! assert!(n_jobs <= n_workers, "too many jobs, will deadlock");
60
//!
61
//! // create a barrier that waits for all jobs plus the starter thread
62
//! let barrier = Arc::new(Barrier::new(n_jobs + 1));
63
//! for _ in 0..n_jobs {
64
//!     let barrier = barrier.clone();
65
//!     let an_atomic = an_atomic.clone();
66
//!
67
//!     pool.execute(move|| {
68
//!         // do the heavy work
69
//!         an_atomic.fetch_add(1, Ordering::Relaxed);
70
//!
71
//!         // then wait for the other threads
72
//!         barrier.wait();
73
//!     });
74
//! }
75
//!
76
//! // wait for the threads to finish the work
77
//! barrier.wait();
78
//! assert_eq!(an_atomic.load(Ordering::SeqCst), /* n_jobs = */ 23);
79
//! ```
80
81
extern crate num_cpus;
82
83
use std::fmt;
84
use std::sync::atomic::{AtomicUsize, Ordering};
85
use std::sync::mpsc::{channel, Receiver, Sender};
86
use std::sync::{Arc, Condvar, Mutex};
87
use std::thread;
88
89
trait FnBox {
90
    fn call_box(self: Box<Self>);
91
}
92
93
impl<F: FnOnce()> FnBox for F {
94
0
    fn call_box(self: Box<F>) {
95
0
        (*self)()
96
0
    }
Unexecuted instantiation: _RNvXCs4c1Xk16ziyI_10threadpoolINtNtCsiBl6Lc3cFal_5alloc5boxed3BoxDINtNtNtCsbQ8arDwx5Xq_4core3ops8function6FnOnceuEp6OutputuNtNtB19_6marker4SendEL_ENtB2_5FnBox8call_boxCscC7OSmV1s5f_4blst
Unexecuted instantiation: _RNvXINICs4c1Xk16ziyI_10threadpool0pEpNtB5_5FnBox8call_boxB5_
97
}
98
99
type Thunk<'a> = Box<FnBox + Send + 'a>;
100
101
struct Sentinel<'a> {
102
    shared_data: &'a Arc<ThreadPoolSharedData>,
103
    active: bool,
104
}
105
106
impl<'a> Sentinel<'a> {
107
0
    fn new(shared_data: &'a Arc<ThreadPoolSharedData>) -> Sentinel<'a> {
108
0
        Sentinel {
109
0
            shared_data: shared_data,
110
0
            active: true,
111
0
        }
112
0
    }
113
114
    /// Cancel and destroy this sentinel.
115
0
    fn cancel(mut self) {
116
0
        self.active = false;
117
0
    }
118
}
119
120
impl<'a> Drop for Sentinel<'a> {
121
0
    fn drop(&mut self) {
122
0
        if self.active {
123
0
            self.shared_data.active_count.fetch_sub(1, Ordering::SeqCst);
124
0
            if thread::panicking() {
125
0
                self.shared_data.panic_count.fetch_add(1, Ordering::SeqCst);
126
0
            }
127
0
            self.shared_data.no_work_notify_all();
128
0
            spawn_in_pool(self.shared_data.clone())
129
0
        }
130
0
    }
131
}
132
133
/// [`ThreadPool`] factory, which can be used in order to configure the properties of the
134
/// [`ThreadPool`].
135
///
136
/// The three configuration options available:
137
///
138
/// * `num_threads`: maximum number of threads that will be alive at any given moment by the built
139
///   [`ThreadPool`]
140
/// * `thread_name`: thread name for each of the threads spawned by the built [`ThreadPool`]
141
/// * `thread_stack_size`: stack size (in bytes) for each of the threads spawned by the built
142
///   [`ThreadPool`]
143
///
144
/// [`ThreadPool`]: struct.ThreadPool.html
145
///
146
/// # Examples
147
///
148
/// Build a [`ThreadPool`] that uses a maximum of eight threads simultaneously and each thread has
149
/// a 8 MB stack size:
150
///
151
/// ```
152
/// let pool = threadpool::Builder::new()
153
///     .num_threads(8)
154
///     .thread_stack_size(8_000_000)
155
///     .build();
156
/// ```
157
#[derive(Clone, Default)]
158
pub struct Builder {
159
    num_threads: Option<usize>,
160
    thread_name: Option<String>,
161
    thread_stack_size: Option<usize>,
162
}
163
164
impl Builder {
165
    /// Initiate a new [`Builder`].
166
    ///
167
    /// [`Builder`]: struct.Builder.html
168
    ///
169
    /// # Examples
170
    ///
171
    /// ```
172
    /// let builder = threadpool::Builder::new();
173
    /// ```
174
0
    pub fn new() -> Builder {
175
0
        Builder {
176
0
            num_threads: None,
177
0
            thread_name: None,
178
0
            thread_stack_size: None,
179
0
        }
180
0
    }
181
182
    /// Set the maximum number of worker-threads that will be alive at any given moment by the built
183
    /// [`ThreadPool`]. If not specified, defaults the number of threads to the number of CPUs.
184
    ///
185
    /// [`ThreadPool`]: struct.ThreadPool.html
186
    ///
187
    /// # Panics
188
    ///
189
    /// This method will panic if `num_threads` is 0.
190
    ///
191
    /// # Examples
192
    ///
193
    /// No more than eight threads will be alive simultaneously for this pool:
194
    ///
195
    /// ```
196
    /// use std::thread;
197
    ///
198
    /// let pool = threadpool::Builder::new()
199
    ///     .num_threads(8)
200
    ///     .build();
201
    ///
202
    /// for _ in 0..100 {
203
    ///     pool.execute(|| {
204
    ///         println!("Hello from a worker thread!")
205
    ///     })
206
    /// }
207
    /// ```
208
0
    pub fn num_threads(mut self, num_threads: usize) -> Builder {
209
0
        assert!(num_threads > 0);
210
0
        self.num_threads = Some(num_threads);
211
0
        self
212
0
    }
213
214
    /// Set the thread name for each of the threads spawned by the built [`ThreadPool`]. If not
215
    /// specified, threads spawned by the thread pool will be unnamed.
216
    ///
217
    /// [`ThreadPool`]: struct.ThreadPool.html
218
    ///
219
    /// # Examples
220
    ///
221
    /// Each thread spawned by this pool will have the name "foo":
222
    ///
223
    /// ```
224
    /// use std::thread;
225
    ///
226
    /// let pool = threadpool::Builder::new()
227
    ///     .thread_name("foo".into())
228
    ///     .build();
229
    ///
230
    /// for _ in 0..100 {
231
    ///     pool.execute(|| {
232
    ///         assert_eq!(thread::current().name(), Some("foo"));
233
    ///     })
234
    /// }
235
    /// ```
236
0
    pub fn thread_name(mut self, name: String) -> Builder {
237
0
        self.thread_name = Some(name);
238
0
        self
239
0
    }
240
241
    /// Set the stack size (in bytes) for each of the threads spawned by the built [`ThreadPool`].
242
    /// If not specified, threads spawned by the threadpool will have a stack size [as specified in
243
    /// the `std::thread` documentation][thread].
244
    ///
245
    /// [thread]: https://doc.rust-lang.org/nightly/std/thread/index.html#stack-size
246
    /// [`ThreadPool`]: struct.ThreadPool.html
247
    ///
248
    /// # Examples
249
    ///
250
    /// Each thread spawned by this pool will have a 4 MB stack:
251
    ///
252
    /// ```
253
    /// let pool = threadpool::Builder::new()
254
    ///     .thread_stack_size(4_000_000)
255
    ///     .build();
256
    ///
257
    /// for _ in 0..100 {
258
    ///     pool.execute(|| {
259
    ///         println!("This thread has a 4 MB stack size!");
260
    ///     })
261
    /// }
262
    /// ```
263
0
    pub fn thread_stack_size(mut self, size: usize) -> Builder {
264
0
        self.thread_stack_size = Some(size);
265
0
        self
266
0
    }
267
268
    /// Finalize the [`Builder`] and build the [`ThreadPool`].
269
    ///
270
    /// [`Builder`]: struct.Builder.html
271
    /// [`ThreadPool`]: struct.ThreadPool.html
272
    ///
273
    /// # Examples
274
    ///
275
    /// ```
276
    /// let pool = threadpool::Builder::new()
277
    ///     .num_threads(8)
278
    ///     .thread_stack_size(4_000_000)
279
    ///     .build();
280
    /// ```
281
0
    pub fn build(self) -> ThreadPool {
282
0
        let (tx, rx) = channel::<Thunk<'static>>();
283
0
284
0
        let num_threads = self.num_threads.unwrap_or_else(num_cpus::get);
285
0
286
0
        let shared_data = Arc::new(ThreadPoolSharedData {
287
0
            name: self.thread_name,
288
0
            job_receiver: Mutex::new(rx),
289
0
            empty_condvar: Condvar::new(),
290
0
            empty_trigger: Mutex::new(()),
291
0
            join_generation: AtomicUsize::new(0),
292
0
            queued_count: AtomicUsize::new(0),
293
0
            active_count: AtomicUsize::new(0),
294
0
            max_thread_count: AtomicUsize::new(num_threads),
295
0
            panic_count: AtomicUsize::new(0),
296
0
            stack_size: self.thread_stack_size,
297
0
        });
298
0
299
0
        // Threadpool threads
300
0
        for _ in 0..num_threads {
301
0
            spawn_in_pool(shared_data.clone());
302
0
        }
303
304
0
        ThreadPool {
305
0
            jobs: tx,
306
0
            shared_data: shared_data,
307
0
        }
308
0
    }
309
}
310
311
struct ThreadPoolSharedData {
312
    name: Option<String>,
313
    job_receiver: Mutex<Receiver<Thunk<'static>>>,
314
    empty_trigger: Mutex<()>,
315
    empty_condvar: Condvar,
316
    join_generation: AtomicUsize,
317
    queued_count: AtomicUsize,
318
    active_count: AtomicUsize,
319
    max_thread_count: AtomicUsize,
320
    panic_count: AtomicUsize,
321
    stack_size: Option<usize>,
322
}
323
324
impl ThreadPoolSharedData {
325
0
    fn has_work(&self) -> bool {
326
0
        self.queued_count.load(Ordering::SeqCst) > 0 || self.active_count.load(Ordering::SeqCst) > 0
327
0
    }
328
329
    /// Notify all observers joining this pool if there is no more work to do.
330
0
    fn no_work_notify_all(&self) {
331
0
        if !self.has_work() {
332
0
            *self
333
0
                .empty_trigger
334
0
                .lock()
335
0
                .expect("Unable to notify all joining threads");
336
0
            self.empty_condvar.notify_all();
337
0
        }
338
0
    }
339
}
340
341
/// Abstraction of a thread pool for basic parallelism.
342
pub struct ThreadPool {
343
    // How the threadpool communicates with subthreads.
344
    //
345
    // This is the only such Sender, so when it is dropped all subthreads will
346
    // quit.
347
    jobs: Sender<Thunk<'static>>,
348
    shared_data: Arc<ThreadPoolSharedData>,
349
}
350
351
impl ThreadPool {
352
    /// Creates a new thread pool capable of executing `num_threads` number of jobs concurrently.
353
    ///
354
    /// # Panics
355
    ///
356
    /// This function will panic if `num_threads` is 0.
357
    ///
358
    /// # Examples
359
    ///
360
    /// Create a new thread pool capable of executing four jobs concurrently:
361
    ///
362
    /// ```
363
    /// use threadpool::ThreadPool;
364
    ///
365
    /// let pool = ThreadPool::new(4);
366
    /// ```
367
0
    pub fn new(num_threads: usize) -> ThreadPool {
368
0
        Builder::new().num_threads(num_threads).build()
369
0
    }
370
371
    /// Creates a new thread pool capable of executing `num_threads` number of jobs concurrently.
372
    /// Each thread will have the [name][thread name] `name`.
373
    ///
374
    /// # Panics
375
    ///
376
    /// This function will panic if `num_threads` is 0.
377
    ///
378
    /// # Examples
379
    ///
380
    /// ```rust
381
    /// use std::thread;
382
    /// use threadpool::ThreadPool;
383
    ///
384
    /// let pool = ThreadPool::with_name("worker".into(), 2);
385
    /// for _ in 0..2 {
386
    ///     pool.execute(|| {
387
    ///         assert_eq!(
388
    ///             thread::current().name(),
389
    ///             Some("worker")
390
    ///         );
391
    ///     });
392
    /// }
393
    /// pool.join();
394
    /// ```
395
    ///
396
    /// [thread name]: https://doc.rust-lang.org/std/thread/struct.Thread.html#method.name
397
0
    pub fn with_name(name: String, num_threads: usize) -> ThreadPool {
398
0
        Builder::new()
399
0
            .num_threads(num_threads)
400
0
            .thread_name(name)
401
0
            .build()
402
0
    }
403
404
    /// **Deprecated: Use [`ThreadPool::with_name`](#method.with_name)**
405
    #[inline(always)]
406
    #[deprecated(since = "1.4.0", note = "use ThreadPool::with_name")]
407
    pub fn new_with_name(name: String, num_threads: usize) -> ThreadPool {
408
        Self::with_name(name, num_threads)
409
    }
410
411
    /// Executes the function `job` on a thread in the pool.
412
    ///
413
    /// # Examples
414
    ///
415
    /// Execute four jobs on a thread pool that can run two jobs concurrently:
416
    ///
417
    /// ```
418
    /// use threadpool::ThreadPool;
419
    ///
420
    /// let pool = ThreadPool::new(2);
421
    /// pool.execute(|| println!("hello"));
422
    /// pool.execute(|| println!("world"));
423
    /// pool.execute(|| println!("foo"));
424
    /// pool.execute(|| println!("bar"));
425
    /// pool.join();
426
    /// ```
427
0
    pub fn execute<F>(&self, job: F)
428
0
    where
429
0
        F: FnOnce() + Send + 'static,
430
0
    {
431
0
        self.shared_data.queued_count.fetch_add(1, Ordering::SeqCst);
432
0
        self.jobs
433
0
            .send(Box::new(job))
434
0
            .expect("ThreadPool::execute unable to send job into queue.");
435
0
    }
Unexecuted instantiation: _RINvMs3_Cs4c1Xk16ziyI_10threadpoolNtB6_10ThreadPool7executeINtNtCsiBl6Lc3cFal_5alloc5boxed3BoxDINtNtNtCsbQ8arDwx5Xq_4core3ops8function6FnOnceuEp6OutputuNtNtB1C_6marker4SendEL_EECscC7OSmV1s5f_4blst
Unexecuted instantiation: _RINvMs3_Cs4c1Xk16ziyI_10threadpoolNtB6_10ThreadPool7executepEB6_
436
437
    /// Returns the number of jobs waiting to executed in the pool.
438
    ///
439
    /// # Examples
440
    ///
441
    /// ```
442
    /// use threadpool::ThreadPool;
443
    /// use std::time::Duration;
444
    /// use std::thread::sleep;
445
    ///
446
    /// let pool = ThreadPool::new(2);
447
    /// for _ in 0..10 {
448
    ///     pool.execute(|| {
449
    ///         sleep(Duration::from_secs(100));
450
    ///     });
451
    /// }
452
    ///
453
    /// sleep(Duration::from_secs(1)); // wait for threads to start
454
    /// assert_eq!(8, pool.queued_count());
455
    /// ```
456
0
    pub fn queued_count(&self) -> usize {
457
0
        self.shared_data.queued_count.load(Ordering::Relaxed)
458
0
    }
459
460
    /// Returns the number of currently active threads.
461
    ///
462
    /// # Examples
463
    ///
464
    /// ```
465
    /// use threadpool::ThreadPool;
466
    /// use std::time::Duration;
467
    /// use std::thread::sleep;
468
    ///
469
    /// let pool = ThreadPool::new(4);
470
    /// for _ in 0..10 {
471
    ///     pool.execute(move || {
472
    ///         sleep(Duration::from_secs(100));
473
    ///     });
474
    /// }
475
    ///
476
    /// sleep(Duration::from_secs(1)); // wait for threads to start
477
    /// assert_eq!(4, pool.active_count());
478
    /// ```
479
0
    pub fn active_count(&self) -> usize {
480
0
        self.shared_data.active_count.load(Ordering::SeqCst)
481
0
    }
482
483
    /// Returns the maximum number of threads the pool will execute concurrently.
484
    ///
485
    /// # Examples
486
    ///
487
    /// ```
488
    /// use threadpool::ThreadPool;
489
    ///
490
    /// let mut pool = ThreadPool::new(4);
491
    /// assert_eq!(4, pool.max_count());
492
    ///
493
    /// pool.set_num_threads(8);
494
    /// assert_eq!(8, pool.max_count());
495
    /// ```
496
0
    pub fn max_count(&self) -> usize {
497
0
        self.shared_data.max_thread_count.load(Ordering::Relaxed)
498
0
    }
499
500
    /// Returns the number of panicked threads over the lifetime of the pool.
501
    ///
502
    /// # Examples
503
    ///
504
    /// ```
505
    /// use threadpool::ThreadPool;
506
    ///
507
    /// let pool = ThreadPool::new(4);
508
    /// for n in 0..10 {
509
    ///     pool.execute(move || {
510
    ///         // simulate a panic
511
    ///         if n % 2 == 0 {
512
    ///             panic!()
513
    ///         }
514
    ///     });
515
    /// }
516
    /// pool.join();
517
    ///
518
    /// assert_eq!(5, pool.panic_count());
519
    /// ```
520
0
    pub fn panic_count(&self) -> usize {
521
0
        self.shared_data.panic_count.load(Ordering::Relaxed)
522
0
    }
523
524
    /// **Deprecated: Use [`ThreadPool::set_num_threads`](#method.set_num_threads)**
525
    #[deprecated(since = "1.3.0", note = "use ThreadPool::set_num_threads")]
526
0
    pub fn set_threads(&mut self, num_threads: usize) {
527
0
        self.set_num_threads(num_threads)
528
0
    }
529
530
    /// Sets the number of worker-threads to use as `num_threads`.
531
    /// Can be used to change the threadpool size during runtime.
532
    /// Will not abort already running or waiting threads.
533
    ///
534
    /// # Panics
535
    ///
536
    /// This function will panic if `num_threads` is 0.
537
    ///
538
    /// # Examples
539
    ///
540
    /// ```
541
    /// use threadpool::ThreadPool;
542
    /// use std::time::Duration;
543
    /// use std::thread::sleep;
544
    ///
545
    /// let mut pool = ThreadPool::new(4);
546
    /// for _ in 0..10 {
547
    ///     pool.execute(move || {
548
    ///         sleep(Duration::from_secs(100));
549
    ///     });
550
    /// }
551
    ///
552
    /// sleep(Duration::from_secs(1)); // wait for threads to start
553
    /// assert_eq!(4, pool.active_count());
554
    /// assert_eq!(6, pool.queued_count());
555
    ///
556
    /// // Increase thread capacity of the pool
557
    /// pool.set_num_threads(8);
558
    ///
559
    /// sleep(Duration::from_secs(1)); // wait for new threads to start
560
    /// assert_eq!(8, pool.active_count());
561
    /// assert_eq!(2, pool.queued_count());
562
    ///
563
    /// // Decrease thread capacity of the pool
564
    /// // No active threads are killed
565
    /// pool.set_num_threads(4);
566
    ///
567
    /// assert_eq!(8, pool.active_count());
568
    /// assert_eq!(2, pool.queued_count());
569
    /// ```
570
0
    pub fn set_num_threads(&mut self, num_threads: usize) {
571
0
        assert!(num_threads >= 1);
572
0
        let prev_num_threads = self
573
0
            .shared_data
574
0
            .max_thread_count
575
0
            .swap(num_threads, Ordering::Release);
576
0
        if let Some(num_spawn) = num_threads.checked_sub(prev_num_threads) {
577
            // Spawn new threads
578
0
            for _ in 0..num_spawn {
579
0
                spawn_in_pool(self.shared_data.clone());
580
0
            }
581
0
        }
582
0
    }
583
584
    /// Block the current thread until all jobs in the pool have been executed.
585
    ///
586
    /// Calling `join` on an empty pool will cause an immediate return.
587
    /// `join` may be called from multiple threads concurrently.
588
    /// A `join` is an atomic point in time. All threads joining before the join
589
    /// event will exit together even if the pool is processing new jobs by the
590
    /// time they get scheduled.
591
    ///
592
    /// Calling `join` from a thread within the pool will cause a deadlock. This
593
    /// behavior is considered safe.
594
    ///
595
    /// # Examples
596
    ///
597
    /// ```
598
    /// use threadpool::ThreadPool;
599
    /// use std::sync::Arc;
600
    /// use std::sync::atomic::{AtomicUsize, Ordering};
601
    ///
602
    /// let pool = ThreadPool::new(8);
603
    /// let test_count = Arc::new(AtomicUsize::new(0));
604
    ///
605
    /// for _ in 0..42 {
606
    ///     let test_count = test_count.clone();
607
    ///     pool.execute(move || {
608
    ///         test_count.fetch_add(1, Ordering::Relaxed);
609
    ///     });
610
    /// }
611
    ///
612
    /// pool.join();
613
    /// assert_eq!(42, test_count.load(Ordering::Relaxed));
614
    /// ```
615
0
    pub fn join(&self) {
616
0
        // fast path requires no mutex
617
0
        if self.shared_data.has_work() == false {
618
0
            return ();
619
0
        }
620
0
621
0
        let generation = self.shared_data.join_generation.load(Ordering::SeqCst);
622
0
        let mut lock = self.shared_data.empty_trigger.lock().unwrap();
623
624
0
        while generation == self.shared_data.join_generation.load(Ordering::Relaxed)
625
0
            && self.shared_data.has_work()
626
0
        {
627
0
            lock = self.shared_data.empty_condvar.wait(lock).unwrap();
628
0
        }
629
630
        // increase generation if we are the first thread to come out of the loop
631
0
        self.shared_data.join_generation.compare_and_swap(
632
0
            generation,
633
0
            generation.wrapping_add(1),
634
0
            Ordering::SeqCst,
635
0
        );
636
0
    }
637
}
638
639
impl Clone for ThreadPool {
640
    /// Cloning a pool will create a new handle to the pool.
641
    /// The behavior is similar to [Arc](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html).
642
    ///
643
    /// We could for example submit jobs from multiple threads concurrently.
644
    ///
645
    /// ```
646
    /// use threadpool::ThreadPool;
647
    /// use std::thread;
648
    /// use std::sync::mpsc::channel;
649
    ///
650
    /// let pool = ThreadPool::with_name("clone example".into(), 2);
651
    ///
652
    /// let results = (0..2)
653
    ///     .map(|i| {
654
    ///         let pool = pool.clone();
655
    ///         thread::spawn(move || {
656
    ///             let (tx, rx) = channel();
657
    ///             for i in 1..12 {
658
    ///                 let tx = tx.clone();
659
    ///                 pool.execute(move || {
660
    ///                     tx.send(i).expect("channel will be waiting");
661
    ///                 });
662
    ///             }
663
    ///             drop(tx);
664
    ///             if i == 0 {
665
    ///                 rx.iter().fold(0, |accumulator, element| accumulator + element)
666
    ///             } else {
667
    ///                 rx.iter().fold(1, |accumulator, element| accumulator * element)
668
    ///             }
669
    ///         })
670
    ///     })
671
    ///     .map(|join_handle| join_handle.join().expect("collect results from threads"))
672
    ///     .collect::<Vec<usize>>();
673
    ///
674
    /// assert_eq!(vec![66, 39916800], results);
675
    /// ```
676
0
    fn clone(&self) -> ThreadPool {
677
0
        ThreadPool {
678
0
            jobs: self.jobs.clone(),
679
0
            shared_data: self.shared_data.clone(),
680
0
        }
681
0
    }
682
}
683
684
/// Create a thread pool with one thread per CPU.
685
/// On machines with hyperthreading,
686
/// this will create one thread per hyperthread.
687
impl Default for ThreadPool {
688
0
    fn default() -> Self {
689
0
        ThreadPool::new(num_cpus::get())
690
0
    }
691
}
692
693
impl fmt::Debug for ThreadPool {
694
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
695
0
        f.debug_struct("ThreadPool")
696
0
            .field("name", &self.shared_data.name)
697
0
            .field("queued_count", &self.queued_count())
698
0
            .field("active_count", &self.active_count())
699
0
            .field("max_count", &self.max_count())
700
0
            .finish()
701
0
    }
702
}
703
704
impl PartialEq for ThreadPool {
705
    /// Check if you are working with the same pool
706
    ///
707
    /// ```
708
    /// use threadpool::ThreadPool;
709
    ///
710
    /// let a = ThreadPool::new(2);
711
    /// let b = ThreadPool::new(2);
712
    ///
713
    /// assert_eq!(a, a);
714
    /// assert_eq!(b, b);
715
    ///
716
    /// # // TODO: change this to assert_ne in the future
717
    /// assert!(a != b);
718
    /// assert!(b != a);
719
    /// ```
720
0
    fn eq(&self, other: &ThreadPool) -> bool {
721
0
        let a: &ThreadPoolSharedData = &*self.shared_data;
722
0
        let b: &ThreadPoolSharedData = &*other.shared_data;
723
0
        a as *const ThreadPoolSharedData == b as *const ThreadPoolSharedData
724
0
        // with rust 1.17 and late:
725
0
        // Arc::ptr_eq(&self.shared_data, &other.shared_data)
726
0
    }
727
}
728
impl Eq for ThreadPool {}
729
730
0
fn spawn_in_pool(shared_data: Arc<ThreadPoolSharedData>) {
731
0
    let mut builder = thread::Builder::new();
732
0
    if let Some(ref name) = shared_data.name {
733
0
        builder = builder.name(name.clone());
734
0
    }
735
0
    if let Some(ref stack_size) = shared_data.stack_size {
736
0
        builder = builder.stack_size(stack_size.to_owned());
737
0
    }
738
0
    builder
739
0
        .spawn(move || {
740
0
            // Will spawn a new thread on panic unless it is cancelled.
741
0
            let sentinel = Sentinel::new(&shared_data);
742
743
            loop {
744
                // Shutdown this thread if the pool has become smaller
745
0
                let thread_counter_val = shared_data.active_count.load(Ordering::Acquire);
746
0
                let max_thread_count_val = shared_data.max_thread_count.load(Ordering::Relaxed);
747
0
                if thread_counter_val >= max_thread_count_val {
748
0
                    break;
749
0
                }
750
0
                let message = {
751
0
                    // Only lock jobs for the time it takes
752
0
                    // to get a job, not run it.
753
0
                    let lock = shared_data
754
0
                        .job_receiver
755
0
                        .lock()
756
0
                        .expect("Worker thread unable to lock job_receiver");
757
0
                    lock.recv()
758
                };
759
760
0
                let job = match message {
761
0
                    Ok(job) => job,
762
                    // The ThreadPool was dropped.
763
0
                    Err(..) => break,
764
                };
765
                // Do not allow IR around the job execution
766
0
                shared_data.active_count.fetch_add(1, Ordering::SeqCst);
767
0
                shared_data.queued_count.fetch_sub(1, Ordering::SeqCst);
768
0
769
0
                job.call_box();
770
0
771
0
                shared_data.active_count.fetch_sub(1, Ordering::SeqCst);
772
0
                shared_data.no_work_notify_all();
773
            }
774
775
0
            sentinel.cancel();
776
0
        })
777
0
        .unwrap();
778
0
}
779
780
#[cfg(test)]
781
mod test {
782
    use super::{Builder, ThreadPool};
783
    use std::sync::atomic::{AtomicUsize, Ordering};
784
    use std::sync::mpsc::{channel, sync_channel};
785
    use std::sync::{Arc, Barrier};
786
    use std::thread::{self, sleep};
787
    use std::time::Duration;
788
789
    const TEST_TASKS: usize = 4;
790
791
    #[test]
792
    fn test_set_num_threads_increasing() {
793
        let new_thread_amount = TEST_TASKS + 8;
794
        let mut pool = ThreadPool::new(TEST_TASKS);
795
        for _ in 0..TEST_TASKS {
796
            pool.execute(move || sleep(Duration::from_secs(23)));
797
        }
798
        sleep(Duration::from_secs(1));
799
        assert_eq!(pool.active_count(), TEST_TASKS);
800
801
        pool.set_num_threads(new_thread_amount);
802
803
        for _ in 0..(new_thread_amount - TEST_TASKS) {
804
            pool.execute(move || sleep(Duration::from_secs(23)));
805
        }
806
        sleep(Duration::from_secs(1));
807
        assert_eq!(pool.active_count(), new_thread_amount);
808
809
        pool.join();
810
    }
811
812
    #[test]
813
    fn test_set_num_threads_decreasing() {
814
        let new_thread_amount = 2;
815
        let mut pool = ThreadPool::new(TEST_TASKS);
816
        for _ in 0..TEST_TASKS {
817
            pool.execute(move || {
818
                assert_eq!(1, 1);
819
            });
820
        }
821
        pool.set_num_threads(new_thread_amount);
822
        for _ in 0..new_thread_amount {
823
            pool.execute(move || sleep(Duration::from_secs(23)));
824
        }
825
        sleep(Duration::from_secs(1));
826
        assert_eq!(pool.active_count(), new_thread_amount);
827
828
        pool.join();
829
    }
830
831
    #[test]
832
    fn test_active_count() {
833
        let pool = ThreadPool::new(TEST_TASKS);
834
        for _ in 0..2 * TEST_TASKS {
835
            pool.execute(move || loop {
836
                sleep(Duration::from_secs(10))
837
            });
838
        }
839
        sleep(Duration::from_secs(1));
840
        let active_count = pool.active_count();
841
        assert_eq!(active_count, TEST_TASKS);
842
        let initialized_count = pool.max_count();
843
        assert_eq!(initialized_count, TEST_TASKS);
844
    }
845
846
    #[test]
847
    fn test_works() {
848
        let pool = ThreadPool::new(TEST_TASKS);
849
850
        let (tx, rx) = channel();
851
        for _ in 0..TEST_TASKS {
852
            let tx = tx.clone();
853
            pool.execute(move || {
854
                tx.send(1).unwrap();
855
            });
856
        }
857
858
        assert_eq!(rx.iter().take(TEST_TASKS).fold(0, |a, b| a + b), TEST_TASKS);
859
    }
860
861
    #[test]
862
    #[should_panic]
863
    fn test_zero_tasks_panic() {
864
        ThreadPool::new(0);
865
    }
866
867
    #[test]
868
    fn test_recovery_from_subtask_panic() {
869
        let pool = ThreadPool::new(TEST_TASKS);
870
871
        // Panic all the existing threads.
872
        for _ in 0..TEST_TASKS {
873
            pool.execute(move || panic!("Ignore this panic, it must!"));
874
        }
875
        pool.join();
876
877
        assert_eq!(pool.panic_count(), TEST_TASKS);
878
879
        // Ensure new threads were spawned to compensate.
880
        let (tx, rx) = channel();
881
        for _ in 0..TEST_TASKS {
882
            let tx = tx.clone();
883
            pool.execute(move || {
884
                tx.send(1).unwrap();
885
            });
886
        }
887
888
        assert_eq!(rx.iter().take(TEST_TASKS).fold(0, |a, b| a + b), TEST_TASKS);
889
    }
890
891
    #[test]
892
    fn test_should_not_panic_on_drop_if_subtasks_panic_after_drop() {
893
        let pool = ThreadPool::new(TEST_TASKS);
894
        let waiter = Arc::new(Barrier::new(TEST_TASKS + 1));
895
896
        // Panic all the existing threads in a bit.
897
        for _ in 0..TEST_TASKS {
898
            let waiter = waiter.clone();
899
            pool.execute(move || {
900
                waiter.wait();
901
                panic!("Ignore this panic, it should!");
902
            });
903
        }
904
905
        drop(pool);
906
907
        // Kick off the failure.
908
        waiter.wait();
909
    }
910
911
    #[test]
912
    fn test_massive_task_creation() {
913
        let test_tasks = 4_200_000;
914
915
        let pool = ThreadPool::new(TEST_TASKS);
916
        let b0 = Arc::new(Barrier::new(TEST_TASKS + 1));
917
        let b1 = Arc::new(Barrier::new(TEST_TASKS + 1));
918
919
        let (tx, rx) = channel();
920
921
        for i in 0..test_tasks {
922
            let tx = tx.clone();
923
            let (b0, b1) = (b0.clone(), b1.clone());
924
925
            pool.execute(move || {
926
                // Wait until the pool has been filled once.
927
                if i < TEST_TASKS {
928
                    b0.wait();
929
                    // wait so the pool can be measured
930
                    b1.wait();
931
                }
932
933
                tx.send(1).is_ok();
934
            });
935
        }
936
937
        b0.wait();
938
        assert_eq!(pool.active_count(), TEST_TASKS);
939
        b1.wait();
940
941
        assert_eq!(rx.iter().take(test_tasks).fold(0, |a, b| a + b), test_tasks);
942
        pool.join();
943
944
        let atomic_active_count = pool.active_count();
945
        assert!(
946
            atomic_active_count == 0,
947
            "atomic_active_count: {}",
948
            atomic_active_count
949
        );
950
    }
951
952
    #[test]
953
    fn test_shrink() {
954
        let test_tasks_begin = TEST_TASKS + 2;
955
956
        let mut pool = ThreadPool::new(test_tasks_begin);
957
        let b0 = Arc::new(Barrier::new(test_tasks_begin + 1));
958
        let b1 = Arc::new(Barrier::new(test_tasks_begin + 1));
959
960
        for _ in 0..test_tasks_begin {
961
            let (b0, b1) = (b0.clone(), b1.clone());
962
            pool.execute(move || {
963
                b0.wait();
964
                b1.wait();
965
            });
966
        }
967
968
        let b2 = Arc::new(Barrier::new(TEST_TASKS + 1));
969
        let b3 = Arc::new(Barrier::new(TEST_TASKS + 1));
970
971
        for _ in 0..TEST_TASKS {
972
            let (b2, b3) = (b2.clone(), b3.clone());
973
            pool.execute(move || {
974
                b2.wait();
975
                b3.wait();
976
            });
977
        }
978
979
        b0.wait();
980
        pool.set_num_threads(TEST_TASKS);
981
982
        assert_eq!(pool.active_count(), test_tasks_begin);
983
        b1.wait();
984
985
        b2.wait();
986
        assert_eq!(pool.active_count(), TEST_TASKS);
987
        b3.wait();
988
    }
989
990
    #[test]
991
    fn test_name() {
992
        let name = "test";
993
        let mut pool = ThreadPool::with_name(name.to_owned(), 2);
994
        let (tx, rx) = sync_channel(0);
995
996
        // initial thread should share the name "test"
997
        for _ in 0..2 {
998
            let tx = tx.clone();
999
            pool.execute(move || {
1000
                let name = thread::current().name().unwrap().to_owned();
1001
                tx.send(name).unwrap();
1002
            });
1003
        }
1004
1005
        // new spawn thread should share the name "test" too.
1006
        pool.set_num_threads(3);
1007
        let tx_clone = tx.clone();
1008
        pool.execute(move || {
1009
            let name = thread::current().name().unwrap().to_owned();
1010
            tx_clone.send(name).unwrap();
1011
            panic!();
1012
        });
1013
1014
        // recover thread should share the name "test" too.
1015
        pool.execute(move || {
1016
            let name = thread::current().name().unwrap().to_owned();
1017
            tx.send(name).unwrap();
1018
        });
1019
1020
        for thread_name in rx.iter().take(4) {
1021
            assert_eq!(name, thread_name);
1022
        }
1023
    }
1024
1025
    #[test]
1026
    fn test_debug() {
1027
        let pool = ThreadPool::new(4);
1028
        let debug = format!("{:?}", pool);
1029
        assert_eq!(
1030
            debug,
1031
            "ThreadPool { name: None, queued_count: 0, active_count: 0, max_count: 4 }"
1032
        );
1033
1034
        let pool = ThreadPool::with_name("hello".into(), 4);
1035
        let debug = format!("{:?}", pool);
1036
        assert_eq!(
1037
            debug,
1038
            "ThreadPool { name: Some(\"hello\"), queued_count: 0, active_count: 0, max_count: 4 }"
1039
        );
1040
1041
        let pool = ThreadPool::new(4);
1042
        pool.execute(move || sleep(Duration::from_secs(5)));
1043
        sleep(Duration::from_secs(1));
1044
        let debug = format!("{:?}", pool);
1045
        assert_eq!(
1046
            debug,
1047
            "ThreadPool { name: None, queued_count: 0, active_count: 1, max_count: 4 }"
1048
        );
1049
    }
1050
1051
    #[test]
1052
    fn test_repeate_join() {
1053
        let pool = ThreadPool::with_name("repeate join test".into(), 8);
1054
        let test_count = Arc::new(AtomicUsize::new(0));
1055
1056
        for _ in 0..42 {
1057
            let test_count = test_count.clone();
1058
            pool.execute(move || {
1059
                sleep(Duration::from_secs(2));
1060
                test_count.fetch_add(1, Ordering::Release);
1061
            });
1062
        }
1063
1064
        println!("{:?}", pool);
1065
        pool.join();
1066
        assert_eq!(42, test_count.load(Ordering::Acquire));
1067
1068
        for _ in 0..42 {
1069
            let test_count = test_count.clone();
1070
            pool.execute(move || {
1071
                sleep(Duration::from_secs(2));
1072
                test_count.fetch_add(1, Ordering::Relaxed);
1073
            });
1074
        }
1075
        pool.join();
1076
        assert_eq!(84, test_count.load(Ordering::Relaxed));
1077
    }
1078
1079
    #[test]
1080
    fn test_multi_join() {
1081
        use std::sync::mpsc::TryRecvError::*;
1082
1083
        // Toggle the following lines to debug the deadlock
1084
        fn error(_s: String) {
1085
            //use ::std::io::Write;
1086
            //let stderr = ::std::io::stderr();
1087
            //let mut stderr = stderr.lock();
1088
            //stderr.write(&_s.as_bytes()).is_ok();
1089
        }
1090
1091
        let pool0 = ThreadPool::with_name("multi join pool0".into(), 4);
1092
        let pool1 = ThreadPool::with_name("multi join pool1".into(), 4);
1093
        let (tx, rx) = channel();
1094
1095
        for i in 0..8 {
1096
            let pool1 = pool1.clone();
1097
            let pool0_ = pool0.clone();
1098
            let tx = tx.clone();
1099
            pool0.execute(move || {
1100
                pool1.execute(move || {
1101
                    error(format!("p1: {} -=- {:?}\n", i, pool0_));
1102
                    pool0_.join();
1103
                    error(format!("p1: send({})\n", i));
1104
                    tx.send(i).expect("send i from pool1 -> main");
1105
                });
1106
                error(format!("p0: {}\n", i));
1107
            });
1108
        }
1109
        drop(tx);
1110
1111
        assert_eq!(rx.try_recv(), Err(Empty));
1112
        error(format!("{:?}\n{:?}\n", pool0, pool1));
1113
        pool0.join();
1114
        error(format!("pool0.join() complete =-= {:?}", pool1));
1115
        pool1.join();
1116
        error("pool1.join() complete\n".into());
1117
        assert_eq!(
1118
            rx.iter().fold(0, |acc, i| acc + i),
1119
            0 + 1 + 2 + 3 + 4 + 5 + 6 + 7
1120
        );
1121
    }
1122
1123
    #[test]
1124
    fn test_empty_pool() {
1125
        // Joining an empty pool must return imminently
1126
        let pool = ThreadPool::new(4);
1127
1128
        pool.join();
1129
1130
        assert!(true);
1131
    }
1132
1133
    #[test]
1134
    fn test_no_fun_or_joy() {
1135
        // What happens when you keep adding jobs after a join
1136
1137
        fn sleepy_function() {
1138
            sleep(Duration::from_secs(6));
1139
        }
1140
1141
        let pool = ThreadPool::with_name("no fun or joy".into(), 8);
1142
1143
        pool.execute(sleepy_function);
1144
1145
        let p_t = pool.clone();
1146
        thread::spawn(move || {
1147
            (0..23).map(|_| p_t.execute(sleepy_function)).count();
1148
        });
1149
1150
        pool.join();
1151
    }
1152
1153
    #[test]
1154
    fn test_clone() {
1155
        let pool = ThreadPool::with_name("clone example".into(), 2);
1156
1157
        // This batch of jobs will occupy the pool for some time
1158
        for _ in 0..6 {
1159
            pool.execute(move || {
1160
                sleep(Duration::from_secs(2));
1161
            });
1162
        }
1163
1164
        // The following jobs will be inserted into the pool in a random fashion
1165
        let t0 = {
1166
            let pool = pool.clone();
1167
            thread::spawn(move || {
1168
                // wait for the first batch of tasks to finish
1169
                pool.join();
1170
1171
                let (tx, rx) = channel();
1172
                for i in 0..42 {
1173
                    let tx = tx.clone();
1174
                    pool.execute(move || {
1175
                        tx.send(i).expect("channel will be waiting");
1176
                    });
1177
                }
1178
                drop(tx);
1179
                rx.iter()
1180
                    .fold(0, |accumulator, element| accumulator + element)
1181
            })
1182
        };
1183
        let t1 = {
1184
            let pool = pool.clone();
1185
            thread::spawn(move || {
1186
                // wait for the first batch of tasks to finish
1187
                pool.join();
1188
1189
                let (tx, rx) = channel();
1190
                for i in 1..12 {
1191
                    let tx = tx.clone();
1192
                    pool.execute(move || {
1193
                        tx.send(i).expect("channel will be waiting");
1194
                    });
1195
                }
1196
                drop(tx);
1197
                rx.iter()
1198
                    .fold(1, |accumulator, element| accumulator * element)
1199
            })
1200
        };
1201
1202
        assert_eq!(
1203
            861,
1204
            t0.join()
1205
                .expect("thread 0 will return after calculating additions",)
1206
        );
1207
        assert_eq!(
1208
            39916800,
1209
            t1.join()
1210
                .expect("thread 1 will return after calculating multiplications",)
1211
        );
1212
    }
1213
1214
    #[test]
1215
    fn test_sync_shared_data() {
1216
        fn assert_sync<T: Sync>() {}
1217
        assert_sync::<super::ThreadPoolSharedData>();
1218
    }
1219
1220
    #[test]
1221
    fn test_send_shared_data() {
1222
        fn assert_send<T: Send>() {}
1223
        assert_send::<super::ThreadPoolSharedData>();
1224
    }
1225
1226
    #[test]
1227
    fn test_send() {
1228
        fn assert_send<T: Send>() {}
1229
        assert_send::<ThreadPool>();
1230
    }
1231
1232
    #[test]
1233
    fn test_cloned_eq() {
1234
        let a = ThreadPool::new(2);
1235
1236
        assert_eq!(a, a.clone());
1237
    }
1238
1239
    #[test]
1240
    /// The scenario is joining threads should not be stuck once their wave
1241
    /// of joins has completed. So once one thread joining on a pool has
1242
    /// succeded other threads joining on the same pool must get out even if
1243
    /// the thread is used for other jobs while the first group is finishing
1244
    /// their join
1245
    ///
1246
    /// In this example this means the waiting threads will exit the join in
1247
    /// groups of four because the waiter pool has four workers.
1248
    fn test_join_wavesurfer() {
1249
        let n_cycles = 4;
1250
        let n_workers = 4;
1251
        let (tx, rx) = channel();
1252
        let builder = Builder::new()
1253
            .num_threads(n_workers)
1254
            .thread_name("join wavesurfer".into());
1255
        let p_waiter = builder.clone().build();
1256
        let p_clock = builder.build();
1257
1258
        let barrier = Arc::new(Barrier::new(3));
1259
        let wave_clock = Arc::new(AtomicUsize::new(0));
1260
        let clock_thread = {
1261
            let barrier = barrier.clone();
1262
            let wave_clock = wave_clock.clone();
1263
            thread::spawn(move || {
1264
                barrier.wait();
1265
                for wave_num in 0..n_cycles {
1266
                    wave_clock.store(wave_num, Ordering::SeqCst);
1267
                    sleep(Duration::from_secs(1));
1268
                }
1269
            })
1270
        };
1271
1272
        {
1273
            let barrier = barrier.clone();
1274
            p_clock.execute(move || {
1275
                barrier.wait();
1276
                // this sleep is for stabilisation on weaker platforms
1277
                sleep(Duration::from_millis(100));
1278
            });
1279
        }
1280
1281
        // prepare three waves of jobs
1282
        for i in 0..3 * n_workers {
1283
            let p_clock = p_clock.clone();
1284
            let tx = tx.clone();
1285
            let wave_clock = wave_clock.clone();
1286
            p_waiter.execute(move || {
1287
                let now = wave_clock.load(Ordering::SeqCst);
1288
                p_clock.join();
1289
                // submit jobs for the second wave
1290
                p_clock.execute(|| sleep(Duration::from_secs(1)));
1291
                let clock = wave_clock.load(Ordering::SeqCst);
1292
                tx.send((now, clock, i)).unwrap();
1293
            });
1294
        }
1295
        println!("all scheduled at {}", wave_clock.load(Ordering::SeqCst));
1296
        barrier.wait();
1297
1298
        p_clock.join();
1299
        //p_waiter.join();
1300
1301
        drop(tx);
1302
        let mut hist = vec![0; n_cycles];
1303
        let mut data = vec![];
1304
        for (now, after, i) in rx.iter() {
1305
            let mut dur = after - now;
1306
            if dur >= n_cycles - 1 {
1307
                dur = n_cycles - 1;
1308
            }
1309
            hist[dur] += 1;
1310
1311
            data.push((now, after, i));
1312
        }
1313
        for (i, n) in hist.iter().enumerate() {
1314
            println!(
1315
                "\t{}: {} {}",
1316
                i,
1317
                n,
1318
                &*(0..*n).fold("".to_owned(), |s, _| s + "*")
1319
            );
1320
        }
1321
        assert!(data.iter().all(|&(cycle, stop, i)| if i < n_workers {
1322
            cycle == stop
1323
        } else {
1324
            cycle < stop
1325
        }));
1326
1327
        clock_thread.join().unwrap();
1328
    }
1329
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typenum-1.17.0/src/array.rs
Line
Count
Source
1
//! A type-level array of type-level numbers.
2
//!
3
//! It is not very featureful right now, and should be considered a work in progress.
4
5
use core::ops::{Add, Div, Mul, Sub};
6
7
use super::*;
8
9
/// The terminating type for type arrays.
10
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
11
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
12
pub struct ATerm;
13
14
impl TypeArray for ATerm {}
15
16
/// `TArr` is a type that acts as an array of types. It is defined similarly to `UInt`, only its
17
/// values can be more than bits, and it is designed to act as an array. So you can only add two if
18
/// they have the same number of elements, for example.
19
///
20
/// This array is only really designed to contain `Integer` types. If you use it with others, you
21
/// may find it lacking functionality.
22
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
23
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
24
pub struct TArr<V, A> {
25
    first: V,
26
    rest: A,
27
}
28
29
impl<V, A> TypeArray for TArr<V, A> {}
30
31
/// Create a new type-level array. Only usable on Rust 1.13.0 or newer.
32
///
33
/// There's not a whole lot you can do with it right now.
34
///
35
/// # Example
36
/// ```rust
37
/// #[macro_use]
38
/// extern crate typenum;
39
/// use typenum::consts::*;
40
///
41
/// type Array = tarr![P3, N4, Z0, P38];
42
/// # fn main() { let _: Array; }
43
#[macro_export]
44
macro_rules! tarr {
45
    () => ( $crate::ATerm );
46
    ($n:ty) => ( $crate::TArr<$n, $crate::ATerm> );
47
    ($n:ty,) => ( $crate::TArr<$n, $crate::ATerm> );
48
    ($n:ty, $($tail:ty),+) => ( $crate::TArr<$n, tarr![$($tail),+]> );
49
    ($n:ty, $($tail:ty),+,) => ( $crate::TArr<$n, tarr![$($tail),+]> );
50
}
51
52
// ---------------------------------------------------------------------------------------
53
// Length
54
55
/// Length of `ATerm` by itself is 0
56
impl Len for ATerm {
57
    type Output = U0;
58
    #[inline]
59
0
    fn len(&self) -> Self::Output {
60
0
        UTerm
61
0
    }
62
}
63
64
/// Size of a `TypeArray`
65
impl<V, A> Len for TArr<V, A>
66
where
67
    A: Len,
68
    Length<A>: Add<B1>,
69
    Sum<Length<A>, B1>: Unsigned,
70
{
71
    type Output = Add1<Length<A>>;
72
    #[inline]
73
0
    fn len(&self) -> Self::Output {
74
0
        self.rest.len() + B1
75
0
    }
76
}
77
78
// ---------------------------------------------------------------------------------------
79
// Add arrays
80
// Note that two arrays are only addable if they are the same length.
81
82
impl Add<ATerm> for ATerm {
83
    type Output = ATerm;
84
    #[inline]
85
0
    fn add(self, _: ATerm) -> Self::Output {
86
0
        ATerm
87
0
    }
88
}
89
90
impl<Al, Vl, Ar, Vr> Add<TArr<Vr, Ar>> for TArr<Vl, Al>
91
where
92
    Al: Add<Ar>,
93
    Vl: Add<Vr>,
94
{
95
    type Output = TArr<Sum<Vl, Vr>, Sum<Al, Ar>>;
96
    #[inline]
97
0
    fn add(self, rhs: TArr<Vr, Ar>) -> Self::Output {
98
0
        TArr {
99
0
            first: self.first + rhs.first,
100
0
            rest: self.rest + rhs.rest,
101
0
        }
102
0
    }
103
}
104
105
// ---------------------------------------------------------------------------------------
106
// Subtract arrays
107
// Note that two arrays are only subtractable if they are the same length.
108
109
impl Sub<ATerm> for ATerm {
110
    type Output = ATerm;
111
    #[inline]
112
0
    fn sub(self, _: ATerm) -> Self::Output {
113
0
        ATerm
114
0
    }
115
}
116
117
impl<Vl, Al, Vr, Ar> Sub<TArr<Vr, Ar>> for TArr<Vl, Al>
118
where
119
    Vl: Sub<Vr>,
120
    Al: Sub<Ar>,
121
{
122
    type Output = TArr<Diff<Vl, Vr>, Diff<Al, Ar>>;
123
    #[inline]
124
0
    fn sub(self, rhs: TArr<Vr, Ar>) -> Self::Output {
125
0
        TArr {
126
0
            first: self.first - rhs.first,
127
0
            rest: self.rest - rhs.rest,
128
0
        }
129
0
    }
130
}
131
132
// ---------------------------------------------------------------------------------------
133
// Multiply an array by a scalar
134
135
impl<Rhs> Mul<Rhs> for ATerm {
136
    type Output = ATerm;
137
    #[inline]
138
0
    fn mul(self, _: Rhs) -> Self::Output {
139
0
        ATerm
140
0
    }
141
}
142
143
impl<V, A, Rhs> Mul<Rhs> for TArr<V, A>
144
where
145
    V: Mul<Rhs>,
146
    A: Mul<Rhs>,
147
    Rhs: Copy,
148
{
149
    type Output = TArr<Prod<V, Rhs>, Prod<A, Rhs>>;
150
    #[inline]
151
0
    fn mul(self, rhs: Rhs) -> Self::Output {
152
0
        TArr {
153
0
            first: self.first * rhs,
154
0
            rest: self.rest * rhs,
155
0
        }
156
0
    }
157
}
158
159
impl Mul<ATerm> for Z0 {
160
    type Output = ATerm;
161
    #[inline]
162
0
    fn mul(self, _: ATerm) -> Self::Output {
163
0
        ATerm
164
0
    }
165
}
166
167
impl<U> Mul<ATerm> for PInt<U>
168
where
169
    U: Unsigned + NonZero,
170
{
171
    type Output = ATerm;
172
    #[inline]
173
0
    fn mul(self, _: ATerm) -> Self::Output {
174
0
        ATerm
175
0
    }
176
}
177
178
impl<U> Mul<ATerm> for NInt<U>
179
where
180
    U: Unsigned + NonZero,
181
{
182
    type Output = ATerm;
183
    #[inline]
184
0
    fn mul(self, _: ATerm) -> Self::Output {
185
0
        ATerm
186
0
    }
187
}
188
189
impl<V, A> Mul<TArr<V, A>> for Z0
190
where
191
    Z0: Mul<A>,
192
{
193
    type Output = TArr<Z0, Prod<Z0, A>>;
194
    #[inline]
195
0
    fn mul(self, rhs: TArr<V, A>) -> Self::Output {
196
0
        TArr {
197
0
            first: Z0,
198
0
            rest: self * rhs.rest,
199
0
        }
200
0
    }
201
}
202
203
impl<V, A, U> Mul<TArr<V, A>> for PInt<U>
204
where
205
    U: Unsigned + NonZero,
206
    PInt<U>: Mul<A> + Mul<V>,
207
{
208
    type Output = TArr<Prod<PInt<U>, V>, Prod<PInt<U>, A>>;
209
    #[inline]
210
0
    fn mul(self, rhs: TArr<V, A>) -> Self::Output {
211
0
        TArr {
212
0
            first: self * rhs.first,
213
0
            rest: self * rhs.rest,
214
0
        }
215
0
    }
216
}
217
218
impl<V, A, U> Mul<TArr<V, A>> for NInt<U>
219
where
220
    U: Unsigned + NonZero,
221
    NInt<U>: Mul<A> + Mul<V>,
222
{
223
    type Output = TArr<Prod<NInt<U>, V>, Prod<NInt<U>, A>>;
224
    #[inline]
225
0
    fn mul(self, rhs: TArr<V, A>) -> Self::Output {
226
0
        TArr {
227
0
            first: self * rhs.first,
228
0
            rest: self * rhs.rest,
229
0
        }
230
0
    }
231
}
232
233
// ---------------------------------------------------------------------------------------
234
// Divide an array by a scalar
235
236
impl<Rhs> Div<Rhs> for ATerm {
237
    type Output = ATerm;
238
    #[inline]
239
0
    fn div(self, _: Rhs) -> Self::Output {
240
0
        ATerm
241
0
    }
242
}
243
244
impl<V, A, Rhs> Div<Rhs> for TArr<V, A>
245
where
246
    V: Div<Rhs>,
247
    A: Div<Rhs>,
248
    Rhs: Copy,
249
{
250
    type Output = TArr<Quot<V, Rhs>, Quot<A, Rhs>>;
251
    #[inline]
252
0
    fn div(self, rhs: Rhs) -> Self::Output {
253
0
        TArr {
254
0
            first: self.first / rhs,
255
0
            rest: self.rest / rhs,
256
0
        }
257
0
    }
258
}
259
260
// ---------------------------------------------------------------------------------------
261
// Partial Divide an array by a scalar
262
263
impl<Rhs> PartialDiv<Rhs> for ATerm {
264
    type Output = ATerm;
265
    #[inline]
266
0
    fn partial_div(self, _: Rhs) -> Self::Output {
267
0
        ATerm
268
0
    }
269
}
270
271
impl<V, A, Rhs> PartialDiv<Rhs> for TArr<V, A>
272
where
273
    V: PartialDiv<Rhs>,
274
    A: PartialDiv<Rhs>,
275
    Rhs: Copy,
276
{
277
    type Output = TArr<PartialQuot<V, Rhs>, PartialQuot<A, Rhs>>;
278
    #[inline]
279
0
    fn partial_div(self, rhs: Rhs) -> Self::Output {
280
0
        TArr {
281
0
            first: self.first.partial_div(rhs),
282
0
            rest: self.rest.partial_div(rhs),
283
0
        }
284
0
    }
285
}
286
287
// ---------------------------------------------------------------------------------------
288
// Modulo an array by a scalar
289
use core::ops::Rem;
290
291
impl<Rhs> Rem<Rhs> for ATerm {
292
    type Output = ATerm;
293
    #[inline]
294
0
    fn rem(self, _: Rhs) -> Self::Output {
295
0
        ATerm
296
0
    }
297
}
298
299
impl<V, A, Rhs> Rem<Rhs> for TArr<V, A>
300
where
301
    V: Rem<Rhs>,
302
    A: Rem<Rhs>,
303
    Rhs: Copy,
304
{
305
    type Output = TArr<Mod<V, Rhs>, Mod<A, Rhs>>;
306
    #[inline]
307
0
    fn rem(self, rhs: Rhs) -> Self::Output {
308
0
        TArr {
309
0
            first: self.first % rhs,
310
0
            rest: self.rest % rhs,
311
0
        }
312
0
    }
313
}
314
315
// ---------------------------------------------------------------------------------------
316
// Negate an array
317
use core::ops::Neg;
318
319
impl Neg for ATerm {
320
    type Output = ATerm;
321
    #[inline]
322
0
    fn neg(self) -> Self::Output {
323
0
        ATerm
324
0
    }
325
}
326
327
impl<V, A> Neg for TArr<V, A>
328
where
329
    V: Neg,
330
    A: Neg,
331
{
332
    type Output = TArr<Negate<V>, Negate<A>>;
333
    #[inline]
334
0
    fn neg(self) -> Self::Output {
335
0
        TArr {
336
0
            first: -self.first,
337
0
            rest: -self.rest,
338
0
        }
339
0
    }
340
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typenum-1.17.0/src/bit.rs
Line
Count
Source
1
//! Type-level bits.
2
//!
3
//! These are rather simple and are used as the building blocks of the
4
//! other number types in this crate.
5
//!
6
//!
7
//! **Type operators** implemented:
8
//!
9
//! - From `core::ops`: `BitAnd`, `BitOr`, `BitXor`, and `Not`.
10
//! - From `typenum`: `Same` and `Cmp`.
11
12
use crate::{private::InternalMarker, Cmp, Equal, Greater, Less, NonZero, PowerOfTwo, Zero};
13
use core::ops::{BitAnd, BitOr, BitXor, Not};
14
15
pub use crate::marker_traits::Bit;
16
17
/// The type-level bit 0.
18
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
19
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
20
pub struct B0;
21
22
impl B0 {
23
    /// Instantiates a singleton representing this bit.
24
    #[inline]
25
0
    pub fn new() -> B0 {
26
0
        B0
27
0
    }
28
}
29
30
/// The type-level bit 1.
31
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
32
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
33
pub struct B1;
34
35
impl B1 {
36
    /// Instantiates a singleton representing this bit.
37
    #[inline]
38
0
    pub fn new() -> B1 {
39
0
        B1
40
0
    }
41
}
42
43
impl Bit for B0 {
44
    const U8: u8 = 0;
45
    const BOOL: bool = false;
46
47
    #[inline]
48
0
    fn new() -> Self {
49
0
        Self
50
0
    }
51
    #[inline]
52
24.5k
    fn to_u8() -> u8 {
53
24.5k
        0
54
24.5k
    }
Unexecuted instantiation: _RNvXs0_NtCs5VhUk8EIQ63_7typenum3bitNtB5_2B0NtNtB7_13marker_traits3Bit5to_u8Cs568wuOlRYFZ_8chia_bls
_RNvXs0_NtCs5VhUk8EIQ63_7typenum3bitNtB5_2B0NtNtB7_13marker_traits3Bit5to_u8Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
52
18.2k
    fn to_u8() -> u8 {
53
18.2k
        0
54
18.2k
    }
_RNvXs0_NtCs5VhUk8EIQ63_7typenum3bitNtB5_2B0NtNtB7_13marker_traits3Bit5to_u8CsjewTDwKBbyD_4k256
Line
Count
Source
52
6.31k
    fn to_u8() -> u8 {
53
6.31k
        0
54
6.31k
    }
Unexecuted instantiation: _RNvXs0_NtCs5VhUk8EIQ63_7typenum3bitNtB5_2B0NtNtB7_13marker_traits3Bit5to_u8B7_
55
    #[inline]
56
0
    fn to_bool() -> bool {
57
0
        false
58
0
    }
59
}
60
61
impl Bit for B1 {
62
    const U8: u8 = 1;
63
    const BOOL: bool = true;
64
65
    #[inline]
66
0
    fn new() -> Self {
67
0
        Self
68
0
    }
69
    #[inline]
70
4.90k
    fn to_u8() -> u8 {
71
4.90k
        1
72
4.90k
    }
Unexecuted instantiation: _RNvXs1_NtCs5VhUk8EIQ63_7typenum3bitNtB5_2B1NtNtB7_13marker_traits3Bit5to_u8Cs568wuOlRYFZ_8chia_bls
_RNvXs1_NtCs5VhUk8EIQ63_7typenum3bitNtB5_2B1NtNtB7_13marker_traits3Bit5to_u8Cs4RkbDk9WRL5_5clvmr
Line
Count
Source
70
3.64k
    fn to_u8() -> u8 {
71
3.64k
        1
72
3.64k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum3bitNtB5_2B1NtNtB7_13marker_traits3Bit5to_u8CsjewTDwKBbyD_4k256
Line
Count
Source
70
1.26k
    fn to_u8() -> u8 {
71
1.26k
        1
72
1.26k
    }
Unexecuted instantiation: _RNvXs1_NtCs5VhUk8EIQ63_7typenum3bitNtB5_2B1NtNtB7_13marker_traits3Bit5to_u8B7_
73
    #[inline]
74
0
    fn to_bool() -> bool {
75
0
        true
76
0
    }
77
}
78
79
impl Zero for B0 {}
80
impl NonZero for B1 {}
81
impl PowerOfTwo for B1 {}
82
83
/// Not of 0 (!0 = 1)
84
impl Not for B0 {
85
    type Output = B1;
86
    #[inline]
87
0
    fn not(self) -> Self::Output {
88
0
        B1
89
0
    }
90
}
91
/// Not of 1 (!1 = 0)
92
impl Not for B1 {
93
    type Output = B0;
94
    #[inline]
95
0
    fn not(self) -> Self::Output {
96
0
        B0
97
0
    }
98
}
99
100
/// And with 0 ( 0 & B = 0)
101
impl<Rhs: Bit> BitAnd<Rhs> for B0 {
102
    type Output = B0;
103
    #[inline]
104
0
    fn bitand(self, _: Rhs) -> Self::Output {
105
0
        B0
106
0
    }
107
}
108
109
/// And with 1 ( 1 & 0 = 0)
110
impl BitAnd<B0> for B1 {
111
    type Output = B0;
112
    #[inline]
113
0
    fn bitand(self, _: B0) -> Self::Output {
114
0
        B0
115
0
    }
116
}
117
118
/// And with 1 ( 1 & 1 = 1)
119
impl BitAnd<B1> for B1 {
120
    type Output = B1;
121
    #[inline]
122
0
    fn bitand(self, _: B1) -> Self::Output {
123
0
        B1
124
0
    }
125
}
126
127
/// Or with 0 ( 0 | 0 = 0)
128
impl BitOr<B0> for B0 {
129
    type Output = B0;
130
    #[inline]
131
0
    fn bitor(self, _: B0) -> Self::Output {
132
0
        B0
133
0
    }
134
}
135
136
/// Or with 0 ( 0 | 1 = 1)
137
impl BitOr<B1> for B0 {
138
    type Output = B1;
139
    #[inline]
140
0
    fn bitor(self, _: B1) -> Self::Output {
141
0
        B1
142
0
    }
143
}
144
145
/// Or with 1 ( 1 | B = 1)
146
impl<Rhs: Bit> BitOr<Rhs> for B1 {
147
    type Output = B1;
148
    #[inline]
149
0
    fn bitor(self, _: Rhs) -> Self::Output {
150
0
        B1
151
0
    }
152
}
153
154
/// Xor between 0 and 0 ( 0 ^ 0 = 0)
155
impl BitXor<B0> for B0 {
156
    type Output = B0;
157
    #[inline]
158
0
    fn bitxor(self, _: B0) -> Self::Output {
159
0
        B0
160
0
    }
161
}
162
/// Xor between 1 and 0 ( 1 ^ 0 = 1)
163
impl BitXor<B0> for B1 {
164
    type Output = B1;
165
    #[inline]
166
0
    fn bitxor(self, _: B0) -> Self::Output {
167
0
        B1
168
0
    }
169
}
170
/// Xor between 0 and 1 ( 0 ^ 1 = 1)
171
impl BitXor<B1> for B0 {
172
    type Output = B1;
173
    #[inline]
174
0
    fn bitxor(self, _: B1) -> Self::Output {
175
0
        B1
176
0
    }
177
}
178
/// Xor between 1 and 1 ( 1 ^ 1 = 0)
179
impl BitXor<B1> for B1 {
180
    type Output = B0;
181
    #[inline]
182
0
    fn bitxor(self, _: B1) -> Self::Output {
183
0
        B0
184
0
    }
185
}
186
187
#[cfg(tests)]
188
mod tests {
189
    // macro for testing operation results. Uses `Same` to ensure the types are equal and
190
    // not just the values they evaluate to.
191
    macro_rules! test_bit_op {
192
        ($op:ident $Lhs:ident = $Answer:ident) => {{
193
            type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
194
            assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
195
        }};
196
        ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => {{
197
            type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
198
            assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
199
        }};
200
    }
201
202
    #[test]
203
    fn bit_operations() {
204
        test_bit_op!(Not B0 = B1);
205
        test_bit_op!(Not B1 = B0);
206
207
        test_bit_op!(B0 BitAnd B0 = B0);
208
        test_bit_op!(B0 BitAnd B1 = B0);
209
        test_bit_op!(B1 BitAnd B0 = B0);
210
        test_bit_op!(B1 BitAnd B1 = B1);
211
212
        test_bit_op!(B0 BitOr B0 = B0);
213
        test_bit_op!(B0 BitOr B1 = B1);
214
        test_bit_op!(B1 BitOr B0 = B1);
215
        test_bit_op!(B1 BitOr B1 = B1);
216
217
        test_bit_op!(B0 BitXor B0 = B0);
218
        test_bit_op!(B0 BitXor B1 = B1);
219
        test_bit_op!(B1 BitXor B0 = B1);
220
        test_bit_op!(B1 BitXor B1 = B0);
221
    }
222
}
223
224
impl Cmp<B0> for B0 {
225
    type Output = Equal;
226
227
    #[inline]
228
0
    fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
229
0
        Equal
230
0
    }
231
}
232
233
impl Cmp<B1> for B0 {
234
    type Output = Less;
235
236
    #[inline]
237
0
    fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
238
0
        Less
239
0
    }
240
}
241
242
impl Cmp<B0> for B1 {
243
    type Output = Greater;
244
245
    #[inline]
246
0
    fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
247
0
        Greater
248
0
    }
249
}
250
251
impl Cmp<B1> for B1 {
252
    type Output = Equal;
253
254
    #[inline]
255
0
    fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
256
0
        Equal
257
0
    }
258
}
259
260
use crate::Min;
261
impl Min<B0> for B0 {
262
    type Output = B0;
263
    #[inline]
264
0
    fn min(self, _: B0) -> B0 {
265
0
        self
266
0
    }
267
}
268
impl Min<B1> for B0 {
269
    type Output = B0;
270
    #[inline]
271
0
    fn min(self, _: B1) -> B0 {
272
0
        self
273
0
    }
274
}
275
impl Min<B0> for B1 {
276
    type Output = B0;
277
    #[inline]
278
0
    fn min(self, rhs: B0) -> B0 {
279
0
        rhs
280
0
    }
281
}
282
impl Min<B1> for B1 {
283
    type Output = B1;
284
    #[inline]
285
0
    fn min(self, _: B1) -> B1 {
286
0
        self
287
0
    }
288
}
289
290
use crate::Max;
291
impl Max<B0> for B0 {
292
    type Output = B0;
293
    #[inline]
294
0
    fn max(self, _: B0) -> B0 {
295
0
        self
296
0
    }
297
}
298
impl Max<B1> for B0 {
299
    type Output = B1;
300
    #[inline]
301
0
    fn max(self, rhs: B1) -> B1 {
302
0
        rhs
303
0
    }
304
}
305
impl Max<B0> for B1 {
306
    type Output = B1;
307
    #[inline]
308
0
    fn max(self, _: B0) -> B1 {
309
0
        self
310
0
    }
311
}
312
impl Max<B1> for B1 {
313
    type Output = B1;
314
    #[inline]
315
0
    fn max(self, _: B1) -> B1 {
316
0
        self
317
0
    }
318
}
319
320
#[cfg(test)]
321
mod tests {
322
    #[test]
323
    fn bit_creation() {
324
        {
325
            use crate::{B0, B1};
326
            let _: B0 = B0::new();
327
            let _: B1 = B1::new();
328
        }
329
330
        {
331
            use crate::{Bit, B0, B1};
332
333
            let _: B0 = <B0 as Bit>::new();
334
            let _: B1 = <B1 as Bit>::new();
335
        }
336
    }
337
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typenum-1.17.0/src/int.rs
Line
Count
Source
1
//! Type-level signed integers.
2
//!
3
//!
4
//! Type **operators** implemented:
5
//!
6
//! From `core::ops`: `Add`, `Sub`, `Mul`, `Div`, and `Rem`.
7
//! From `typenum`: `Same`, `Cmp`, and `Pow`.
8
//!
9
//! Rather than directly using the structs defined in this module, it is recommended that
10
//! you import and use the relevant aliases from the [consts](../consts/index.html) module.
11
//!
12
//! Note that operators that work on the underlying structure of the number are
13
//! intentionally not implemented. This is because this implementation of signed integers
14
//! does *not* use twos-complement, and implementing them would require making arbitrary
15
//! choices, causing the results of such operators to be difficult to reason about.
16
//!
17
//! # Example
18
//! ```rust
19
//! use std::ops::{Add, Div, Mul, Rem, Sub};
20
//! use typenum::{Integer, N3, P2};
21
//!
22
//! assert_eq!(<N3 as Add<P2>>::Output::to_i32(), -1);
23
//! assert_eq!(<N3 as Sub<P2>>::Output::to_i32(), -5);
24
//! assert_eq!(<N3 as Mul<P2>>::Output::to_i32(), -6);
25
//! assert_eq!(<N3 as Div<P2>>::Output::to_i32(), -1);
26
//! assert_eq!(<N3 as Rem<P2>>::Output::to_i32(), -1);
27
//! ```
28
29
pub use crate::marker_traits::Integer;
30
use crate::{
31
    bit::{Bit, B0, B1},
32
    consts::{N1, P1, U0, U1},
33
    private::{Internal, InternalMarker, PrivateDivInt, PrivateIntegerAdd, PrivateRem},
34
    uint::{UInt, Unsigned},
35
    Cmp, Equal, Greater, Less, NonZero, Pow, PowerOfTwo, ToInt, Zero,
36
};
37
use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
38
39
/// Type-level signed integers with positive sign.
40
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
41
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
42
pub struct PInt<U: Unsigned + NonZero> {
43
    pub(crate) n: U,
44
}
45
46
/// Type-level signed integers with negative sign.
47
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
48
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
49
pub struct NInt<U: Unsigned + NonZero> {
50
    pub(crate) n: U,
51
}
52
53
impl<U: Unsigned + NonZero> PInt<U> {
54
    /// Instantiates a singleton representing this strictly positive integer.
55
    #[inline]
56
0
    pub fn new() -> PInt<U> {
57
0
        PInt::default()
58
0
    }
59
}
60
61
impl<U: Unsigned + NonZero> NInt<U> {
62
    /// Instantiates a singleton representing this strictly negative integer.
63
    #[inline]
64
0
    pub fn new() -> NInt<U> {
65
0
        NInt::default()
66
0
    }
67
}
68
69
/// The type-level signed integer 0.
70
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
71
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
72
pub struct Z0;
73
74
impl Z0 {
75
    /// Instantiates a singleton representing the integer 0.
76
    #[inline]
77
0
    pub fn new() -> Z0 {
78
0
        Z0
79
0
    }
80
}
81
82
impl<U: Unsigned + NonZero> NonZero for PInt<U> {}
83
impl<U: Unsigned + NonZero> NonZero for NInt<U> {}
84
impl Zero for Z0 {}
85
86
impl<U: Unsigned + NonZero + PowerOfTwo> PowerOfTwo for PInt<U> {}
87
88
impl Integer for Z0 {
89
    const I8: i8 = 0;
90
    const I16: i16 = 0;
91
    const I32: i32 = 0;
92
    const I64: i64 = 0;
93
    #[cfg(feature = "i128")]
94
    const I128: i128 = 0;
95
    const ISIZE: isize = 0;
96
97
    #[inline]
98
0
    fn to_i8() -> i8 {
99
0
        0
100
0
    }
101
    #[inline]
102
0
    fn to_i16() -> i16 {
103
0
        0
104
0
    }
105
    #[inline]
106
0
    fn to_i32() -> i32 {
107
0
        0
108
0
    }
109
    #[inline]
110
0
    fn to_i64() -> i64 {
111
0
        0
112
0
    }
113
    #[cfg(feature = "i128")]
114
    #[inline]
115
    fn to_i128() -> i128 {
116
        0
117
    }
118
    #[inline]
119
0
    fn to_isize() -> isize {
120
0
        0
121
0
    }
122
}
123
124
impl<U: Unsigned + NonZero> Integer for PInt<U> {
125
    const I8: i8 = U::I8;
126
    const I16: i16 = U::I16;
127
    const I32: i32 = U::I32;
128
    const I64: i64 = U::I64;
129
    #[cfg(feature = "i128")]
130
    const I128: i128 = U::I128;
131
    const ISIZE: isize = U::ISIZE;
132
133
    #[inline]
134
0
    fn to_i8() -> i8 {
135
0
        <U as Unsigned>::to_i8()
136
0
    }
137
    #[inline]
138
0
    fn to_i16() -> i16 {
139
0
        <U as Unsigned>::to_i16()
140
0
    }
141
    #[inline]
142
0
    fn to_i32() -> i32 {
143
0
        <U as Unsigned>::to_i32()
144
0
    }
145
    #[inline]
146
0
    fn to_i64() -> i64 {
147
0
        <U as Unsigned>::to_i64()
148
0
    }
149
    #[cfg(feature = "i128")]
150
    #[inline]
151
    fn to_i128() -> i128 {
152
        <U as Unsigned>::to_i128()
153
    }
154
    #[inline]
155
0
    fn to_isize() -> isize {
156
0
        <U as Unsigned>::to_isize()
157
0
    }
158
}
159
160
// Simply negating the result of e.g. `U::I8` will result in overflow for `std::i8::MIN`. Instead,
161
// we use the fact that `U: NonZero` by subtracting one from the `U::U8` before negating.
162
impl<U: Unsigned + NonZero> Integer for NInt<U> {
163
    const I8: i8 = -((U::U8 - 1) as i8) - 1;
164
    const I16: i16 = -((U::U16 - 1) as i16) - 1;
165
    const I32: i32 = -((U::U32 - 1) as i32) - 1;
166
    const I64: i64 = -((U::U64 - 1) as i64) - 1;
167
    #[cfg(feature = "i128")]
168
    const I128: i128 = -((U::U128 - 1) as i128) - 1;
169
    const ISIZE: isize = -((U::USIZE - 1) as isize) - 1;
170
171
    #[inline]
172
0
    fn to_i8() -> i8 {
173
0
        Self::I8
174
0
    }
175
    #[inline]
176
0
    fn to_i16() -> i16 {
177
0
        Self::I16
178
0
    }
179
    #[inline]
180
0
    fn to_i32() -> i32 {
181
0
        Self::I32
182
0
    }
183
    #[inline]
184
0
    fn to_i64() -> i64 {
185
0
        Self::I64
186
0
    }
187
    #[cfg(feature = "i128")]
188
    #[inline]
189
    fn to_i128() -> i128 {
190
        Self::I128
191
    }
192
    #[inline]
193
0
    fn to_isize() -> isize {
194
0
        Self::ISIZE
195
0
    }
196
}
197
198
// ---------------------------------------------------------------------------------------
199
// Neg
200
201
/// `-Z0 = Z0`
202
impl Neg for Z0 {
203
    type Output = Z0;
204
    #[inline]
205
0
    fn neg(self) -> Self::Output {
206
0
        Z0
207
0
    }
208
}
209
210
/// `-PInt = NInt`
211
impl<U: Unsigned + NonZero> Neg for PInt<U> {
212
    type Output = NInt<U>;
213
    #[inline]
214
0
    fn neg(self) -> Self::Output {
215
0
        NInt::new()
216
0
    }
217
}
218
219
/// `-NInt = PInt`
220
impl<U: Unsigned + NonZero> Neg for NInt<U> {
221
    type Output = PInt<U>;
222
    #[inline]
223
0
    fn neg(self) -> Self::Output {
224
0
        PInt::new()
225
0
    }
226
}
227
228
// ---------------------------------------------------------------------------------------
229
// Add
230
231
/// `Z0 + I = I`
232
impl<I: Integer> Add<I> for Z0 {
233
    type Output = I;
234
    #[inline]
235
0
    fn add(self, rhs: I) -> Self::Output {
236
0
        rhs
237
0
    }
238
}
239
240
/// `PInt + Z0 = PInt`
241
impl<U: Unsigned + NonZero> Add<Z0> for PInt<U> {
242
    type Output = PInt<U>;
243
    #[inline]
244
0
    fn add(self, _: Z0) -> Self::Output {
245
0
        PInt::new()
246
0
    }
247
}
248
249
/// `NInt + Z0 = NInt`
250
impl<U: Unsigned + NonZero> Add<Z0> for NInt<U> {
251
    type Output = NInt<U>;
252
    #[inline]
253
0
    fn add(self, _: Z0) -> Self::Output {
254
0
        NInt::new()
255
0
    }
256
}
257
258
/// `P(Ul) + P(Ur) = P(Ul + Ur)`
259
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for PInt<Ul>
260
where
261
    Ul: Add<Ur>,
262
    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
263
{
264
    type Output = PInt<<Ul as Add<Ur>>::Output>;
265
    #[inline]
266
0
    fn add(self, _: PInt<Ur>) -> Self::Output {
267
0
        PInt::new()
268
0
    }
269
}
270
271
/// `N(Ul) + N(Ur) = N(Ul + Ur)`
272
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for NInt<Ul>
273
where
274
    Ul: Add<Ur>,
275
    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
276
{
277
    type Output = NInt<<Ul as Add<Ur>>::Output>;
278
    #[inline]
279
0
    fn add(self, _: NInt<Ur>) -> Self::Output {
280
0
        NInt::new()
281
0
    }
282
}
283
284
/// `P(Ul) + N(Ur)`: We resolve this with our `PrivateAdd`
285
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for PInt<Ul>
286
where
287
    Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
288
{
289
    type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
290
    #[inline]
291
0
    fn add(self, rhs: NInt<Ur>) -> Self::Output {
292
0
        let lhs = self.n;
293
0
        let rhs = rhs.n;
294
0
        let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs);
295
0
        lhs.private_integer_add(lhs_cmp_rhs, rhs)
296
0
    }
297
}
298
299
/// `N(Ul) + P(Ur)`: We resolve this with our `PrivateAdd`
300
// We just do the same thing as above, swapping Lhs and Rhs
301
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for NInt<Ul>
302
where
303
    Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
304
{
305
    type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
306
    #[inline]
307
0
    fn add(self, rhs: PInt<Ur>) -> Self::Output {
308
0
        let lhs = self.n;
309
0
        let rhs = rhs.n;
310
0
        let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs);
311
0
        rhs.private_integer_add(rhs_cmp_lhs, lhs)
312
0
    }
313
}
314
315
/// `P + N = 0` where `P == N`
316
impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Equal, N> for P {
317
    type Output = Z0;
318
319
    #[inline]
320
0
    fn private_integer_add(self, _: Equal, _: N) -> Self::Output {
321
0
        Z0
322
0
    }
323
}
324
325
/// `P + N = Positive` where `P > N`
326
impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Greater, N> for P
327
where
328
    P: Sub<N>,
329
    <P as Sub<N>>::Output: Unsigned + NonZero,
330
{
331
    type Output = PInt<<P as Sub<N>>::Output>;
332
333
    #[inline]
334
0
    fn private_integer_add(self, _: Greater, n: N) -> Self::Output {
335
0
        PInt { n: self - n }
336
0
    }
337
}
338
339
/// `P + N = Negative` where `P < N`
340
impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Less, N> for P
341
where
342
    N: Sub<P>,
343
    <N as Sub<P>>::Output: Unsigned + NonZero,
344
{
345
    type Output = NInt<<N as Sub<P>>::Output>;
346
347
    #[inline]
348
0
    fn private_integer_add(self, _: Less, n: N) -> Self::Output {
349
0
        NInt { n: n - self }
350
0
    }
351
}
352
353
// ---------------------------------------------------------------------------------------
354
// Sub
355
356
/// `Z0 - Z0 = Z0`
357
impl Sub<Z0> for Z0 {
358
    type Output = Z0;
359
    #[inline]
360
0
    fn sub(self, _: Z0) -> Self::Output {
361
0
        Z0
362
0
    }
363
}
364
365
/// `Z0 - P = N`
366
impl<U: Unsigned + NonZero> Sub<PInt<U>> for Z0 {
367
    type Output = NInt<U>;
368
    #[inline]
369
0
    fn sub(self, _: PInt<U>) -> Self::Output {
370
0
        NInt::new()
371
0
    }
372
}
373
374
/// `Z0 - N = P`
375
impl<U: Unsigned + NonZero> Sub<NInt<U>> for Z0 {
376
    type Output = PInt<U>;
377
    #[inline]
378
0
    fn sub(self, _: NInt<U>) -> Self::Output {
379
0
        PInt::new()
380
0
    }
381
}
382
383
/// `PInt - Z0 = PInt`
384
impl<U: Unsigned + NonZero> Sub<Z0> for PInt<U> {
385
    type Output = PInt<U>;
386
    #[inline]
387
0
    fn sub(self, _: Z0) -> Self::Output {
388
0
        PInt::new()
389
0
    }
390
}
391
392
/// `NInt - Z0 = NInt`
393
impl<U: Unsigned + NonZero> Sub<Z0> for NInt<U> {
394
    type Output = NInt<U>;
395
    #[inline]
396
0
    fn sub(self, _: Z0) -> Self::Output {
397
0
        NInt::new()
398
0
    }
399
}
400
401
/// `P(Ul) - N(Ur) = P(Ul + Ur)`
402
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for PInt<Ul>
403
where
404
    Ul: Add<Ur>,
405
    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
406
{
407
    type Output = PInt<<Ul as Add<Ur>>::Output>;
408
    #[inline]
409
0
    fn sub(self, _: NInt<Ur>) -> Self::Output {
410
0
        PInt::new()
411
0
    }
412
}
413
414
/// `N(Ul) - P(Ur) = N(Ul + Ur)`
415
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for NInt<Ul>
416
where
417
    Ul: Add<Ur>,
418
    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
419
{
420
    type Output = NInt<<Ul as Add<Ur>>::Output>;
421
    #[inline]
422
0
    fn sub(self, _: PInt<Ur>) -> Self::Output {
423
0
        NInt::new()
424
0
    }
425
}
426
427
/// `P(Ul) - P(Ur)`: We resolve this with our `PrivateAdd`
428
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for PInt<Ul>
429
where
430
    Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
431
{
432
    type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
433
    #[inline]
434
0
    fn sub(self, rhs: PInt<Ur>) -> Self::Output {
435
0
        let lhs = self.n;
436
0
        let rhs = rhs.n;
437
0
        let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs);
438
0
        lhs.private_integer_add(lhs_cmp_rhs, rhs)
439
0
    }
440
}
441
442
/// `N(Ul) - N(Ur)`: We resolve this with our `PrivateAdd`
443
// We just do the same thing as above, swapping Lhs and Rhs
444
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for NInt<Ul>
445
where
446
    Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
447
{
448
    type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
449
    #[inline]
450
0
    fn sub(self, rhs: NInt<Ur>) -> Self::Output {
451
0
        let lhs = self.n;
452
0
        let rhs = rhs.n;
453
0
        let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs);
454
0
        rhs.private_integer_add(rhs_cmp_lhs, lhs)
455
0
    }
456
}
457
458
// ---------------------------------------------------------------------------------------
459
// Mul
460
461
/// `Z0 * I = Z0`
462
impl<I: Integer> Mul<I> for Z0 {
463
    type Output = Z0;
464
    #[inline]
465
0
    fn mul(self, _: I) -> Self::Output {
466
0
        Z0
467
0
    }
468
}
469
470
/// `P * Z0 = Z0`
471
impl<U: Unsigned + NonZero> Mul<Z0> for PInt<U> {
472
    type Output = Z0;
473
    #[inline]
474
0
    fn mul(self, _: Z0) -> Self::Output {
475
0
        Z0
476
0
    }
477
}
478
479
/// `N * Z0 = Z0`
480
impl<U: Unsigned + NonZero> Mul<Z0> for NInt<U> {
481
    type Output = Z0;
482
    #[inline]
483
0
    fn mul(self, _: Z0) -> Self::Output {
484
0
        Z0
485
0
    }
486
}
487
488
/// P(Ul) * P(Ur) = P(Ul * Ur)
489
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for PInt<Ul>
490
where
491
    Ul: Mul<Ur>,
492
    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
493
{
494
    type Output = PInt<<Ul as Mul<Ur>>::Output>;
495
    #[inline]
496
0
    fn mul(self, _: PInt<Ur>) -> Self::Output {
497
0
        PInt::new()
498
0
    }
499
}
500
501
/// N(Ul) * N(Ur) = P(Ul * Ur)
502
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for NInt<Ul>
503
where
504
    Ul: Mul<Ur>,
505
    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
506
{
507
    type Output = PInt<<Ul as Mul<Ur>>::Output>;
508
    #[inline]
509
0
    fn mul(self, _: NInt<Ur>) -> Self::Output {
510
0
        PInt::new()
511
0
    }
512
}
513
514
/// P(Ul) * N(Ur) = N(Ul * Ur)
515
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for PInt<Ul>
516
where
517
    Ul: Mul<Ur>,
518
    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
519
{
520
    type Output = NInt<<Ul as Mul<Ur>>::Output>;
521
    #[inline]
522
0
    fn mul(self, _: NInt<Ur>) -> Self::Output {
523
0
        NInt::new()
524
0
    }
525
}
526
527
/// N(Ul) * P(Ur) = N(Ul * Ur)
528
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for NInt<Ul>
529
where
530
    Ul: Mul<Ur>,
531
    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
532
{
533
    type Output = NInt<<Ul as Mul<Ur>>::Output>;
534
    #[inline]
535
0
    fn mul(self, _: PInt<Ur>) -> Self::Output {
536
0
        NInt::new()
537
0
    }
538
}
539
540
// ---------------------------------------------------------------------------------------
541
// Div
542
543
/// `Z0 / I = Z0` where `I != 0`
544
impl<I: Integer + NonZero> Div<I> for Z0 {
545
    type Output = Z0;
546
    #[inline]
547
0
    fn div(self, _: I) -> Self::Output {
548
0
        Z0
549
0
    }
550
}
551
552
macro_rules! impl_int_div {
553
    ($A:ident, $B:ident, $R:ident) => {
554
        /// `$A<Ul> / $B<Ur> = $R<Ul / Ur>`
555
        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Div<$B<Ur>> for $A<Ul>
556
        where
557
            Ul: Cmp<Ur>,
558
            $A<Ul>: PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>,
559
        {
560
            type Output = <$A<Ul> as PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>>::Output;
561
            #[inline]
562
0
            fn div(self, rhs: $B<Ur>) -> Self::Output {
563
0
                let lhs_cmp_rhs = self.n.compare::<Internal>(&rhs.n);
564
0
                self.private_div_int(lhs_cmp_rhs, rhs)
565
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints25_0ppEINtB5_4PIntpEINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivIBG_pEE3divB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints29_0ppEINtB5_4PIntpEINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivINtB5_4NIntpEE3divB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2d_0ppEINtB5_4NIntpEINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivINtB5_4PIntpEE3divB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2h_0ppEINtB5_4NIntpEINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3DivIBG_pEE3divB7_
566
        }
567
        impl<Ul, Ur> PrivateDivInt<Less, $B<Ur>> for $A<Ul>
568
        where
569
            Ul: Unsigned + NonZero,
570
            Ur: Unsigned + NonZero,
571
        {
572
            type Output = Z0;
573
574
            #[inline]
575
0
            fn private_div_int(self, _: Less, _: $B<Ur>) -> Self::Output {
576
0
                Z0
577
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints26_0ppEINtB5_4PIntpEINtNtB7_7private13PrivateDivIntNtB7_4LessIBG_pEE15private_div_intB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2a_0ppEINtB5_4PIntpEINtNtB7_7private13PrivateDivIntNtB7_4LessINtB5_4NIntpEE15private_div_intB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2e_0ppEINtB5_4NIntpEINtNtB7_7private13PrivateDivIntNtB7_4LessINtB5_4PIntpEE15private_div_intB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2i_0ppEINtB5_4NIntpEINtNtB7_7private13PrivateDivIntNtB7_4LessIBG_pEE15private_div_intB7_
578
        }
579
        impl<Ul, Ur> PrivateDivInt<Equal, $B<Ur>> for $A<Ul>
580
        where
581
            Ul: Unsigned + NonZero,
582
            Ur: Unsigned + NonZero,
583
        {
584
            type Output = $R<U1>;
585
586
            #[inline]
587
0
            fn private_div_int(self, _: Equal, _: $B<Ur>) -> Self::Output {
588
0
                $R { n: U1::new() }
589
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints27_0ppEINtB5_4PIntpEINtNtB7_7private13PrivateDivIntNtB7_5EqualIBG_pEE15private_div_intB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2b_0ppEINtB5_4PIntpEINtNtB7_7private13PrivateDivIntNtB7_5EqualINtB5_4NIntpEE15private_div_intB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2f_0ppEINtB5_4NIntpEINtNtB7_7private13PrivateDivIntNtB7_5EqualINtB5_4PIntpEE15private_div_intB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2j_0ppEINtB5_4NIntpEINtNtB7_7private13PrivateDivIntNtB7_5EqualIBG_pEE15private_div_intB7_
590
        }
591
        impl<Ul, Ur> PrivateDivInt<Greater, $B<Ur>> for $A<Ul>
592
        where
593
            Ul: Unsigned + NonZero + Div<Ur>,
594
            Ur: Unsigned + NonZero,
595
            <Ul as Div<Ur>>::Output: Unsigned + NonZero,
596
        {
597
            type Output = $R<<Ul as Div<Ur>>::Output>;
598
599
            #[inline]
600
0
            fn private_div_int(self, _: Greater, d: $B<Ur>) -> Self::Output {
601
0
                $R { n: self.n / d.n }
602
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints28_0ppEINtB5_4PIntpEINtNtB7_7private13PrivateDivIntNtB7_7GreaterIBG_pEE15private_div_intB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2c_0ppEINtB5_4PIntpEINtNtB7_7private13PrivateDivIntNtB7_7GreaterINtB5_4NIntpEE15private_div_intB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2g_0ppEINtB5_4NIntpEINtNtB7_7private13PrivateDivIntNtB7_7GreaterINtB5_4PIntpEE15private_div_intB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2k_0ppEINtB5_4NIntpEINtNtB7_7private13PrivateDivIntNtB7_7GreaterIBG_pEE15private_div_intB7_
603
        }
604
    };
605
}
606
607
impl_int_div!(PInt, PInt, PInt);
608
impl_int_div!(PInt, NInt, NInt);
609
impl_int_div!(NInt, PInt, NInt);
610
impl_int_div!(NInt, NInt, PInt);
611
612
// ---------------------------------------------------------------------------------------
613
// PartialDiv
614
615
use crate::{PartialDiv, Quot};
616
617
impl<M, N> PartialDiv<N> for M
618
where
619
    M: Integer + Div<N> + Rem<N, Output = Z0>,
620
{
621
    type Output = Quot<M, N>;
622
    #[inline]
623
0
    fn partial_div(self, rhs: N) -> Self::Output {
624
0
        self / rhs
625
0
    }
626
}
627
628
// ---------------------------------------------------------------------------------------
629
// Cmp
630
631
/// 0 == 0
632
impl Cmp<Z0> for Z0 {
633
    type Output = Equal;
634
635
    #[inline]
636
0
    fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
637
0
        Equal
638
0
    }
639
}
640
641
/// 0 > -X
642
impl<U: Unsigned + NonZero> Cmp<NInt<U>> for Z0 {
643
    type Output = Greater;
644
645
    #[inline]
646
0
    fn compare<IM: InternalMarker>(&self, _: &NInt<U>) -> Self::Output {
647
0
        Greater
648
0
    }
649
}
650
651
/// 0 < X
652
impl<U: Unsigned + NonZero> Cmp<PInt<U>> for Z0 {
653
    type Output = Less;
654
655
    #[inline]
656
0
    fn compare<IM: InternalMarker>(&self, _: &PInt<U>) -> Self::Output {
657
0
        Less
658
0
    }
659
}
660
661
/// X > 0
662
impl<U: Unsigned + NonZero> Cmp<Z0> for PInt<U> {
663
    type Output = Greater;
664
665
    #[inline]
666
0
    fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
667
0
        Greater
668
0
    }
669
}
670
671
/// -X < 0
672
impl<U: Unsigned + NonZero> Cmp<Z0> for NInt<U> {
673
    type Output = Less;
674
675
    #[inline]
676
0
    fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
677
0
        Less
678
0
    }
679
}
680
681
/// -X < Y
682
impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<PInt<P>> for NInt<N> {
683
    type Output = Less;
684
685
    #[inline]
686
0
    fn compare<IM: InternalMarker>(&self, _: &PInt<P>) -> Self::Output {
687
0
        Less
688
0
    }
689
}
690
691
/// X > - Y
692
impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<NInt<N>> for PInt<P> {
693
    type Output = Greater;
694
695
    #[inline]
696
0
    fn compare<IM: InternalMarker>(&self, _: &NInt<N>) -> Self::Output {
697
0
        Greater
698
0
    }
699
}
700
701
/// X <==> Y
702
impl<Pl: Cmp<Pr> + Unsigned + NonZero, Pr: Unsigned + NonZero> Cmp<PInt<Pr>> for PInt<Pl> {
703
    type Output = <Pl as Cmp<Pr>>::Output;
704
705
    #[inline]
706
0
    fn compare<IM: InternalMarker>(&self, rhs: &PInt<Pr>) -> Self::Output {
707
0
        self.n.compare::<Internal>(&rhs.n)
708
0
    }
709
}
710
711
/// -X <==> -Y
712
impl<Nl: Unsigned + NonZero, Nr: Cmp<Nl> + Unsigned + NonZero> Cmp<NInt<Nr>> for NInt<Nl> {
713
    type Output = <Nr as Cmp<Nl>>::Output;
714
715
    #[inline]
716
0
    fn compare<IM: InternalMarker>(&self, rhs: &NInt<Nr>) -> Self::Output {
717
0
        rhs.n.compare::<Internal>(&self.n)
718
0
    }
719
}
720
721
// ---------------------------------------------------------------------------------------
722
// Rem
723
724
/// `Z0 % I = Z0` where `I != 0`
725
impl<I: Integer + NonZero> Rem<I> for Z0 {
726
    type Output = Z0;
727
    #[inline]
728
0
    fn rem(self, _: I) -> Self::Output {
729
0
        Z0
730
0
    }
731
}
732
733
macro_rules! impl_int_rem {
734
    ($A:ident, $B:ident, $R:ident) => {
735
        /// `$A<Ul> % $B<Ur> = $R<Ul % Ur>`
736
        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Rem<$B<Ur>> for $A<Ul>
737
        where
738
            Ul: Rem<Ur>,
739
            $A<Ul>: PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>,
740
        {
741
            type Output = <$A<Ul> as PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>>::Output;
742
            #[inline]
743
0
            fn rem(self, rhs: $B<Ur>) -> Self::Output {
744
0
                self.private_rem(self.n % rhs.n, rhs)
745
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2l_0ppEINtB5_4PIntpEINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemIBG_pEE3remB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2o_0ppEINtB5_4PIntpEINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemINtB5_4NIntpEE3remB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2r_0ppEINtB5_4NIntpEINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemINtB5_4PIntpEE3remB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2u_0ppEINtB5_4NIntpEINtNtNtCsbQ8arDwx5Xq_4core3ops5arith3RemIBG_pEE3remB7_
746
        }
747
        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> PrivateRem<U0, $B<Ur>> for $A<Ul> {
748
            type Output = Z0;
749
750
            #[inline]
751
0
            fn private_rem(self, _: U0, _: $B<Ur>) -> Self::Output {
752
0
                Z0
753
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2m_0ppEINtB5_4PIntpEINtNtB7_7private10PrivateRemNtNtB7_4uint5UTermIBG_pEE11private_remB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2p_0ppEINtB5_4PIntpEINtNtB7_7private10PrivateRemNtNtB7_4uint5UTermINtB5_4NIntpEE11private_remB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2s_0ppEINtB5_4NIntpEINtNtB7_7private10PrivateRemNtNtB7_4uint5UTermINtB5_4PIntpEE11private_remB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2v_0ppEINtB5_4NIntpEINtNtB7_7private10PrivateRemNtNtB7_4uint5UTermIBG_pEE11private_remB7_
754
        }
755
        impl<Ul, Ur, U, B> PrivateRem<UInt<U, B>, $B<Ur>> for $A<Ul>
756
        where
757
            Ul: Unsigned + NonZero,
758
            Ur: Unsigned + NonZero,
759
            U: Unsigned,
760
            B: Bit,
761
        {
762
            type Output = $R<UInt<U, B>>;
763
764
            #[inline]
765
0
            fn private_rem(self, urem: UInt<U, B>, _: $B<Ur>) -> Self::Output {
766
0
                $R { n: urem }
767
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2n_0ppppEINtB5_4PIntpEINtNtB7_7private10PrivateRemINtNtB7_4uint4UIntppEIBI_pEE11private_remB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2q_0ppppEINtB5_4PIntpEINtNtB7_7private10PrivateRemINtNtB7_4uint4UIntppEINtB5_4NIntpEE11private_remB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2t_0ppppEINtB5_4NIntpEINtNtB7_7private10PrivateRemINtNtB7_4uint4UIntppEINtB5_4PIntpEE11private_remB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum3ints2w_0ppppEINtB5_4NIntpEINtNtB7_7private10PrivateRemINtNtB7_4uint4UIntppEIBI_pEE11private_remB7_
768
        }
769
    };
770
}
771
772
impl_int_rem!(PInt, PInt, PInt);
773
impl_int_rem!(PInt, NInt, PInt);
774
impl_int_rem!(NInt, PInt, NInt);
775
impl_int_rem!(NInt, NInt, NInt);
776
777
// ---------------------------------------------------------------------------------------
778
// Pow
779
780
/// 0^0 = 1
781
impl Pow<Z0> for Z0 {
782
    type Output = P1;
783
    #[inline]
784
0
    fn powi(self, _: Z0) -> Self::Output {
785
0
        P1::new()
786
0
    }
787
}
788
789
/// 0^P = 0
790
impl<U: Unsigned + NonZero> Pow<PInt<U>> for Z0 {
791
    type Output = Z0;
792
    #[inline]
793
0
    fn powi(self, _: PInt<U>) -> Self::Output {
794
0
        Z0
795
0
    }
796
}
797
798
/// 0^N = 0
799
impl<U: Unsigned + NonZero> Pow<NInt<U>> for Z0 {
800
    type Output = Z0;
801
    #[inline]
802
0
    fn powi(self, _: NInt<U>) -> Self::Output {
803
0
        Z0
804
0
    }
805
}
806
807
/// 1^N = 1
808
impl<U: Unsigned + NonZero> Pow<NInt<U>> for P1 {
809
    type Output = P1;
810
    #[inline]
811
0
    fn powi(self, _: NInt<U>) -> Self::Output {
812
0
        P1::new()
813
0
    }
814
}
815
816
/// (-1)^N = 1 if N is even
817
impl<U: Unsigned> Pow<NInt<UInt<U, B0>>> for N1 {
818
    type Output = P1;
819
    #[inline]
820
0
    fn powi(self, _: NInt<UInt<U, B0>>) -> Self::Output {
821
0
        P1::new()
822
0
    }
823
}
824
825
/// (-1)^N = -1 if N is odd
826
impl<U: Unsigned> Pow<NInt<UInt<U, B1>>> for N1 {
827
    type Output = N1;
828
    #[inline]
829
0
    fn powi(self, _: NInt<UInt<U, B1>>) -> Self::Output {
830
0
        N1::new()
831
0
    }
832
}
833
834
/// P^0 = 1
835
impl<U: Unsigned + NonZero> Pow<Z0> for PInt<U> {
836
    type Output = P1;
837
    #[inline]
838
0
    fn powi(self, _: Z0) -> Self::Output {
839
0
        P1::new()
840
0
    }
841
}
842
843
/// N^0 = 1
844
impl<U: Unsigned + NonZero> Pow<Z0> for NInt<U> {
845
    type Output = P1;
846
    #[inline]
847
0
    fn powi(self, _: Z0) -> Self::Output {
848
0
        P1::new()
849
0
    }
850
}
851
852
/// P(Ul)^P(Ur) = P(Ul^Ur)
853
impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Pow<PInt<Ur>> for PInt<Ul>
854
where
855
    Ul: Pow<Ur>,
856
    <Ul as Pow<Ur>>::Output: Unsigned + NonZero,
857
{
858
    type Output = PInt<<Ul as Pow<Ur>>::Output>;
859
    #[inline]
860
0
    fn powi(self, _: PInt<Ur>) -> Self::Output {
861
0
        PInt::new()
862
0
    }
863
}
864
865
/// N(Ul)^P(Ur) = P(Ul^Ur) if Ur is even
866
impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B0>>> for NInt<Ul>
867
where
868
    Ul: Pow<UInt<Ur, B0>>,
869
    <Ul as Pow<UInt<Ur, B0>>>::Output: Unsigned + NonZero,
870
{
871
    type Output = PInt<<Ul as Pow<UInt<Ur, B0>>>::Output>;
872
    #[inline]
873
0
    fn powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output {
874
0
        PInt::new()
875
0
    }
876
}
877
878
/// N(Ul)^P(Ur) = N(Ul^Ur) if Ur is odd
879
impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B1>>> for NInt<Ul>
880
where
881
    Ul: Pow<UInt<Ur, B1>>,
882
    <Ul as Pow<UInt<Ur, B1>>>::Output: Unsigned + NonZero,
883
{
884
    type Output = NInt<<Ul as Pow<UInt<Ur, B1>>>::Output>;
885
    #[inline]
886
0
    fn powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output {
887
0
        NInt::new()
888
0
    }
889
}
890
891
// ---------------------------------------------------------------------------------------
892
// Gcd
893
use crate::{Gcd, Gcf};
894
895
impl Gcd<Z0> for Z0 {
896
    type Output = Z0;
897
}
898
899
impl<U> Gcd<PInt<U>> for Z0
900
where
901
    U: Unsigned + NonZero,
902
{
903
    type Output = PInt<U>;
904
}
905
906
impl<U> Gcd<Z0> for PInt<U>
907
where
908
    U: Unsigned + NonZero,
909
{
910
    type Output = PInt<U>;
911
}
912
913
impl<U> Gcd<NInt<U>> for Z0
914
where
915
    U: Unsigned + NonZero,
916
{
917
    type Output = PInt<U>;
918
}
919
920
impl<U> Gcd<Z0> for NInt<U>
921
where
922
    U: Unsigned + NonZero,
923
{
924
    type Output = PInt<U>;
925
}
926
927
impl<U1, U2> Gcd<PInt<U2>> for PInt<U1>
928
where
929
    U1: Unsigned + NonZero + Gcd<U2>,
930
    U2: Unsigned + NonZero,
931
    Gcf<U1, U2>: Unsigned + NonZero,
932
{
933
    type Output = PInt<Gcf<U1, U2>>;
934
}
935
936
impl<U1, U2> Gcd<PInt<U2>> for NInt<U1>
937
where
938
    U1: Unsigned + NonZero + Gcd<U2>,
939
    U2: Unsigned + NonZero,
940
    Gcf<U1, U2>: Unsigned + NonZero,
941
{
942
    type Output = PInt<Gcf<U1, U2>>;
943
}
944
945
impl<U1, U2> Gcd<NInt<U2>> for PInt<U1>
946
where
947
    U1: Unsigned + NonZero + Gcd<U2>,
948
    U2: Unsigned + NonZero,
949
    Gcf<U1, U2>: Unsigned + NonZero,
950
{
951
    type Output = PInt<Gcf<U1, U2>>;
952
}
953
954
impl<U1, U2> Gcd<NInt<U2>> for NInt<U1>
955
where
956
    U1: Unsigned + NonZero + Gcd<U2>,
957
    U2: Unsigned + NonZero,
958
    Gcf<U1, U2>: Unsigned + NonZero,
959
{
960
    type Output = PInt<Gcf<U1, U2>>;
961
}
962
963
// ---------------------------------------------------------------------------------------
964
// Min
965
use crate::{Max, Maximum, Min, Minimum};
966
967
impl Min<Z0> for Z0 {
968
    type Output = Z0;
969
    #[inline]
970
0
    fn min(self, _: Z0) -> Self::Output {
971
0
        self
972
0
    }
973
}
974
975
impl<U> Min<PInt<U>> for Z0
976
where
977
    U: Unsigned + NonZero,
978
{
979
    type Output = Z0;
980
    #[inline]
981
0
    fn min(self, _: PInt<U>) -> Self::Output {
982
0
        self
983
0
    }
984
}
985
986
impl<U> Min<NInt<U>> for Z0
987
where
988
    U: Unsigned + NonZero,
989
{
990
    type Output = NInt<U>;
991
    #[inline]
992
0
    fn min(self, rhs: NInt<U>) -> Self::Output {
993
0
        rhs
994
0
    }
995
}
996
997
impl<U> Min<Z0> for PInt<U>
998
where
999
    U: Unsigned + NonZero,
1000
{
1001
    type Output = Z0;
1002
    #[inline]
1003
0
    fn min(self, rhs: Z0) -> Self::Output {
1004
0
        rhs
1005
0
    }
1006
}
1007
1008
impl<U> Min<Z0> for NInt<U>
1009
where
1010
    U: Unsigned + NonZero,
1011
{
1012
    type Output = NInt<U>;
1013
    #[inline]
1014
0
    fn min(self, _: Z0) -> Self::Output {
1015
0
        self
1016
0
    }
1017
}
1018
1019
impl<Ul, Ur> Min<PInt<Ur>> for PInt<Ul>
1020
where
1021
    Ul: Unsigned + NonZero + Min<Ur>,
1022
    Ur: Unsigned + NonZero,
1023
    Minimum<Ul, Ur>: Unsigned + NonZero,
1024
{
1025
    type Output = PInt<Minimum<Ul, Ur>>;
1026
    #[inline]
1027
0
    fn min(self, rhs: PInt<Ur>) -> Self::Output {
1028
0
        PInt {
1029
0
            n: self.n.min(rhs.n),
1030
0
        }
1031
0
    }
1032
}
1033
1034
impl<Ul, Ur> Min<PInt<Ur>> for NInt<Ul>
1035
where
1036
    Ul: Unsigned + NonZero,
1037
    Ur: Unsigned + NonZero,
1038
{
1039
    type Output = NInt<Ul>;
1040
    #[inline]
1041
0
    fn min(self, _: PInt<Ur>) -> Self::Output {
1042
0
        self
1043
0
    }
1044
}
1045
1046
impl<Ul, Ur> Min<NInt<Ur>> for PInt<Ul>
1047
where
1048
    Ul: Unsigned + NonZero,
1049
    Ur: Unsigned + NonZero,
1050
{
1051
    type Output = NInt<Ur>;
1052
    #[inline]
1053
0
    fn min(self, rhs: NInt<Ur>) -> Self::Output {
1054
0
        rhs
1055
0
    }
1056
}
1057
1058
impl<Ul, Ur> Min<NInt<Ur>> for NInt<Ul>
1059
where
1060
    Ul: Unsigned + NonZero + Max<Ur>,
1061
    Ur: Unsigned + NonZero,
1062
    Maximum<Ul, Ur>: Unsigned + NonZero,
1063
{
1064
    type Output = NInt<Maximum<Ul, Ur>>;
1065
    #[inline]
1066
0
    fn min(self, rhs: NInt<Ur>) -> Self::Output {
1067
0
        NInt {
1068
0
            n: self.n.max(rhs.n),
1069
0
        }
1070
0
    }
1071
}
1072
1073
// ---------------------------------------------------------------------------------------
1074
// Max
1075
1076
impl Max<Z0> for Z0 {
1077
    type Output = Z0;
1078
    #[inline]
1079
0
    fn max(self, _: Z0) -> Self::Output {
1080
0
        self
1081
0
    }
1082
}
1083
1084
impl<U> Max<PInt<U>> for Z0
1085
where
1086
    U: Unsigned + NonZero,
1087
{
1088
    type Output = PInt<U>;
1089
    #[inline]
1090
0
    fn max(self, rhs: PInt<U>) -> Self::Output {
1091
0
        rhs
1092
0
    }
1093
}
1094
1095
impl<U> Max<NInt<U>> for Z0
1096
where
1097
    U: Unsigned + NonZero,
1098
{
1099
    type Output = Z0;
1100
    #[inline]
1101
0
    fn max(self, _: NInt<U>) -> Self::Output {
1102
0
        self
1103
0
    }
1104
}
1105
1106
impl<U> Max<Z0> for PInt<U>
1107
where
1108
    U: Unsigned + NonZero,
1109
{
1110
    type Output = PInt<U>;
1111
    #[inline]
1112
0
    fn max(self, _: Z0) -> Self::Output {
1113
0
        self
1114
0
    }
1115
}
1116
1117
impl<U> Max<Z0> for NInt<U>
1118
where
1119
    U: Unsigned + NonZero,
1120
{
1121
    type Output = Z0;
1122
    #[inline]
1123
0
    fn max(self, rhs: Z0) -> Self::Output {
1124
0
        rhs
1125
0
    }
1126
}
1127
1128
impl<Ul, Ur> Max<PInt<Ur>> for PInt<Ul>
1129
where
1130
    Ul: Unsigned + NonZero + Max<Ur>,
1131
    Ur: Unsigned + NonZero,
1132
    Maximum<Ul, Ur>: Unsigned + NonZero,
1133
{
1134
    type Output = PInt<Maximum<Ul, Ur>>;
1135
    #[inline]
1136
0
    fn max(self, rhs: PInt<Ur>) -> Self::Output {
1137
0
        PInt {
1138
0
            n: self.n.max(rhs.n),
1139
0
        }
1140
0
    }
1141
}
1142
1143
impl<Ul, Ur> Max<PInt<Ur>> for NInt<Ul>
1144
where
1145
    Ul: Unsigned + NonZero,
1146
    Ur: Unsigned + NonZero,
1147
{
1148
    type Output = PInt<Ur>;
1149
    #[inline]
1150
0
    fn max(self, rhs: PInt<Ur>) -> Self::Output {
1151
0
        rhs
1152
0
    }
1153
}
1154
1155
impl<Ul, Ur> Max<NInt<Ur>> for PInt<Ul>
1156
where
1157
    Ul: Unsigned + NonZero,
1158
    Ur: Unsigned + NonZero,
1159
{
1160
    type Output = PInt<Ul>;
1161
    #[inline]
1162
0
    fn max(self, _: NInt<Ur>) -> Self::Output {
1163
0
        self
1164
0
    }
1165
}
1166
1167
impl<Ul, Ur> Max<NInt<Ur>> for NInt<Ul>
1168
where
1169
    Ul: Unsigned + NonZero + Min<Ur>,
1170
    Ur: Unsigned + NonZero,
1171
    Minimum<Ul, Ur>: Unsigned + NonZero,
1172
{
1173
    type Output = NInt<Minimum<Ul, Ur>>;
1174
    #[inline]
1175
0
    fn max(self, rhs: NInt<Ur>) -> Self::Output {
1176
0
        NInt {
1177
0
            n: self.n.min(rhs.n),
1178
0
        }
1179
0
    }
1180
}
1181
1182
// -----------------------------------------
1183
// ToInt
1184
1185
impl ToInt<i8> for Z0 {
1186
    #[inline]
1187
0
    fn to_int() -> i8 {
1188
0
        Self::I8
1189
0
    }
1190
    const INT: i8 = Self::I8;
1191
}
1192
1193
impl ToInt<i16> for Z0 {
1194
    #[inline]
1195
0
    fn to_int() -> i16 {
1196
0
        Self::I16
1197
0
    }
1198
    const INT: i16 = Self::I16;
1199
}
1200
1201
impl ToInt<i32> for Z0 {
1202
    #[inline]
1203
0
    fn to_int() -> i32 {
1204
0
        Self::I32
1205
0
    }
1206
    const INT: i32 = Self::I32;
1207
}
1208
1209
impl ToInt<i64> for Z0 {
1210
    #[inline]
1211
0
    fn to_int() -> i64 {
1212
0
        Self::I64
1213
0
    }
1214
    const INT: i64 = Self::I64;
1215
}
1216
1217
// negative numbers
1218
1219
impl<U> ToInt<i8> for NInt<U>
1220
where
1221
    U: Unsigned + NonZero,
1222
{
1223
    #[inline]
1224
0
    fn to_int() -> i8 {
1225
0
        Self::I8
1226
0
    }
1227
    const INT: i8 = Self::I8;
1228
}
1229
1230
impl<U> ToInt<i16> for NInt<U>
1231
where
1232
    U: Unsigned + NonZero,
1233
{
1234
    #[inline]
1235
0
    fn to_int() -> i16 {
1236
0
        Self::I16
1237
0
    }
1238
    const INT: i16 = Self::I16;
1239
}
1240
1241
impl<U> ToInt<i32> for NInt<U>
1242
where
1243
    U: Unsigned + NonZero,
1244
{
1245
    #[inline]
1246
0
    fn to_int() -> i32 {
1247
0
        Self::I32
1248
0
    }
1249
    const INT: i32 = Self::I32;
1250
}
1251
1252
impl<U> ToInt<i64> for NInt<U>
1253
where
1254
    U: Unsigned + NonZero,
1255
{
1256
    #[inline]
1257
0
    fn to_int() -> i64 {
1258
0
        Self::I64
1259
0
    }
1260
    const INT: i64 = Self::I64;
1261
}
1262
1263
// positive numbers
1264
1265
impl<U> ToInt<i8> for PInt<U>
1266
where
1267
    U: Unsigned + NonZero,
1268
{
1269
    #[inline]
1270
0
    fn to_int() -> i8 {
1271
0
        Self::I8
1272
0
    }
1273
    const INT: i8 = Self::I8;
1274
}
1275
1276
impl<U> ToInt<i16> for PInt<U>
1277
where
1278
    U: Unsigned + NonZero,
1279
{
1280
    #[inline]
1281
0
    fn to_int() -> i16 {
1282
0
        Self::I16
1283
0
    }
1284
    const INT: i16 = Self::I16;
1285
}
1286
1287
impl<U> ToInt<i32> for PInt<U>
1288
where
1289
    U: Unsigned + NonZero,
1290
{
1291
    #[inline]
1292
0
    fn to_int() -> i32 {
1293
0
        Self::I32
1294
0
    }
1295
    const INT: i32 = Self::I32;
1296
}
1297
1298
impl<U> ToInt<i64> for PInt<U>
1299
where
1300
    U: Unsigned + NonZero,
1301
{
1302
    #[inline]
1303
0
    fn to_int() -> i64 {
1304
0
        Self::I64
1305
0
    }
1306
    const INT: i64 = Self::I64;
1307
}
1308
1309
#[cfg(test)]
1310
mod tests {
1311
    use crate::{consts::*, Integer, ToInt};
1312
1313
    #[test]
1314
    fn to_ix_min() {
1315
        assert_eq!(N128::to_i8(), ::core::i8::MIN);
1316
        assert_eq!(N32768::to_i16(), ::core::i16::MIN);
1317
    }
1318
1319
    #[test]
1320
    fn int_toint_test() {
1321
        // i8
1322
        assert_eq!(0_i8, Z0::to_int());
1323
        assert_eq!(1_i8, P1::to_int());
1324
        assert_eq!(2_i8, P2::to_int());
1325
        assert_eq!(3_i8, P3::to_int());
1326
        assert_eq!(4_i8, P4::to_int());
1327
        assert_eq!(-1_i8, N1::to_int());
1328
        assert_eq!(-2_i8, N2::to_int());
1329
        assert_eq!(-3_i8, N3::to_int());
1330
        assert_eq!(-4_i8, N4::to_int());
1331
        assert_eq!(0_i8, Z0::INT);
1332
        assert_eq!(1_i8, P1::INT);
1333
        assert_eq!(2_i8, P2::INT);
1334
        assert_eq!(3_i8, P3::INT);
1335
        assert_eq!(4_i8, P4::INT);
1336
        assert_eq!(-1_i8, N1::INT);
1337
        assert_eq!(-2_i8, N2::INT);
1338
        assert_eq!(-3_i8, N3::INT);
1339
        assert_eq!(-4_i8, N4::INT);
1340
1341
        // i16
1342
        assert_eq!(0_i16, Z0::to_int());
1343
        assert_eq!(1_i16, P1::to_int());
1344
        assert_eq!(2_i16, P2::to_int());
1345
        assert_eq!(3_i16, P3::to_int());
1346
        assert_eq!(4_i16, P4::to_int());
1347
        assert_eq!(-1_i16, N1::to_int());
1348
        assert_eq!(-2_i16, N2::to_int());
1349
        assert_eq!(-3_i16, N3::to_int());
1350
        assert_eq!(-4_i16, N4::to_int());
1351
        assert_eq!(0_i16, Z0::INT);
1352
        assert_eq!(1_i16, P1::INT);
1353
        assert_eq!(2_i16, P2::INT);
1354
        assert_eq!(3_i16, P3::INT);
1355
        assert_eq!(4_i16, P4::INT);
1356
        assert_eq!(-1_i16, N1::INT);
1357
        assert_eq!(-2_i16, N2::INT);
1358
        assert_eq!(-3_i16, N3::INT);
1359
        assert_eq!(-4_i16, N4::INT);
1360
1361
        // i32
1362
        assert_eq!(0_i32, Z0::to_int());
1363
        assert_eq!(1_i32, P1::to_int());
1364
        assert_eq!(2_i32, P2::to_int());
1365
        assert_eq!(3_i32, P3::to_int());
1366
        assert_eq!(4_i32, P4::to_int());
1367
        assert_eq!(-1_i32, N1::to_int());
1368
        assert_eq!(-2_i32, N2::to_int());
1369
        assert_eq!(-3_i32, N3::to_int());
1370
        assert_eq!(-4_i32, N4::to_int());
1371
        assert_eq!(0_i32, Z0::INT);
1372
        assert_eq!(1_i32, P1::INT);
1373
        assert_eq!(2_i32, P2::INT);
1374
        assert_eq!(3_i32, P3::INT);
1375
        assert_eq!(4_i32, P4::INT);
1376
        assert_eq!(-1_i32, N1::INT);
1377
        assert_eq!(-2_i32, N2::INT);
1378
        assert_eq!(-3_i32, N3::INT);
1379
        assert_eq!(-4_i32, N4::INT);
1380
1381
        // i64
1382
        assert_eq!(0_i64, Z0::to_int());
1383
        assert_eq!(1_i64, P1::to_int());
1384
        assert_eq!(2_i64, P2::to_int());
1385
        assert_eq!(3_i64, P3::to_int());
1386
        assert_eq!(4_i64, P4::to_int());
1387
        assert_eq!(-1_i64, N1::to_int());
1388
        assert_eq!(-2_i64, N2::to_int());
1389
        assert_eq!(-3_i64, N3::to_int());
1390
        assert_eq!(-4_i64, N4::to_int());
1391
        assert_eq!(0_i64, Z0::INT);
1392
        assert_eq!(1_i64, P1::INT);
1393
        assert_eq!(2_i64, P2::INT);
1394
        assert_eq!(3_i64, P3::INT);
1395
        assert_eq!(4_i64, P4::INT);
1396
        assert_eq!(-1_i64, N1::INT);
1397
        assert_eq!(-2_i64, N2::INT);
1398
        assert_eq!(-3_i64, N3::INT);
1399
        assert_eq!(-4_i64, N4::INT);
1400
    }
1401
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typenum-1.17.0/src/lib.rs
Line
Count
Source
1
//! This crate provides type-level numbers evaluated at compile time. It depends only on libcore.
2
//!
3
//! The traits defined or used in this crate are used in a typical manner. They can be divided into
4
//! two categories: **marker traits** and **type operators**.
5
//!
6
//! Many of the marker traits have functions defined, but they all do essentially the same thing:
7
//! convert a type into its runtime counterpart, and are really just there for debugging. For
8
//! example,
9
//!
10
//! ```rust
11
//! use typenum::{Integer, N4};
12
//!
13
//! assert_eq!(N4::to_i32(), -4);
14
//! ```
15
//!
16
//! **Type operators** are traits that behave as functions at the type level. These are the meat of
17
//! this library. Where possible, traits defined in libcore have been used, but their attached
18
//! functions have not been implemented.
19
//!
20
//! For example, the `Add` trait is implemented for both unsigned and signed integers, but the
21
//! `add` function is not. As there are never any objects of the types defined here, it wouldn't
22
//! make sense to implement it. What is important is its associated type `Output`, which is where
23
//! the addition happens.
24
//!
25
//! ```rust
26
//! use std::ops::Add;
27
//! use typenum::{Integer, P3, P4};
28
//!
29
//! type X = <P3 as Add<P4>>::Output;
30
//! assert_eq!(<X as Integer>::to_i32(), 7);
31
//! ```
32
//!
33
//! In addition, helper aliases are defined for type operators. For example, the above snippet
34
//! could be replaced with
35
//!
36
//! ```rust
37
//! use typenum::{Integer, Sum, P3, P4};
38
//!
39
//! type X = Sum<P3, P4>;
40
//! assert_eq!(<X as Integer>::to_i32(), 7);
41
//! ```
42
//!
43
//! Documented in each module is the full list of type operators implemented.
44
45
#![no_std]
46
#![forbid(unsafe_code)]
47
#![warn(missing_docs)]
48
#![cfg_attr(feature = "strict", deny(missing_docs))]
49
#![cfg_attr(feature = "strict", deny(warnings))]
50
#![cfg_attr(
51
    feature = "cargo-clippy",
52
    allow(
53
        clippy::len_without_is_empty,
54
        clippy::many_single_char_names,
55
        clippy::new_without_default,
56
        clippy::suspicious_arithmetic_impl,
57
        clippy::type_complexity,
58
        clippy::wrong_self_convention,
59
    )
60
)]
61
#![cfg_attr(feature = "cargo-clippy", deny(clippy::missing_inline_in_public_items))]
62
#![doc(html_root_url = "https://docs.rs/typenum/1.17.0")]
63
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
64
65
// For debugging macros:
66
// #![feature(trace_macros)]
67
// trace_macros!(true);
68
69
use core::cmp::Ordering;
70
71
mod generated {
72
    include!(concat!(env!("OUT_DIR"), "/op.rs"));
73
    include!(concat!(env!("OUT_DIR"), "/consts.rs"));
74
75
    #[cfg(feature = "const-generics")]
76
    include!(concat!(env!("OUT_DIR"), "/generic_const_mappings.rs"));
77
}
78
79
pub mod bit;
80
pub mod int;
81
pub mod marker_traits;
82
pub mod operator_aliases;
83
pub mod private;
84
pub mod type_operators;
85
pub mod uint;
86
87
pub mod array;
88
89
pub use crate::{
90
    array::{ATerm, TArr},
91
    generated::consts,
92
    int::{NInt, PInt},
93
    marker_traits::*,
94
    operator_aliases::*,
95
    type_operators::*,
96
    uint::{UInt, UTerm},
97
};
98
99
#[doc(no_inline)]
100
#[rustfmt::skip]
101
pub use consts::{
102
    False, True, B0, B1,
103
    U0, U1, U2, *,
104
    N1, N2, Z0, P1, P2, *,
105
};
106
107
#[cfg(feature = "const-generics")]
108
pub use crate::generated::generic_const_mappings;
109
110
#[cfg(feature = "const-generics")]
111
#[doc(no_inline)]
112
pub use generic_const_mappings::{Const, ToUInt, U};
113
114
/// A potential output from `Cmp`, this is the type equivalent to the enum variant
115
/// `core::cmp::Ordering::Greater`.
116
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
117
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
118
pub struct Greater;
119
120
/// A potential output from `Cmp`, this is the type equivalent to the enum variant
121
/// `core::cmp::Ordering::Less`.
122
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
123
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
124
pub struct Less;
125
126
/// A potential output from `Cmp`, this is the type equivalent to the enum variant
127
/// `core::cmp::Ordering::Equal`.
128
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
129
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
130
pub struct Equal;
131
132
/// Returns `core::cmp::Ordering::Greater`
133
impl Ord for Greater {
134
    #[inline]
135
0
    fn to_ordering() -> Ordering {
136
0
        Ordering::Greater
137
0
    }
138
}
139
140
/// Returns `core::cmp::Ordering::Less`
141
impl Ord for Less {
142
    #[inline]
143
0
    fn to_ordering() -> Ordering {
144
0
        Ordering::Less
145
0
    }
146
}
147
148
/// Returns `core::cmp::Ordering::Equal`
149
impl Ord for Equal {
150
    #[inline]
151
0
    fn to_ordering() -> Ordering {
152
0
        Ordering::Equal
153
0
    }
154
}
155
156
/// Asserts that two types are the same.
157
#[macro_export]
158
macro_rules! assert_type_eq {
159
    ($a:ty, $b:ty) => {
160
        const _: core::marker::PhantomData<<$a as $crate::Same<$b>>::Output> =
161
            core::marker::PhantomData;
162
    };
163
}
164
165
/// Asserts that a type is `True`, aka `B1`.
166
#[macro_export]
167
macro_rules! assert_type {
168
    ($a:ty) => {
169
        const _: core::marker::PhantomData<<$a as $crate::Same<True>>::Output> =
170
            core::marker::PhantomData;
171
    };
172
}
173
174
mod sealed {
175
    use crate::{
176
        ATerm, Bit, Equal, Greater, Less, NInt, NonZero, PInt, TArr, UInt, UTerm, Unsigned, B0, B1,
177
        Z0,
178
    };
179
180
    pub trait Sealed {}
181
182
    impl Sealed for B0 {}
183
    impl Sealed for B1 {}
184
185
    impl Sealed for UTerm {}
186
    impl<U: Unsigned, B: Bit> Sealed for UInt<U, B> {}
187
188
    impl Sealed for Z0 {}
189
    impl<U: Unsigned + NonZero> Sealed for PInt<U> {}
190
    impl<U: Unsigned + NonZero> Sealed for NInt<U> {}
191
192
    impl Sealed for Less {}
193
    impl Sealed for Equal {}
194
    impl Sealed for Greater {}
195
196
    impl Sealed for ATerm {}
197
    impl<V, A> Sealed for TArr<V, A> {}
198
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typenum-1.17.0/src/private.rs
Line
Count
Source
1
//! **Ignore me!** This module is for things that are conceptually private but that must
2
//! be made public for typenum to work correctly.
3
//!
4
//! Unless you are working on typenum itself, **there is no need to view anything here**.
5
//!
6
//! Certainly don't implement any of the traits here for anything.
7
//!
8
//!
9
//! Just look away.
10
//!
11
//!
12
//! Loooooooooooooooooooooooooooooooooook awaaaaaaaaaaaayyyyyyyyyyyyyyyyyyyyyyyyyyyyy...
13
//!
14
//!
15
//! If you do manage to find something of use in here, please let me know. If you can make a
16
//! compelling case, it may be moved out of __private.
17
//!
18
//! Note: Aliases for private type operators will all be named simply that operator followed
19
//! by an abbreviated name of its associated type.
20
21
#![doc(hidden)]
22
23
use crate::{
24
    bit::{Bit, B0, B1},
25
    uint::{UInt, UTerm, Unsigned},
26
};
27
28
/// A marker for restricting a method on a public trait to internal use only.
29
pub(crate) enum Internal {}
30
31
pub trait InternalMarker {}
32
33
impl InternalMarker for Internal {}
34
35
/// Convenience trait. Calls `Invert` -> `TrimTrailingZeros` -> `Invert`
36
pub trait Trim {
37
    type Output;
38
39
    fn trim(self) -> Self::Output;
40
}
41
pub type TrimOut<A> = <A as Trim>::Output;
42
43
/// Gets rid of all zeros until it hits a one.
44
45
// ONLY IMPLEMENT FOR INVERTED NUMBERS!
46
pub trait TrimTrailingZeros {
47
    type Output;
48
49
    fn trim_trailing_zeros(self) -> Self::Output;
50
}
51
pub type TrimTrailingZerosOut<A> = <A as TrimTrailingZeros>::Output;
52
53
/// Converts between standard numbers and inverted ones that have the most significant
54
/// digit on the outside.
55
pub trait Invert {
56
    type Output;
57
58
    fn invert(self) -> Self::Output;
59
}
60
pub type InvertOut<A> = <A as Invert>::Output;
61
62
/// Doubly private! Called by invert to make the magic happen once its done the first step.
63
/// The Rhs is what we've got so far.
64
pub trait PrivateInvert<Rhs> {
65
    type Output;
66
67
    fn private_invert(self, rhs: Rhs) -> Self::Output;
68
}
69
pub type PrivateInvertOut<A, Rhs> = <A as PrivateInvert<Rhs>>::Output;
70
71
/// Terminating character for `InvertedUInt`s
72
pub struct InvertedUTerm;
73
74
/// Inverted `UInt` (has most significant digit on the outside)
75
pub struct InvertedUInt<IU: InvertedUnsigned, B: Bit> {
76
    msb: IU,
77
    lsb: B,
78
}
79
80
/// Does the real anding for `UInt`s; `And` just calls this and then `Trim`.
81
pub trait PrivateAnd<Rhs = Self> {
82
    type Output;
83
84
    fn private_and(self, rhs: Rhs) -> Self::Output;
85
}
86
pub type PrivateAndOut<A, Rhs> = <A as PrivateAnd<Rhs>>::Output;
87
88
/// Does the real xoring for `UInt`s; `Xor` just calls this and then `Trim`.
89
pub trait PrivateXor<Rhs = Self> {
90
    type Output;
91
92
    fn private_xor(self, rhs: Rhs) -> Self::Output;
93
}
94
pub type PrivateXorOut<A, Rhs> = <A as PrivateXor<Rhs>>::Output;
95
96
/// Does the real subtraction for `UInt`s; `Sub` just calls this and then `Trim`.
97
pub trait PrivateSub<Rhs = Self> {
98
    type Output;
99
100
    fn private_sub(self, rhs: Rhs) -> Self::Output;
101
}
102
pub type PrivateSubOut<A, Rhs> = <A as PrivateSub<Rhs>>::Output;
103
104
/// Used for addition of signed integers; `C = P.cmp(N)`
105
/// Assumes `P = Self` is positive and `N` is negative
106
/// where `P` and `N` are both passed as unsigned integers
107
pub trait PrivateIntegerAdd<C, N> {
108
    type Output;
109
110
    fn private_integer_add(self, _: C, _: N) -> Self::Output;
111
}
112
pub type PrivateIntegerAddOut<P, C, N> = <P as PrivateIntegerAdd<C, N>>::Output;
113
114
pub trait PrivatePow<Y, N> {
115
    type Output;
116
117
    fn private_pow(self, _: Y, _: N) -> Self::Output;
118
}
119
pub type PrivatePowOut<A, Y, N> = <A as PrivatePow<Y, N>>::Output;
120
121
/// Performs `Shl` on `Lhs` so that `SizeOf(Lhs) = SizeOf(Rhs)`
122
/// Fails if `SizeOf(Lhs) > SizeOf(Rhs)`
123
pub trait ShiftDiff<Rhs> {
124
    type Output;
125
}
126
pub type ShiftDiffOut<A, Rhs> = <A as ShiftDiff<Rhs>>::Output;
127
128
/// Gives `SizeOf(Lhs) - SizeOf(Rhs)`
129
pub trait BitDiff<Rhs> {
130
    type Output;
131
}
132
pub type BitDiffOut<A, Rhs> = <A as BitDiff<Rhs>>::Output;
133
134
/// Inverted unsigned numbers
135
pub trait InvertedUnsigned {
136
    fn to_u64() -> u64;
137
}
138
139
impl InvertedUnsigned for InvertedUTerm {
140
    #[inline]
141
0
    fn to_u64() -> u64 {
142
0
        0
143
0
    }
144
}
145
146
impl<IU: InvertedUnsigned, B: Bit> InvertedUnsigned for InvertedUInt<IU, B> {
147
    #[inline]
148
0
    fn to_u64() -> u64 {
149
0
        u64::from(B::to_u8()) | IU::to_u64() << 1
150
0
    }
151
}
152
153
impl Invert for UTerm {
154
    type Output = InvertedUTerm;
155
156
    #[inline]
157
0
    fn invert(self) -> Self::Output {
158
0
        InvertedUTerm
159
0
    }
160
}
161
162
impl<U: Unsigned, B: Bit> Invert for UInt<U, B>
163
where
164
    U: PrivateInvert<InvertedUInt<InvertedUTerm, B>>,
165
{
166
    type Output = PrivateInvertOut<U, InvertedUInt<InvertedUTerm, B>>;
167
168
    #[inline]
169
0
    fn invert(self) -> Self::Output {
170
0
        self.msb.private_invert(InvertedUInt {
171
0
            msb: InvertedUTerm,
172
0
            lsb: self.lsb,
173
0
        })
174
0
    }
175
}
176
177
impl<IU: InvertedUnsigned> PrivateInvert<IU> for UTerm {
178
    type Output = IU;
179
180
    #[inline]
181
0
    fn private_invert(self, rhs: IU) -> Self::Output {
182
0
        rhs
183
0
    }
184
}
185
186
impl<IU: InvertedUnsigned, U: Unsigned, B: Bit> PrivateInvert<IU> for UInt<U, B>
187
where
188
    U: PrivateInvert<InvertedUInt<IU, B>>,
189
{
190
    type Output = PrivateInvertOut<U, InvertedUInt<IU, B>>;
191
192
    #[inline]
193
0
    fn private_invert(self, rhs: IU) -> Self::Output {
194
0
        self.msb.private_invert(InvertedUInt {
195
0
            msb: rhs,
196
0
            lsb: self.lsb,
197
0
        })
198
0
    }
199
}
200
201
#[test]
202
fn test_inversion() {
203
    type Test4 = <crate::consts::U4 as Invert>::Output;
204
    type Test5 = <crate::consts::U5 as Invert>::Output;
205
    type Test12 = <crate::consts::U12 as Invert>::Output;
206
    type Test16 = <crate::consts::U16 as Invert>::Output;
207
208
    assert_eq!(1, <Test4 as InvertedUnsigned>::to_u64());
209
    assert_eq!(5, <Test5 as InvertedUnsigned>::to_u64());
210
    assert_eq!(3, <Test12 as InvertedUnsigned>::to_u64());
211
    assert_eq!(1, <Test16 as InvertedUnsigned>::to_u64());
212
}
213
214
impl Invert for InvertedUTerm {
215
    type Output = UTerm;
216
217
    #[inline]
218
0
    fn invert(self) -> Self::Output {
219
0
        UTerm
220
0
    }
221
}
222
223
impl<IU: InvertedUnsigned, B: Bit> Invert for InvertedUInt<IU, B>
224
where
225
    IU: PrivateInvert<UInt<UTerm, B>>,
226
{
227
    type Output = <IU as PrivateInvert<UInt<UTerm, B>>>::Output;
228
229
    #[inline]
230
0
    fn invert(self) -> Self::Output {
231
0
        self.msb.private_invert(UInt {
232
0
            msb: UTerm,
233
0
            lsb: self.lsb,
234
0
        })
235
0
    }
236
}
237
238
impl<U: Unsigned> PrivateInvert<U> for InvertedUTerm {
239
    type Output = U;
240
241
    #[inline]
242
0
    fn private_invert(self, rhs: U) -> Self::Output {
243
0
        rhs
244
0
    }
245
}
246
247
impl<U: Unsigned, IU: InvertedUnsigned, B: Bit> PrivateInvert<U> for InvertedUInt<IU, B>
248
where
249
    IU: PrivateInvert<UInt<U, B>>,
250
{
251
    type Output = <IU as PrivateInvert<UInt<U, B>>>::Output;
252
253
    #[inline]
254
0
    fn private_invert(self, rhs: U) -> Self::Output {
255
0
        self.msb.private_invert(UInt {
256
0
            msb: rhs,
257
0
            lsb: self.lsb,
258
0
        })
259
0
    }
260
}
261
262
#[test]
263
fn test_double_inversion() {
264
    type Test4 = <<crate::consts::U4 as Invert>::Output as Invert>::Output;
265
    type Test5 = <<crate::consts::U5 as Invert>::Output as Invert>::Output;
266
    type Test12 = <<crate::consts::U12 as Invert>::Output as Invert>::Output;
267
    type Test16 = <<crate::consts::U16 as Invert>::Output as Invert>::Output;
268
269
    assert_eq!(4, <Test4 as Unsigned>::to_u64());
270
    assert_eq!(5, <Test5 as Unsigned>::to_u64());
271
    assert_eq!(12, <Test12 as Unsigned>::to_u64());
272
    assert_eq!(16, <Test16 as Unsigned>::to_u64());
273
}
274
275
impl TrimTrailingZeros for InvertedUTerm {
276
    type Output = InvertedUTerm;
277
278
    #[inline]
279
0
    fn trim_trailing_zeros(self) -> Self::Output {
280
0
        InvertedUTerm
281
0
    }
282
}
283
284
impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B1> {
285
    type Output = Self;
286
287
    #[inline]
288
0
    fn trim_trailing_zeros(self) -> Self::Output {
289
0
        self
290
0
    }
291
}
292
293
impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B0>
294
where
295
    IU: TrimTrailingZeros,
296
{
297
    type Output = <IU as TrimTrailingZeros>::Output;
298
299
    #[inline]
300
0
    fn trim_trailing_zeros(self) -> Self::Output {
301
0
        self.msb.trim_trailing_zeros()
302
0
    }
303
}
304
305
impl<U: Unsigned> Trim for U
306
where
307
    U: Invert,
308
    <U as Invert>::Output: TrimTrailingZeros,
309
    <<U as Invert>::Output as TrimTrailingZeros>::Output: Invert,
310
{
311
    type Output = <<<U as Invert>::Output as TrimTrailingZeros>::Output as Invert>::Output;
312
313
    #[inline]
314
0
    fn trim(self) -> Self::Output {
315
0
        self.invert().trim_trailing_zeros().invert()
316
0
    }
317
}
318
319
// Note: Trimming is tested when we do subtraction.
320
321
pub trait PrivateCmp<Rhs, SoFar> {
322
    type Output;
323
324
    fn private_cmp(&self, _: &Rhs, _: SoFar) -> Self::Output;
325
}
326
pub type PrivateCmpOut<A, Rhs, SoFar> = <A as PrivateCmp<Rhs, SoFar>>::Output;
327
328
// Set Bit
329
pub trait PrivateSetBit<I, B> {
330
    type Output;
331
332
    fn private_set_bit(self, _: I, _: B) -> Self::Output;
333
}
334
pub type PrivateSetBitOut<N, I, B> = <N as PrivateSetBit<I, B>>::Output;
335
336
// Div
337
pub trait PrivateDiv<N, D, Q, R, I> {
338
    type Quotient;
339
    type Remainder;
340
341
    fn private_div_quotient(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Quotient;
342
343
    fn private_div_remainder(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Remainder;
344
}
345
346
pub type PrivateDivQuot<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Quotient;
347
pub type PrivateDivRem<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Remainder;
348
349
pub trait PrivateDivIf<N, D, Q, R, I, RcmpD> {
350
    type Quotient;
351
    type Remainder;
352
353
    fn private_div_if_quotient(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Quotient;
354
355
    fn private_div_if_remainder(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Remainder;
356
}
357
358
pub type PrivateDivIfQuot<N, D, Q, R, I, RcmpD> =
359
    <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Quotient;
360
pub type PrivateDivIfRem<N, D, Q, R, I, RcmpD> =
361
    <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Remainder;
362
363
// Div for signed ints
364
pub trait PrivateDivInt<C, Divisor> {
365
    type Output;
366
367
    fn private_div_int(self, _: C, _: Divisor) -> Self::Output;
368
}
369
pub type PrivateDivIntOut<A, C, Divisor> = <A as PrivateDivInt<C, Divisor>>::Output;
370
371
pub trait PrivateRem<URem, Divisor> {
372
    type Output;
373
374
    fn private_rem(self, _: URem, _: Divisor) -> Self::Output;
375
}
376
pub type PrivateRemOut<A, URem, Divisor> = <A as PrivateRem<URem, Divisor>>::Output;
377
378
// min max
379
pub trait PrivateMin<Rhs, CmpResult> {
380
    type Output;
381
    fn private_min(self, rhs: Rhs) -> Self::Output;
382
}
383
pub type PrivateMinOut<A, B, CmpResult> = <A as PrivateMin<B, CmpResult>>::Output;
384
385
pub trait PrivateMax<Rhs, CmpResult> {
386
    type Output;
387
    fn private_max(self, rhs: Rhs) -> Self::Output;
388
}
389
pub type PrivateMaxOut<A, B, CmpResult> = <A as PrivateMax<B, CmpResult>>::Output;
390
391
// Comparisons
392
393
use crate::{Equal, False, Greater, Less, True};
394
395
pub trait IsLessPrivate<Rhs, Cmp> {
396
    type Output: Bit;
397
398
    fn is_less_private(self, _: Rhs, _: Cmp) -> Self::Output;
399
}
400
401
impl<A, B> IsLessPrivate<B, Less> for A {
402
    type Output = True;
403
404
    #[inline]
405
0
    fn is_less_private(self, _: B, _: Less) -> Self::Output {
406
0
        B1
407
0
    }
408
}
409
impl<A, B> IsLessPrivate<B, Equal> for A {
410
    type Output = False;
411
412
    #[inline]
413
0
    fn is_less_private(self, _: B, _: Equal) -> Self::Output {
414
0
        B0
415
0
    }
416
}
417
impl<A, B> IsLessPrivate<B, Greater> for A {
418
    type Output = False;
419
420
    #[inline]
421
0
    fn is_less_private(self, _: B, _: Greater) -> Self::Output {
422
0
        B0
423
0
    }
424
}
425
426
pub trait IsEqualPrivate<Rhs, Cmp> {
427
    type Output: Bit;
428
429
    fn is_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
430
}
431
432
impl<A, B> IsEqualPrivate<B, Less> for A {
433
    type Output = False;
434
435
    #[inline]
436
0
    fn is_equal_private(self, _: B, _: Less) -> Self::Output {
437
0
        B0
438
0
    }
439
}
440
impl<A, B> IsEqualPrivate<B, Equal> for A {
441
    type Output = True;
442
443
    #[inline]
444
0
    fn is_equal_private(self, _: B, _: Equal) -> Self::Output {
445
0
        B1
446
0
    }
447
}
448
impl<A, B> IsEqualPrivate<B, Greater> for A {
449
    type Output = False;
450
451
    #[inline]
452
0
    fn is_equal_private(self, _: B, _: Greater) -> Self::Output {
453
0
        B0
454
0
    }
455
}
456
457
pub trait IsGreaterPrivate<Rhs, Cmp> {
458
    type Output: Bit;
459
460
    fn is_greater_private(self, _: Rhs, _: Cmp) -> Self::Output;
461
}
462
463
impl<A, B> IsGreaterPrivate<B, Less> for A {
464
    type Output = False;
465
466
    #[inline]
467
0
    fn is_greater_private(self, _: B, _: Less) -> Self::Output {
468
0
        B0
469
0
    }
470
}
471
impl<A, B> IsGreaterPrivate<B, Equal> for A {
472
    type Output = False;
473
474
    #[inline]
475
0
    fn is_greater_private(self, _: B, _: Equal) -> Self::Output {
476
0
        B0
477
0
    }
478
}
479
impl<A, B> IsGreaterPrivate<B, Greater> for A {
480
    type Output = True;
481
482
    #[inline]
483
0
    fn is_greater_private(self, _: B, _: Greater) -> Self::Output {
484
0
        B1
485
0
    }
486
}
487
488
pub trait IsLessOrEqualPrivate<Rhs, Cmp> {
489
    type Output: Bit;
490
491
    fn is_less_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
492
}
493
494
impl<A, B> IsLessOrEqualPrivate<B, Less> for A {
495
    type Output = True;
496
497
    #[inline]
498
0
    fn is_less_or_equal_private(self, _: B, _: Less) -> Self::Output {
499
0
        B1
500
0
    }
501
}
502
impl<A, B> IsLessOrEqualPrivate<B, Equal> for A {
503
    type Output = True;
504
505
    #[inline]
506
0
    fn is_less_or_equal_private(self, _: B, _: Equal) -> Self::Output {
507
0
        B1
508
0
    }
509
}
510
impl<A, B> IsLessOrEqualPrivate<B, Greater> for A {
511
    type Output = False;
512
513
    #[inline]
514
0
    fn is_less_or_equal_private(self, _: B, _: Greater) -> Self::Output {
515
0
        B0
516
0
    }
517
}
518
519
pub trait IsNotEqualPrivate<Rhs, Cmp> {
520
    type Output: Bit;
521
522
    fn is_not_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
523
}
524
525
impl<A, B> IsNotEqualPrivate<B, Less> for A {
526
    type Output = True;
527
528
    #[inline]
529
0
    fn is_not_equal_private(self, _: B, _: Less) -> Self::Output {
530
0
        B1
531
0
    }
532
}
533
impl<A, B> IsNotEqualPrivate<B, Equal> for A {
534
    type Output = False;
535
536
    #[inline]
537
0
    fn is_not_equal_private(self, _: B, _: Equal) -> Self::Output {
538
0
        B0
539
0
    }
540
}
541
impl<A, B> IsNotEqualPrivate<B, Greater> for A {
542
    type Output = True;
543
544
    #[inline]
545
0
    fn is_not_equal_private(self, _: B, _: Greater) -> Self::Output {
546
0
        B1
547
0
    }
548
}
549
550
pub trait IsGreaterOrEqualPrivate<Rhs, Cmp> {
551
    type Output: Bit;
552
553
    fn is_greater_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
554
}
555
556
impl<A, B> IsGreaterOrEqualPrivate<B, Less> for A {
557
    type Output = False;
558
559
    #[inline]
560
0
    fn is_greater_or_equal_private(self, _: B, _: Less) -> Self::Output {
561
0
        B0
562
0
    }
563
}
564
impl<A, B> IsGreaterOrEqualPrivate<B, Equal> for A {
565
    type Output = True;
566
567
    #[inline]
568
0
    fn is_greater_or_equal_private(self, _: B, _: Equal) -> Self::Output {
569
0
        B1
570
0
    }
571
}
572
impl<A, B> IsGreaterOrEqualPrivate<B, Greater> for A {
573
    type Output = True;
574
575
    #[inline]
576
0
    fn is_greater_or_equal_private(self, _: B, _: Greater) -> Self::Output {
577
0
        B1
578
0
    }
579
}
580
581
pub trait PrivateSquareRoot {
582
    type Output;
583
}
584
585
pub trait PrivateLogarithm2 {
586
    type Output;
587
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typenum-1.17.0/src/type_operators.rs
Line
Count
Source
1
//! Useful **type operators** that are not defined in `core::ops`.
2
3
use crate::{
4
    private::{Internal, InternalMarker},
5
    Bit, NInt, NonZero, PInt, UInt, UTerm, Unsigned, Z0,
6
};
7
8
/// A **type operator** that ensures that `Rhs` is the same as `Self`, it is mainly useful
9
/// for writing macros that can take arbitrary binary or unary operators.
10
///
11
/// `Same` is implemented generically for all types; it should never need to be implemented
12
/// for anything else.
13
///
14
/// Note that Rust lazily evaluates types, so this will only fail for two different types if
15
/// the `Output` is used.
16
///
17
/// # Example
18
/// ```rust
19
/// use typenum::{Same, Unsigned, U4, U5};
20
///
21
/// assert_eq!(<U5 as Same<U5>>::Output::to_u32(), 5);
22
///
23
/// // Only an error if we use it:
24
/// # #[allow(dead_code)]
25
/// type Undefined = <U5 as Same<U4>>::Output;
26
/// // Compiler error:
27
/// // Undefined::to_u32();
28
/// ```
29
pub trait Same<Rhs = Self> {
30
    /// Should always be `Self`
31
    type Output;
32
}
33
34
impl<T> Same<T> for T {
35
    type Output = T;
36
}
37
38
/// A **type operator** that returns the absolute value.
39
///
40
/// # Example
41
/// ```rust
42
/// use typenum::{Abs, Integer, N5};
43
///
44
/// assert_eq!(<N5 as Abs>::Output::to_i32(), 5);
45
/// ```
46
pub trait Abs {
47
    /// The absolute value.
48
    type Output;
49
}
50
51
impl Abs for Z0 {
52
    type Output = Z0;
53
}
54
55
impl<U: Unsigned + NonZero> Abs for PInt<U> {
56
    type Output = Self;
57
}
58
59
impl<U: Unsigned + NonZero> Abs for NInt<U> {
60
    type Output = PInt<U>;
61
}
62
63
/// A **type operator** that provides exponentiation by repeated squaring.
64
///
65
/// # Example
66
/// ```rust
67
/// use typenum::{Integer, Pow, N3, P3};
68
///
69
/// assert_eq!(<N3 as Pow<P3>>::Output::to_i32(), -27);
70
/// ```
71
pub trait Pow<Exp> {
72
    /// The result of the exponentiation.
73
    type Output;
74
    /// This function isn't used in this crate, but may be useful for others.
75
    /// It is implemented for primitives.
76
    ///
77
    /// # Example
78
    /// ```rust
79
    /// use typenum::{Pow, U3};
80
    ///
81
    /// let a = 7u32.powi(U3::new());
82
    /// let b = 7u32.pow(3);
83
    /// assert_eq!(a, b);
84
    ///
85
    /// let x = 3.0.powi(U3::new());
86
    /// let y = 27.0;
87
    /// assert_eq!(x, y);
88
    /// ```
89
    fn powi(self, exp: Exp) -> Self::Output;
90
}
91
92
macro_rules! impl_pow_f {
93
    ($t:ty) => {
94
        impl Pow<UTerm> for $t {
95
            type Output = $t;
96
            #[inline]
97
0
            fn powi(self, _: UTerm) -> Self::Output {
98
0
                1.0
99
0
            }
Unexecuted instantiation: _RNvXs8_NtCs5VhUk8EIQ63_7typenum14type_operatorsfINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
Unexecuted instantiation: _RNvXsd_NtCs5VhUk8EIQ63_7typenum14type_operatorsdINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
100
        }
101
102
        impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t {
103
            type Output = $t;
104
            // powi is unstable in core, so we have to write this function ourselves.
105
            // copied from num::pow::pow
106
            #[inline]
107
0
            fn powi(self, _: UInt<U, B>) -> Self::Output {
108
0
                let mut exp = <UInt<U, B> as Unsigned>::to_u32();
109
0
                let mut base = self;
110
0
111
0
                if exp == 0 {
112
0
                    return 1.0;
113
0
                }
114
115
0
                while exp & 1 == 0 {
116
0
                    base *= base;
117
0
                    exp >>= 1;
118
0
                }
119
0
                if exp == 1 {
120
0
                    return base;
121
0
                }
122
0
123
0
                let mut acc = base.clone();
124
0
                while exp > 1 {
125
0
                    exp >>= 1;
126
0
                    base *= base;
127
0
                    if exp & 1 == 1 {
128
0
                        acc *= base.clone();
129
0
                    }
130
                }
131
0
                acc
132
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorss9_0ppEfINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorsse_0ppEdINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
133
        }
134
135
        impl Pow<Z0> for $t {
136
            type Output = $t;
137
            #[inline]
138
0
            fn powi(self, _: Z0) -> Self::Output {
139
0
                1.0
140
0
            }
Unexecuted instantiation: _RNvXsa_NtCs5VhUk8EIQ63_7typenum14type_operatorsfINtB5_3PowNtNtB7_3int2Z0E4powiB7_
Unexecuted instantiation: _RNvXsf_NtCs5VhUk8EIQ63_7typenum14type_operatorsdINtB5_3PowNtNtB7_3int2Z0E4powiB7_
141
        }
142
143
        impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t {
144
            type Output = $t;
145
            // powi is unstable in core, so we have to write this function ourselves.
146
            // copied from num::pow::pow
147
            #[inline]
148
0
            fn powi(self, _: PInt<U>) -> Self::Output {
149
0
                let mut exp = U::to_u32();
150
0
                let mut base = self;
151
0
152
0
                if exp == 0 {
153
0
                    return 1.0;
154
0
                }
155
156
0
                while exp & 1 == 0 {
157
0
                    base *= base;
158
0
                    exp >>= 1;
159
0
                }
160
0
                if exp == 1 {
161
0
                    return base;
162
0
                }
163
0
164
0
                let mut acc = base.clone();
165
0
                while exp > 1 {
166
0
                    exp >>= 1;
167
0
                    base *= base;
168
0
                    if exp & 1 == 1 {
169
0
                        acc *= base.clone();
170
0
                    }
171
                }
172
0
                acc
173
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssb_0pEfINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssg_0pEdINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
174
        }
175
176
        impl<U: Unsigned + NonZero> Pow<NInt<U>> for $t {
177
            type Output = $t;
178
179
            #[inline]
180
0
            fn powi(self, _: NInt<U>) -> Self::Output {
181
0
                <$t as Pow<PInt<U>>>::powi(self, PInt::new()).recip()
182
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssc_0pEfINtB5_3PowINtNtB7_3int4NIntpEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssh_0pEdINtB5_3PowINtNtB7_3int4NIntpEE4powiB7_
183
        }
184
    };
185
}
186
187
impl_pow_f!(f32);
188
impl_pow_f!(f64);
189
190
macro_rules! impl_pow_i {
191
    () => ();
192
    ($(#[$meta:meta])*  $t: ty $(, $tail:tt)*) => (
193
        $(#[$meta])*
194
        impl Pow<UTerm> for $t {
195
            type Output = $t;
196
            #[inline]
197
0
            fn powi(self, _: UTerm) -> Self::Output {
198
0
                1
199
0
            }
Unexecuted instantiation: _RNvXsi_NtCs5VhUk8EIQ63_7typenum14type_operatorshINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
Unexecuted instantiation: _RNvXsm_NtCs5VhUk8EIQ63_7typenum14type_operatorstINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
Unexecuted instantiation: _RNvXsq_NtCs5VhUk8EIQ63_7typenum14type_operatorsmINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
Unexecuted instantiation: _RNvXsu_NtCs5VhUk8EIQ63_7typenum14type_operatorsyINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
Unexecuted instantiation: _RNvXsy_NtCs5VhUk8EIQ63_7typenum14type_operatorsjINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
Unexecuted instantiation: _RNvXsC_NtCs5VhUk8EIQ63_7typenum14type_operatorsaINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
Unexecuted instantiation: _RNvXsG_NtCs5VhUk8EIQ63_7typenum14type_operatorssINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
Unexecuted instantiation: _RNvXsK_NtCs5VhUk8EIQ63_7typenum14type_operatorslINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
Unexecuted instantiation: _RNvXsO_NtCs5VhUk8EIQ63_7typenum14type_operatorsxINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
Unexecuted instantiation: _RNvXsS_NtCs5VhUk8EIQ63_7typenum14type_operatorsiINtB5_3PowNtNtB7_4uint5UTermE4powiB7_
200
        }
201
202
        $(#[$meta])*
203
        impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t {
204
            type Output = $t;
205
            #[inline]
206
0
            fn powi(self, _: UInt<U, B>) -> Self::Output {
207
0
                self.pow(<UInt<U, B> as Unsigned>::to_u32())
208
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssj_0ppEhINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssn_0ppEtINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssr_0ppEmINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssv_0ppEyINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssz_0ppEjINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssD_0ppEaINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssH_0ppEsINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssL_0ppElINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssP_0ppExINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssT_0ppEiINtB5_3PowINtNtB7_4uint4UIntppEE4powiB7_
209
        }
210
211
        $(#[$meta])*
212
        impl Pow<Z0> for $t {
213
            type Output = $t;
214
            #[inline]
215
0
            fn powi(self, _: Z0) -> Self::Output {
216
0
                1
217
0
            }
Unexecuted instantiation: _RNvXsk_NtCs5VhUk8EIQ63_7typenum14type_operatorshINtB5_3PowNtNtB7_3int2Z0E4powiB7_
Unexecuted instantiation: _RNvXso_NtCs5VhUk8EIQ63_7typenum14type_operatorstINtB5_3PowNtNtB7_3int2Z0E4powiB7_
Unexecuted instantiation: _RNvXss_NtCs5VhUk8EIQ63_7typenum14type_operatorsmINtB5_3PowNtNtB7_3int2Z0E4powiB7_
Unexecuted instantiation: _RNvXsw_NtCs5VhUk8EIQ63_7typenum14type_operatorsyINtB5_3PowNtNtB7_3int2Z0E4powiB7_
Unexecuted instantiation: _RNvXsA_NtCs5VhUk8EIQ63_7typenum14type_operatorsjINtB5_3PowNtNtB7_3int2Z0E4powiB7_
Unexecuted instantiation: _RNvXsE_NtCs5VhUk8EIQ63_7typenum14type_operatorsaINtB5_3PowNtNtB7_3int2Z0E4powiB7_
Unexecuted instantiation: _RNvXsI_NtCs5VhUk8EIQ63_7typenum14type_operatorssINtB5_3PowNtNtB7_3int2Z0E4powiB7_
Unexecuted instantiation: _RNvXsM_NtCs5VhUk8EIQ63_7typenum14type_operatorslINtB5_3PowNtNtB7_3int2Z0E4powiB7_
Unexecuted instantiation: _RNvXsQ_NtCs5VhUk8EIQ63_7typenum14type_operatorsxINtB5_3PowNtNtB7_3int2Z0E4powiB7_
Unexecuted instantiation: _RNvXsU_NtCs5VhUk8EIQ63_7typenum14type_operatorsiINtB5_3PowNtNtB7_3int2Z0E4powiB7_
218
        }
219
220
        $(#[$meta])*
221
        impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t {
222
            type Output = $t;
223
            #[inline]
224
0
            fn powi(self, _: PInt<U>) -> Self::Output {
225
0
                self.pow(U::to_u32())
226
0
            }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssl_0pEhINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssp_0pEtINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorsst_0pEmINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssx_0pEyINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssB_0pEjINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssF_0pEaINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssJ_0pEsINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssN_0pElINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssR_0pExINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum14type_operatorssV_0pEiINtB5_3PowINtNtB7_3int4PIntpEE4powiB7_
227
        }
228
229
        impl_pow_i!($($tail),*);
230
    );
231
}
232
233
impl_pow_i!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
234
#[cfg(feature = "i128")]
235
impl_pow_i!(
236
    #[cfg_attr(docsrs, doc(cfg(feature = "i128")))]
237
    u128,
238
    i128
239
);
240
241
#[test]
242
fn pow_test() {
243
    use crate::consts::*;
244
    let z0 = Z0::new();
245
    let p3 = P3::new();
246
247
    let u0 = U0::new();
248
    let u3 = U3::new();
249
    let n3 = N3::new();
250
251
    macro_rules! check {
252
        ($x:ident) => {
253
            assert_eq!($x.powi(z0), 1);
254
            assert_eq!($x.powi(u0), 1);
255
256
            assert_eq!($x.powi(p3), $x * $x * $x);
257
            assert_eq!($x.powi(u3), $x * $x * $x);
258
        };
259
        ($x:ident, $f:ident) => {
260
            assert!((<$f as Pow<Z0>>::powi(*$x, z0) - 1.0).abs() < ::core::$f::EPSILON);
261
            assert!((<$f as Pow<U0>>::powi(*$x, u0) - 1.0).abs() < ::core::$f::EPSILON);
262
263
            assert!((<$f as Pow<P3>>::powi(*$x, p3) - $x * $x * $x).abs() < ::core::$f::EPSILON);
264
            assert!((<$f as Pow<U3>>::powi(*$x, u3) - $x * $x * $x).abs() < ::core::$f::EPSILON);
265
266
            if *$x == 0.0 {
267
                assert!(<$f as Pow<N3>>::powi(*$x, n3).is_infinite());
268
            } else {
269
                assert!(
270
                    (<$f as Pow<N3>>::powi(*$x, n3) - 1. / $x / $x / $x).abs()
271
                        < ::core::$f::EPSILON
272
                );
273
            }
274
        };
275
    }
276
277
    for x in &[0i8, -3, 2] {
278
        check!(x);
279
    }
280
    for x in &[0u8, 1, 5] {
281
        check!(x);
282
    }
283
    for x in &[0usize, 1, 5, 40] {
284
        check!(x);
285
    }
286
    for x in &[0isize, 1, 2, -30, -22, 48] {
287
        check!(x);
288
    }
289
    for x in &[0.0f32, 2.2, -3.5, 378.223] {
290
        check!(x, f32);
291
    }
292
    for x in &[0.0f64, 2.2, -3.5, -2387.2, 234.22] {
293
        check!(x, f64);
294
    }
295
}
296
297
/// A **type operator** for comparing `Self` and `Rhs`. It provides a similar functionality to
298
/// the function
299
/// [`core::cmp::Ord::cmp`](https://doc.rust-lang.org/nightly/core/cmp/trait.Ord.html#tymethod.cmp)
300
/// but for types.
301
///
302
/// # Example
303
/// ```rust
304
/// use typenum::{Cmp, Ord, N3, P2, P5};
305
/// use std::cmp::Ordering;
306
///
307
/// assert_eq!(<P2 as Cmp<N3>>::Output::to_ordering(), Ordering::Greater);
308
/// assert_eq!(<P2 as Cmp<P2>>::Output::to_ordering(), Ordering::Equal);
309
/// assert_eq!(<P2 as Cmp<P5>>::Output::to_ordering(), Ordering::Less);
310
pub trait Cmp<Rhs = Self> {
311
    /// The result of the comparison. It should only ever be one of `Greater`, `Less`, or `Equal`.
312
    type Output;
313
314
    #[doc(hidden)]
315
    fn compare<IM: InternalMarker>(&self, _: &Rhs) -> Self::Output;
316
}
317
318
/// A **type operator** that gives the length of an `Array` or the number of bits in a `UInt`.
319
pub trait Len {
320
    /// The length as a type-level unsigned integer.
321
    type Output: crate::Unsigned;
322
    /// This function isn't used in this crate, but may be useful for others.
323
    fn len(&self) -> Self::Output;
324
}
325
326
/// Division as a partial function. This **type operator** performs division just as `Div`, but is
327
/// only defined when the result is an integer (i.e. there is no remainder).
328
pub trait PartialDiv<Rhs = Self> {
329
    /// The type of the result of the division
330
    type Output;
331
    /// Method for performing the division
332
    fn partial_div(self, _: Rhs) -> Self::Output;
333
}
334
335
/// A **type operator** that returns the minimum of `Self` and `Rhs`.
336
pub trait Min<Rhs = Self> {
337
    /// The type of the minimum of `Self` and `Rhs`
338
    type Output;
339
    /// Method returning the minimum
340
    fn min(self, rhs: Rhs) -> Self::Output;
341
}
342
343
/// A **type operator** that returns the maximum of `Self` and `Rhs`.
344
pub trait Max<Rhs = Self> {
345
    /// The type of the maximum of `Self` and `Rhs`
346
    type Output;
347
    /// Method returning the maximum
348
    fn max(self, rhs: Rhs) -> Self::Output;
349
}
350
351
use crate::Compare;
352
353
/// A **type operator** that returns `True` if `Self < Rhs`, otherwise returns `False`.
354
pub trait IsLess<Rhs = Self> {
355
    /// The type representing either `True` or `False`
356
    type Output: Bit;
357
    /// Method returning `True` or `False`.
358
    fn is_less(self, rhs: Rhs) -> Self::Output;
359
}
360
361
use crate::private::IsLessPrivate;
362
impl<A, B> IsLess<B> for A
363
where
364
    A: Cmp<B> + IsLessPrivate<B, Compare<A, B>>,
365
{
366
    type Output = <A as IsLessPrivate<B, Compare<A, B>>>::Output;
367
368
    #[inline]
369
0
    fn is_less(self, rhs: B) -> Self::Output {
370
0
        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
371
0
        self.is_less_private(rhs, lhs_cmp_rhs)
372
0
    }
373
}
374
375
/// A **type operator** that returns `True` if `Self == Rhs`, otherwise returns `False`.
376
pub trait IsEqual<Rhs = Self> {
377
    /// The type representing either `True` or `False`
378
    type Output: Bit;
379
    /// Method returning `True` or `False`.
380
    fn is_equal(self, rhs: Rhs) -> Self::Output;
381
}
382
383
use crate::private::IsEqualPrivate;
384
impl<A, B> IsEqual<B> for A
385
where
386
    A: Cmp<B> + IsEqualPrivate<B, Compare<A, B>>,
387
{
388
    type Output = <A as IsEqualPrivate<B, Compare<A, B>>>::Output;
389
390
    #[inline]
391
0
    fn is_equal(self, rhs: B) -> Self::Output {
392
0
        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
393
0
        self.is_equal_private(rhs, lhs_cmp_rhs)
394
0
    }
395
}
396
397
/// A **type operator** that returns `True` if `Self > Rhs`, otherwise returns `False`.
398
pub trait IsGreater<Rhs = Self> {
399
    /// The type representing either `True` or `False`
400
    type Output: Bit;
401
    /// Method returning `True` or `False`.
402
    fn is_greater(self, rhs: Rhs) -> Self::Output;
403
}
404
405
use crate::private::IsGreaterPrivate;
406
impl<A, B> IsGreater<B> for A
407
where
408
    A: Cmp<B> + IsGreaterPrivate<B, Compare<A, B>>,
409
{
410
    type Output = <A as IsGreaterPrivate<B, Compare<A, B>>>::Output;
411
412
    #[inline]
413
0
    fn is_greater(self, rhs: B) -> Self::Output {
414
0
        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
415
0
        self.is_greater_private(rhs, lhs_cmp_rhs)
416
0
    }
417
}
418
419
/// A **type operator** that returns `True` if `Self <= Rhs`, otherwise returns `False`.
420
pub trait IsLessOrEqual<Rhs = Self> {
421
    /// The type representing either `True` or `False`
422
    type Output: Bit;
423
    /// Method returning `True` or `False`.
424
    fn is_less_or_equal(self, rhs: Rhs) -> Self::Output;
425
}
426
427
use crate::private::IsLessOrEqualPrivate;
428
impl<A, B> IsLessOrEqual<B> for A
429
where
430
    A: Cmp<B> + IsLessOrEqualPrivate<B, Compare<A, B>>,
431
{
432
    type Output = <A as IsLessOrEqualPrivate<B, Compare<A, B>>>::Output;
433
434
    #[inline]
435
0
    fn is_less_or_equal(self, rhs: B) -> Self::Output {
436
0
        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
437
0
        self.is_less_or_equal_private(rhs, lhs_cmp_rhs)
438
0
    }
439
}
440
441
/// A **type operator** that returns `True` if `Self != Rhs`, otherwise returns `False`.
442
pub trait IsNotEqual<Rhs = Self> {
443
    /// The type representing either `True` or `False`
444
    type Output: Bit;
445
    /// Method returning `True` or `False`.
446
    fn is_not_equal(self, rhs: Rhs) -> Self::Output;
447
}
448
449
use crate::private::IsNotEqualPrivate;
450
impl<A, B> IsNotEqual<B> for A
451
where
452
    A: Cmp<B> + IsNotEqualPrivate<B, Compare<A, B>>,
453
{
454
    type Output = <A as IsNotEqualPrivate<B, Compare<A, B>>>::Output;
455
456
    #[inline]
457
0
    fn is_not_equal(self, rhs: B) -> Self::Output {
458
0
        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
459
0
        self.is_not_equal_private(rhs, lhs_cmp_rhs)
460
0
    }
461
}
462
463
/// A **type operator** that returns `True` if `Self >= Rhs`, otherwise returns `False`.
464
pub trait IsGreaterOrEqual<Rhs = Self> {
465
    /// The type representing either `True` or `False`
466
    type Output: Bit;
467
    /// Method returning `True` or `False`.
468
    fn is_greater_or_equal(self, rhs: Rhs) -> Self::Output;
469
}
470
471
use crate::private::IsGreaterOrEqualPrivate;
472
impl<A, B> IsGreaterOrEqual<B> for A
473
where
474
    A: Cmp<B> + IsGreaterOrEqualPrivate<B, Compare<A, B>>,
475
{
476
    type Output = <A as IsGreaterOrEqualPrivate<B, Compare<A, B>>>::Output;
477
478
    #[inline]
479
0
    fn is_greater_or_equal(self, rhs: B) -> Self::Output {
480
0
        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
481
0
        self.is_greater_or_equal_private(rhs, lhs_cmp_rhs)
482
0
    }
483
}
484
485
/**
486
A convenience macro for comparing type numbers. Use `op!` instead.
487
488
Due to the intricacies of the macro system, if the left-hand operand is more complex than a simple
489
`ident`, you must place a comma between it and the comparison sign.
490
491
For example, you can do `cmp!(P5 > P3)` or `cmp!(typenum::P5, > typenum::P3)` but not
492
`cmp!(typenum::P5 > typenum::P3)`.
493
494
The result of this comparison will always be one of `True` (aka `B1`) or `False` (aka `B0`).
495
496
# Example
497
```rust
498
#[macro_use] extern crate typenum;
499
use typenum::consts::*;
500
use typenum::Bit;
501
502
fn main() {
503
type Result = cmp!(P9 == op!(P1 + P2 * (P2 - N2)));
504
assert_eq!(Result::to_bool(), true);
505
}
506
```
507
 */
508
#[deprecated(since = "1.9.0", note = "use the `op!` macro instead")]
509
#[macro_export]
510
macro_rules! cmp {
511
    ($a:ident < $b:ty) => {
512
        <$a as $crate::IsLess<$b>>::Output
513
    };
514
    ($a:ty, < $b:ty) => {
515
        <$a as $crate::IsLess<$b>>::Output
516
    };
517
518
    ($a:ident == $b:ty) => {
519
        <$a as $crate::IsEqual<$b>>::Output
520
    };
521
    ($a:ty, == $b:ty) => {
522
        <$a as $crate::IsEqual<$b>>::Output
523
    };
524
525
    ($a:ident > $b:ty) => {
526
        <$a as $crate::IsGreater<$b>>::Output
527
    };
528
    ($a:ty, > $b:ty) => {
529
        <$a as $crate::IsGreater<$b>>::Output
530
    };
531
532
    ($a:ident <= $b:ty) => {
533
        <$a as $crate::IsLessOrEqual<$b>>::Output
534
    };
535
    ($a:ty, <= $b:ty) => {
536
        <$a as $crate::IsLessOrEqual<$b>>::Output
537
    };
538
539
    ($a:ident != $b:ty) => {
540
        <$a as $crate::IsNotEqual<$b>>::Output
541
    };
542
    ($a:ty, != $b:ty) => {
543
        <$a as $crate::IsNotEqual<$b>>::Output
544
    };
545
546
    ($a:ident >= $b:ty) => {
547
        <$a as $crate::IsGreaterOrEqual<$b>>::Output
548
    };
549
    ($a:ty, >= $b:ty) => {
550
        <$a as $crate::IsGreaterOrEqual<$b>>::Output
551
    };
552
}
553
554
/// A **type operator** for taking the integer square root of `Self`.
555
///
556
/// The integer square root of `n` is the largest integer `m` such
557
/// that `n >= m*m`. This definition is equivalent to truncating the
558
/// real-valued square root: `floor(real_sqrt(n))`.
559
pub trait SquareRoot {
560
    /// The result of the integer square root.
561
    type Output;
562
}
563
564
/// A **type operator** for taking the integer binary logarithm of `Self`.
565
///
566
/// The integer binary logarighm of `n` is the largest integer `m` such
567
/// that `n >= 2^m`. This definition is equivalent to truncating the
568
/// real-valued binary logarithm: `floor(log2(n))`.
569
pub trait Logarithm2 {
570
    /// The result of the integer binary logarithm.
571
    type Output;
572
}
573
574
/// A **type operator** that computes the [greatest common divisor][gcd] of `Self` and `Rhs`.
575
///
576
/// [gcd]: https://en.wikipedia.org/wiki/Greatest_common_divisor
577
///
578
/// # Example
579
///
580
/// ```rust
581
/// use typenum::{Gcd, Unsigned, U12, U8};
582
///
583
/// assert_eq!(<U12 as Gcd<U8>>::Output::to_i32(), 4);
584
/// ```
585
pub trait Gcd<Rhs> {
586
    /// The greatest common divisor.
587
    type Output;
588
}
589
590
/// A **type operator** for taking a concrete integer value from a type.
591
///
592
/// It returns arbitrary integer value without explicitly specifying the
593
/// type. It is useful when you pass the values to methods that accept
594
/// distinct types without runtime casting.
595
pub trait ToInt<T> {
596
    /// Method returning the concrete value for the type.
597
    fn to_int() -> T;
598
    /// The concrete value for the type. Can be used in `const` contexts.
599
    const INT: T;
600
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typenum-1.17.0/src/uint.rs
Line
Count
Source
1
//! Type-level unsigned integers.
2
//!
3
//!
4
//! **Type operators** implemented:
5
//!
6
//! From `::core::ops`: `BitAnd`, `BitOr`, `BitXor`, `Shl`, `Shr`, `Add`, `Sub`,
7
//!                 `Mul`, `Div`, and `Rem`.
8
//! From `typenum`: `Same`, `Cmp`, and `Pow`.
9
//!
10
//! Rather than directly using the structs defined in this module, it is recommended that
11
//! you import and use the relevant aliases from the [consts](../consts/index.html) module.
12
//!
13
//! # Example
14
//! ```rust
15
//! use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub};
16
//! use typenum::{Unsigned, U1, U2, U3, U4};
17
//!
18
//! assert_eq!(<U3 as BitAnd<U2>>::Output::to_u32(), 2);
19
//! assert_eq!(<U3 as BitOr<U4>>::Output::to_u32(), 7);
20
//! assert_eq!(<U3 as BitXor<U2>>::Output::to_u32(), 1);
21
//! assert_eq!(<U3 as Shl<U1>>::Output::to_u32(), 6);
22
//! assert_eq!(<U3 as Shr<U1>>::Output::to_u32(), 1);
23
//! assert_eq!(<U3 as Add<U2>>::Output::to_u32(), 5);
24
//! assert_eq!(<U3 as Sub<U2>>::Output::to_u32(), 1);
25
//! assert_eq!(<U3 as Mul<U2>>::Output::to_u32(), 6);
26
//! assert_eq!(<U3 as Div<U2>>::Output::to_u32(), 1);
27
//! assert_eq!(<U3 as Rem<U2>>::Output::to_u32(), 1);
28
//! ```
29
30
use crate::{
31
    bit::{Bit, B0, B1},
32
    consts::{U0, U1},
33
    private::{
34
        BitDiff, BitDiffOut, Internal, InternalMarker, PrivateAnd, PrivateAndOut, PrivateCmp,
35
        PrivateCmpOut, PrivateLogarithm2, PrivatePow, PrivatePowOut, PrivateSquareRoot, PrivateSub,
36
        PrivateSubOut, PrivateXor, PrivateXorOut, Trim, TrimOut,
37
    },
38
    Add1, Cmp, Double, Equal, Gcd, Gcf, GrEq, Greater, IsGreaterOrEqual, Len, Length, Less, Log2,
39
    Logarithm2, Maximum, Minimum, NonZero, Or, Ord, Pow, Prod, Shleft, Shright, Sqrt, Square,
40
    SquareRoot, Sub1, Sum, ToInt, Zero,
41
};
42
use core::ops::{Add, BitAnd, BitOr, BitXor, Mul, Shl, Shr, Sub};
43
44
pub use crate::marker_traits::{PowerOfTwo, Unsigned};
45
46
/// The terminating type for `UInt`; it always comes after the most significant
47
/// bit. `UTerm` by itself represents zero, which is aliased to `U0`.
48
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
49
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
50
pub struct UTerm;
51
52
impl UTerm {
53
    /// Instantiates a singleton representing this unsigned integer.
54
    #[inline]
55
0
    pub fn new() -> UTerm {
56
0
        UTerm
57
0
    }
58
}
59
60
impl Unsigned for UTerm {
61
    const U8: u8 = 0;
62
    const U16: u16 = 0;
63
    const U32: u32 = 0;
64
    const U64: u64 = 0;
65
    #[cfg(feature = "i128")]
66
    const U128: u128 = 0;
67
    const USIZE: usize = 0;
68
69
    const I8: i8 = 0;
70
    const I16: i16 = 0;
71
    const I32: i32 = 0;
72
    const I64: i64 = 0;
73
    #[cfg(feature = "i128")]
74
    const I128: i128 = 0;
75
    const ISIZE: isize = 0;
76
77
    #[inline]
78
0
    fn to_u8() -> u8 {
79
0
        0
80
0
    }
81
    #[inline]
82
0
    fn to_u16() -> u16 {
83
0
        0
84
0
    }
85
    #[inline]
86
0
    fn to_u32() -> u32 {
87
0
        0
88
0
    }
89
    #[inline]
90
0
    fn to_u64() -> u64 {
91
0
        0
92
0
    }
93
    #[cfg(feature = "i128")]
94
    #[inline]
95
    fn to_u128() -> u128 {
96
        0
97
    }
98
    #[inline]
99
4.90k
    fn to_usize() -> usize {
100
4.90k
        0
101
4.90k
    }
Unexecuted instantiation: _RNvXs_NtCs5VhUk8EIQ63_7typenum4uintNtB4_5UTermNtNtB6_13marker_traits8Unsigned8to_usizeCs568wuOlRYFZ_8chia_bls
_RNvXs_NtCs5VhUk8EIQ63_7typenum4uintNtB4_5UTermNtNtB6_13marker_traits8Unsigned8to_usizeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
99
3.64k
    fn to_usize() -> usize {
100
3.64k
        0
101
3.64k
    }
_RNvXs_NtCs5VhUk8EIQ63_7typenum4uintNtB4_5UTermNtNtB6_13marker_traits8Unsigned8to_usizeCsjewTDwKBbyD_4k256
Line
Count
Source
99
1.26k
    fn to_usize() -> usize {
100
1.26k
        0
101
1.26k
    }
Unexecuted instantiation: _RNvXs_NtCs5VhUk8EIQ63_7typenum4uintNtB4_5UTermNtNtB6_13marker_traits8Unsigned8to_usizeB6_
102
103
    #[inline]
104
0
    fn to_i8() -> i8 {
105
0
        0
106
0
    }
107
    #[inline]
108
0
    fn to_i16() -> i16 {
109
0
        0
110
0
    }
111
    #[inline]
112
0
    fn to_i32() -> i32 {
113
0
        0
114
0
    }
115
    #[inline]
116
0
    fn to_i64() -> i64 {
117
0
        0
118
0
    }
119
    #[cfg(feature = "i128")]
120
    #[inline]
121
    fn to_i128() -> i128 {
122
        0
123
    }
124
    #[inline]
125
0
    fn to_isize() -> isize {
126
0
        0
127
0
    }
128
}
129
130
/// `UInt` is defined recursively, where `B` is the least significant bit and `U` is the rest
131
/// of the number. Conceptually, `U` should be bound by the trait `Unsigned` and `B` should
132
/// be bound by the trait `Bit`, but enforcing these bounds causes linear instead of
133
/// logrithmic scaling in some places, so they are left off for now. They may be enforced in
134
/// future.
135
///
136
/// In order to keep numbers unique, leading zeros are not allowed, so `UInt<UTerm, B0>` is
137
/// forbidden.
138
///
139
/// # Example
140
/// ```rust
141
/// use typenum::{UInt, UTerm, B0, B1};
142
///
143
/// # #[allow(dead_code)]
144
/// type U6 = UInt<UInt<UInt<UTerm, B1>, B1>, B0>;
145
/// ```
146
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
147
#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
148
pub struct UInt<U, B> {
149
    /// The more significant bits of `Self`.
150
    pub(crate) msb: U,
151
    /// The least significant bit of `Self`.
152
    pub(crate) lsb: B,
153
}
154
155
impl<U: Unsigned, B: Bit> UInt<U, B> {
156
    /// Instantiates a singleton representing this unsigned integer.
157
    #[inline]
158
0
    pub fn new() -> UInt<U, B> {
159
0
        UInt::default()
160
0
    }
161
}
162
163
impl<U: Unsigned, B: Bit> Unsigned for UInt<U, B> {
164
    const U8: u8 = B::U8 | U::U8 << 1;
165
    const U16: u16 = B::U8 as u16 | U::U16 << 1;
166
    const U32: u32 = B::U8 as u32 | U::U32 << 1;
167
    const U64: u64 = B::U8 as u64 | U::U64 << 1;
168
    #[cfg(feature = "i128")]
169
    const U128: u128 = B::U8 as u128 | U::U128 << 1;
170
    const USIZE: usize = B::U8 as usize | U::USIZE << 1;
171
172
    const I8: i8 = B::U8 as i8 | U::I8 << 1;
173
    const I16: i16 = B::U8 as i16 | U::I16 << 1;
174
    const I32: i32 = B::U8 as i32 | U::I32 << 1;
175
    const I64: i64 = B::U8 as i64 | U::I64 << 1;
176
    #[cfg(feature = "i128")]
177
    const I128: i128 = B::U8 as i128 | U::I128 << 1;
178
    const ISIZE: isize = B::U8 as isize | U::ISIZE << 1;
179
180
    #[inline]
181
0
    fn to_u8() -> u8 {
182
0
        B::to_u8() | U::to_u8() << 1
183
0
    }
184
    #[inline]
185
0
    fn to_u16() -> u16 {
186
0
        u16::from(B::to_u8()) | U::to_u16() << 1
187
0
    }
188
    #[inline]
189
0
    fn to_u32() -> u32 {
190
0
        u32::from(B::to_u8()) | U::to_u32() << 1
191
0
    }
192
    #[inline]
193
0
    fn to_u64() -> u64 {
194
0
        u64::from(B::to_u8()) | U::to_u64() << 1
195
0
    }
196
    #[cfg(feature = "i128")]
197
    #[inline]
198
    fn to_u128() -> u128 {
199
        u128::from(B::to_u8()) | U::to_u128() << 1
200
    }
201
    #[inline]
202
29.4k
    fn to_usize() -> usize {
203
29.4k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
29.4k
    }
Unexecuted instantiation: _RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_IBz_IBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB1g_2B0EB1t_EB1t_EB1t_EB1t_ENtNtB7_13marker_traits8Unsigned8to_usizeCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_IBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB1c_2B0EB1p_EB1p_EB1p_ENtNtB7_13marker_traits8Unsigned8to_usizeCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB18_2B0EB1l_EB1l_ENtNtB7_13marker_traits8Unsigned8to_usizeCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB14_2B0EB1h_ENtNtB7_13marker_traits8Unsigned8to_usizeCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_NtB5_5UTermNtNtB7_3bit2B1ENtB10_2B0ENtNtB7_13marker_traits8Unsigned8to_usizeCs568wuOlRYFZ_8chia_bls
Unexecuted instantiation: _RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntNtB5_5UTermNtNtB7_3bit2B1ENtNtB7_13marker_traits8Unsigned8to_usizeCs568wuOlRYFZ_8chia_bls
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_IBz_IBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB1g_2B0EB1t_EB1t_EB1t_EB1t_ENtNtB7_13marker_traits8Unsigned8to_usizeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
202
3.64k
    fn to_usize() -> usize {
203
3.64k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
3.64k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_IBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB1c_2B0EB1p_EB1p_EB1p_ENtNtB7_13marker_traits8Unsigned8to_usizeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
202
3.64k
    fn to_usize() -> usize {
203
3.64k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
3.64k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB18_2B0EB1l_EB1l_ENtNtB7_13marker_traits8Unsigned8to_usizeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
202
3.64k
    fn to_usize() -> usize {
203
3.64k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
3.64k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB14_2B0EB1h_ENtNtB7_13marker_traits8Unsigned8to_usizeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
202
3.64k
    fn to_usize() -> usize {
203
3.64k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
3.64k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_NtB5_5UTermNtNtB7_3bit2B1ENtB10_2B0ENtNtB7_13marker_traits8Unsigned8to_usizeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
202
3.64k
    fn to_usize() -> usize {
203
3.64k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
3.64k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntNtB5_5UTermNtNtB7_3bit2B1ENtNtB7_13marker_traits8Unsigned8to_usizeCs4RkbDk9WRL5_5clvmr
Line
Count
Source
202
3.64k
    fn to_usize() -> usize {
203
3.64k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
3.64k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_IBz_IBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB1g_2B0EB1t_EB1t_EB1t_EB1t_ENtNtB7_13marker_traits8Unsigned8to_usizeCsjewTDwKBbyD_4k256
Line
Count
Source
202
1.26k
    fn to_usize() -> usize {
203
1.26k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
1.26k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_IBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB1c_2B0EB1p_EB1p_EB1p_ENtNtB7_13marker_traits8Unsigned8to_usizeCsjewTDwKBbyD_4k256
Line
Count
Source
202
1.26k
    fn to_usize() -> usize {
203
1.26k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
1.26k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB18_2B0EB1l_EB1l_ENtNtB7_13marker_traits8Unsigned8to_usizeCsjewTDwKBbyD_4k256
Line
Count
Source
202
1.26k
    fn to_usize() -> usize {
203
1.26k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
1.26k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_IBz_NtB5_5UTermNtNtB7_3bit2B1ENtB14_2B0EB1h_ENtNtB7_13marker_traits8Unsigned8to_usizeCsjewTDwKBbyD_4k256
Line
Count
Source
202
1.26k
    fn to_usize() -> usize {
203
1.26k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
1.26k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntIBz_NtB5_5UTermNtNtB7_3bit2B1ENtB10_2B0ENtNtB7_13marker_traits8Unsigned8to_usizeCsjewTDwKBbyD_4k256
Line
Count
Source
202
1.26k
    fn to_usize() -> usize {
203
1.26k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
1.26k
    }
_RNvXs1_NtCs5VhUk8EIQ63_7typenum4uintINtB5_4UIntNtB5_5UTermNtNtB7_3bit2B1ENtNtB7_13marker_traits8Unsigned8to_usizeCsjewTDwKBbyD_4k256
Line
Count
Source
202
1.26k
    fn to_usize() -> usize {
203
1.26k
        usize::from(B::to_u8()) | U::to_usize() << 1
204
1.26k
    }
Unexecuted instantiation: _RNvXININtCs5VhUk8EIQ63_7typenum4uints1_0ppEINtB5_4UIntppENtNtB7_13marker_traits8Unsigned8to_usizeB7_
205
206
    #[inline]
207
0
    fn to_i8() -> i8 {
208
0
        B::to_u8() as i8 | U::to_i8() << 1
209
0
    }
210
    #[inline]
211
0
    fn to_i16() -> i16 {
212
0
        i16::from(B::to_u8()) | U::to_i16() << 1
213
0
    }
214
    #[inline]
215
0
    fn to_i32() -> i32 {
216
0
        i32::from(B::to_u8()) | U::to_i32() << 1
217
0
    }
218
    #[inline]
219
0
    fn to_i64() -> i64 {
220
0
        i64::from(B::to_u8()) | U::to_i64() << 1
221
0
    }
222
    #[cfg(feature = "i128")]
223
    #[inline]
224
    fn to_i128() -> i128 {
225
        i128::from(B::to_u8()) | U::to_i128() << 1
226
    }
227
    #[inline]
228
0
    fn to_isize() -> isize {
229
0
        B::to_u8() as isize | U::to_isize() << 1
230
0
    }
231
}
232
233
impl<U: Unsigned, B: Bit> NonZero for UInt<U, B> {}
234
impl Zero for UTerm {}
235
236
impl PowerOfTwo for UInt<UTerm, B1> {}
237
impl<U: Unsigned + PowerOfTwo> PowerOfTwo for UInt<U, B0> {}
238
239
// ---------------------------------------------------------------------------------------
240
// Getting length of unsigned integers, which is defined as the number of bits before `UTerm`
241
242
/// Length of `UTerm` by itself is 0
243
impl Len for UTerm {
244
    type Output = U0;
245
    #[inline]
246
0
    fn len(&self) -> Self::Output {
247
0
        UTerm
248
0
    }
249
}
250
251
/// Length of a bit is 1
252
impl<U: Unsigned, B: Bit> Len for UInt<U, B>
253
where
254
    U: Len,
255
    Length<U>: Add<B1>,
256
    Add1<Length<U>>: Unsigned,
257
{
258
    type Output = Add1<Length<U>>;
259
    #[inline]
260
0
    fn len(&self) -> Self::Output {
261
0
        self.msb.len() + B1
262
0
    }
263
}
264
265
// ---------------------------------------------------------------------------------------
266
// Adding bits to unsigned integers
267
268
/// `UTerm + B0 = UTerm`
269
impl Add<B0> for UTerm {
270
    type Output = UTerm;
271
    #[inline]
272
0
    fn add(self, _: B0) -> Self::Output {
273
0
        UTerm
274
0
    }
275
}
276
277
/// `U + B0 = U`
278
impl<U: Unsigned, B: Bit> Add<B0> for UInt<U, B> {
279
    type Output = UInt<U, B>;
280
    #[inline]
281
0
    fn add(self, _: B0) -> Self::Output {
282
0
        UInt::new()
283
0
    }
284
}
285
286
/// `UTerm + B1 = UInt<UTerm, B1>`
287
impl Add<B1> for UTerm {
288
    type Output = UInt<UTerm, B1>;
289
    #[inline]
290
0
    fn add(self, _: B1) -> Self::Output {
291
0
        UInt::new()
292
0
    }
293
}
294
295
/// `UInt<U, B0> + B1 = UInt<U + B1>`
296
impl<U: Unsigned> Add<B1> for UInt<U, B0> {
297
    type Output = UInt<U, B1>;
298
    #[inline]
299
0
    fn add(self, _: B1) -> Self::Output {
300
0
        UInt::new()
301
0
    }
302
}
303
304
/// `UInt<U, B1> + B1 = UInt<U + B1, B0>`
305
impl<U: Unsigned> Add<B1> for UInt<U, B1>
306
where
307
    U: Add<B1>,
308
    Add1<U>: Unsigned,
309
{
310
    type Output = UInt<Add1<U>, B0>;
311
    #[inline]
312
0
    fn add(self, _: B1) -> Self::Output {
313
0
        UInt::new()
314
0
    }
315
}
316
317
// ---------------------------------------------------------------------------------------
318
// Adding unsigned integers
319
320
/// `UTerm + U = U`
321
impl<U: Unsigned> Add<U> for UTerm {
322
    type Output = U;
323
    #[inline]
324
0
    fn add(self, rhs: U) -> Self::Output {
325
0
        rhs
326
0
    }
327
}
328
329
/// `UInt<U, B> + UTerm = UInt<U, B>`
330
impl<U: Unsigned, B: Bit> Add<UTerm> for UInt<U, B> {
331
    type Output = UInt<U, B>;
332
    #[inline]
333
0
    fn add(self, _: UTerm) -> Self::Output {
334
0
        UInt::new()
335
0
    }
336
}
337
338
/// `UInt<Ul, B0> + UInt<Ur, B0> = UInt<Ul + Ur, B0>`
339
impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B0>> for UInt<Ul, B0>
340
where
341
    Ul: Add<Ur>,
342
{
343
    type Output = UInt<Sum<Ul, Ur>, B0>;
344
    #[inline]
345
0
    fn add(self, rhs: UInt<Ur, B0>) -> Self::Output {
346
0
        UInt {
347
0
            msb: self.msb + rhs.msb,
348
0
            lsb: B0,
349
0
        }
350
0
    }
351
}
352
353
/// `UInt<Ul, B0> + UInt<Ur, B1> = UInt<Ul + Ur, B1>`
354
impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B1>> for UInt<Ul, B0>
355
where
356
    Ul: Add<Ur>,
357
{
358
    type Output = UInt<Sum<Ul, Ur>, B1>;
359
    #[inline]
360
0
    fn add(self, rhs: UInt<Ur, B1>) -> Self::Output {
361
0
        UInt {
362
0
            msb: self.msb + rhs.msb,
363
0
            lsb: B1,
364
0
        }
365
0
    }
366
}
367
368
/// `UInt<Ul, B1> + UInt<Ur, B0> = UInt<Ul + Ur, B1>`
369
impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B0>> for UInt<Ul, B1>
370
where
371
    Ul: Add<Ur>,
372
{
373
    type Output = UInt<Sum<Ul, Ur>, B1>;
374
    #[inline]
375
0
    fn add(self, rhs: UInt<Ur, B0>) -> Self::Output {
376
0
        UInt {
377
0
            msb: self.msb + rhs.msb,
378
0
            lsb: B1,
379
0
        }
380
0
    }
381
}
382
383
/// `UInt<Ul, B1> + UInt<Ur, B1> = UInt<(Ul + Ur) + B1, B0>`
384
impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B1>> for UInt<Ul, B1>
385
where
386
    Ul: Add<Ur>,
387
    Sum<Ul, Ur>: Add<B1>,
388
{
389
    type Output = UInt<Add1<Sum<Ul, Ur>>, B0>;
390
    #[inline]
391
0
    fn add(self, rhs: UInt<Ur, B1>) -> Self::Output {
392
0
        UInt {
393
0
            msb: self.msb + rhs.msb + B1,
394
0
            lsb: B0,
395
0
        }
396
0
    }
397
}
398
399
// ---------------------------------------------------------------------------------------
400
// Subtracting bits from unsigned integers
401
402
/// `UTerm - B0 = Term`
403
impl Sub<B0> for UTerm {
404
    type Output = UTerm;
405
    #[inline]
406
0
    fn sub(self, _: B0) -> Self::Output {
407
0
        UTerm
408
0
    }
409
}
410
411
/// `UInt - B0 = UInt`
412
impl<U: Unsigned, B: Bit> Sub<B0> for UInt<U, B> {
413
    type Output = UInt<U, B>;
414
    #[inline]
415
0
    fn sub(self, _: B0) -> Self::Output {
416
0
        UInt::new()
417
0
    }
418
}
419
420
/// `UInt<U, B1> - B1 = UInt<U, B0>`
421
impl<U: Unsigned, B: Bit> Sub<B1> for UInt<UInt<U, B>, B1> {
422
    type Output = UInt<UInt<U, B>, B0>;
423
    #[inline]
424
0
    fn sub(self, _: B1) -> Self::Output {
425
0
        UInt::new()
426
0
    }
427
}
428
429
/// `UInt<UTerm, B1> - B1 = UTerm`
430
impl Sub<B1> for UInt<UTerm, B1> {
431
    type Output = UTerm;
432
    #[inline]
433
0
    fn sub(self, _: B1) -> Self::Output {
434
0
        UTerm
435
0
    }
436
}
437
438
/// `UInt<U, B0> - B1 = UInt<U - B1, B1>`
439
impl<U: Unsigned> Sub<B1> for UInt<U, B0>
440
where
441
    U: Sub<B1>,
442
    Sub1<U>: Unsigned,
443
{
444
    type Output = UInt<Sub1<U>, B1>;
445
    #[inline]
446
0
    fn sub(self, _: B1) -> Self::Output {
447
0
        UInt::new()
448
0
    }
449
}
450
451
// ---------------------------------------------------------------------------------------
452
// Subtracting unsigned integers
453
454
/// `UTerm - UTerm = UTerm`
455
impl Sub<UTerm> for UTerm {
456
    type Output = UTerm;
457
    #[inline]
458
0
    fn sub(self, _: UTerm) -> Self::Output {
459
0
        UTerm
460
0
    }
461
}
462
463
/// Subtracting unsigned integers. We just do our `PrivateSub` and then `Trim` the output.
464
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> Sub<Ur> for UInt<Ul, Bl>
465
where
466
    UInt<Ul, Bl>: PrivateSub<Ur>,
467
    PrivateSubOut<UInt<Ul, Bl>, Ur>: Trim,
468
{
469
    type Output = TrimOut<PrivateSubOut<UInt<Ul, Bl>, Ur>>;
470
    #[inline]
471
0
    fn sub(self, rhs: Ur) -> Self::Output {
472
0
        self.private_sub(rhs).trim()
473
0
    }
474
}
475
476
/// `U - UTerm = U`
477
impl<U: Unsigned> PrivateSub<UTerm> for U {
478
    type Output = U;
479
480
    #[inline]
481
0
    fn private_sub(self, _: UTerm) -> Self::Output {
482
0
        self
483
0
    }
484
}
485
486
/// `UInt<Ul, B0> - UInt<Ur, B0> = UInt<Ul - Ur, B0>`
487
impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B0>> for UInt<Ul, B0>
488
where
489
    Ul: PrivateSub<Ur>,
490
{
491
    type Output = UInt<PrivateSubOut<Ul, Ur>, B0>;
492
493
    #[inline]
494
0
    fn private_sub(self, rhs: UInt<Ur, B0>) -> Self::Output {
495
0
        UInt {
496
0
            msb: self.msb.private_sub(rhs.msb),
497
0
            lsb: B0,
498
0
        }
499
0
    }
500
}
501
502
/// `UInt<Ul, B0> - UInt<Ur, B1> = UInt<(Ul - Ur) - B1, B1>`
503
impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B1>> for UInt<Ul, B0>
504
where
505
    Ul: PrivateSub<Ur>,
506
    PrivateSubOut<Ul, Ur>: Sub<B1>,
507
{
508
    type Output = UInt<Sub1<PrivateSubOut<Ul, Ur>>, B1>;
509
510
    #[inline]
511
0
    fn private_sub(self, rhs: UInt<Ur, B1>) -> Self::Output {
512
0
        UInt {
513
0
            msb: self.msb.private_sub(rhs.msb) - B1,
514
0
            lsb: B1,
515
0
        }
516
0
    }
517
}
518
519
/// `UInt<Ul, B1> - UInt<Ur, B0> = UInt<Ul - Ur, B1>`
520
impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B0>> for UInt<Ul, B1>
521
where
522
    Ul: PrivateSub<Ur>,
523
{
524
    type Output = UInt<PrivateSubOut<Ul, Ur>, B1>;
525
526
    #[inline]
527
0
    fn private_sub(self, rhs: UInt<Ur, B0>) -> Self::Output {
528
0
        UInt {
529
0
            msb: self.msb.private_sub(rhs.msb),
530
0
            lsb: B1,
531
0
        }
532
0
    }
533
}
534
535
/// `UInt<Ul, B1> - UInt<Ur, B1> = UInt<Ul - Ur, B0>`
536
impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B1>> for UInt<Ul, B1>
537
where
538
    Ul: PrivateSub<Ur>,
539
{
540
    type Output = UInt<PrivateSubOut<Ul, Ur>, B0>;
541
542
    #[inline]
543
0
    fn private_sub(self, rhs: UInt<Ur, B1>) -> Self::Output {
544
0
        UInt {
545
0
            msb: self.msb.private_sub(rhs.msb),
546
0
            lsb: B0,
547
0
        }
548
0
    }
549
}
550
551
// ---------------------------------------------------------------------------------------
552
// And unsigned integers
553
554
/// 0 & X = 0
555
impl<Ur: Unsigned> BitAnd<Ur> for UTerm {
556
    type Output = UTerm;
557
    #[inline]
558
0
    fn bitand(self, _: Ur) -> Self::Output {
559
0
        UTerm
560
0
    }
561
}
562
563
/// Anding unsigned integers.
564
/// We use our `PrivateAnd` operator and then `Trim` the output.
565
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> BitAnd<Ur> for UInt<Ul, Bl>
566
where
567
    UInt<Ul, Bl>: PrivateAnd<Ur>,
568
    PrivateAndOut<UInt<Ul, Bl>, Ur>: Trim,
569
{
570
    type Output = TrimOut<PrivateAndOut<UInt<Ul, Bl>, Ur>>;
571
    #[inline]
572
0
    fn bitand(self, rhs: Ur) -> Self::Output {
573
0
        self.private_and(rhs).trim()
574
0
    }
575
}
576
577
/// `UTerm & X = UTerm`
578
impl<U: Unsigned> PrivateAnd<U> for UTerm {
579
    type Output = UTerm;
580
581
    #[inline]
582
0
    fn private_and(self, _: U) -> Self::Output {
583
0
        UTerm
584
0
    }
585
}
586
587
/// `X & UTerm = UTerm`
588
impl<B: Bit, U: Unsigned> PrivateAnd<UTerm> for UInt<U, B> {
589
    type Output = UTerm;
590
591
    #[inline]
592
0
    fn private_and(self, _: UTerm) -> Self::Output {
593
0
        UTerm
594
0
    }
595
}
596
597
/// `UInt<Ul, B0> & UInt<Ur, B0> = UInt<Ul & Ur, B0>`
598
impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B0>> for UInt<Ul, B0>
599
where
600
    Ul: PrivateAnd<Ur>,
601
{
602
    type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
603
604
    #[inline]
605
0
    fn private_and(self, rhs: UInt<Ur, B0>) -> Self::Output {
606
0
        UInt {
607
0
            msb: self.msb.private_and(rhs.msb),
608
0
            lsb: B0,
609
0
        }
610
0
    }
611
}
612
613
/// `UInt<Ul, B0> & UInt<Ur, B1> = UInt<Ul & Ur, B0>`
614
impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B1>> for UInt<Ul, B0>
615
where
616
    Ul: PrivateAnd<Ur>,
617
{
618
    type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
619
620
    #[inline]
621
0
    fn private_and(self, rhs: UInt<Ur, B1>) -> Self::Output {
622
0
        UInt {
623
0
            msb: self.msb.private_and(rhs.msb),
624
0
            lsb: B0,
625
0
        }
626
0
    }
627
}
628
629
/// `UInt<Ul, B1> & UInt<Ur, B0> = UInt<Ul & Ur, B0>`
630
impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B0>> for UInt<Ul, B1>
631
where
632
    Ul: PrivateAnd<Ur>,
633
{
634
    type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
635
636
    #[inline]
637
0
    fn private_and(self, rhs: UInt<Ur, B0>) -> Self::Output {
638
0
        UInt {
639
0
            msb: self.msb.private_and(rhs.msb),
640
0
            lsb: B0,
641
0
        }
642
0
    }
643
}
644
645
/// `UInt<Ul, B1> & UInt<Ur, B1> = UInt<Ul & Ur, B1>`
646
impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B1>> for UInt<Ul, B1>
647
where
648
    Ul: PrivateAnd<Ur>,
649
{
650
    type Output = UInt<PrivateAndOut<Ul, Ur>, B1>;
651
652
    #[inline]
653
0
    fn private_and(self, rhs: UInt<Ur, B1>) -> Self::Output {
654
0
        UInt {
655
0
            msb: self.msb.private_and(rhs.msb),
656
0
            lsb: B1,
657
0
        }
658
0
    }
659
}
660
661
// ---------------------------------------------------------------------------------------
662
// Or unsigned integers
663
664
/// `UTerm | X = X`
665
impl<U: Unsigned> BitOr<U> for UTerm {
666
    type Output = U;
667
    #[inline]
668
0
    fn bitor(self, rhs: U) -> Self::Output {
669
0
        rhs
670
0
    }
671
}
672
673
///  `X | UTerm = X`
674
impl<B: Bit, U: Unsigned> BitOr<UTerm> for UInt<U, B> {
675
    type Output = Self;
676
    #[inline]
677
0
    fn bitor(self, _: UTerm) -> Self::Output {
678
0
        UInt::new()
679
0
    }
680
}
681
682
/// `UInt<Ul, B0> | UInt<Ur, B0> = UInt<Ul | Ur, B0>`
683
impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B0>> for UInt<Ul, B0>
684
where
685
    Ul: BitOr<Ur>,
686
{
687
    type Output = UInt<<Ul as BitOr<Ur>>::Output, B0>;
688
    #[inline]
689
0
    fn bitor(self, rhs: UInt<Ur, B0>) -> Self::Output {
690
0
        UInt {
691
0
            msb: self.msb.bitor(rhs.msb),
692
0
            lsb: B0,
693
0
        }
694
0
    }
695
}
696
697
/// `UInt<Ul, B0> | UInt<Ur, B1> = UInt<Ul | Ur, B1>`
698
impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B1>> for UInt<Ul, B0>
699
where
700
    Ul: BitOr<Ur>,
701
{
702
    type Output = UInt<Or<Ul, Ur>, B1>;
703
    #[inline]
704
0
    fn bitor(self, rhs: UInt<Ur, B1>) -> Self::Output {
705
0
        UInt {
706
0
            msb: self.msb.bitor(rhs.msb),
707
0
            lsb: self.lsb.bitor(rhs.lsb),
708
0
        }
709
0
    }
710
}
711
712
/// `UInt<Ul, B1> | UInt<Ur, B0> = UInt<Ul | Ur, B1>`
713
impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B0>> for UInt<Ul, B1>
714
where
715
    Ul: BitOr<Ur>,
716
{
717
    type Output = UInt<Or<Ul, Ur>, B1>;
718
    #[inline]
719
0
    fn bitor(self, rhs: UInt<Ur, B0>) -> Self::Output {
720
0
        UInt {
721
0
            msb: self.msb.bitor(rhs.msb),
722
0
            lsb: self.lsb.bitor(rhs.lsb),
723
0
        }
724
0
    }
725
}
726
727
/// `UInt<Ul, B1> | UInt<Ur, B1> = UInt<Ul | Ur, B1>`
728
impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B1>> for UInt<Ul, B1>
729
where
730
    Ul: BitOr<Ur>,
731
{
732
    type Output = UInt<Or<Ul, Ur>, B1>;
733
    #[inline]
734
0
    fn bitor(self, rhs: UInt<Ur, B1>) -> Self::Output {
735
0
        UInt {
736
0
            msb: self.msb.bitor(rhs.msb),
737
0
            lsb: self.lsb.bitor(rhs.lsb),
738
0
        }
739
0
    }
740
}
741
742
// ---------------------------------------------------------------------------------------
743
// Xor unsigned integers
744
745
/// 0 ^ X = X
746
impl<Ur: Unsigned> BitXor<Ur> for UTerm {
747
    type Output = Ur;
748
    #[inline]
749
0
    fn bitxor(self, rhs: Ur) -> Self::Output {
750
0
        rhs
751
0
    }
752
}
753
754
/// Xoring unsigned integers.
755
/// We use our `PrivateXor` operator and then `Trim` the output.
756
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> BitXor<Ur> for UInt<Ul, Bl>
757
where
758
    UInt<Ul, Bl>: PrivateXor<Ur>,
759
    PrivateXorOut<UInt<Ul, Bl>, Ur>: Trim,
760
{
761
    type Output = TrimOut<PrivateXorOut<UInt<Ul, Bl>, Ur>>;
762
    #[inline]
763
0
    fn bitxor(self, rhs: Ur) -> Self::Output {
764
0
        self.private_xor(rhs).trim()
765
0
    }
766
}
767
768
/// `UTerm ^ X = X`
769
impl<U: Unsigned> PrivateXor<U> for UTerm {
770
    type Output = U;
771
772
    #[inline]
773
0
    fn private_xor(self, rhs: U) -> Self::Output {
774
0
        rhs
775
0
    }
776
}
777
778
/// `X ^ UTerm = X`
779
impl<B: Bit, U: Unsigned> PrivateXor<UTerm> for UInt<U, B> {
780
    type Output = Self;
781
782
    #[inline]
783
0
    fn private_xor(self, _: UTerm) -> Self::Output {
784
0
        self
785
0
    }
786
}
787
788
/// `UInt<Ul, B0> ^ UInt<Ur, B0> = UInt<Ul ^ Ur, B0>`
789
impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B0>> for UInt<Ul, B0>
790
where
791
    Ul: PrivateXor<Ur>,
792
{
793
    type Output = UInt<PrivateXorOut<Ul, Ur>, B0>;
794
795
    #[inline]
796
0
    fn private_xor(self, rhs: UInt<Ur, B0>) -> Self::Output {
797
0
        UInt {
798
0
            msb: self.msb.private_xor(rhs.msb),
799
0
            lsb: B0,
800
0
        }
801
0
    }
802
}
803
804
/// `UInt<Ul, B0> ^ UInt<Ur, B1> = UInt<Ul ^ Ur, B1>`
805
impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B1>> for UInt<Ul, B0>
806
where
807
    Ul: PrivateXor<Ur>,
808
{
809
    type Output = UInt<PrivateXorOut<Ul, Ur>, B1>;
810
811
    #[inline]
812
0
    fn private_xor(self, rhs: UInt<Ur, B1>) -> Self::Output {
813
0
        UInt {
814
0
            msb: self.msb.private_xor(rhs.msb),
815
0
            lsb: B1,
816
0
        }
817
0
    }
818
}
819
820
/// `UInt<Ul, B1> ^ UInt<Ur, B0> = UInt<Ul ^ Ur, B1>`
821
impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B0>> for UInt<Ul, B1>
822
where
823
    Ul: PrivateXor<Ur>,
824
{
825
    type Output = UInt<PrivateXorOut<Ul, Ur>, B1>;
826
827
    #[inline]
828
0
    fn private_xor(self, rhs: UInt<Ur, B0>) -> Self::Output {
829
0
        UInt {
830
0
            msb: self.msb.private_xor(rhs.msb),
831
0
            lsb: B1,
832
0
        }
833
0
    }
834
}
835
836
/// `UInt<Ul, B1> ^ UInt<Ur, B1> = UInt<Ul ^ Ur, B0>`
837
impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B1>> for UInt<Ul, B1>
838
where
839
    Ul: PrivateXor<Ur>,
840
{
841
    type Output = UInt<PrivateXorOut<Ul, Ur>, B0>;
842
843
    #[inline]
844
0
    fn private_xor(self, rhs: UInt<Ur, B1>) -> Self::Output {
845
0
        UInt {
846
0
            msb: self.msb.private_xor(rhs.msb),
847
0
            lsb: B0,
848
0
        }
849
0
    }
850
}
851
852
// ---------------------------------------------------------------------------------------
853
// Shl unsigned integers
854
855
/// Shifting `UTerm` by a 0 bit: `UTerm << B0 = UTerm`
856
impl Shl<B0> for UTerm {
857
    type Output = UTerm;
858
    #[inline]
859
0
    fn shl(self, _: B0) -> Self::Output {
860
0
        UTerm
861
0
    }
862
}
863
864
/// Shifting `UTerm` by a 1 bit: `UTerm << B1 = UTerm`
865
impl Shl<B1> for UTerm {
866
    type Output = UTerm;
867
    #[inline]
868
0
    fn shl(self, _: B1) -> Self::Output {
869
0
        UTerm
870
0
    }
871
}
872
873
/// Shifting left any unsigned by a zero bit: `U << B0 = U`
874
impl<U: Unsigned, B: Bit> Shl<B0> for UInt<U, B> {
875
    type Output = UInt<U, B>;
876
    #[inline]
877
0
    fn shl(self, _: B0) -> Self::Output {
878
0
        UInt::new()
879
0
    }
880
}
881
882
/// Shifting left a `UInt` by a one bit: `UInt<U, B> << B1 = UInt<UInt<U, B>, B0>`
883
impl<U: Unsigned, B: Bit> Shl<B1> for UInt<U, B> {
884
    type Output = UInt<UInt<U, B>, B0>;
885
    #[inline]
886
0
    fn shl(self, _: B1) -> Self::Output {
887
0
        UInt::new()
888
0
    }
889
}
890
891
/// Shifting left `UInt` by `UTerm`: `UInt<U, B> << UTerm = UInt<U, B>`
892
impl<U: Unsigned, B: Bit> Shl<UTerm> for UInt<U, B> {
893
    type Output = UInt<U, B>;
894
    #[inline]
895
0
    fn shl(self, _: UTerm) -> Self::Output {
896
0
        UInt::new()
897
0
    }
898
}
899
900
/// Shifting left `UTerm` by an unsigned integer: `UTerm << U = UTerm`
901
impl<U: Unsigned> Shl<U> for UTerm {
902
    type Output = UTerm;
903
    #[inline]
904
0
    fn shl(self, _: U) -> Self::Output {
905
0
        UTerm
906
0
    }
907
}
908
909
/// Shifting left `UInt` by `UInt`: `X << Y` = `UInt(X, B0) << (Y - 1)`
910
impl<U: Unsigned, B: Bit, Ur: Unsigned, Br: Bit> Shl<UInt<Ur, Br>> for UInt<U, B>
911
where
912
    UInt<Ur, Br>: Sub<B1>,
913
    UInt<UInt<U, B>, B0>: Shl<Sub1<UInt<Ur, Br>>>,
914
{
915
    type Output = Shleft<UInt<UInt<U, B>, B0>, Sub1<UInt<Ur, Br>>>;
916
    #[inline]
917
0
    fn shl(self, rhs: UInt<Ur, Br>) -> Self::Output {
918
0
        (UInt { msb: self, lsb: B0 }).shl(rhs - B1)
919
0
    }
920
}
921
922
// ---------------------------------------------------------------------------------------
923
// Shr unsigned integers
924
925
/// Shifting right a `UTerm` by an unsigned integer: `UTerm >> U = UTerm`
926
impl<U: Unsigned> Shr<U> for UTerm {
927
    type Output = UTerm;
928
    #[inline]
929
0
    fn shr(self, _: U) -> Self::Output {
930
0
        UTerm
931
0
    }
932
}
933
934
/// Shifting right `UInt` by `UTerm`: `UInt<U, B> >> UTerm = UInt<U, B>`
935
impl<U: Unsigned, B: Bit> Shr<UTerm> for UInt<U, B> {
936
    type Output = UInt<U, B>;
937
    #[inline]
938
0
    fn shr(self, _: UTerm) -> Self::Output {
939
0
        UInt::new()
940
0
    }
941
}
942
943
/// Shifting right `UTerm` by a 0 bit: `UTerm >> B0 = UTerm`
944
impl Shr<B0> for UTerm {
945
    type Output = UTerm;
946
    #[inline]
947
0
    fn shr(self, _: B0) -> Self::Output {
948
0
        UTerm
949
0
    }
950
}
951
952
/// Shifting right `UTerm` by a 1 bit: `UTerm >> B1 = UTerm`
953
impl Shr<B1> for UTerm {
954
    type Output = UTerm;
955
    #[inline]
956
0
    fn shr(self, _: B1) -> Self::Output {
957
0
        UTerm
958
0
    }
959
}
960
961
/// Shifting right any unsigned by a zero bit: `U >> B0 = U`
962
impl<U: Unsigned, B: Bit> Shr<B0> for UInt<U, B> {
963
    type Output = UInt<U, B>;
964
    #[inline]
965
0
    fn shr(self, _: B0) -> Self::Output {
966
0
        UInt::new()
967
0
    }
968
}
969
970
/// Shifting right a `UInt` by a 1 bit: `UInt<U, B> >> B1 = U`
971
impl<U: Unsigned, B: Bit> Shr<B1> for UInt<U, B> {
972
    type Output = U;
973
    #[inline]
974
0
    fn shr(self, _: B1) -> Self::Output {
975
0
        self.msb
976
0
    }
977
}
978
979
/// Shifting right `UInt` by `UInt`: `UInt(U, B) >> Y` = `U >> (Y - 1)`
980
impl<U: Unsigned, B: Bit, Ur: Unsigned, Br: Bit> Shr<UInt<Ur, Br>> for UInt<U, B>
981
where
982
    UInt<Ur, Br>: Sub<B1>,
983
    U: Shr<Sub1<UInt<Ur, Br>>>,
984
{
985
    type Output = Shright<U, Sub1<UInt<Ur, Br>>>;
986
    #[inline]
987
0
    fn shr(self, rhs: UInt<Ur, Br>) -> Self::Output {
988
0
        self.msb.shr(rhs - B1)
989
0
    }
990
}
991
992
// ---------------------------------------------------------------------------------------
993
// Multiply unsigned integers
994
995
/// `UInt * B0 = UTerm`
996
impl<U: Unsigned, B: Bit> Mul<B0> for UInt<U, B> {
997
    type Output = UTerm;
998
    #[inline]
999
0
    fn mul(self, _: B0) -> Self::Output {
1000
0
        UTerm
1001
0
    }
1002
}
1003
1004
/// `UTerm * B0 = UTerm`
1005
impl Mul<B0> for UTerm {
1006
    type Output = UTerm;
1007
    #[inline]
1008
0
    fn mul(self, _: B0) -> Self::Output {
1009
0
        UTerm
1010
0
    }
1011
}
1012
1013
/// `UTerm * B1 = UTerm`
1014
impl Mul<B1> for UTerm {
1015
    type Output = UTerm;
1016
    #[inline]
1017
0
    fn mul(self, _: B1) -> Self::Output {
1018
0
        UTerm
1019
0
    }
1020
}
1021
1022
/// `UInt * B1 = UInt`
1023
impl<U: Unsigned, B: Bit> Mul<B1> for UInt<U, B> {
1024
    type Output = UInt<U, B>;
1025
    #[inline]
1026
0
    fn mul(self, _: B1) -> Self::Output {
1027
0
        UInt::new()
1028
0
    }
1029
}
1030
1031
/// `UInt<U, B> * UTerm = UTerm`
1032
impl<U: Unsigned, B: Bit> Mul<UTerm> for UInt<U, B> {
1033
    type Output = UTerm;
1034
    #[inline]
1035
0
    fn mul(self, _: UTerm) -> Self::Output {
1036
0
        UTerm
1037
0
    }
1038
}
1039
1040
/// `UTerm * U = UTerm`
1041
impl<U: Unsigned> Mul<U> for UTerm {
1042
    type Output = UTerm;
1043
    #[inline]
1044
0
    fn mul(self, _: U) -> Self::Output {
1045
0
        UTerm
1046
0
    }
1047
}
1048
1049
/// `UInt<Ul, B0> * UInt<Ur, B> = UInt<(Ul * UInt<Ur, B>), B0>`
1050
impl<Ul: Unsigned, B: Bit, Ur: Unsigned> Mul<UInt<Ur, B>> for UInt<Ul, B0>
1051
where
1052
    Ul: Mul<UInt<Ur, B>>,
1053
{
1054
    type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>;
1055
    #[inline]
1056
0
    fn mul(self, rhs: UInt<Ur, B>) -> Self::Output {
1057
0
        UInt {
1058
0
            msb: self.msb * rhs,
1059
0
            lsb: B0,
1060
0
        }
1061
0
    }
1062
}
1063
1064
/// `UInt<Ul, B1> * UInt<Ur, B> = UInt<(Ul * UInt<Ur, B>), B0> + UInt<Ur, B>`
1065
impl<Ul: Unsigned, B: Bit, Ur: Unsigned> Mul<UInt<Ur, B>> for UInt<Ul, B1>
1066
where
1067
    Ul: Mul<UInt<Ur, B>>,
1068
    UInt<Prod<Ul, UInt<Ur, B>>, B0>: Add<UInt<Ur, B>>,
1069
{
1070
    type Output = Sum<UInt<Prod<Ul, UInt<Ur, B>>, B0>, UInt<Ur, B>>;
1071
    #[inline]
1072
0
    fn mul(self, rhs: UInt<Ur, B>) -> Self::Output {
1073
0
        UInt {
1074
0
            msb: self.msb * rhs,
1075
0
            lsb: B0,
1076
0
        } + rhs
1077
0
    }
1078
}
1079
1080
// ---------------------------------------------------------------------------------------
1081
// Compare unsigned integers
1082
1083
/// Zero == Zero
1084
impl Cmp<UTerm> for UTerm {
1085
    type Output = Equal;
1086
1087
    #[inline]
1088
0
    fn compare<IM: InternalMarker>(&self, _: &UTerm) -> Self::Output {
1089
0
        Equal
1090
0
    }
1091
}
1092
1093
/// Nonzero > Zero
1094
impl<U: Unsigned, B: Bit> Cmp<UTerm> for UInt<U, B> {
1095
    type Output = Greater;
1096
1097
    #[inline]
1098
0
    fn compare<IM: InternalMarker>(&self, _: &UTerm) -> Self::Output {
1099
0
        Greater
1100
0
    }
1101
}
1102
1103
/// Zero < Nonzero
1104
impl<U: Unsigned, B: Bit> Cmp<UInt<U, B>> for UTerm {
1105
    type Output = Less;
1106
1107
    #[inline]
1108
0
    fn compare<IM: InternalMarker>(&self, _: &UInt<U, B>) -> Self::Output {
1109
0
        Less
1110
0
    }
1111
}
1112
1113
/// `UInt<Ul, B0>` cmp with `UInt<Ur, B0>`: `SoFar` is `Equal`
1114
impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B0>> for UInt<Ul, B0>
1115
where
1116
    Ul: PrivateCmp<Ur, Equal>,
1117
{
1118
    type Output = PrivateCmpOut<Ul, Ur, Equal>;
1119
1120
    #[inline]
1121
0
    fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B0>) -> Self::Output {
1122
0
        self.msb.private_cmp(&rhs.msb, Equal)
1123
0
    }
1124
}
1125
1126
/// `UInt<Ul, B1>` cmp with `UInt<Ur, B1>`: `SoFar` is `Equal`
1127
impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B1>> for UInt<Ul, B1>
1128
where
1129
    Ul: PrivateCmp<Ur, Equal>,
1130
{
1131
    type Output = PrivateCmpOut<Ul, Ur, Equal>;
1132
1133
    #[inline]
1134
0
    fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B1>) -> Self::Output {
1135
0
        self.msb.private_cmp(&rhs.msb, Equal)
1136
0
    }
1137
}
1138
1139
/// `UInt<Ul, B0>` cmp with `UInt<Ur, B1>`: `SoFar` is `Less`
1140
impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B1>> for UInt<Ul, B0>
1141
where
1142
    Ul: PrivateCmp<Ur, Less>,
1143
{
1144
    type Output = PrivateCmpOut<Ul, Ur, Less>;
1145
1146
    #[inline]
1147
0
    fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B1>) -> Self::Output {
1148
0
        self.msb.private_cmp(&rhs.msb, Less)
1149
0
    }
1150
}
1151
1152
/// `UInt<Ul, B1>` cmp with `UInt<Ur, B0>`: `SoFar` is `Greater`
1153
impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B0>> for UInt<Ul, B1>
1154
where
1155
    Ul: PrivateCmp<Ur, Greater>,
1156
{
1157
    type Output = PrivateCmpOut<Ul, Ur, Greater>;
1158
1159
    #[inline]
1160
0
    fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B0>) -> Self::Output {
1161
0
        self.msb.private_cmp(&rhs.msb, Greater)
1162
0
    }
1163
}
1164
1165
/// Comparing non-terimal bits, with both having bit `B0`.
1166
/// These are `Equal`, so we propagate `SoFar`.
1167
impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B0>, SoFar> for UInt<Ul, B0>
1168
where
1169
    Ul: Unsigned,
1170
    Ur: Unsigned,
1171
    SoFar: Ord,
1172
    Ul: PrivateCmp<Ur, SoFar>,
1173
{
1174
    type Output = PrivateCmpOut<Ul, Ur, SoFar>;
1175
1176
    #[inline]
1177
0
    fn private_cmp(&self, rhs: &UInt<Ur, B0>, so_far: SoFar) -> Self::Output {
1178
0
        self.msb.private_cmp(&rhs.msb, so_far)
1179
0
    }
1180
}
1181
1182
/// Comparing non-terimal bits, with both having bit `B1`.
1183
/// These are `Equal`, so we propagate `SoFar`.
1184
impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B1>, SoFar> for UInt<Ul, B1>
1185
where
1186
    Ul: Unsigned,
1187
    Ur: Unsigned,
1188
    SoFar: Ord,
1189
    Ul: PrivateCmp<Ur, SoFar>,
1190
{
1191
    type Output = PrivateCmpOut<Ul, Ur, SoFar>;
1192
1193
    #[inline]
1194
0
    fn private_cmp(&self, rhs: &UInt<Ur, B1>, so_far: SoFar) -> Self::Output {
1195
0
        self.msb.private_cmp(&rhs.msb, so_far)
1196
0
    }
1197
}
1198
1199
/// Comparing non-terimal bits, with `Lhs` having bit `B0` and `Rhs` having bit `B1`.
1200
/// `SoFar`, Lhs is `Less`.
1201
impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B1>, SoFar> for UInt<Ul, B0>
1202
where
1203
    Ul: Unsigned,
1204
    Ur: Unsigned,
1205
    SoFar: Ord,
1206
    Ul: PrivateCmp<Ur, Less>,
1207
{
1208
    type Output = PrivateCmpOut<Ul, Ur, Less>;
1209
1210
    #[inline]
1211
0
    fn private_cmp(&self, rhs: &UInt<Ur, B1>, _: SoFar) -> Self::Output {
1212
0
        self.msb.private_cmp(&rhs.msb, Less)
1213
0
    }
1214
}
1215
1216
/// Comparing non-terimal bits, with `Lhs` having bit `B1` and `Rhs` having bit `B0`.
1217
/// `SoFar`, Lhs is `Greater`.
1218
impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B0>, SoFar> for UInt<Ul, B1>
1219
where
1220
    Ul: Unsigned,
1221
    Ur: Unsigned,
1222
    SoFar: Ord,
1223
    Ul: PrivateCmp<Ur, Greater>,
1224
{
1225
    type Output = PrivateCmpOut<Ul, Ur, Greater>;
1226
1227
    #[inline]
1228
0
    fn private_cmp(&self, rhs: &UInt<Ur, B0>, _: SoFar) -> Self::Output {
1229
0
        self.msb.private_cmp(&rhs.msb, Greater)
1230
0
    }
1231
}
1232
1233
/// Got to the end of just the `Lhs`. It's `Less`.
1234
impl<U: Unsigned, B: Bit, SoFar: Ord> PrivateCmp<UInt<U, B>, SoFar> for UTerm {
1235
    type Output = Less;
1236
1237
    #[inline]
1238
0
    fn private_cmp(&self, _: &UInt<U, B>, _: SoFar) -> Self::Output {
1239
0
        Less
1240
0
    }
1241
}
1242
1243
/// Got to the end of just the `Rhs`. `Lhs` is `Greater`.
1244
impl<U: Unsigned, B: Bit, SoFar: Ord> PrivateCmp<UTerm, SoFar> for UInt<U, B> {
1245
    type Output = Greater;
1246
1247
    #[inline]
1248
0
    fn private_cmp(&self, _: &UTerm, _: SoFar) -> Self::Output {
1249
0
        Greater
1250
0
    }
1251
}
1252
1253
/// Got to the end of both! Return `SoFar`
1254
impl<SoFar: Ord> PrivateCmp<UTerm, SoFar> for UTerm {
1255
    type Output = SoFar;
1256
1257
    #[inline]
1258
0
    fn private_cmp(&self, _: &UTerm, so_far: SoFar) -> Self::Output {
1259
0
        so_far
1260
0
    }
1261
}
1262
1263
// ---------------------------------------------------------------------------------------
1264
// Getting difference in number of bits
1265
1266
impl<Ul, Bl, Ur, Br> BitDiff<UInt<Ur, Br>> for UInt<Ul, Bl>
1267
where
1268
    Ul: Unsigned,
1269
    Bl: Bit,
1270
    Ur: Unsigned,
1271
    Br: Bit,
1272
    Ul: BitDiff<Ur>,
1273
{
1274
    type Output = BitDiffOut<Ul, Ur>;
1275
}
1276
1277
impl<Ul> BitDiff<UTerm> for Ul
1278
where
1279
    Ul: Unsigned + Len,
1280
{
1281
    type Output = Length<Ul>;
1282
}
1283
1284
// ---------------------------------------------------------------------------------------
1285
// Shifting one number until it's the size of another
1286
use crate::private::ShiftDiff;
1287
impl<Ul: Unsigned, Ur: Unsigned> ShiftDiff<Ur> for Ul
1288
where
1289
    Ur: BitDiff<Ul>,
1290
    Ul: Shl<BitDiffOut<Ur, Ul>>,
1291
{
1292
    type Output = Shleft<Ul, BitDiffOut<Ur, Ul>>;
1293
}
1294
1295
// ---------------------------------------------------------------------------------------
1296
// Powers of unsigned integers
1297
1298
/// X^N
1299
impl<X: Unsigned, N: Unsigned> Pow<N> for X
1300
where
1301
    X: PrivatePow<U1, N>,
1302
{
1303
    type Output = PrivatePowOut<X, U1, N>;
1304
    #[inline]
1305
0
    fn powi(self, n: N) -> Self::Output {
1306
0
        self.private_pow(U1::new(), n)
1307
0
    }
1308
}
1309
1310
impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U0> for X {
1311
    type Output = Y;
1312
1313
    #[inline]
1314
0
    fn private_pow(self, y: Y, _: U0) -> Self::Output {
1315
0
        y
1316
0
    }
1317
}
1318
1319
impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U1> for X
1320
where
1321
    X: Mul<Y>,
1322
{
1323
    type Output = Prod<X, Y>;
1324
1325
    #[inline]
1326
0
    fn private_pow(self, y: Y, _: U1) -> Self::Output {
1327
0
        self * y
1328
0
    }
1329
}
1330
1331
/// N is even
1332
impl<Y: Unsigned, U: Unsigned, B: Bit, X: Unsigned> PrivatePow<Y, UInt<UInt<U, B>, B0>> for X
1333
where
1334
    X: Mul,
1335
    Square<X>: PrivatePow<Y, UInt<U, B>>,
1336
{
1337
    type Output = PrivatePowOut<Square<X>, Y, UInt<U, B>>;
1338
1339
    #[inline]
1340
0
    fn private_pow(self, y: Y, n: UInt<UInt<U, B>, B0>) -> Self::Output {
1341
0
        (self * self).private_pow(y, n.msb)
1342
0
    }
1343
}
1344
1345
/// N is odd
1346
impl<Y: Unsigned, U: Unsigned, B: Bit, X: Unsigned> PrivatePow<Y, UInt<UInt<U, B>, B1>> for X
1347
where
1348
    X: Mul + Mul<Y>,
1349
    Square<X>: PrivatePow<Prod<X, Y>, UInt<U, B>>,
1350
{
1351
    type Output = PrivatePowOut<Square<X>, Prod<X, Y>, UInt<U, B>>;
1352
1353
    #[inline]
1354
0
    fn private_pow(self, y: Y, n: UInt<UInt<U, B>, B1>) -> Self::Output {
1355
0
        (self * self).private_pow(self * y, n.msb)
1356
0
    }
1357
}
1358
1359
//------------------------------------------
1360
// Greatest Common Divisor
1361
1362
/// The even number 2*N
1363
#[allow(unused)] // Silence spurious warning on older versions of rust
1364
type Even<N> = UInt<N, B0>;
1365
1366
/// The odd number 2*N + 1
1367
type Odd<N> = UInt<N, B1>;
1368
1369
/// gcd(0, 0) = 0
1370
impl Gcd<U0> for U0 {
1371
    type Output = U0;
1372
}
1373
1374
/// gcd(x, 0) = x
1375
impl<X> Gcd<U0> for X
1376
where
1377
    X: Unsigned + NonZero,
1378
{
1379
    type Output = X;
1380
}
1381
1382
/// gcd(0, y) = y
1383
impl<Y> Gcd<Y> for U0
1384
where
1385
    Y: Unsigned + NonZero,
1386
{
1387
    type Output = Y;
1388
}
1389
1390
/// gcd(x, y) = 2*gcd(x/2, y/2) if both x and y even
1391
impl<Xp, Yp> Gcd<Even<Yp>> for Even<Xp>
1392
where
1393
    Xp: Gcd<Yp>,
1394
    Even<Xp>: NonZero,
1395
    Even<Yp>: NonZero,
1396
{
1397
    type Output = UInt<Gcf<Xp, Yp>, B0>;
1398
}
1399
1400
/// gcd(x, y) = gcd(x, y/2) if x odd and y even
1401
impl<Xp, Yp> Gcd<Even<Yp>> for Odd<Xp>
1402
where
1403
    Odd<Xp>: Gcd<Yp>,
1404
    Even<Yp>: NonZero,
1405
{
1406
    type Output = Gcf<Odd<Xp>, Yp>;
1407
}
1408
1409
/// gcd(x, y) = gcd(x/2, y) if x even and y odd
1410
impl<Xp, Yp> Gcd<Odd<Yp>> for Even<Xp>
1411
where
1412
    Xp: Gcd<Odd<Yp>>,
1413
    Even<Xp>: NonZero,
1414
{
1415
    type Output = Gcf<Xp, Odd<Yp>>;
1416
}
1417
1418
/// gcd(x, y) = gcd([max(x, y) - min(x, y)], min(x, y)) if both x and y odd
1419
///
1420
/// This will immediately invoke the case for x even and y odd because the difference of two odd
1421
/// numbers is an even number.
1422
impl<Xp, Yp> Gcd<Odd<Yp>> for Odd<Xp>
1423
where
1424
    Odd<Xp>: Max<Odd<Yp>> + Min<Odd<Yp>>,
1425
    Odd<Yp>: Max<Odd<Xp>> + Min<Odd<Xp>>,
1426
    Maximum<Odd<Xp>, Odd<Yp>>: Sub<Minimum<Odd<Xp>, Odd<Yp>>>,
1427
    Diff<Maximum<Odd<Xp>, Odd<Yp>>, Minimum<Odd<Xp>, Odd<Yp>>>: Gcd<Minimum<Odd<Xp>, Odd<Yp>>>,
1428
{
1429
    type Output =
1430
        Gcf<Diff<Maximum<Odd<Xp>, Odd<Yp>>, Minimum<Odd<Xp>, Odd<Yp>>>, Minimum<Odd<Xp>, Odd<Yp>>>;
1431
}
1432
1433
#[cfg(test)]
1434
mod gcd_tests {
1435
    use super::*;
1436
    use crate::consts::*;
1437
1438
    macro_rules! gcd_test {
1439
        (
1440
            $( $a:ident, $b:ident => $c:ident ),* $(,)*
1441
        ) => {
1442
            $(
1443
                assert_eq!(<Gcf<$a, $b> as Unsigned>::to_usize(), $c::to_usize());
1444
                assert_eq!(<Gcf<$b, $a> as Unsigned>::to_usize(), $c::to_usize());
1445
             )*
1446
        }
1447
    }
1448
1449
    #[test]
1450
    fn gcd() {
1451
        gcd_test! {
1452
            U0,   U0    => U0,
1453
            U0,   U42   => U42,
1454
            U12,  U8    => U4,
1455
            U13,  U1013 => U1,  // Two primes
1456
            U9,   U26   => U1,  // Not prime but coprime
1457
            U143, U273  => U13,
1458
            U117, U273  => U39,
1459
        }
1460
    }
1461
}
1462
1463
// -----------------------------------------
1464
// GetBit
1465
1466
#[allow(missing_docs)]
1467
pub trait GetBit<I> {
1468
    #[allow(missing_docs)]
1469
    type Output;
1470
1471
    #[doc(hidden)]
1472
    fn get_bit<IM: InternalMarker>(&self, _: &I) -> Self::Output;
1473
}
1474
1475
#[allow(missing_docs)]
1476
pub type GetBitOut<N, I> = <N as GetBit<I>>::Output;
1477
1478
// Base case
1479
impl<Un, Bn> GetBit<U0> for UInt<Un, Bn>
1480
where
1481
    Bn: Copy,
1482
{
1483
    type Output = Bn;
1484
1485
    #[inline]
1486
0
    fn get_bit<IM: InternalMarker>(&self, _: &U0) -> Self::Output {
1487
0
        self.lsb
1488
0
    }
1489
}
1490
1491
// Recursion case
1492
impl<Un, Bn, Ui, Bi> GetBit<UInt<Ui, Bi>> for UInt<Un, Bn>
1493
where
1494
    UInt<Ui, Bi>: Copy + Sub<B1>,
1495
    Un: GetBit<Sub1<UInt<Ui, Bi>>>,
1496
{
1497
    type Output = GetBitOut<Un, Sub1<UInt<Ui, Bi>>>;
1498
1499
    #[inline]
1500
0
    fn get_bit<IM: InternalMarker>(&self, i: &UInt<Ui, Bi>) -> Self::Output {
1501
0
        self.msb.get_bit::<Internal>(&(*i - B1))
1502
0
    }
1503
}
1504
1505
// Ran out of bits
1506
impl<I> GetBit<I> for UTerm {
1507
    type Output = B0;
1508
1509
    #[inline]
1510
0
    fn get_bit<IM: InternalMarker>(&self, _: &I) -> Self::Output {
1511
0
        B0
1512
0
    }
1513
}
1514
1515
#[test]
1516
fn test_get_bit() {
1517
    use crate::consts::*;
1518
    use crate::Same;
1519
    type T1 = <GetBitOut<U2, U0> as Same<B0>>::Output;
1520
    type T2 = <GetBitOut<U2, U1> as Same<B1>>::Output;
1521
    type T3 = <GetBitOut<U2, U2> as Same<B0>>::Output;
1522
1523
    <T1 as Bit>::to_bool();
1524
    <T2 as Bit>::to_bool();
1525
    <T3 as Bit>::to_bool();
1526
}
1527
1528
// -----------------------------------------
1529
// SetBit
1530
1531
/// A **type operator** that, when implemented for unsigned integer `N`, sets the bit at position
1532
/// `I` to `B`.
1533
pub trait SetBit<I, B> {
1534
    #[allow(missing_docs)]
1535
    type Output;
1536
1537
    #[doc(hidden)]
1538
    fn set_bit<IM: InternalMarker>(self, _: I, _: B) -> Self::Output;
1539
}
1540
/// Alias for the result of calling `SetBit`: `SetBitOut<N, I, B> = <N as SetBit<I, B>>::Output`.
1541
pub type SetBitOut<N, I, B> = <N as SetBit<I, B>>::Output;
1542
1543
use crate::private::{PrivateSetBit, PrivateSetBitOut};
1544
1545
// Call private one then trim it
1546
impl<N, I, B> SetBit<I, B> for N
1547
where
1548
    N: PrivateSetBit<I, B>,
1549
    PrivateSetBitOut<N, I, B>: Trim,
1550
{
1551
    type Output = TrimOut<PrivateSetBitOut<N, I, B>>;
1552
1553
    #[inline]
1554
0
    fn set_bit<IM: InternalMarker>(self, i: I, b: B) -> Self::Output {
1555
0
        self.private_set_bit(i, b).trim()
1556
0
    }
1557
}
1558
1559
// Base case
1560
impl<Un, Bn, B> PrivateSetBit<U0, B> for UInt<Un, Bn> {
1561
    type Output = UInt<Un, B>;
1562
1563
    #[inline]
1564
0
    fn private_set_bit(self, _: U0, b: B) -> Self::Output {
1565
0
        UInt {
1566
0
            msb: self.msb,
1567
0
            lsb: b,
1568
0
        }
1569
0
    }
1570
}
1571
1572
// Recursion case
1573
impl<Un, Bn, Ui, Bi, B> PrivateSetBit<UInt<Ui, Bi>, B> for UInt<Un, Bn>
1574
where
1575
    UInt<Ui, Bi>: Sub<B1>,
1576
    Un: PrivateSetBit<Sub1<UInt<Ui, Bi>>, B>,
1577
{
1578
    type Output = UInt<PrivateSetBitOut<Un, Sub1<UInt<Ui, Bi>>, B>, Bn>;
1579
1580
    #[inline]
1581
0
    fn private_set_bit(self, i: UInt<Ui, Bi>, b: B) -> Self::Output {
1582
0
        UInt {
1583
0
            msb: self.msb.private_set_bit(i - B1, b),
1584
0
            lsb: self.lsb,
1585
0
        }
1586
0
    }
1587
}
1588
1589
// Ran out of bits, setting B0
1590
impl<I> PrivateSetBit<I, B0> for UTerm {
1591
    type Output = UTerm;
1592
1593
    #[inline]
1594
0
    fn private_set_bit(self, _: I, _: B0) -> Self::Output {
1595
0
        UTerm
1596
0
    }
1597
}
1598
1599
// Ran out of bits, setting B1
1600
impl<I> PrivateSetBit<I, B1> for UTerm
1601
where
1602
    U1: Shl<I>,
1603
{
1604
    type Output = Shleft<U1, I>;
1605
1606
    #[inline]
1607
0
    fn private_set_bit(self, i: I, _: B1) -> Self::Output {
1608
0
        <U1 as Shl<I>>::shl(U1::new(), i)
1609
0
    }
1610
}
1611
1612
#[test]
1613
fn test_set_bit() {
1614
    use crate::consts::*;
1615
    use crate::Same;
1616
    type T1 = <SetBitOut<U2, U0, B0> as Same<U2>>::Output;
1617
    type T2 = <SetBitOut<U2, U0, B1> as Same<U3>>::Output;
1618
    type T3 = <SetBitOut<U2, U1, B0> as Same<U0>>::Output;
1619
    type T4 = <SetBitOut<U2, U1, B1> as Same<U2>>::Output;
1620
    type T5 = <SetBitOut<U2, U2, B0> as Same<U2>>::Output;
1621
    type T6 = <SetBitOut<U2, U2, B1> as Same<U6>>::Output;
1622
    type T7 = <SetBitOut<U2, U3, B0> as Same<U2>>::Output;
1623
    type T8 = <SetBitOut<U2, U3, B1> as Same<U10>>::Output;
1624
    type T9 = <SetBitOut<U2, U4, B0> as Same<U2>>::Output;
1625
    type T10 = <SetBitOut<U2, U4, B1> as Same<U18>>::Output;
1626
1627
    type T11 = <SetBitOut<U3, U0, B0> as Same<U2>>::Output;
1628
1629
    <T1 as Unsigned>::to_u32();
1630
    <T2 as Unsigned>::to_u32();
1631
    <T3 as Unsigned>::to_u32();
1632
    <T4 as Unsigned>::to_u32();
1633
    <T5 as Unsigned>::to_u32();
1634
    <T6 as Unsigned>::to_u32();
1635
    <T7 as Unsigned>::to_u32();
1636
    <T8 as Unsigned>::to_u32();
1637
    <T9 as Unsigned>::to_u32();
1638
    <T10 as Unsigned>::to_u32();
1639
    <T11 as Unsigned>::to_u32();
1640
}
1641
1642
// -----------------------------------------
1643
1644
// Division algorithm:
1645
// We have N / D:
1646
// let Q = 0, R = 0
1647
// NBits = len(N)
1648
// for I in NBits-1..0:
1649
//   R <<=1
1650
//   R[0] = N[i]
1651
//   let C = R.cmp(D)
1652
//   if C == Equal or Greater:
1653
//     R -= D
1654
//     Q[i] = 1
1655
1656
#[cfg(tests)]
1657
mod tests {
1658
    macro_rules! test_div {
1659
        ($a:ident / $b:ident = $c:ident) => {{
1660
            type R = Quot<$a, $b>;
1661
            assert_eq!(<R as Unsigned>::to_usize(), $c::to_usize());
1662
        }};
1663
    }
1664
    #[test]
1665
    fn test_div() {
1666
        use crate::consts::*;
1667
        use crate::{Quot, Same};
1668
1669
        test_div!(U0 / U1 = U0);
1670
        test_div!(U1 / U1 = U1);
1671
        test_div!(U2 / U1 = U2);
1672
        test_div!(U3 / U1 = U3);
1673
        test_div!(U4 / U1 = U4);
1674
1675
        test_div!(U0 / U2 = U0);
1676
        test_div!(U1 / U2 = U0);
1677
        test_div!(U2 / U2 = U1);
1678
        test_div!(U3 / U2 = U1);
1679
        test_div!(U4 / U2 = U2);
1680
        test_div!(U6 / U2 = U3);
1681
        test_div!(U7 / U2 = U3);
1682
1683
        type T = <SetBitOut<U0, U1, B1> as Same<U2>>::Output;
1684
        <T as Unsigned>::to_u32();
1685
    }
1686
}
1687
// -----------------------------------------
1688
// Div
1689
use core::ops::Div;
1690
1691
// 0 // N
1692
impl<Ur: Unsigned, Br: Bit> Div<UInt<Ur, Br>> for UTerm {
1693
    type Output = UTerm;
1694
    #[inline]
1695
0
    fn div(self, _: UInt<Ur, Br>) -> Self::Output {
1696
0
        UTerm
1697
0
    }
1698
}
1699
1700
// M // N
1701
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> Div<UInt<Ur, Br>> for UInt<Ul, Bl>
1702
where
1703
    UInt<Ul, Bl>: Len,
1704
    Length<UInt<Ul, Bl>>: Sub<B1>,
1705
    (): PrivateDiv<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>,
1706
{
1707
    type Output = PrivateDivQuot<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>;
1708
    #[inline]
1709
    #[cfg_attr(feature = "cargo-clippy", allow(clippy::suspicious_arithmetic_impl))]
1710
0
    fn div(self, rhs: UInt<Ur, Br>) -> Self::Output {
1711
0
        ().private_div_quotient(self, rhs, U0::new(), U0::new(), self.len() - B1)
1712
0
    }
1713
}
1714
1715
// -----------------------------------------
1716
// Rem
1717
use core::ops::Rem;
1718
1719
// 0 % N
1720
impl<Ur: Unsigned, Br: Bit> Rem<UInt<Ur, Br>> for UTerm {
1721
    type Output = UTerm;
1722
    #[inline]
1723
0
    fn rem(self, _: UInt<Ur, Br>) -> Self::Output {
1724
0
        UTerm
1725
0
    }
1726
}
1727
1728
// M % N
1729
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> Rem<UInt<Ur, Br>> for UInt<Ul, Bl>
1730
where
1731
    UInt<Ul, Bl>: Len,
1732
    Length<UInt<Ul, Bl>>: Sub<B1>,
1733
    (): PrivateDiv<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>,
1734
{
1735
    type Output = PrivateDivRem<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>;
1736
    #[inline]
1737
0
    fn rem(self, rhs: UInt<Ur, Br>) -> Self::Output {
1738
0
        ().private_div_remainder(self, rhs, UTerm, UTerm, self.len() - B1)
1739
0
    }
1740
}
1741
1742
// -----------------------------------------
1743
// PrivateDiv
1744
use crate::private::{PrivateDiv, PrivateDivQuot, PrivateDivRem};
1745
1746
use crate::Compare;
1747
// R == 0: We set R = UInt<UTerm, N[i]>, then call out to PrivateDivIf for the if statement
1748
impl<N, D, Q, I> PrivateDiv<N, D, Q, U0, I> for ()
1749
where
1750
    N: GetBit<I>,
1751
    UInt<UTerm, GetBitOut<N, I>>: Trim,
1752
    TrimOut<UInt<UTerm, GetBitOut<N, I>>>: Cmp<D>,
1753
    (): PrivateDivIf<
1754
        N,
1755
        D,
1756
        Q,
1757
        TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
1758
        I,
1759
        Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>,
1760
    >,
1761
{
1762
    type Quotient = PrivateDivIfQuot<
1763
        N,
1764
        D,
1765
        Q,
1766
        TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
1767
        I,
1768
        Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>,
1769
    >;
1770
    type Remainder = PrivateDivIfRem<
1771
        N,
1772
        D,
1773
        Q,
1774
        TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
1775
        I,
1776
        Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>,
1777
    >;
1778
1779
    #[inline]
1780
0
    fn private_div_quotient(self, n: N, d: D, q: Q, _: U0, i: I) -> Self::Quotient
1781
0
where {
1782
0
        let r = (UInt {
1783
0
            msb: UTerm,
1784
0
            lsb: n.get_bit::<Internal>(&i),
1785
0
        })
1786
0
        .trim();
1787
0
        let r_cmp_d = r.compare::<Internal>(&d);
1788
0
        ().private_div_if_quotient(n, d, q, r, i, r_cmp_d)
1789
0
    }
1790
1791
    #[inline]
1792
0
    fn private_div_remainder(self, n: N, d: D, q: Q, _: U0, i: I) -> Self::Remainder {
1793
0
        let r = (UInt {
1794
0
            msb: UTerm,
1795
0
            lsb: n.get_bit::<Internal>(&i),
1796
0
        })
1797
0
        .trim();
1798
0
        let r_cmp_d = r.compare::<Internal>(&d);
1799
0
        ().private_div_if_remainder(n, d, q, r, i, r_cmp_d)
1800
0
    }
1801
}
1802
1803
// R > 0: We perform R <<= 1 and R[0] = N[i], then call out to PrivateDivIf for the if statement
1804
impl<N, D, Q, Ur, Br, I> PrivateDiv<N, D, Q, UInt<Ur, Br>, I> for ()
1805
where
1806
    N: GetBit<I>,
1807
    UInt<UInt<Ur, Br>, GetBitOut<N, I>>: Cmp<D>,
1808
    (): PrivateDivIf<
1809
        N,
1810
        D,
1811
        Q,
1812
        UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
1813
        I,
1814
        Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>,
1815
    >,
1816
{
1817
    type Quotient = PrivateDivIfQuot<
1818
        N,
1819
        D,
1820
        Q,
1821
        UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
1822
        I,
1823
        Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>,
1824
    >;
1825
    type Remainder = PrivateDivIfRem<
1826
        N,
1827
        D,
1828
        Q,
1829
        UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
1830
        I,
1831
        Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>,
1832
    >;
1833
1834
    #[inline]
1835
0
    fn private_div_quotient(self, n: N, d: D, q: Q, r: UInt<Ur, Br>, i: I) -> Self::Quotient {
1836
0
        let r = UInt {
1837
0
            msb: r,
1838
0
            lsb: n.get_bit::<Internal>(&i),
1839
0
        };
1840
0
        let r_cmp_d = r.compare::<Internal>(&d);
1841
0
        ().private_div_if_quotient(n, d, q, r, i, r_cmp_d)
1842
0
    }
1843
1844
    #[inline]
1845
0
    fn private_div_remainder(self, n: N, d: D, q: Q, r: UInt<Ur, Br>, i: I) -> Self::Remainder {
1846
0
        let r = UInt {
1847
0
            msb: r,
1848
0
            lsb: n.get_bit::<Internal>(&i),
1849
0
        };
1850
0
        let r_cmp_d = r.compare::<Internal>(&d);
1851
0
        ().private_div_if_remainder(n, d, q, r, i, r_cmp_d)
1852
0
    }
1853
}
1854
1855
// -----------------------------------------
1856
// PrivateDivIf
1857
1858
use crate::private::{PrivateDivIf, PrivateDivIfQuot, PrivateDivIfRem};
1859
1860
// R < D, I > 0, we do nothing and recurse
1861
impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Less> for ()
1862
where
1863
    UInt<Ui, Bi>: Sub<B1>,
1864
    (): PrivateDiv<N, D, Q, R, Sub1<UInt<Ui, Bi>>>,
1865
{
1866
    type Quotient = PrivateDivQuot<N, D, Q, R, Sub1<UInt<Ui, Bi>>>;
1867
    type Remainder = PrivateDivRem<N, D, Q, R, Sub1<UInt<Ui, Bi>>>;
1868
1869
    #[inline]
1870
0
    fn private_div_if_quotient(
1871
0
        self,
1872
0
        n: N,
1873
0
        d: D,
1874
0
        q: Q,
1875
0
        r: R,
1876
0
        i: UInt<Ui, Bi>,
1877
0
        _: Less,
1878
0
    ) -> Self::Quotient
1879
0
where {
1880
0
        ().private_div_quotient(n, d, q, r, i - B1)
1881
0
    }
1882
1883
    #[inline]
1884
0
    fn private_div_if_remainder(
1885
0
        self,
1886
0
        n: N,
1887
0
        d: D,
1888
0
        q: Q,
1889
0
        r: R,
1890
0
        i: UInt<Ui, Bi>,
1891
0
        _: Less,
1892
0
    ) -> Self::Remainder
1893
0
where {
1894
0
        ().private_div_remainder(n, d, q, r, i - B1)
1895
0
    }
1896
}
1897
1898
// R == D, I > 0, we set R = 0, Q[I] = 1 and recurse
1899
impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Equal> for ()
1900
where
1901
    UInt<Ui, Bi>: Copy + Sub<B1>,
1902
    Q: SetBit<UInt<Ui, Bi>, B1>,
1903
    (): PrivateDiv<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>,
1904
{
1905
    type Quotient = PrivateDivQuot<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>;
1906
    type Remainder = PrivateDivRem<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>;
1907
1908
    #[inline]
1909
0
    fn private_div_if_quotient(
1910
0
        self,
1911
0
        n: N,
1912
0
        d: D,
1913
0
        q: Q,
1914
0
        _: R,
1915
0
        i: UInt<Ui, Bi>,
1916
0
        _: Equal,
1917
0
    ) -> Self::Quotient
1918
0
where {
1919
0
        ().private_div_quotient(n, d, q.set_bit::<Internal>(i, B1), U0::new(), i - B1)
1920
0
    }
1921
1922
    #[inline]
1923
0
    fn private_div_if_remainder(
1924
0
        self,
1925
0
        n: N,
1926
0
        d: D,
1927
0
        q: Q,
1928
0
        _: R,
1929
0
        i: UInt<Ui, Bi>,
1930
0
        _: Equal,
1931
0
    ) -> Self::Remainder
1932
0
where {
1933
0
        ().private_div_remainder(n, d, q.set_bit::<Internal>(i, B1), U0::new(), i - B1)
1934
0
    }
1935
}
1936
1937
use crate::Diff;
1938
// R > D, I > 0, we set R -= D, Q[I] = 1 and recurse
1939
impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Greater> for ()
1940
where
1941
    D: Copy,
1942
    UInt<Ui, Bi>: Copy + Sub<B1>,
1943
    R: Sub<D>,
1944
    Q: SetBit<UInt<Ui, Bi>, B1>,
1945
    (): PrivateDiv<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, Diff<R, D>, Sub1<UInt<Ui, Bi>>>,
1946
{
1947
    type Quotient =
1948
        PrivateDivQuot<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, Diff<R, D>, Sub1<UInt<Ui, Bi>>>;
1949
    type Remainder =
1950
        PrivateDivRem<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, Diff<R, D>, Sub1<UInt<Ui, Bi>>>;
1951
1952
    #[inline]
1953
0
    fn private_div_if_quotient(
1954
0
        self,
1955
0
        n: N,
1956
0
        d: D,
1957
0
        q: Q,
1958
0
        r: R,
1959
0
        i: UInt<Ui, Bi>,
1960
0
        _: Greater,
1961
0
    ) -> Self::Quotient
1962
0
where {
1963
0
        ().private_div_quotient(n, d, q.set_bit::<Internal>(i, B1), r - d, i - B1)
1964
0
    }
1965
1966
    #[inline]
1967
0
    fn private_div_if_remainder(
1968
0
        self,
1969
0
        n: N,
1970
0
        d: D,
1971
0
        q: Q,
1972
0
        r: R,
1973
0
        i: UInt<Ui, Bi>,
1974
0
        _: Greater,
1975
0
    ) -> Self::Remainder
1976
0
where {
1977
0
        ().private_div_remainder(n, d, q.set_bit::<Internal>(i, B1), r - d, i - B1)
1978
0
    }
1979
}
1980
1981
// R < D, I == 0: we do nothing, and return
1982
impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Less> for () {
1983
    type Quotient = Q;
1984
    type Remainder = R;
1985
1986
    #[inline]
1987
0
    fn private_div_if_quotient(self, _: N, _: D, q: Q, _: R, _: U0, _: Less) -> Self::Quotient {
1988
0
        q
1989
0
    }
1990
1991
    #[inline]
1992
0
    fn private_div_if_remainder(self, _: N, _: D, _: Q, r: R, _: U0, _: Less) -> Self::Remainder {
1993
0
        r
1994
0
    }
1995
}
1996
1997
// R == D, I == 0: we set R = 0, Q[I] = 1, and return
1998
impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Equal> for ()
1999
where
2000
    Q: SetBit<U0, B1>,
2001
{
2002
    type Quotient = SetBitOut<Q, U0, B1>;
2003
    type Remainder = U0;
2004
2005
    #[inline]
2006
0
    fn private_div_if_quotient(self, _: N, _: D, q: Q, _: R, i: U0, _: Equal) -> Self::Quotient {
2007
0
        q.set_bit::<Internal>(i, B1)
2008
0
    }
2009
2010
    #[inline]
2011
0
    fn private_div_if_remainder(self, _: N, _: D, _: Q, _: R, i: U0, _: Equal) -> Self::Remainder {
2012
0
        i
2013
0
    }
2014
}
2015
2016
// R > D, I == 0: We set R -= D, Q[I] = 1, and return
2017
impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Greater> for ()
2018
where
2019
    R: Sub<D>,
2020
    Q: SetBit<U0, B1>,
2021
{
2022
    type Quotient = SetBitOut<Q, U0, B1>;
2023
    type Remainder = Diff<R, D>;
2024
2025
    #[inline]
2026
0
    fn private_div_if_quotient(self, _: N, _: D, q: Q, _: R, i: U0, _: Greater) -> Self::Quotient {
2027
0
        q.set_bit::<Internal>(i, B1)
2028
0
    }
2029
2030
    #[inline]
2031
0
    fn private_div_if_remainder(
2032
0
        self,
2033
0
        _: N,
2034
0
        d: D,
2035
0
        _: Q,
2036
0
        r: R,
2037
0
        _: U0,
2038
0
        _: Greater,
2039
0
    ) -> Self::Remainder {
2040
0
        r - d
2041
0
    }
2042
}
2043
2044
// -----------------------------------------
2045
// PartialDiv
2046
use crate::{PartialDiv, Quot};
2047
impl<Ur: Unsigned, Br: Bit> PartialDiv<UInt<Ur, Br>> for UTerm {
2048
    type Output = UTerm;
2049
    #[inline]
2050
0
    fn partial_div(self, _: UInt<Ur, Br>) -> Self::Output {
2051
0
        UTerm
2052
0
    }
2053
}
2054
2055
// M / N
2056
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> PartialDiv<UInt<Ur, Br>> for UInt<Ul, Bl>
2057
where
2058
    UInt<Ul, Bl>: Div<UInt<Ur, Br>> + Rem<UInt<Ur, Br>, Output = U0>,
2059
{
2060
    type Output = Quot<UInt<Ul, Bl>, UInt<Ur, Br>>;
2061
    #[inline]
2062
0
    fn partial_div(self, rhs: UInt<Ur, Br>) -> Self::Output {
2063
0
        self / rhs
2064
0
    }
2065
}
2066
2067
// -----------------------------------------
2068
// PrivateMin
2069
use crate::private::{PrivateMin, PrivateMinOut};
2070
2071
impl<U, B, Ur> PrivateMin<Ur, Equal> for UInt<U, B>
2072
where
2073
    Ur: Unsigned,
2074
    U: Unsigned,
2075
    B: Bit,
2076
{
2077
    type Output = UInt<U, B>;
2078
    #[inline]
2079
0
    fn private_min(self, _: Ur) -> Self::Output {
2080
0
        self
2081
0
    }
2082
}
2083
2084
impl<U, B, Ur> PrivateMin<Ur, Less> for UInt<U, B>
2085
where
2086
    Ur: Unsigned,
2087
    U: Unsigned,
2088
    B: Bit,
2089
{
2090
    type Output = UInt<U, B>;
2091
    #[inline]
2092
0
    fn private_min(self, _: Ur) -> Self::Output {
2093
0
        self
2094
0
    }
2095
}
2096
2097
impl<U, B, Ur> PrivateMin<Ur, Greater> for UInt<U, B>
2098
where
2099
    Ur: Unsigned,
2100
    U: Unsigned,
2101
    B: Bit,
2102
{
2103
    type Output = Ur;
2104
    #[inline]
2105
0
    fn private_min(self, rhs: Ur) -> Self::Output {
2106
0
        rhs
2107
0
    }
2108
}
2109
2110
// -----------------------------------------
2111
// Min
2112
use crate::Min;
2113
2114
impl<U> Min<U> for UTerm
2115
where
2116
    U: Unsigned,
2117
{
2118
    type Output = UTerm;
2119
    #[inline]
2120
0
    fn min(self, _: U) -> Self::Output {
2121
0
        self
2122
0
    }
2123
}
2124
2125
impl<U, B, Ur> Min<Ur> for UInt<U, B>
2126
where
2127
    U: Unsigned,
2128
    B: Bit,
2129
    Ur: Unsigned,
2130
    UInt<U, B>: Cmp<Ur> + PrivateMin<Ur, Compare<UInt<U, B>, Ur>>,
2131
{
2132
    type Output = PrivateMinOut<UInt<U, B>, Ur, Compare<UInt<U, B>, Ur>>;
2133
    #[inline]
2134
0
    fn min(self, rhs: Ur) -> Self::Output {
2135
0
        self.private_min(rhs)
2136
0
    }
2137
}
2138
2139
// -----------------------------------------
2140
// PrivateMax
2141
use crate::private::{PrivateMax, PrivateMaxOut};
2142
2143
impl<U, B, Ur> PrivateMax<Ur, Equal> for UInt<U, B>
2144
where
2145
    Ur: Unsigned,
2146
    U: Unsigned,
2147
    B: Bit,
2148
{
2149
    type Output = UInt<U, B>;
2150
    #[inline]
2151
0
    fn private_max(self, _: Ur) -> Self::Output {
2152
0
        self
2153
0
    }
2154
}
2155
2156
impl<U, B, Ur> PrivateMax<Ur, Less> for UInt<U, B>
2157
where
2158
    Ur: Unsigned,
2159
    U: Unsigned,
2160
    B: Bit,
2161
{
2162
    type Output = Ur;
2163
    #[inline]
2164
0
    fn private_max(self, rhs: Ur) -> Self::Output {
2165
0
        rhs
2166
0
    }
2167
}
2168
2169
impl<U, B, Ur> PrivateMax<Ur, Greater> for UInt<U, B>
2170
where
2171
    Ur: Unsigned,
2172
    U: Unsigned,
2173
    B: Bit,
2174
{
2175
    type Output = UInt<U, B>;
2176
    #[inline]
2177
0
    fn private_max(self, _: Ur) -> Self::Output {
2178
0
        self
2179
0
    }
2180
}
2181
2182
// -----------------------------------------
2183
// Max
2184
use crate::Max;
2185
2186
impl<U> Max<U> for UTerm
2187
where
2188
    U: Unsigned,
2189
{
2190
    type Output = U;
2191
    #[inline]
2192
0
    fn max(self, rhs: U) -> Self::Output {
2193
0
        rhs
2194
0
    }
2195
}
2196
2197
impl<U, B, Ur> Max<Ur> for UInt<U, B>
2198
where
2199
    U: Unsigned,
2200
    B: Bit,
2201
    Ur: Unsigned,
2202
    UInt<U, B>: Cmp<Ur> + PrivateMax<Ur, Compare<UInt<U, B>, Ur>>,
2203
{
2204
    type Output = PrivateMaxOut<UInt<U, B>, Ur, Compare<UInt<U, B>, Ur>>;
2205
    #[inline]
2206
0
    fn max(self, rhs: Ur) -> Self::Output {
2207
0
        self.private_max(rhs)
2208
0
    }
2209
}
2210
2211
// -----------------------------------------
2212
// SquareRoot
2213
2214
impl<N> SquareRoot for N
2215
where
2216
    N: PrivateSquareRoot,
2217
{
2218
    type Output = <Self as PrivateSquareRoot>::Output;
2219
}
2220
2221
// sqrt(0) = 0.
2222
impl PrivateSquareRoot for UTerm {
2223
    type Output = UTerm;
2224
}
2225
2226
// sqrt(1) = 1.
2227
impl PrivateSquareRoot for UInt<UTerm, B1> {
2228
    type Output = UInt<UTerm, B1>;
2229
}
2230
2231
// General case of sqrt(Self) where Self >= 2. If a and b are
2232
// bit-valued and Self = 4*u + 2*a + b, then the integer-valued
2233
// (fractional part truncated) square root of Self is either 2*sqrt(u)
2234
// or 2*sqrt(u)+1. Guess and check by comparing (2*sqrt(u)+1)^2
2235
// against Self. Since the `typenum` result of that comparison is a
2236
// bit, directly add that bit to 2*sqrt(u).
2237
//
2238
// Use `Sum<Double<Sqrt<U>>, GrEq<...>>` instead of `UInt<Sqrt<U>,
2239
// GrEq<...>>` because `Sqrt<U>` can turn out to be `UTerm` and
2240
// `GrEq<...>` can turn out to be `B0`, which would not be a valid
2241
// UInt as leading zeros are disallowed.
2242
impl<U, Ba, Bb> PrivateSquareRoot for UInt<UInt<U, Ba>, Bb>
2243
where
2244
    U: Unsigned,
2245
    Ba: Bit,
2246
    Bb: Bit,
2247
    U: SquareRoot,
2248
    Sqrt<U>: Shl<B1>,
2249
    Double<Sqrt<U>>: Add<B1>,
2250
    Add1<Double<Sqrt<U>>>: Mul,
2251
    Self: IsGreaterOrEqual<Square<Add1<Double<Sqrt<U>>>>>,
2252
    Double<Sqrt<U>>: Add<GrEq<Self, Square<Add1<Double<Sqrt<U>>>>>>,
2253
{
2254
    type Output = Sum<Double<Sqrt<U>>, GrEq<Self, Square<Add1<Double<Sqrt<U>>>>>>;
2255
}
2256
2257
#[test]
2258
fn sqrt_test() {
2259
    use crate::consts::*;
2260
2261
    assert_eq!(0, <Sqrt<U0>>::to_u32());
2262
2263
    assert_eq!(1, <Sqrt<U1>>::to_u32());
2264
    assert_eq!(1, <Sqrt<U2>>::to_u32());
2265
    assert_eq!(1, <Sqrt<U3>>::to_u32());
2266
2267
    assert_eq!(2, <Sqrt<U4>>::to_u32());
2268
    assert_eq!(2, <Sqrt<U5>>::to_u32());
2269
    assert_eq!(2, <Sqrt<U6>>::to_u32());
2270
    assert_eq!(2, <Sqrt<U7>>::to_u32());
2271
    assert_eq!(2, <Sqrt<U8>>::to_u32());
2272
2273
    assert_eq!(3, <Sqrt<U9>>::to_u32());
2274
    assert_eq!(3, <Sqrt<U10>>::to_u32());
2275
    assert_eq!(3, <Sqrt<U11>>::to_u32());
2276
    assert_eq!(3, <Sqrt<U12>>::to_u32());
2277
    assert_eq!(3, <Sqrt<U13>>::to_u32());
2278
    assert_eq!(3, <Sqrt<U14>>::to_u32());
2279
    assert_eq!(3, <Sqrt<U15>>::to_u32());
2280
2281
    assert_eq!(4, <Sqrt<U16>>::to_u32());
2282
    assert_eq!(4, <Sqrt<U17>>::to_u32());
2283
    assert_eq!(4, <Sqrt<U18>>::to_u32());
2284
    assert_eq!(4, <Sqrt<U19>>::to_u32());
2285
    assert_eq!(4, <Sqrt<U20>>::to_u32());
2286
    assert_eq!(4, <Sqrt<U21>>::to_u32());
2287
    assert_eq!(4, <Sqrt<U22>>::to_u32());
2288
    assert_eq!(4, <Sqrt<U23>>::to_u32());
2289
    assert_eq!(4, <Sqrt<U24>>::to_u32());
2290
2291
    assert_eq!(5, <Sqrt<U25>>::to_u32());
2292
    assert_eq!(5, <Sqrt<U26>>::to_u32());
2293
    // ...
2294
}
2295
2296
// -----------------------------------------
2297
// Logarithm2
2298
2299
impl<N> Logarithm2 for N
2300
where
2301
    N: PrivateLogarithm2,
2302
{
2303
    type Output = <Self as PrivateLogarithm2>::Output;
2304
}
2305
2306
// log2(1) = 0.
2307
impl PrivateLogarithm2 for UInt<UTerm, B1> {
2308
    type Output = U0;
2309
}
2310
2311
// General case of log2(Self) where Self >= 2.
2312
impl<U, B> PrivateLogarithm2 for UInt<U, B>
2313
where
2314
    U: Unsigned + Logarithm2,
2315
    B: Bit,
2316
    Log2<U>: Add<B1>,
2317
{
2318
    type Output = Add1<Log2<U>>;
2319
}
2320
2321
// -----------------------------------------
2322
// ToInt
2323
2324
impl ToInt<i8> for UTerm {
2325
    #[inline]
2326
0
    fn to_int() -> i8 {
2327
0
        Self::I8
2328
0
    }
2329
    const INT: i8 = Self::I8;
2330
}
2331
2332
impl ToInt<i16> for UTerm {
2333
    #[inline]
2334
0
    fn to_int() -> i16 {
2335
0
        Self::I16
2336
0
    }
2337
    const INT: i16 = Self::I16;
2338
}
2339
2340
impl ToInt<i32> for UTerm {
2341
    #[inline]
2342
0
    fn to_int() -> i32 {
2343
0
        Self::I32
2344
0
    }
2345
    const INT: i32 = Self::I32;
2346
}
2347
2348
impl ToInt<i64> for UTerm {
2349
    #[inline]
2350
0
    fn to_int() -> i64 {
2351
0
        Self::I64
2352
0
    }
2353
    const INT: i64 = Self::I64;
2354
}
2355
2356
impl ToInt<u8> for UTerm {
2357
    #[inline]
2358
0
    fn to_int() -> u8 {
2359
0
        Self::U8
2360
0
    }
2361
    const INT: u8 = Self::U8;
2362
}
2363
2364
impl ToInt<u16> for UTerm {
2365
    #[inline]
2366
0
    fn to_int() -> u16 {
2367
0
        Self::U16
2368
0
    }
2369
    const INT: u16 = Self::U16;
2370
}
2371
2372
impl ToInt<u32> for UTerm {
2373
    #[inline]
2374
0
    fn to_int() -> u32 {
2375
0
        Self::U32
2376
0
    }
2377
    const INT: u32 = Self::U32;
2378
}
2379
2380
impl ToInt<u64> for UTerm {
2381
    #[inline]
2382
0
    fn to_int() -> u64 {
2383
0
        Self::U64
2384
0
    }
2385
    const INT: u64 = Self::U64;
2386
}
2387
2388
impl ToInt<usize> for UTerm {
2389
    #[inline]
2390
0
    fn to_int() -> usize {
2391
0
        Self::USIZE
2392
0
    }
2393
    const INT: usize = Self::USIZE;
2394
}
2395
2396
impl<U, B> ToInt<i8> for UInt<U, B>
2397
where
2398
    U: Unsigned,
2399
    B: Bit,
2400
{
2401
    #[inline]
2402
0
    fn to_int() -> i8 {
2403
0
        Self::I8
2404
0
    }
2405
    const INT: i8 = Self::I8;
2406
}
2407
2408
impl<U, B> ToInt<i16> for UInt<U, B>
2409
where
2410
    U: Unsigned,
2411
    B: Bit,
2412
{
2413
    #[inline]
2414
0
    fn to_int() -> i16 {
2415
0
        Self::I16
2416
0
    }
2417
    const INT: i16 = Self::I16;
2418
}
2419
2420
impl<U, B> ToInt<i32> for UInt<U, B>
2421
where
2422
    U: Unsigned,
2423
    B: Bit,
2424
{
2425
    #[inline]
2426
0
    fn to_int() -> i32 {
2427
0
        Self::I32
2428
0
    }
2429
    const INT: i32 = Self::I32;
2430
}
2431
2432
impl<U, B> ToInt<i64> for UInt<U, B>
2433
where
2434
    U: Unsigned,
2435
    B: Bit,
2436
{
2437
    #[inline]
2438
0
    fn to_int() -> i64 {
2439
0
        Self::I64
2440
0
    }
2441
    const INT: i64 = Self::I64;
2442
}
2443
2444
impl<U, B> ToInt<u8> for UInt<U, B>
2445
where
2446
    U: Unsigned,
2447
    B: Bit,
2448
{
2449
    #[inline]
2450
0
    fn to_int() -> u8 {
2451
0
        Self::U8
2452
0
    }
2453
    const INT: u8 = Self::U8;
2454
}
2455
2456
impl<U, B> ToInt<u16> for UInt<U, B>
2457
where
2458
    U: Unsigned,
2459
    B: Bit,
2460
{
2461
    #[inline]
2462
0
    fn to_int() -> u16 {
2463
0
        Self::U16
2464
0
    }
2465
    const INT: u16 = Self::U16;
2466
}
2467
2468
impl<U, B> ToInt<u32> for UInt<U, B>
2469
where
2470
    U: Unsigned,
2471
    B: Bit,
2472
{
2473
    #[inline]
2474
0
    fn to_int() -> u32 {
2475
0
        Self::U32
2476
0
    }
2477
    const INT: u32 = Self::U32;
2478
}
2479
2480
impl<U, B> ToInt<u64> for UInt<U, B>
2481
where
2482
    U: Unsigned,
2483
    B: Bit,
2484
{
2485
    #[inline]
2486
0
    fn to_int() -> u64 {
2487
0
        Self::U64
2488
0
    }
2489
    const INT: u64 = Self::U64;
2490
}
2491
2492
impl<U, B> ToInt<usize> for UInt<U, B>
2493
where
2494
    U: Unsigned,
2495
    B: Bit,
2496
{
2497
    #[inline]
2498
0
    fn to_int() -> usize {
2499
0
        Self::USIZE
2500
0
    }
2501
    const INT: usize = Self::USIZE;
2502
}
2503
2504
#[cfg(test)]
2505
mod tests {
2506
    use crate::consts::*;
2507
    use crate::{Log2, ToInt, Unsigned};
2508
2509
    #[test]
2510
    fn log2_test() {
2511
        assert_eq!(0, <Log2<U1>>::to_u32());
2512
2513
        assert_eq!(1, <Log2<U2>>::to_u32());
2514
        assert_eq!(1, <Log2<U3>>::to_u32());
2515
2516
        assert_eq!(2, <Log2<U4>>::to_u32());
2517
        assert_eq!(2, <Log2<U5>>::to_u32());
2518
        assert_eq!(2, <Log2<U6>>::to_u32());
2519
        assert_eq!(2, <Log2<U7>>::to_u32());
2520
2521
        assert_eq!(3, <Log2<U8>>::to_u32());
2522
        assert_eq!(3, <Log2<U9>>::to_u32());
2523
        assert_eq!(3, <Log2<U10>>::to_u32());
2524
        assert_eq!(3, <Log2<U11>>::to_u32());
2525
        assert_eq!(3, <Log2<U12>>::to_u32());
2526
        assert_eq!(3, <Log2<U13>>::to_u32());
2527
        assert_eq!(3, <Log2<U14>>::to_u32());
2528
        assert_eq!(3, <Log2<U15>>::to_u32());
2529
2530
        assert_eq!(4, <Log2<U16>>::to_u32());
2531
        assert_eq!(4, <Log2<U17>>::to_u32());
2532
        assert_eq!(4, <Log2<U18>>::to_u32());
2533
        assert_eq!(4, <Log2<U19>>::to_u32());
2534
        assert_eq!(4, <Log2<U20>>::to_u32());
2535
        assert_eq!(4, <Log2<U21>>::to_u32());
2536
        assert_eq!(4, <Log2<U22>>::to_u32());
2537
        assert_eq!(4, <Log2<U23>>::to_u32());
2538
        assert_eq!(4, <Log2<U24>>::to_u32());
2539
        assert_eq!(4, <Log2<U25>>::to_u32());
2540
        assert_eq!(4, <Log2<U26>>::to_u32());
2541
        assert_eq!(4, <Log2<U27>>::to_u32());
2542
        assert_eq!(4, <Log2<U28>>::to_u32());
2543
        assert_eq!(4, <Log2<U29>>::to_u32());
2544
        assert_eq!(4, <Log2<U30>>::to_u32());
2545
        assert_eq!(4, <Log2<U31>>::to_u32());
2546
2547
        assert_eq!(5, <Log2<U32>>::to_u32());
2548
        assert_eq!(5, <Log2<U33>>::to_u32());
2549
2550
        // ...
2551
    }
2552
2553
    #[test]
2554
    fn uint_toint_test() {
2555
        // i8
2556
        assert_eq!(0_i8, U0::to_int());
2557
        assert_eq!(1_i8, U1::to_int());
2558
        assert_eq!(2_i8, U2::to_int());
2559
        assert_eq!(3_i8, U3::to_int());
2560
        assert_eq!(4_i8, U4::to_int());
2561
        assert_eq!(0_i8, U0::INT);
2562
        assert_eq!(1_i8, U1::INT);
2563
        assert_eq!(2_i8, U2::INT);
2564
        assert_eq!(3_i8, U3::INT);
2565
        assert_eq!(4_i8, U4::INT);
2566
2567
        // i16
2568
        assert_eq!(0_i16, U0::to_int());
2569
        assert_eq!(1_i16, U1::to_int());
2570
        assert_eq!(2_i16, U2::to_int());
2571
        assert_eq!(3_i16, U3::to_int());
2572
        assert_eq!(4_i16, U4::to_int());
2573
        assert_eq!(0_i16, U0::INT);
2574
        assert_eq!(1_i16, U1::INT);
2575
        assert_eq!(2_i16, U2::INT);
2576
        assert_eq!(3_i16, U3::INT);
2577
        assert_eq!(4_i16, U4::INT);
2578
2579
        // i32
2580
        assert_eq!(0_i32, U0::to_int());
2581
        assert_eq!(1_i32, U1::to_int());
2582
        assert_eq!(2_i32, U2::to_int());
2583
        assert_eq!(3_i32, U3::to_int());
2584
        assert_eq!(4_i32, U4::to_int());
2585
        assert_eq!(0_i32, U0::INT);
2586
        assert_eq!(1_i32, U1::INT);
2587
        assert_eq!(2_i32, U2::INT);
2588
        assert_eq!(3_i32, U3::INT);
2589
        assert_eq!(4_i32, U4::INT);
2590
2591
        // i64
2592
        assert_eq!(0_i64, U0::to_int());
2593
        assert_eq!(1_i64, U1::to_int());
2594
        assert_eq!(2_i64, U2::to_int());
2595
        assert_eq!(3_i64, U3::to_int());
2596
        assert_eq!(4_i64, U4::to_int());
2597
        assert_eq!(0_i64, U0::INT);
2598
        assert_eq!(1_i64, U1::INT);
2599
        assert_eq!(2_i64, U2::INT);
2600
        assert_eq!(3_i64, U3::INT);
2601
        assert_eq!(4_i64, U4::INT);
2602
2603
        // u8
2604
        assert_eq!(0_u8, U0::to_int());
2605
        assert_eq!(1_u8, U1::to_int());
2606
        assert_eq!(2_u8, U2::to_int());
2607
        assert_eq!(3_u8, U3::to_int());
2608
        assert_eq!(4_u8, U4::to_int());
2609
        assert_eq!(0_u8, U0::INT);
2610
        assert_eq!(1_u8, U1::INT);
2611
        assert_eq!(2_u8, U2::INT);
2612
        assert_eq!(3_u8, U3::INT);
2613
        assert_eq!(4_u8, U4::INT);
2614
2615
        // u16
2616
        assert_eq!(0_u16, U0::to_int());
2617
        assert_eq!(1_u16, U1::to_int());
2618
        assert_eq!(2_u16, U2::to_int());
2619
        assert_eq!(3_u16, U3::to_int());
2620
        assert_eq!(4_u16, U4::to_int());
2621
        assert_eq!(0_u16, U0::INT);
2622
        assert_eq!(1_u16, U1::INT);
2623
        assert_eq!(2_u16, U2::INT);
2624
        assert_eq!(3_u16, U3::INT);
2625
        assert_eq!(4_u16, U4::INT);
2626
2627
        // u32
2628
        assert_eq!(0_u32, U0::to_int());
2629
        assert_eq!(1_u32, U1::to_int());
2630
        assert_eq!(2_u32, U2::to_int());
2631
        assert_eq!(3_u32, U3::to_int());
2632
        assert_eq!(4_u32, U4::to_int());
2633
        assert_eq!(0_u32, U0::INT);
2634
        assert_eq!(1_u32, U1::INT);
2635
        assert_eq!(2_u32, U2::INT);
2636
        assert_eq!(3_u32, U3::INT);
2637
        assert_eq!(4_u32, U4::INT);
2638
2639
        // u64
2640
        assert_eq!(0_u64, U0::to_int());
2641
        assert_eq!(1_u64, U1::to_int());
2642
        assert_eq!(2_u64, U2::to_int());
2643
        assert_eq!(3_u64, U3::to_int());
2644
        assert_eq!(4_u64, U4::to_int());
2645
        assert_eq!(0_u64, U0::INT);
2646
        assert_eq!(1_u64, U1::INT);
2647
        assert_eq!(2_u64, U2::INT);
2648
        assert_eq!(3_u64, U3::INT);
2649
        assert_eq!(4_u64, U4::INT);
2650
2651
        // usize
2652
        assert_eq!(0_usize, U0::to_int());
2653
        assert_eq!(1_usize, U1::to_int());
2654
        assert_eq!(2_usize, U2::to_int());
2655
        assert_eq!(3_usize, U3::to_int());
2656
        assert_eq!(4_usize, U4::to_int());
2657
        assert_eq!(0_usize, U0::INT);
2658
        assert_eq!(1_usize, U1::INT);
2659
        assert_eq!(2_usize, U2::INT);
2660
        assert_eq!(3_usize, U3::INT);
2661
        assert_eq!(4_usize, U4::INT);
2662
    }
2663
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zerocopy-0.7.35/src/lib.rs
Line
Count
Source
1
// Copyright 2018 The Fuchsia Authors
2
//
3
// Licensed under the 2-Clause BSD License <LICENSE-BSD or
4
// https://opensource.org/license/bsd-2-clause>, Apache License, Version 2.0
5
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
6
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
7
// This file may not be copied, modified, or distributed except according to
8
// those terms.
9
10
// After updating the following doc comment, make sure to run the following
11
// command to update `README.md` based on its contents:
12
//
13
//   ./generate-readme.sh > README.md
14
15
//! *<span style="font-size: 100%; color:grey;">Want to help improve zerocopy?
16
//! Fill out our [user survey][user-survey]!</span>*
17
//!
18
//! ***<span style="font-size: 140%">Fast, safe, <span
19
//! style="color:red;">compile error</span>. Pick two.</span>***
20
//!
21
//! Zerocopy makes zero-cost memory manipulation effortless. We write `unsafe`
22
//! so you don't have to.
23
//!
24
//! # Overview
25
//!
26
//! Zerocopy provides four core marker traits, each of which can be derived
27
//! (e.g., `#[derive(FromZeroes)]`):
28
//! - [`FromZeroes`] indicates that a sequence of zero bytes represents a valid
29
//!   instance of a type
30
//! - [`FromBytes`] indicates that a type may safely be converted from an
31
//!   arbitrary byte sequence
32
//! - [`AsBytes`] indicates that a type may safely be converted *to* a byte
33
//!   sequence
34
//! - [`Unaligned`] indicates that a type's alignment requirement is 1
35
//!
36
//! Types which implement a subset of these traits can then be converted to/from
37
//! byte sequences with little to no runtime overhead.
38
//!
39
//! Zerocopy also provides byte-order aware integer types that support these
40
//! conversions; see the [`byteorder`] module. These types are especially useful
41
//! for network parsing.
42
//!
43
//! [user-survey]: https://docs.google.com/forms/d/e/1FAIpQLSdzBNTN9tzwsmtyZxRFNL02K36IWCdHWW2ZBckyQS2xiO3i8Q/viewform?usp=published_options
44
//!
45
//! # Cargo Features
46
//!
47
//! - **`alloc`**   
48
//!   By default, `zerocopy` is `no_std`. When the `alloc` feature is enabled,
49
//!   the `alloc` crate is added as a dependency, and some allocation-related
50
//!   functionality is added.
51
//!
52
//! - **`byteorder`** (enabled by default)   
53
//!   Adds the [`byteorder`] module and a dependency on the `byteorder` crate.
54
//!   The `byteorder` module provides byte order-aware equivalents of the
55
//!   multi-byte primitive numerical types. Unlike their primitive equivalents,
56
//!   the types in this module have no alignment requirement and support byte
57
//!   order conversions. This can be useful in handling file formats, network
58
//!   packet layouts, etc which don't provide alignment guarantees and which may
59
//!   use a byte order different from that of the execution platform.
60
//!
61
//! - **`derive`**   
62
//!   Provides derives for the core marker traits via the `zerocopy-derive`
63
//!   crate. These derives are re-exported from `zerocopy`, so it is not
64
//!   necessary to depend on `zerocopy-derive` directly.   
65
//!
66
//!   However, you may experience better compile times if you instead directly
67
//!   depend on both `zerocopy` and `zerocopy-derive` in your `Cargo.toml`,
68
//!   since doing so will allow Rust to compile these crates in parallel. To do
69
//!   so, do *not* enable the `derive` feature, and list both dependencies in
70
//!   your `Cargo.toml` with the same leading non-zero version number; e.g:
71
//!
72
//!   ```toml
73
//!   [dependencies]
74
//!   zerocopy = "0.X"
75
//!   zerocopy-derive = "0.X"
76
//!   ```
77
//!
78
//! - **`simd`**   
79
//!   When the `simd` feature is enabled, `FromZeroes`, `FromBytes`, and
80
//!   `AsBytes` impls are emitted for all stable SIMD types which exist on the
81
//!   target platform. Note that the layout of SIMD types is not yet stabilized,
82
//!   so these impls may be removed in the future if layout changes make them
83
//!   invalid. For more information, see the Unsafe Code Guidelines Reference
84
//!   page on the [layout of packed SIMD vectors][simd-layout].
85
//!
86
//! - **`simd-nightly`**   
87
//!   Enables the `simd` feature and adds support for SIMD types which are only
88
//!   available on nightly. Since these types are unstable, support for any type
89
//!   may be removed at any point in the future.
90
//!
91
//! [simd-layout]: https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html
92
//!
93
//! # Security Ethos
94
//!
95
//! Zerocopy is expressly designed for use in security-critical contexts. We
96
//! strive to ensure that that zerocopy code is sound under Rust's current
97
//! memory model, and *any future memory model*. We ensure this by:
98
//! - **...not 'guessing' about Rust's semantics.**   
99
//!   We annotate `unsafe` code with a precise rationale for its soundness that
100
//!   cites a relevant section of Rust's official documentation. When Rust's
101
//!   documented semantics are unclear, we work with the Rust Operational
102
//!   Semantics Team to clarify Rust's documentation.
103
//! - **...rigorously testing our implementation.**   
104
//!   We run tests using [Miri], ensuring that zerocopy is sound across a wide
105
//!   array of supported target platforms of varying endianness and pointer
106
//!   width, and across both current and experimental memory models of Rust.
107
//! - **...formally proving the correctness of our implementation.**   
108
//!   We apply formal verification tools like [Kani][kani] to prove zerocopy's
109
//!   correctness.
110
//!
111
//! For more information, see our full [soundness policy].
112
//!
113
//! [Miri]: https://github.com/rust-lang/miri
114
//! [Kani]: https://github.com/model-checking/kani
115
//! [soundness policy]: https://github.com/google/zerocopy/blob/main/POLICIES.md#soundness
116
//!
117
//! # Relationship to Project Safe Transmute
118
//!
119
//! [Project Safe Transmute] is an official initiative of the Rust Project to
120
//! develop language-level support for safer transmutation. The Project consults
121
//! with crates like zerocopy to identify aspects of safer transmutation that
122
//! would benefit from compiler support, and has developed an [experimental,
123
//! compiler-supported analysis][mcp-transmutability] which determines whether,
124
//! for a given type, any value of that type may be soundly transmuted into
125
//! another type. Once this functionality is sufficiently mature, zerocopy
126
//! intends to replace its internal transmutability analysis (implemented by our
127
//! custom derives) with the compiler-supported one. This change will likely be
128
//! an implementation detail that is invisible to zerocopy's users.
129
//!
130
//! Project Safe Transmute will not replace the need for most of zerocopy's
131
//! higher-level abstractions. The experimental compiler analysis is a tool for
132
//! checking the soundness of `unsafe` code, not a tool to avoid writing
133
//! `unsafe` code altogether. For the foreseeable future, crates like zerocopy
134
//! will still be required in order to provide higher-level abstractions on top
135
//! of the building block provided by Project Safe Transmute.
136
//!
137
//! [Project Safe Transmute]: https://rust-lang.github.io/rfcs/2835-project-safe-transmute.html
138
//! [mcp-transmutability]: https://github.com/rust-lang/compiler-team/issues/411
139
//!
140
//! # MSRV
141
//!
142
//! See our [MSRV policy].
143
//!
144
//! [MSRV policy]: https://github.com/google/zerocopy/blob/main/POLICIES.md#msrv
145
//!
146
//! # Changelog
147
//!
148
//! Zerocopy uses [GitHub Releases].
149
//!
150
//! [GitHub Releases]: https://github.com/google/zerocopy/releases
151
152
// Sometimes we want to use lints which were added after our MSRV.
153
// `unknown_lints` is `warn` by default and we deny warnings in CI, so without
154
// this attribute, any unknown lint would cause a CI failure when testing with
155
// our MSRV.
156
//
157
// TODO(#1201): Remove `unexpected_cfgs`
158
#![allow(unknown_lints, non_local_definitions, unexpected_cfgs)]
159
#![deny(renamed_and_removed_lints)]
160
#![deny(
161
    anonymous_parameters,
162
    deprecated_in_future,
163
    late_bound_lifetime_arguments,
164
    missing_copy_implementations,
165
    missing_debug_implementations,
166
    missing_docs,
167
    path_statements,
168
    patterns_in_fns_without_body,
169
    rust_2018_idioms,
170
    trivial_numeric_casts,
171
    unreachable_pub,
172
    unsafe_op_in_unsafe_fn,
173
    unused_extern_crates,
174
    // We intentionally choose not to deny `unused_qualifications`. When items
175
    // are added to the prelude (e.g., `core::mem::size_of`), this has the
176
    // consequence of making some uses trigger this lint on the latest toolchain
177
    // (e.g., `mem::size_of`), but fixing it (e.g. by replacing with `size_of`)
178
    // does not work on older toolchains.
179
    //
180
    // We tested a more complicated fix in #1413, but ultimately decided that,
181
    // since this lint is just a minor style lint, the complexity isn't worth it
182
    // - it's fine to occasionally have unused qualifications slip through,
183
    // especially since these do not affect our user-facing API in any way.
184
    variant_size_differences
185
)]
186
#![cfg_attr(
187
    __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS,
188
    deny(fuzzy_provenance_casts, lossy_provenance_casts)
189
)]
190
#![deny(
191
    clippy::all,
192
    clippy::alloc_instead_of_core,
193
    clippy::arithmetic_side_effects,
194
    clippy::as_underscore,
195
    clippy::assertions_on_result_states,
196
    clippy::as_conversions,
197
    clippy::correctness,
198
    clippy::dbg_macro,
199
    clippy::decimal_literal_representation,
200
    clippy::get_unwrap,
201
    clippy::indexing_slicing,
202
    clippy::missing_inline_in_public_items,
203
    clippy::missing_safety_doc,
204
    clippy::obfuscated_if_else,
205
    clippy::perf,
206
    clippy::print_stdout,
207
    clippy::std_instead_of_core,
208
    clippy::style,
209
    clippy::suspicious,
210
    clippy::todo,
211
    clippy::undocumented_unsafe_blocks,
212
    clippy::unimplemented,
213
    clippy::unnested_or_patterns,
214
    clippy::unwrap_used,
215
    clippy::use_debug
216
)]
217
#![deny(
218
    rustdoc::bare_urls,
219
    rustdoc::broken_intra_doc_links,
220
    rustdoc::invalid_codeblock_attributes,
221
    rustdoc::invalid_html_tags,
222
    rustdoc::invalid_rust_codeblocks,
223
    rustdoc::missing_crate_level_docs,
224
    rustdoc::private_intra_doc_links
225
)]
226
// In test code, it makes sense to weight more heavily towards concise, readable
227
// code over correct or debuggable code.
228
#![cfg_attr(any(test, kani), allow(
229
    // In tests, you get line numbers and have access to source code, so panic
230
    // messages are less important. You also often unwrap a lot, which would
231
    // make expect'ing instead very verbose.
232
    clippy::unwrap_used,
233
    // In tests, there's no harm to "panic risks" - the worst that can happen is
234
    // that your test will fail, and you'll fix it. By contrast, panic risks in
235
    // production code introduce the possibly of code panicking unexpectedly "in
236
    // the field".
237
    clippy::arithmetic_side_effects,
238
    clippy::indexing_slicing,
239
))]
240
#![cfg_attr(not(test), no_std)]
241
#![cfg_attr(
242
    all(feature = "simd-nightly", any(target_arch = "x86", target_arch = "x86_64")),
243
    feature(stdarch_x86_avx512)
244
)]
245
#![cfg_attr(
246
    all(feature = "simd-nightly", target_arch = "arm"),
247
    feature(stdarch_arm_dsp, stdarch_arm_neon_intrinsics)
248
)]
249
#![cfg_attr(
250
    all(feature = "simd-nightly", any(target_arch = "powerpc", target_arch = "powerpc64")),
251
    feature(stdarch_powerpc)
252
)]
253
#![cfg_attr(doc_cfg, feature(doc_cfg))]
254
#![cfg_attr(
255
    __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS,
256
    feature(layout_for_ptr, strict_provenance)
257
)]
258
259
// This is a hack to allow zerocopy-derive derives to work in this crate. They
260
// assume that zerocopy is linked as an extern crate, so they access items from
261
// it as `zerocopy::Xxx`. This makes that still work.
262
#[cfg(any(feature = "derive", test))]
263
extern crate self as zerocopy;
264
265
#[macro_use]
266
mod macros;
267
268
#[cfg(feature = "byteorder")]
269
#[cfg_attr(doc_cfg, doc(cfg(feature = "byteorder")))]
270
pub mod byteorder;
271
#[doc(hidden)]
272
pub mod macro_util;
273
mod post_monomorphization_compile_fail_tests;
274
mod util;
275
// TODO(#252): If we make this pub, come up with a better name.
276
mod wrappers;
277
278
#[cfg(feature = "byteorder")]
279
#[cfg_attr(doc_cfg, doc(cfg(feature = "byteorder")))]
280
pub use crate::byteorder::*;
281
pub use crate::wrappers::*;
282
283
#[cfg(any(feature = "derive", test))]
284
#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
285
pub use zerocopy_derive::Unaligned;
286
287
// `pub use` separately here so that we can mark it `#[doc(hidden)]`.
288
//
289
// TODO(#29): Remove this or add a doc comment.
290
#[cfg(any(feature = "derive", test))]
291
#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
292
#[doc(hidden)]
293
pub use zerocopy_derive::KnownLayout;
294
295
use core::{
296
    cell::{self, RefMut},
297
    cmp::Ordering,
298
    fmt::{self, Debug, Display, Formatter},
299
    hash::Hasher,
300
    marker::PhantomData,
301
    mem::{self, ManuallyDrop, MaybeUninit},
302
    num::{
303
        NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
304
        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,
305
    },
306
    ops::{Deref, DerefMut},
307
    ptr::{self, NonNull},
308
    slice,
309
};
310
311
#[cfg(feature = "alloc")]
312
extern crate alloc;
313
#[cfg(feature = "alloc")]
314
use alloc::{boxed::Box, vec::Vec};
315
316
#[cfg(any(feature = "alloc", kani))]
317
use core::alloc::Layout;
318
319
// Used by `TryFromBytes::is_bit_valid`.
320
#[doc(hidden)]
321
pub use crate::util::ptr::Ptr;
322
323
// For each polyfill, as soon as the corresponding feature is stable, the
324
// polyfill import will be unused because method/function resolution will prefer
325
// the inherent method/function over a trait method/function. Thus, we suppress
326
// the `unused_imports` warning.
327
//
328
// See the documentation on `util::polyfills` for more information.
329
#[allow(unused_imports)]
330
use crate::util::polyfills::NonNullExt as _;
331
332
#[rustversion::nightly]
333
#[cfg(all(test, not(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)))]
334
const _: () = {
335
    #[deprecated = "some tests may be skipped due to missing RUSTFLAGS=\"--cfg __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS\""]
336
    const _WARNING: () = ();
337
    #[warn(deprecated)]
338
    _WARNING
339
};
340
341
/// The target pointer width, counted in bits.
342
const POINTER_WIDTH_BITS: usize = mem::size_of::<usize>() * 8;
343
344
/// The layout of a type which might be dynamically-sized.
345
///
346
/// `DstLayout` describes the layout of sized types, slice types, and "slice
347
/// DSTs" - ie, those that are known by the type system to have a trailing slice
348
/// (as distinguished from `dyn Trait` types - such types *might* have a
349
/// trailing slice type, but the type system isn't aware of it).
350
///
351
/// # Safety
352
///
353
/// Unlike [`core::alloc::Layout`], `DstLayout` is only used to describe full
354
/// Rust types - ie, those that satisfy the layout requirements outlined by
355
/// [the reference]. Callers may assume that an instance of `DstLayout`
356
/// satisfies any conditions imposed on Rust types by the reference.
357
///
358
/// If `layout: DstLayout` describes a type, `T`, then it is guaranteed that:
359
/// - `layout.align` is equal to `T`'s alignment
360
/// - If `layout.size_info` is `SizeInfo::Sized { size }`, then `T: Sized` and
361
///   `size_of::<T>() == size`
362
/// - If `layout.size_info` is `SizeInfo::SliceDst(slice_layout)`, then
363
///   - `T` is a slice DST
364
/// - The `size` of an instance of `T` with `elems` trailing slice elements is
365
///   equal to `slice_layout.offset + slice_layout.elem_size * elems` rounded up
366
///   to the nearest multiple of `layout.align`. Any bytes in the range
367
///   `[slice_layout.offset + slice_layout.elem_size * elems, size)` are padding
368
///   and must not be assumed to be initialized.
369
///
370
/// [the reference]: https://doc.rust-lang.org/reference/type-layout.html
371
#[doc(hidden)]
372
#[allow(missing_debug_implementations, missing_copy_implementations)]
373
#[cfg_attr(any(kani, test), derive(Copy, Clone, Debug, PartialEq, Eq))]
374
pub struct DstLayout {
375
    align: NonZeroUsize,
376
    size_info: SizeInfo,
377
}
378
379
#[cfg_attr(any(kani, test), derive(Copy, Clone, Debug, PartialEq, Eq))]
380
enum SizeInfo<E = usize> {
381
    Sized { _size: usize },
382
    SliceDst(TrailingSliceLayout<E>),
383
}
384
385
#[cfg_attr(any(kani, test), derive(Copy, Clone, Debug, PartialEq, Eq))]
386
struct TrailingSliceLayout<E = usize> {
387
    // The offset of the first byte of the trailing slice field. Note that this
388
    // is NOT the same as the minimum size of the type. For example, consider
389
    // the following type:
390
    //
391
    //   struct Foo {
392
    //       a: u16,
393
    //       b: u8,
394
    //       c: [u8],
395
    //   }
396
    //
397
    // In `Foo`, `c` is at byte offset 3. When `c.len() == 0`, `c` is followed
398
    // by a padding byte.
399
    _offset: usize,
400
    // The size of the element type of the trailing slice field.
401
    _elem_size: E,
402
}
403
404
impl SizeInfo {
405
    /// Attempts to create a `SizeInfo` from `Self` in which `elem_size` is a
406
    /// `NonZeroUsize`. If `elem_size` is 0, returns `None`.
407
    #[allow(unused)]
408
0
    const fn try_to_nonzero_elem_size(&self) -> Option<SizeInfo<NonZeroUsize>> {
409
0
        Some(match *self {
410
0
            SizeInfo::Sized { _size } => SizeInfo::Sized { _size },
411
0
            SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size }) => {
412
0
                if let Some(_elem_size) = NonZeroUsize::new(_elem_size) {
413
0
                    SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size })
414
                } else {
415
0
                    return None;
416
                }
417
            }
418
        })
419
0
    }
420
}
421
422
#[doc(hidden)]
423
#[derive(Copy, Clone)]
424
#[cfg_attr(test, derive(Debug))]
425
#[allow(missing_debug_implementations)]
426
pub enum _CastType {
427
    _Prefix,
428
    _Suffix,
429
}
430
431
impl DstLayout {
432
    /// The minimum possible alignment of a type.
433
    const MIN_ALIGN: NonZeroUsize = match NonZeroUsize::new(1) {
434
        Some(min_align) => min_align,
435
        None => unreachable!(),
436
    };
437
438
    /// The maximum theoretic possible alignment of a type.
439
    ///
440
    /// For compatibility with future Rust versions, this is defined as the
441
    /// maximum power-of-two that fits into a `usize`. See also
442
    /// [`DstLayout::CURRENT_MAX_ALIGN`].
443
    const THEORETICAL_MAX_ALIGN: NonZeroUsize =
444
        match NonZeroUsize::new(1 << (POINTER_WIDTH_BITS - 1)) {
445
            Some(max_align) => max_align,
446
            None => unreachable!(),
447
        };
448
449
    /// The current, documented max alignment of a type \[1\].
450
    ///
451
    /// \[1\] Per <https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers>:
452
    ///
453
    ///   The alignment value must be a power of two from 1 up to
454
    ///   2<sup>29</sup>.
455
    #[cfg(not(kani))]
456
    const CURRENT_MAX_ALIGN: NonZeroUsize = match NonZeroUsize::new(1 << 28) {
457
        Some(max_align) => max_align,
458
        None => unreachable!(),
459
    };
460
461
    /// Constructs a `DstLayout` for a zero-sized type with `repr_align`
462
    /// alignment (or 1). If `repr_align` is provided, then it must be a power
463
    /// of two.
464
    ///
465
    /// # Panics
466
    ///
467
    /// This function panics if the supplied `repr_align` is not a power of two.
468
    ///
469
    /// # Safety
470
    ///
471
    /// Unsafe code may assume that the contract of this function is satisfied.
472
    #[doc(hidden)]
473
    #[inline]
474
0
    pub const fn new_zst(repr_align: Option<NonZeroUsize>) -> DstLayout {
475
0
        let align = match repr_align {
476
0
            Some(align) => align,
477
0
            None => Self::MIN_ALIGN,
478
        };
479
480
0
        assert!(align.is_power_of_two());
481
482
0
        DstLayout { align, size_info: SizeInfo::Sized { _size: 0 } }
483
0
    }
484
485
    /// Constructs a `DstLayout` which describes `T`.
486
    ///
487
    /// # Safety
488
    ///
489
    /// Unsafe code may assume that `DstLayout` is the correct layout for `T`.
490
    #[doc(hidden)]
491
    #[inline]
492
0
    pub const fn for_type<T>() -> DstLayout {
493
0
        // SAFETY: `align` is correct by construction. `T: Sized`, and so it is
494
0
        // sound to initialize `size_info` to `SizeInfo::Sized { size }`; the
495
0
        // `size` field is also correct by construction.
496
0
        DstLayout {
497
0
            align: match NonZeroUsize::new(mem::align_of::<T>()) {
498
0
                Some(align) => align,
499
0
                None => unreachable!(),
500
            },
501
0
            size_info: SizeInfo::Sized { _size: mem::size_of::<T>() },
502
0
        }
503
0
    }
504
505
    /// Constructs a `DstLayout` which describes `[T]`.
506
    ///
507
    /// # Safety
508
    ///
509
    /// Unsafe code may assume that `DstLayout` is the correct layout for `[T]`.
510
0
    const fn for_slice<T>() -> DstLayout {
511
0
        // SAFETY: The alignment of a slice is equal to the alignment of its
512
0
        // element type, and so `align` is initialized correctly.
513
0
        //
514
0
        // Since this is just a slice type, there is no offset between the
515
0
        // beginning of the type and the beginning of the slice, so it is
516
0
        // correct to set `offset: 0`. The `elem_size` is correct by
517
0
        // construction. Since `[T]` is a (degenerate case of a) slice DST, it
518
0
        // is correct to initialize `size_info` to `SizeInfo::SliceDst`.
519
0
        DstLayout {
520
0
            align: match NonZeroUsize::new(mem::align_of::<T>()) {
521
0
                Some(align) => align,
522
0
                None => unreachable!(),
523
            },
524
0
            size_info: SizeInfo::SliceDst(TrailingSliceLayout {
525
0
                _offset: 0,
526
0
                _elem_size: mem::size_of::<T>(),
527
0
            }),
528
0
        }
529
0
    }
530
531
    /// Like `Layout::extend`, this creates a layout that describes a record
532
    /// whose layout consists of `self` followed by `next` that includes the
533
    /// necessary inter-field padding, but not any trailing padding.
534
    ///
535
    /// In order to match the layout of a `#[repr(C)]` struct, this method
536
    /// should be invoked for each field in declaration order. To add trailing
537
    /// padding, call `DstLayout::pad_to_align` after extending the layout for
538
    /// all fields. If `self` corresponds to a type marked with
539
    /// `repr(packed(N))`, then `repr_packed` should be set to `Some(N)`,
540
    /// otherwise `None`.
541
    ///
542
    /// This method cannot be used to match the layout of a record with the
543
    /// default representation, as that representation is mostly unspecified.
544
    ///
545
    /// # Safety
546
    ///
547
    /// If a (potentially hypothetical) valid `repr(C)` Rust type begins with
548
    /// fields whose layout are `self`, and those fields are immediately
549
    /// followed by a field whose layout is `field`, then unsafe code may rely
550
    /// on `self.extend(field, repr_packed)` producing a layout that correctly
551
    /// encompasses those two components.
552
    ///
553
    /// We make no guarantees to the behavior of this method if these fragments
554
    /// cannot appear in a valid Rust type (e.g., the concatenation of the
555
    /// layouts would lead to a size larger than `isize::MAX`).
556
    #[doc(hidden)]
557
    #[inline]
558
0
    pub const fn extend(self, field: DstLayout, repr_packed: Option<NonZeroUsize>) -> Self {
559
        use util::{core_layout::padding_needed_for, max, min};
560
561
        // If `repr_packed` is `None`, there are no alignment constraints, and
562
        // the value can be defaulted to `THEORETICAL_MAX_ALIGN`.
563
0
        let max_align = match repr_packed {
564
0
            Some(max_align) => max_align,
565
0
            None => Self::THEORETICAL_MAX_ALIGN,
566
        };
567
568
0
        assert!(max_align.is_power_of_two());
569
570
        // We use Kani to prove that this method is robust to future increases
571
        // in Rust's maximum allowed alignment. However, if such a change ever
572
        // actually occurs, we'd like to be notified via assertion failures.
573
        #[cfg(not(kani))]
574
        {
575
0
            debug_assert!(self.align.get() <= DstLayout::CURRENT_MAX_ALIGN.get());
576
0
            debug_assert!(field.align.get() <= DstLayout::CURRENT_MAX_ALIGN.get());
577
0
            if let Some(repr_packed) = repr_packed {
578
0
                debug_assert!(repr_packed.get() <= DstLayout::CURRENT_MAX_ALIGN.get());
579
0
            }
580
        }
581
582
        // The field's alignment is clamped by `repr_packed` (i.e., the
583
        // `repr(packed(N))` attribute, if any) [1].
584
        //
585
        // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
586
        //
587
        //   The alignments of each field, for the purpose of positioning
588
        //   fields, is the smaller of the specified alignment and the alignment
589
        //   of the field's type.
590
0
        let field_align = min(field.align, max_align);
591
0
592
0
        // The struct's alignment is the maximum of its previous alignment and
593
0
        // `field_align`.
594
0
        let align = max(self.align, field_align);
595
596
0
        let size_info = match self.size_info {
597
            // If the layout is already a DST, we panic; DSTs cannot be extended
598
            // with additional fields.
599
0
            SizeInfo::SliceDst(..) => panic!("Cannot extend a DST with additional fields."),
600
601
0
            SizeInfo::Sized { _size: preceding_size } => {
602
0
                // Compute the minimum amount of inter-field padding needed to
603
0
                // satisfy the field's alignment, and offset of the trailing
604
0
                // field. [1]
605
0
                //
606
0
                // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
607
0
                //
608
0
                //   Inter-field padding is guaranteed to be the minimum
609
0
                //   required in order to satisfy each field's (possibly
610
0
                //   altered) alignment.
611
0
                let padding = padding_needed_for(preceding_size, field_align);
612
613
                // This will not panic (and is proven to not panic, with Kani)
614
                // if the layout components can correspond to a leading layout
615
                // fragment of a valid Rust type, but may panic otherwise (e.g.,
616
                // combining or aligning the components would create a size
617
                // exceeding `isize::MAX`).
618
0
                let offset = match preceding_size.checked_add(padding) {
619
0
                    Some(offset) => offset,
620
0
                    None => panic!("Adding padding to `self`'s size overflows `usize`."),
621
                };
622
623
0
                match field.size_info {
624
0
                    SizeInfo::Sized { _size: field_size } => {
625
                        // If the trailing field is sized, the resulting layout
626
                        // will be sized. Its size will be the sum of the
627
                        // preceeding layout, the size of the new field, and the
628
                        // size of inter-field padding between the two.
629
                        //
630
                        // This will not panic (and is proven with Kani to not
631
                        // panic) if the layout components can correspond to a
632
                        // leading layout fragment of a valid Rust type, but may
633
                        // panic otherwise (e.g., combining or aligning the
634
                        // components would create a size exceeding
635
                        // `usize::MAX`).
636
0
                        let size = match offset.checked_add(field_size) {
637
0
                            Some(size) => size,
638
0
                            None => panic!("`field` cannot be appended without the total size overflowing `usize`"),
639
                        };
640
0
                        SizeInfo::Sized { _size: size }
641
                    }
642
                    SizeInfo::SliceDst(TrailingSliceLayout {
643
0
                        _offset: trailing_offset,
644
0
                        _elem_size,
645
                    }) => {
646
                        // If the trailing field is dynamically sized, so too
647
                        // will the resulting layout. The offset of the trailing
648
                        // slice component is the sum of the offset of the
649
                        // trailing field and the trailing slice offset within
650
                        // that field.
651
                        //
652
                        // This will not panic (and is proven with Kani to not
653
                        // panic) if the layout components can correspond to a
654
                        // leading layout fragment of a valid Rust type, but may
655
                        // panic otherwise (e.g., combining or aligning the
656
                        // components would create a size exceeding
657
                        // `usize::MAX`).
658
0
                        let offset = match offset.checked_add(trailing_offset) {
659
0
                            Some(offset) => offset,
660
0
                            None => panic!("`field` cannot be appended without the total size overflowing `usize`"),
661
                        };
662
0
                        SizeInfo::SliceDst(TrailingSliceLayout { _offset: offset, _elem_size })
663
                    }
664
                }
665
            }
666
        };
667
668
0
        DstLayout { align, size_info }
669
0
    }
670
671
    /// Like `Layout::pad_to_align`, this routine rounds the size of this layout
672
    /// up to the nearest multiple of this type's alignment or `repr_packed`
673
    /// (whichever is less). This method leaves DST layouts unchanged, since the
674
    /// trailing padding of DSTs is computed at runtime.
675
    ///
676
    /// In order to match the layout of a `#[repr(C)]` struct, this method
677
    /// should be invoked after the invocations of [`DstLayout::extend`]. If
678
    /// `self` corresponds to a type marked with `repr(packed(N))`, then
679
    /// `repr_packed` should be set to `Some(N)`, otherwise `None`.
680
    ///
681
    /// This method cannot be used to match the layout of a record with the
682
    /// default representation, as that representation is mostly unspecified.
683
    ///
684
    /// # Safety
685
    ///
686
    /// If a (potentially hypothetical) valid `repr(C)` type begins with fields
687
    /// whose layout are `self` followed only by zero or more bytes of trailing
688
    /// padding (not included in `self`), then unsafe code may rely on
689
    /// `self.pad_to_align(repr_packed)` producing a layout that correctly
690
    /// encapsulates the layout of that type.
691
    ///
692
    /// We make no guarantees to the behavior of this method if `self` cannot
693
    /// appear in a valid Rust type (e.g., because the addition of trailing
694
    /// padding would lead to a size larger than `isize::MAX`).
695
    #[doc(hidden)]
696
    #[inline]
697
0
    pub const fn pad_to_align(self) -> Self {
698
        use util::core_layout::padding_needed_for;
699
700
0
        let size_info = match self.size_info {
701
            // For sized layouts, we add the minimum amount of trailing padding
702
            // needed to satisfy alignment.
703
0
            SizeInfo::Sized { _size: unpadded_size } => {
704
0
                let padding = padding_needed_for(unpadded_size, self.align);
705
0
                let size = match unpadded_size.checked_add(padding) {
706
0
                    Some(size) => size,
707
0
                    None => panic!("Adding padding caused size to overflow `usize`."),
708
                };
709
0
                SizeInfo::Sized { _size: size }
710
            }
711
            // For DST layouts, trailing padding depends on the length of the
712
            // trailing DST and is computed at runtime. This does not alter the
713
            // offset or element size of the layout, so we leave `size_info`
714
            // unchanged.
715
0
            size_info @ SizeInfo::SliceDst(_) => size_info,
716
        };
717
718
0
        DstLayout { align: self.align, size_info }
719
0
    }
720
721
    /// Validates that a cast is sound from a layout perspective.
722
    ///
723
    /// Validates that the size and alignment requirements of a type with the
724
    /// layout described in `self` would not be violated by performing a
725
    /// `cast_type` cast from a pointer with address `addr` which refers to a
726
    /// memory region of size `bytes_len`.
727
    ///
728
    /// If the cast is valid, `validate_cast_and_convert_metadata` returns
729
    /// `(elems, split_at)`. If `self` describes a dynamically-sized type, then
730
    /// `elems` is the maximum number of trailing slice elements for which a
731
    /// cast would be valid (for sized types, `elem` is meaningless and should
732
    /// be ignored). `split_at` is the index at which to split the memory region
733
    /// in order for the prefix (suffix) to contain the result of the cast, and
734
    /// in order for the remaining suffix (prefix) to contain the leftover
735
    /// bytes.
736
    ///
737
    /// There are three conditions under which a cast can fail:
738
    /// - The smallest possible value for the type is larger than the provided
739
    ///   memory region
740
    /// - A prefix cast is requested, and `addr` does not satisfy `self`'s
741
    ///   alignment requirement
742
    /// - A suffix cast is requested, and `addr + bytes_len` does not satisfy
743
    ///   `self`'s alignment requirement (as a consequence, since all instances
744
    ///   of the type are a multiple of its alignment, no size for the type will
745
    ///   result in a starting address which is properly aligned)
746
    ///
747
    /// # Safety
748
    ///
749
    /// The caller may assume that this implementation is correct, and may rely
750
    /// on that assumption for the soundness of their code. In particular, the
751
    /// caller may assume that, if `validate_cast_and_convert_metadata` returns
752
    /// `Some((elems, split_at))`, then:
753
    /// - A pointer to the type (for dynamically sized types, this includes
754
    ///   `elems` as its pointer metadata) describes an object of size `size <=
755
    ///   bytes_len`
756
    /// - If this is a prefix cast:
757
    ///   - `addr` satisfies `self`'s alignment
758
    ///   - `size == split_at`
759
    /// - If this is a suffix cast:
760
    ///   - `split_at == bytes_len - size`
761
    ///   - `addr + split_at` satisfies `self`'s alignment
762
    ///
763
    /// Note that this method does *not* ensure that a pointer constructed from
764
    /// its return values will be a valid pointer. In particular, this method
765
    /// does not reason about `isize` overflow, which is a requirement of many
766
    /// Rust pointer APIs, and may at some point be determined to be a validity
767
    /// invariant of pointer types themselves. This should never be a problem so
768
    /// long as the arguments to this method are derived from a known-valid
769
    /// pointer (e.g., one derived from a safe Rust reference), but it is
770
    /// nonetheless the caller's responsibility to justify that pointer
771
    /// arithmetic will not overflow based on a safety argument *other than* the
772
    /// mere fact that this method returned successfully.
773
    ///
774
    /// # Panics
775
    ///
776
    /// `validate_cast_and_convert_metadata` will panic if `self` describes a
777
    /// DST whose trailing slice element is zero-sized.
778
    ///
779
    /// If `addr + bytes_len` overflows `usize`,
780
    /// `validate_cast_and_convert_metadata` may panic, or it may return
781
    /// incorrect results. No guarantees are made about when
782
    /// `validate_cast_and_convert_metadata` will panic. The caller should not
783
    /// rely on `validate_cast_and_convert_metadata` panicking in any particular
784
    /// condition, even if `debug_assertions` are enabled.
785
    #[allow(unused)]
786
0
    const fn validate_cast_and_convert_metadata(
787
0
        &self,
788
0
        addr: usize,
789
0
        bytes_len: usize,
790
0
        cast_type: _CastType,
791
0
    ) -> Option<(usize, usize)> {
792
        // `debug_assert!`, but with `#[allow(clippy::arithmetic_side_effects)]`.
793
        macro_rules! __debug_assert {
794
            ($e:expr $(, $msg:expr)?) => {
795
                debug_assert!({
796
                    #[allow(clippy::arithmetic_side_effects)]
797
                    let e = $e;
798
                    e
799
                } $(, $msg)?);
800
            };
801
        }
802
803
        // Note that, in practice, `self` is always a compile-time constant. We
804
        // do this check earlier than needed to ensure that we always panic as a
805
        // result of bugs in the program (such as calling this function on an
806
        // invalid type) instead of allowing this panic to be hidden if the cast
807
        // would have failed anyway for runtime reasons (such as a too-small
808
        // memory region).
809
        //
810
        // TODO(#67): Once our MSRV is 1.65, use let-else:
811
        // https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html#let-else-statements
812
0
        let size_info = match self.size_info.try_to_nonzero_elem_size() {
813
0
            Some(size_info) => size_info,
814
0
            None => panic!("attempted to cast to slice type with zero-sized element"),
815
        };
816
817
        // Precondition
818
0
        __debug_assert!(addr.checked_add(bytes_len).is_some(), "`addr` + `bytes_len` > usize::MAX");
819
820
        // Alignment checks go in their own block to avoid introducing variables
821
        // into the top-level scope.
822
        {
823
            // We check alignment for `addr` (for prefix casts) or `addr +
824
            // bytes_len` (for suffix casts). For a prefix cast, the correctness
825
            // of this check is trivial - `addr` is the address the object will
826
            // live at.
827
            //
828
            // For a suffix cast, we know that all valid sizes for the type are
829
            // a multiple of the alignment (and by safety precondition, we know
830
            // `DstLayout` may only describe valid Rust types). Thus, a
831
            // validly-sized instance which lives at a validly-aligned address
832
            // must also end at a validly-aligned address. Thus, if the end
833
            // address for a suffix cast (`addr + bytes_len`) is not aligned,
834
            // then no valid start address will be aligned either.
835
0
            let offset = match cast_type {
836
0
                _CastType::_Prefix => 0,
837
0
                _CastType::_Suffix => bytes_len,
838
            };
839
840
            // Addition is guaranteed not to overflow because `offset <=
841
            // bytes_len`, and `addr + bytes_len <= usize::MAX` is a
842
            // precondition of this method. Modulus is guaranteed not to divide
843
            // by 0 because `align` is non-zero.
844
            #[allow(clippy::arithmetic_side_effects)]
845
0
            if (addr + offset) % self.align.get() != 0 {
846
0
                return None;
847
0
            }
848
        }
849
850
0
        let (elems, self_bytes) = match size_info {
851
0
            SizeInfo::Sized { _size: size } => {
852
0
                if size > bytes_len {
853
0
                    return None;
854
0
                }
855
0
                (0, size)
856
            }
857
0
            SizeInfo::SliceDst(TrailingSliceLayout { _offset: offset, _elem_size: elem_size }) => {
858
0
                // Calculate the maximum number of bytes that could be consumed
859
0
                // - any number of bytes larger than this will either not be a
860
0
                // multiple of the alignment, or will be larger than
861
0
                // `bytes_len`.
862
0
                let max_total_bytes =
863
0
                    util::round_down_to_next_multiple_of_alignment(bytes_len, self.align);
864
                // Calculate the maximum number of bytes that could be consumed
865
                // by the trailing slice.
866
                //
867
                // TODO(#67): Once our MSRV is 1.65, use let-else:
868
                // https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html#let-else-statements
869
0
                let max_slice_and_padding_bytes = match max_total_bytes.checked_sub(offset) {
870
0
                    Some(max) => max,
871
                    // `bytes_len` too small even for 0 trailing slice elements.
872
0
                    None => return None,
873
                };
874
875
                // Calculate the number of elements that fit in
876
                // `max_slice_and_padding_bytes`; any remaining bytes will be
877
                // considered padding.
878
                //
879
                // Guaranteed not to divide by zero: `elem_size` is non-zero.
880
                #[allow(clippy::arithmetic_side_effects)]
881
0
                let elems = max_slice_and_padding_bytes / elem_size.get();
882
0
                // Guaranteed not to overflow on multiplication: `usize::MAX >=
883
0
                // max_slice_and_padding_bytes >= (max_slice_and_padding_bytes /
884
0
                // elem_size) * elem_size`.
885
0
                //
886
0
                // Guaranteed not to overflow on addition:
887
0
                // - max_slice_and_padding_bytes == max_total_bytes - offset
888
0
                // - elems * elem_size <= max_slice_and_padding_bytes == max_total_bytes - offset
889
0
                // - elems * elem_size + offset <= max_total_bytes <= usize::MAX
890
0
                #[allow(clippy::arithmetic_side_effects)]
891
0
                let without_padding = offset + elems * elem_size.get();
892
0
                // `self_bytes` is equal to the offset bytes plus the bytes
893
0
                // consumed by the trailing slice plus any padding bytes
894
0
                // required to satisfy the alignment. Note that we have computed
895
0
                // the maximum number of trailing slice elements that could fit
896
0
                // in `self_bytes`, so any padding is guaranteed to be less than
897
0
                // the size of an extra element.
898
0
                //
899
0
                // Guaranteed not to overflow:
900
0
                // - By previous comment: without_padding == elems * elem_size +
901
0
                //   offset <= max_total_bytes
902
0
                // - By construction, `max_total_bytes` is a multiple of
903
0
                //   `self.align`.
904
0
                // - At most, adding padding needed to round `without_padding`
905
0
                //   up to the next multiple of the alignment will bring
906
0
                //   `self_bytes` up to `max_total_bytes`.
907
0
                #[allow(clippy::arithmetic_side_effects)]
908
0
                let self_bytes = without_padding
909
0
                    + util::core_layout::padding_needed_for(without_padding, self.align);
910
0
                (elems, self_bytes)
911
            }
912
        };
913
914
0
        __debug_assert!(self_bytes <= bytes_len);
915
916
0
        let split_at = match cast_type {
917
0
            _CastType::_Prefix => self_bytes,
918
            // Guaranteed not to underflow:
919
            // - In the `Sized` branch, only returns `size` if `size <=
920
            //   bytes_len`.
921
            // - In the `SliceDst` branch, calculates `self_bytes <=
922
            //   max_toatl_bytes`, which is upper-bounded by `bytes_len`.
923
            #[allow(clippy::arithmetic_side_effects)]
924
0
            _CastType::_Suffix => bytes_len - self_bytes,
925
        };
926
927
0
        Some((elems, split_at))
928
0
    }
929
}
930
931
/// A trait which carries information about a type's layout that is used by the
932
/// internals of this crate.
933
///
934
/// This trait is not meant for consumption by code outside of this crate. While
935
/// the normal semver stability guarantees apply with respect to which types
936
/// implement this trait and which trait implementations are implied by this
937
/// trait, no semver stability guarantees are made regarding its internals; they
938
/// may change at any time, and code which makes use of them may break.
939
///
940
/// # Safety
941
///
942
/// This trait does not convey any safety guarantees to code outside this crate.
943
#[doc(hidden)] // TODO: Remove this once KnownLayout is used by other APIs
944
pub unsafe trait KnownLayout {
945
    // The `Self: Sized` bound makes it so that `KnownLayout` can still be
946
    // object safe. It's not currently object safe thanks to `const LAYOUT`, and
947
    // it likely won't be in the future, but there's no reason not to be
948
    // forwards-compatible with object safety.
949
    #[doc(hidden)]
950
    fn only_derive_is_allowed_to_implement_this_trait()
951
    where
952
        Self: Sized;
953
954
    #[doc(hidden)]
955
    const LAYOUT: DstLayout;
956
957
    /// SAFETY: The returned pointer has the same address and provenance as
958
    /// `bytes`. If `Self` is a DST, the returned pointer's referent has `elems`
959
    /// elements in its trailing slice. If `Self` is sized, `elems` is ignored.
960
    #[doc(hidden)]
961
    fn raw_from_ptr_len(bytes: NonNull<u8>, elems: usize) -> NonNull<Self>;
962
}
963
964
// SAFETY: Delegates safety to `DstLayout::for_slice`.
965
unsafe impl<T: KnownLayout> KnownLayout for [T] {
966
    #[allow(clippy::missing_inline_in_public_items)]
967
0
    fn only_derive_is_allowed_to_implement_this_trait()
968
0
    where
969
0
        Self: Sized,
970
0
    {
971
0
    }
972
    const LAYOUT: DstLayout = DstLayout::for_slice::<T>();
973
974
    // SAFETY: `.cast` preserves address and provenance. The returned pointer
975
    // refers to an object with `elems` elements by construction.
976
    #[inline(always)]
977
0
    fn raw_from_ptr_len(data: NonNull<u8>, elems: usize) -> NonNull<Self> {
978
0
        // TODO(#67): Remove this allow. See NonNullExt for more details.
979
0
        #[allow(unstable_name_collisions)]
980
0
        NonNull::slice_from_raw_parts(data.cast::<T>(), elems)
981
0
    }
982
}
983
984
#[rustfmt::skip]
985
impl_known_layout!(
986
    (),
987
    u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize, f32, f64,
988
    bool, char,
989
    NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32,
990
    NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize
991
);
992
#[rustfmt::skip]
993
impl_known_layout!(
994
    T         => Option<T>,
995
    T: ?Sized => PhantomData<T>,
996
    T         => Wrapping<T>,
997
    T         => MaybeUninit<T>,
998
    T: ?Sized => *const T,
999
    T: ?Sized => *mut T,
1000
);
1001
impl_known_layout!(const N: usize, T => [T; N]);
1002
1003
safety_comment! {
1004
    /// SAFETY:
1005
    /// `str` and `ManuallyDrop<[T]>` [1] have the same representations as
1006
    /// `[u8]` and `[T]` repsectively. `str` has different bit validity than
1007
    /// `[u8]`, but that doesn't affect the soundness of this impl.
1008
    ///
1009
    /// [1] Per https://doc.rust-lang.org/nightly/core/mem/struct.ManuallyDrop.html:
1010
    ///
1011
    ///   `ManuallyDrop<T>` is guaranteed to have the same layout and bit
1012
    ///   validity as `T`
1013
    ///
1014
    /// TODO(#429):
1015
    /// -  Add quotes from docs.
1016
    /// -  Once [1] (added in
1017
    /// https://github.com/rust-lang/rust/pull/115522) is available on stable,
1018
    /// quote the stable docs instead of the nightly docs.
1019
    unsafe_impl_known_layout!(#[repr([u8])] str);
1020
    unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] ManuallyDrop<T>);
1021
}
1022
1023
/// Analyzes whether a type is [`FromZeroes`].
1024
///
1025
/// This derive analyzes, at compile time, whether the annotated type satisfies
1026
/// the [safety conditions] of `FromZeroes` and implements `FromZeroes` if it is
1027
/// sound to do so. This derive can be applied to structs, enums, and unions;
1028
/// e.g.:
1029
///
1030
/// ```
1031
/// # use zerocopy_derive::FromZeroes;
1032
/// #[derive(FromZeroes)]
1033
/// struct MyStruct {
1034
/// # /*
1035
///     ...
1036
/// # */
1037
/// }
1038
///
1039
/// #[derive(FromZeroes)]
1040
/// #[repr(u8)]
1041
/// enum MyEnum {
1042
/// #   Variant0,
1043
/// # /*
1044
///     ...
1045
/// # */
1046
/// }
1047
///
1048
/// #[derive(FromZeroes)]
1049
/// union MyUnion {
1050
/// #   variant: u8,
1051
/// # /*
1052
///     ...
1053
/// # */
1054
/// }
1055
/// ```
1056
///
1057
/// [safety conditions]: trait@FromZeroes#safety
1058
///
1059
/// # Analysis
1060
///
1061
/// *This section describes, roughly, the analysis performed by this derive to
1062
/// determine whether it is sound to implement `FromZeroes` for a given type.
1063
/// Unless you are modifying the implementation of this derive, or attempting to
1064
/// manually implement `FromZeroes` for a type yourself, you don't need to read
1065
/// this section.*
1066
///
1067
/// If a type has the following properties, then this derive can implement
1068
/// `FromZeroes` for that type:
1069
///
1070
/// - If the type is a struct, all of its fields must be `FromZeroes`.
1071
/// - If the type is an enum, it must be C-like (meaning that all variants have
1072
///   no fields) and it must have a variant with a discriminant of `0`. See [the
1073
///   reference] for a description of how discriminant values are chosen.
1074
/// - The type must not contain any [`UnsafeCell`]s (this is required in order
1075
///   for it to be sound to construct a `&[u8]` and a `&T` to the same region of
1076
///   memory). The type may contain references or pointers to `UnsafeCell`s so
1077
///   long as those values can themselves be initialized from zeroes
1078
///   (`FromZeroes` is not currently implemented for, e.g.,
1079
///   `Option<&UnsafeCell<_>>`, but it could be one day).
1080
///
1081
/// This analysis is subject to change. Unsafe code may *only* rely on the
1082
/// documented [safety conditions] of `FromZeroes`, and must *not* rely on the
1083
/// implementation details of this derive.
1084
///
1085
/// [the reference]: https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-fieldless-enumerations
1086
/// [`UnsafeCell`]: core::cell::UnsafeCell
1087
///
1088
/// ## Why isn't an explicit representation required for structs?
1089
///
1090
/// Neither this derive, nor the [safety conditions] of `FromZeroes`, requires
1091
/// that structs are marked with `#[repr(C)]`.
1092
///
1093
/// Per the [Rust reference](reference),
1094
///
1095
/// > The representation of a type can change the padding between fields, but
1096
/// > does not change the layout of the fields themselves.
1097
///
1098
/// [reference]: https://doc.rust-lang.org/reference/type-layout.html#representations
1099
///
1100
/// Since the layout of structs only consists of padding bytes and field bytes,
1101
/// a struct is soundly `FromZeroes` if:
1102
/// 1. its padding is soundly `FromZeroes`, and
1103
/// 2. its fields are soundly `FromZeroes`.
1104
///
1105
/// The answer to the first question is always yes: padding bytes do not have
1106
/// any validity constraints. A [discussion] of this question in the Unsafe Code
1107
/// Guidelines Working Group concluded that it would be virtually unimaginable
1108
/// for future versions of rustc to add validity constraints to padding bytes.
1109
///
1110
/// [discussion]: https://github.com/rust-lang/unsafe-code-guidelines/issues/174
1111
///
1112
/// Whether a struct is soundly `FromZeroes` therefore solely depends on whether
1113
/// its fields are `FromZeroes`.
1114
// TODO(#146): Document why we don't require an enum to have an explicit `repr`
1115
// attribute.
1116
#[cfg(any(feature = "derive", test))]
1117
#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
1118
pub use zerocopy_derive::FromZeroes;
1119
1120
/// Types whose validity can be checked at runtime, allowing them to be
1121
/// conditionally converted from byte slices.
1122
///
1123
/// WARNING: Do not implement this trait yourself! Instead, use
1124
/// `#[derive(TryFromBytes)]`.
1125
///
1126
/// `TryFromBytes` types can safely be deserialized from an untrusted sequence
1127
/// of bytes by performing a runtime check that the byte sequence contains a
1128
/// valid instance of `Self`.
1129
///
1130
/// `TryFromBytes` is ignorant of byte order. For byte order-aware types, see
1131
/// the [`byteorder`] module.
1132
///
1133
/// # What is a "valid instance"?
1134
///
1135
/// In Rust, each type has *bit validity*, which refers to the set of bit
1136
/// patterns which may appear in an instance of that type. It is impossible for
1137
/// safe Rust code to produce values which violate bit validity (ie, values
1138
/// outside of the "valid" set of bit patterns). If `unsafe` code produces an
1139
/// invalid value, this is considered [undefined behavior].
1140
///
1141
/// Rust's bit validity rules are currently being decided, which means that some
1142
/// types have three classes of bit patterns: those which are definitely valid,
1143
/// and whose validity is documented in the language; those which may or may not
1144
/// be considered valid at some point in the future; and those which are
1145
/// definitely invalid.
1146
///
1147
/// Zerocopy takes a conservative approach, and only considers a bit pattern to
1148
/// be valid if its validity is a documenteed guarantee provided by the
1149
/// language.
1150
///
1151
/// For most use cases, Rust's current guarantees align with programmers'
1152
/// intuitions about what ought to be valid. As a result, zerocopy's
1153
/// conservatism should not affect most users. One notable exception is unions,
1154
/// whose bit validity is very up in the air; zerocopy does not permit
1155
/// implementing `TryFromBytes` for any union type.
1156
///
1157
/// If you are negatively affected by lack of support for a particular type,
1158
/// we encourage you to let us know by [filing an issue][github-repo].
1159
///
1160
/// # Safety
1161
///
1162
/// On its own, `T: TryFromBytes` does not make any guarantees about the layout
1163
/// or representation of `T`. It merely provides the ability to perform a
1164
/// validity check at runtime via methods like [`try_from_ref`].
1165
///
1166
/// Currently, it is not possible to stably implement `TryFromBytes` other than
1167
/// by using `#[derive(TryFromBytes)]`. While there are `#[doc(hidden)]` items
1168
/// on this trait that provide well-defined safety invariants, no stability
1169
/// guarantees are made with respect to these items. In particular, future
1170
/// releases of zerocopy may make backwards-breaking changes to these items,
1171
/// including changes that only affect soundness, which may cause code which
1172
/// uses those items to silently become unsound.
1173
///
1174
/// [undefined behavior]: https://raphlinus.github.io/programming/rust/2018/08/17/undefined-behavior.html
1175
/// [github-repo]: https://github.com/google/zerocopy
1176
/// [`try_from_ref`]: TryFromBytes::try_from_ref
1177
// TODO(#5): Update `try_from_ref` doc link once it exists
1178
#[doc(hidden)]
1179
pub unsafe trait TryFromBytes {
1180
    /// Does a given memory range contain a valid instance of `Self`?
1181
    ///
1182
    /// # Safety
1183
    ///
1184
    /// ## Preconditions
1185
    ///
1186
    /// The memory referenced by `candidate` may only be accessed via reads for
1187
    /// the duration of this method call. This prohibits writes through mutable
1188
    /// references and through [`UnsafeCell`]s. There may exist immutable
1189
    /// references to the same memory which contain `UnsafeCell`s so long as:
1190
    /// - Those `UnsafeCell`s exist at the same byte ranges as `UnsafeCell`s in
1191
    ///   `Self`. This is a bidirectional property: `Self` may not contain
1192
    ///   `UnsafeCell`s where other references to the same memory do not, and
1193
    ///   vice-versa.
1194
    /// - Those `UnsafeCell`s are never used to perform mutation for the
1195
    ///   duration of this method call.
1196
    ///
1197
    /// The memory referenced by `candidate` may not be referenced by any
1198
    /// mutable references even if these references are not used to perform
1199
    /// mutation.
1200
    ///
1201
    /// `candidate` is not required to refer to a valid `Self`. However, it must
1202
    /// satisfy the requirement that uninitialized bytes may only be present
1203
    /// where it is possible for them to be present in `Self`. This is a dynamic
1204
    /// property: if, at a particular byte offset, a valid enum discriminant is
1205
    /// set, the subsequent bytes may only have uninitialized bytes as
1206
    /// specificed by the corresponding enum.
1207
    ///
1208
    /// Formally, given `len = size_of_val_raw(candidate)`, at every byte
1209
    /// offset, `b`, in the range `[0, len)`:
1210
    /// - If, in all instances `s: Self` of length `len`, the byte at offset `b`
1211
    ///   in `s` is initialized, then the byte at offset `b` within `*candidate`
1212
    ///   must be initialized.
1213
    /// - Let `c` be the contents of the byte range `[0, b)` in `*candidate`.
1214
    ///   Let `S` be the subset of valid instances of `Self` of length `len`
1215
    ///   which contain `c` in the offset range `[0, b)`. If, for all instances
1216
    ///   of `s: Self` in `S`, the byte at offset `b` in `s` is initialized,
1217
    ///   then the byte at offset `b` in `*candidate` must be initialized.
1218
    ///
1219
    ///   Pragmatically, this means that if `*candidate` is guaranteed to
1220
    ///   contain an enum type at a particular offset, and the enum discriminant
1221
    ///   stored in `*candidate` corresponds to a valid variant of that enum
1222
    ///   type, then it is guaranteed that the appropriate bytes of `*candidate`
1223
    ///   are initialized as defined by that variant's bit validity (although
1224
    ///   note that the variant may contain another enum type, in which case the
1225
    ///   same rules apply depending on the state of its discriminant, and so on
1226
    ///   recursively).
1227
    ///
1228
    /// ## Postconditions
1229
    ///
1230
    /// Unsafe code may assume that, if `is_bit_valid(candidate)` returns true,
1231
    /// `*candidate` contains a valid `Self`.
1232
    ///
1233
    /// # Panics
1234
    ///
1235
    /// `is_bit_valid` may panic. Callers are responsible for ensuring that any
1236
    /// `unsafe` code remains sound even in the face of `is_bit_valid`
1237
    /// panicking. (We support user-defined validation routines; so long as
1238
    /// these routines are not required to be `unsafe`, there is no way to
1239
    /// ensure that these do not generate panics.)
1240
    ///
1241
    /// [`UnsafeCell`]: core::cell::UnsafeCell
1242
    #[doc(hidden)]
1243
    unsafe fn is_bit_valid(candidate: Ptr<'_, Self>) -> bool;
1244
1245
    /// Attempts to interpret a byte slice as a `Self`.
1246
    ///
1247
    /// `try_from_ref` validates that `bytes` contains a valid `Self`, and that
1248
    /// it satisfies `Self`'s alignment requirement. If it does, then `bytes` is
1249
    /// reinterpreted as a `Self`.
1250
    ///
1251
    /// Note that Rust's bit validity rules are still being decided. As such,
1252
    /// there exist types whose bit validity is ambiguous. See the
1253
    /// `TryFromBytes` docs for a discussion of how these cases are handled.
1254
    // TODO(#251): In a future in which we distinguish between `FromBytes` and
1255
    // `RefFromBytes`, this requires `where Self: RefFromBytes` to disallow
1256
    // interior mutability.
1257
    #[inline]
1258
    #[doc(hidden)] // TODO(#5): Finalize name before remove this attribute.
1259
0
    fn try_from_ref(bytes: &[u8]) -> Option<&Self>
1260
0
    where
1261
0
        Self: KnownLayout,
1262
0
    {
1263
0
        let maybe_self = Ptr::from(bytes).try_cast_into_no_leftover::<Self>()?;
1264
1265
        // SAFETY:
1266
        // - Since `bytes` is an immutable reference, we know that no mutable
1267
        //   references exist to this memory region.
1268
        // - Since `[u8]` contains no `UnsafeCell`s, we know there are no
1269
        //   `&UnsafeCell` references to this memory region.
1270
        // - Since we don't permit implementing `TryFromBytes` for types which
1271
        //   contain `UnsafeCell`s, there are no `UnsafeCell`s in `Self`, and so
1272
        //   the requirement that all references contain `UnsafeCell`s at the
1273
        //   same offsets is trivially satisfied.
1274
        // - All bytes of `bytes` are initialized.
1275
        //
1276
        // This call may panic. If that happens, it doesn't cause any soundness
1277
        // issues, as we have not generated any invalid state which we need to
1278
        // fix before returning.
1279
0
        if unsafe { !Self::is_bit_valid(maybe_self) } {
1280
0
            return None;
1281
0
        }
1282
0
1283
0
        // SAFETY:
1284
0
        // - Preconditions for `as_ref`:
1285
0
        //   - `is_bit_valid` guarantees that `*maybe_self` contains a valid
1286
0
        //     `Self`. Since `&[u8]` does not permit interior mutation, this
1287
0
        //     cannot be invalidated after this method returns.
1288
0
        //   - Since the argument and return types are immutable references,
1289
0
        //     Rust will prevent the caller from producing any mutable
1290
0
        //     references to the same memory region.
1291
0
        //   - Since `Self` is not allowed to contain any `UnsafeCell`s and the
1292
0
        //     same is true of `[u8]`, interior mutation is not possible. Thus,
1293
0
        //     no mutation is possible. For the same reason, there is no
1294
0
        //     mismatch between the two types in terms of which byte ranges are
1295
0
        //     referenced as `UnsafeCell`s.
1296
0
        // - Since interior mutation isn't possible within `Self`, there's no
1297
0
        //   way for the returned reference to be used to modify the byte range,
1298
0
        //   and thus there's no way for the returned reference to be used to
1299
0
        //   write an invalid `[u8]` which would be observable via the original
1300
0
        //   `&[u8]`.
1301
0
        Some(unsafe { maybe_self.as_ref() })
1302
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB1d_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYbNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYcNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYeNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy12TryFromBytes12try_from_refB5_
1303
}
1304
1305
/// Types for which a sequence of bytes all set to zero represents a valid
1306
/// instance of the type.
1307
///
1308
/// Any memory region of the appropriate length which is guaranteed to contain
1309
/// only zero bytes can be viewed as any `FromZeroes` type with no runtime
1310
/// overhead. This is useful whenever memory is known to be in a zeroed state,
1311
/// such memory returned from some allocation routines.
1312
///
1313
/// # Implementation
1314
///
1315
/// **Do not implement this trait yourself!** Instead, use
1316
/// [`#[derive(FromZeroes)]`][derive] (requires the `derive` Cargo feature);
1317
/// e.g.:
1318
///
1319
/// ```
1320
/// # use zerocopy_derive::FromZeroes;
1321
/// #[derive(FromZeroes)]
1322
/// struct MyStruct {
1323
/// # /*
1324
///     ...
1325
/// # */
1326
/// }
1327
///
1328
/// #[derive(FromZeroes)]
1329
/// #[repr(u8)]
1330
/// enum MyEnum {
1331
/// #   Variant0,
1332
/// # /*
1333
///     ...
1334
/// # */
1335
/// }
1336
///
1337
/// #[derive(FromZeroes)]
1338
/// union MyUnion {
1339
/// #   variant: u8,
1340
/// # /*
1341
///     ...
1342
/// # */
1343
/// }
1344
/// ```
1345
///
1346
/// This derive performs a sophisticated, compile-time safety analysis to
1347
/// determine whether a type is `FromZeroes`.
1348
///
1349
/// # Safety
1350
///
1351
/// *This section describes what is required in order for `T: FromZeroes`, and
1352
/// what unsafe code may assume of such types. If you don't plan on implementing
1353
/// `FromZeroes` manually, and you don't plan on writing unsafe code that
1354
/// operates on `FromZeroes` types, then you don't need to read this section.*
1355
///
1356
/// If `T: FromZeroes`, then unsafe code may assume that:
1357
/// - It is sound to treat any initialized sequence of zero bytes of length
1358
///   `size_of::<T>()` as a `T`.
1359
/// - Given `b: &[u8]` where `b.len() == size_of::<T>()`, `b` is aligned to
1360
///   `align_of::<T>()`, and `b` contains only zero bytes, it is sound to
1361
///   construct a `t: &T` at the same address as `b`, and it is sound for both
1362
///   `b` and `t` to be live at the same time.
1363
///
1364
/// If a type is marked as `FromZeroes` which violates this contract, it may
1365
/// cause undefined behavior.
1366
///
1367
/// `#[derive(FromZeroes)]` only permits [types which satisfy these
1368
/// requirements][derive-analysis].
1369
///
1370
#[cfg_attr(
1371
    feature = "derive",
1372
    doc = "[derive]: zerocopy_derive::FromZeroes",
1373
    doc = "[derive-analysis]: zerocopy_derive::FromZeroes#analysis"
1374
)]
1375
#[cfg_attr(
1376
    not(feature = "derive"),
1377
    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromZeroes.html"),
1378
    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromZeroes.html#analysis"),
1379
)]
1380
pub unsafe trait FromZeroes {
1381
    // The `Self: Sized` bound makes it so that `FromZeroes` is still object
1382
    // safe.
1383
    #[doc(hidden)]
1384
    fn only_derive_is_allowed_to_implement_this_trait()
1385
    where
1386
        Self: Sized;
1387
1388
    /// Overwrites `self` with zeroes.
1389
    ///
1390
    /// Sets every byte in `self` to 0. While this is similar to doing `*self =
1391
    /// Self::new_zeroed()`, it differs in that `zero` does not semantically
1392
    /// drop the current value and replace it with a new one - it simply
1393
    /// modifies the bytes of the existing value.
1394
    ///
1395
    /// # Examples
1396
    ///
1397
    /// ```
1398
    /// # use zerocopy::FromZeroes;
1399
    /// # use zerocopy_derive::*;
1400
    /// #
1401
    /// #[derive(FromZeroes)]
1402
    /// #[repr(C)]
1403
    /// struct PacketHeader {
1404
    ///     src_port: [u8; 2],
1405
    ///     dst_port: [u8; 2],
1406
    ///     length: [u8; 2],
1407
    ///     checksum: [u8; 2],
1408
    /// }
1409
    ///
1410
    /// let mut header = PacketHeader {
1411
    ///     src_port: 100u16.to_be_bytes(),
1412
    ///     dst_port: 200u16.to_be_bytes(),
1413
    ///     length: 300u16.to_be_bytes(),
1414
    ///     checksum: 400u16.to_be_bytes(),
1415
    /// };
1416
    ///
1417
    /// header.zero();
1418
    ///
1419
    /// assert_eq!(header.src_port, [0, 0]);
1420
    /// assert_eq!(header.dst_port, [0, 0]);
1421
    /// assert_eq!(header.length, [0, 0]);
1422
    /// assert_eq!(header.checksum, [0, 0]);
1423
    /// ```
1424
    #[inline(always)]
1425
    fn zero(&mut self) {
1426
        let slf: *mut Self = self;
1427
        let len = mem::size_of_val(self);
1428
        // SAFETY:
1429
        // - `self` is guaranteed by the type system to be valid for writes of
1430
        //   size `size_of_val(self)`.
1431
        // - `u8`'s alignment is 1, and thus `self` is guaranteed to be aligned
1432
        //   as required by `u8`.
1433
        // - Since `Self: FromZeroes`, the all-zeroes instance is a valid
1434
        //   instance of `Self.`
1435
        //
1436
        // TODO(#429): Add references to docs and quotes.
1437
        unsafe { ptr::write_bytes(slf.cast::<u8>(), 0, len) };
1438
    }
1439
1440
    /// Creates an instance of `Self` from zeroed bytes.
1441
    ///
1442
    /// # Examples
1443
    ///
1444
    /// ```
1445
    /// # use zerocopy::FromZeroes;
1446
    /// # use zerocopy_derive::*;
1447
    /// #
1448
    /// #[derive(FromZeroes)]
1449
    /// #[repr(C)]
1450
    /// struct PacketHeader {
1451
    ///     src_port: [u8; 2],
1452
    ///     dst_port: [u8; 2],
1453
    ///     length: [u8; 2],
1454
    ///     checksum: [u8; 2],
1455
    /// }
1456
    ///
1457
    /// let header: PacketHeader = FromZeroes::new_zeroed();
1458
    ///
1459
    /// assert_eq!(header.src_port, [0, 0]);
1460
    /// assert_eq!(header.dst_port, [0, 0]);
1461
    /// assert_eq!(header.length, [0, 0]);
1462
    /// assert_eq!(header.checksum, [0, 0]);
1463
    /// ```
1464
    #[inline(always)]
1465
    fn new_zeroed() -> Self
1466
    where
1467
        Self: Sized,
1468
    {
1469
        // SAFETY: `FromZeroes` says that the all-zeroes bit pattern is legal.
1470
        unsafe { mem::zeroed() }
1471
    }
1472
1473
    /// Creates a `Box<Self>` from zeroed bytes.
1474
    ///
1475
    /// This function is useful for allocating large values on the heap and
1476
    /// zero-initializing them, without ever creating a temporary instance of
1477
    /// `Self` on the stack. For example, `<[u8; 1048576]>::new_box_zeroed()`
1478
    /// will allocate `[u8; 1048576]` directly on the heap; it does not require
1479
    /// storing `[u8; 1048576]` in a temporary variable on the stack.
1480
    ///
1481
    /// On systems that use a heap implementation that supports allocating from
1482
    /// pre-zeroed memory, using `new_box_zeroed` (or related functions) may
1483
    /// have performance benefits.
1484
    ///
1485
    /// Note that `Box<Self>` can be converted to `Arc<Self>` and other
1486
    /// container types without reallocation.
1487
    ///
1488
    /// # Panics
1489
    ///
1490
    /// Panics if allocation of `size_of::<Self>()` bytes fails.
1491
    #[cfg(feature = "alloc")]
1492
    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
1493
    #[inline]
1494
    fn new_box_zeroed() -> Box<Self>
1495
    where
1496
        Self: Sized,
1497
    {
1498
        // If `T` is a ZST, then return a proper boxed instance of it. There is
1499
        // no allocation, but `Box` does require a correct dangling pointer.
1500
        let layout = Layout::new::<Self>();
1501
        if layout.size() == 0 {
1502
            return Box::new(Self::new_zeroed());
1503
        }
1504
1505
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1506
        #[allow(clippy::undocumented_unsafe_blocks)]
1507
        let ptr = unsafe { alloc::alloc::alloc_zeroed(layout).cast::<Self>() };
1508
        if ptr.is_null() {
1509
            alloc::alloc::handle_alloc_error(layout);
1510
        }
1511
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1512
        #[allow(clippy::undocumented_unsafe_blocks)]
1513
        unsafe {
1514
            Box::from_raw(ptr)
1515
        }
1516
    }
1517
1518
    /// Creates a `Box<[Self]>` (a boxed slice) from zeroed bytes.
1519
    ///
1520
    /// This function is useful for allocating large values of `[Self]` on the
1521
    /// heap and zero-initializing them, without ever creating a temporary
1522
    /// instance of `[Self; _]` on the stack. For example,
1523
    /// `u8::new_box_slice_zeroed(1048576)` will allocate the slice directly on
1524
    /// the heap; it does not require storing the slice on the stack.
1525
    ///
1526
    /// On systems that use a heap implementation that supports allocating from
1527
    /// pre-zeroed memory, using `new_box_slice_zeroed` may have performance
1528
    /// benefits.
1529
    ///
1530
    /// If `Self` is a zero-sized type, then this function will return a
1531
    /// `Box<[Self]>` that has the correct `len`. Such a box cannot contain any
1532
    /// actual information, but its `len()` property will report the correct
1533
    /// value.
1534
    ///
1535
    /// # Panics
1536
    ///
1537
    /// * Panics if `size_of::<Self>() * len` overflows.
1538
    /// * Panics if allocation of `size_of::<Self>() * len` bytes fails.
1539
    #[cfg(feature = "alloc")]
1540
    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
1541
    #[inline]
1542
    fn new_box_slice_zeroed(len: usize) -> Box<[Self]>
1543
    where
1544
        Self: Sized,
1545
    {
1546
        let size = mem::size_of::<Self>()
1547
            .checked_mul(len)
1548
            .expect("mem::size_of::<Self>() * len overflows `usize`");
1549
        let align = mem::align_of::<Self>();
1550
        // On stable Rust versions <= 1.64.0, `Layout::from_size_align` has a
1551
        // bug in which sufficiently-large allocations (those which, when
1552
        // rounded up to the alignment, overflow `isize`) are not rejected,
1553
        // which can cause undefined behavior. See #64 for details.
1554
        //
1555
        // TODO(#67): Once our MSRV is > 1.64.0, remove this assertion.
1556
        #[allow(clippy::as_conversions)]
1557
        let max_alloc = (isize::MAX as usize).saturating_sub(align);
1558
        assert!(size <= max_alloc);
1559
        // TODO(https://github.com/rust-lang/rust/issues/55724): Use
1560
        // `Layout::repeat` once it's stabilized.
1561
        let layout =
1562
            Layout::from_size_align(size, align).expect("total allocation size overflows `isize`");
1563
1564
        let ptr = if layout.size() != 0 {
1565
            // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1566
            #[allow(clippy::undocumented_unsafe_blocks)]
1567
            let ptr = unsafe { alloc::alloc::alloc_zeroed(layout).cast::<Self>() };
1568
            if ptr.is_null() {
1569
                alloc::alloc::handle_alloc_error(layout);
1570
            }
1571
            ptr
1572
        } else {
1573
            // `Box<[T]>` does not allocate when `T` is zero-sized or when `len`
1574
            // is zero, but it does require a non-null dangling pointer for its
1575
            // allocation.
1576
            NonNull::<Self>::dangling().as_ptr()
1577
        };
1578
1579
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1580
        #[allow(clippy::undocumented_unsafe_blocks)]
1581
        unsafe {
1582
            Box::from_raw(slice::from_raw_parts_mut(ptr, len))
1583
        }
1584
    }
1585
1586
    /// Creates a `Vec<Self>` from zeroed bytes.
1587
    ///
1588
    /// This function is useful for allocating large values of `Vec`s and
1589
    /// zero-initializing them, without ever creating a temporary instance of
1590
    /// `[Self; _]` (or many temporary instances of `Self`) on the stack. For
1591
    /// example, `u8::new_vec_zeroed(1048576)` will allocate directly on the
1592
    /// heap; it does not require storing intermediate values on the stack.
1593
    ///
1594
    /// On systems that use a heap implementation that supports allocating from
1595
    /// pre-zeroed memory, using `new_vec_zeroed` may have performance benefits.
1596
    ///
1597
    /// If `Self` is a zero-sized type, then this function will return a
1598
    /// `Vec<Self>` that has the correct `len`. Such a `Vec` cannot contain any
1599
    /// actual information, but its `len()` property will report the correct
1600
    /// value.
1601
    ///
1602
    /// # Panics
1603
    ///
1604
    /// * Panics if `size_of::<Self>() * len` overflows.
1605
    /// * Panics if allocation of `size_of::<Self>() * len` bytes fails.
1606
    #[cfg(feature = "alloc")]
1607
    #[cfg_attr(doc_cfg, doc(cfg(feature = "new_vec_zeroed")))]
1608
    #[inline(always)]
1609
    fn new_vec_zeroed(len: usize) -> Vec<Self>
1610
    where
1611
        Self: Sized,
1612
    {
1613
        Self::new_box_slice_zeroed(len).into()
1614
    }
1615
}
1616
1617
/// Analyzes whether a type is [`FromBytes`].
1618
///
1619
/// This derive analyzes, at compile time, whether the annotated type satisfies
1620
/// the [safety conditions] of `FromBytes` and implements `FromBytes` if it is
1621
/// sound to do so. This derive can be applied to structs, enums, and unions;
1622
/// e.g.:
1623
///
1624
/// ```
1625
/// # use zerocopy_derive::{FromBytes, FromZeroes};
1626
/// #[derive(FromZeroes, FromBytes)]
1627
/// struct MyStruct {
1628
/// # /*
1629
///     ...
1630
/// # */
1631
/// }
1632
///
1633
/// #[derive(FromZeroes, FromBytes)]
1634
/// #[repr(u8)]
1635
/// enum MyEnum {
1636
/// #   V00, V01, V02, V03, V04, V05, V06, V07, V08, V09, V0A, V0B, V0C, V0D, V0E,
1637
/// #   V0F, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V1A, V1B, V1C, V1D,
1638
/// #   V1E, V1F, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V2A, V2B, V2C,
1639
/// #   V2D, V2E, V2F, V30, V31, V32, V33, V34, V35, V36, V37, V38, V39, V3A, V3B,
1640
/// #   V3C, V3D, V3E, V3F, V40, V41, V42, V43, V44, V45, V46, V47, V48, V49, V4A,
1641
/// #   V4B, V4C, V4D, V4E, V4F, V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
1642
/// #   V5A, V5B, V5C, V5D, V5E, V5F, V60, V61, V62, V63, V64, V65, V66, V67, V68,
1643
/// #   V69, V6A, V6B, V6C, V6D, V6E, V6F, V70, V71, V72, V73, V74, V75, V76, V77,
1644
/// #   V78, V79, V7A, V7B, V7C, V7D, V7E, V7F, V80, V81, V82, V83, V84, V85, V86,
1645
/// #   V87, V88, V89, V8A, V8B, V8C, V8D, V8E, V8F, V90, V91, V92, V93, V94, V95,
1646
/// #   V96, V97, V98, V99, V9A, V9B, V9C, V9D, V9E, V9F, VA0, VA1, VA2, VA3, VA4,
1647
/// #   VA5, VA6, VA7, VA8, VA9, VAA, VAB, VAC, VAD, VAE, VAF, VB0, VB1, VB2, VB3,
1648
/// #   VB4, VB5, VB6, VB7, VB8, VB9, VBA, VBB, VBC, VBD, VBE, VBF, VC0, VC1, VC2,
1649
/// #   VC3, VC4, VC5, VC6, VC7, VC8, VC9, VCA, VCB, VCC, VCD, VCE, VCF, VD0, VD1,
1650
/// #   VD2, VD3, VD4, VD5, VD6, VD7, VD8, VD9, VDA, VDB, VDC, VDD, VDE, VDF, VE0,
1651
/// #   VE1, VE2, VE3, VE4, VE5, VE6, VE7, VE8, VE9, VEA, VEB, VEC, VED, VEE, VEF,
1652
/// #   VF0, VF1, VF2, VF3, VF4, VF5, VF6, VF7, VF8, VF9, VFA, VFB, VFC, VFD, VFE,
1653
/// #   VFF,
1654
/// # /*
1655
///     ...
1656
/// # */
1657
/// }
1658
///
1659
/// #[derive(FromZeroes, FromBytes)]
1660
/// union MyUnion {
1661
/// #   variant: u8,
1662
/// # /*
1663
///     ...
1664
/// # */
1665
/// }
1666
/// ```
1667
///
1668
/// [safety conditions]: trait@FromBytes#safety
1669
///
1670
/// # Analysis
1671
///
1672
/// *This section describes, roughly, the analysis performed by this derive to
1673
/// determine whether it is sound to implement `FromBytes` for a given type.
1674
/// Unless you are modifying the implementation of this derive, or attempting to
1675
/// manually implement `FromBytes` for a type yourself, you don't need to read
1676
/// this section.*
1677
///
1678
/// If a type has the following properties, then this derive can implement
1679
/// `FromBytes` for that type:
1680
///
1681
/// - If the type is a struct, all of its fields must be `FromBytes`.
1682
/// - If the type is an enum:
1683
///   - It must be a C-like enum (meaning that all variants have no fields).
1684
///   - It must have a defined representation (`repr`s `C`, `u8`, `u16`, `u32`,
1685
///     `u64`, `usize`, `i8`, `i16`, `i32`, `i64`, or `isize`).
1686
///   - The maximum number of discriminants must be used (so that every possible
1687
///     bit pattern is a valid one). Be very careful when using the `C`,
1688
///     `usize`, or `isize` representations, as their size is
1689
///     platform-dependent.
1690
/// - The type must not contain any [`UnsafeCell`]s (this is required in order
1691
///   for it to be sound to construct a `&[u8]` and a `&T` to the same region of
1692
///   memory). The type may contain references or pointers to `UnsafeCell`s so
1693
///   long as those values can themselves be initialized from zeroes
1694
///   (`FromBytes` is not currently implemented for, e.g., `Option<*const
1695
///   UnsafeCell<_>>`, but it could be one day).
1696
///
1697
/// [`UnsafeCell`]: core::cell::UnsafeCell
1698
///
1699
/// This analysis is subject to change. Unsafe code may *only* rely on the
1700
/// documented [safety conditions] of `FromBytes`, and must *not* rely on the
1701
/// implementation details of this derive.
1702
///
1703
/// ## Why isn't an explicit representation required for structs?
1704
///
1705
/// Neither this derive, nor the [safety conditions] of `FromBytes`, requires
1706
/// that structs are marked with `#[repr(C)]`.
1707
///
1708
/// Per the [Rust reference](reference),
1709
///
1710
/// > The representation of a type can change the padding between fields, but
1711
/// > does not change the layout of the fields themselves.
1712
///
1713
/// [reference]: https://doc.rust-lang.org/reference/type-layout.html#representations
1714
///
1715
/// Since the layout of structs only consists of padding bytes and field bytes,
1716
/// a struct is soundly `FromBytes` if:
1717
/// 1. its padding is soundly `FromBytes`, and
1718
/// 2. its fields are soundly `FromBytes`.
1719
///
1720
/// The answer to the first question is always yes: padding bytes do not have
1721
/// any validity constraints. A [discussion] of this question in the Unsafe Code
1722
/// Guidelines Working Group concluded that it would be virtually unimaginable
1723
/// for future versions of rustc to add validity constraints to padding bytes.
1724
///
1725
/// [discussion]: https://github.com/rust-lang/unsafe-code-guidelines/issues/174
1726
///
1727
/// Whether a struct is soundly `FromBytes` therefore solely depends on whether
1728
/// its fields are `FromBytes`.
1729
// TODO(#146): Document why we don't require an enum to have an explicit `repr`
1730
// attribute.
1731
#[cfg(any(feature = "derive", test))]
1732
#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
1733
pub use zerocopy_derive::FromBytes;
1734
1735
/// Types for which any bit pattern is valid.
1736
///
1737
/// Any memory region of the appropriate length which contains initialized bytes
1738
/// can be viewed as any `FromBytes` type with no runtime overhead. This is
1739
/// useful for efficiently parsing bytes as structured data.
1740
///
1741
/// # Implementation
1742
///
1743
/// **Do not implement this trait yourself!** Instead, use
1744
/// [`#[derive(FromBytes)]`][derive] (requires the `derive` Cargo feature);
1745
/// e.g.:
1746
///
1747
/// ```
1748
/// # use zerocopy_derive::{FromBytes, FromZeroes};
1749
/// #[derive(FromZeroes, FromBytes)]
1750
/// struct MyStruct {
1751
/// # /*
1752
///     ...
1753
/// # */
1754
/// }
1755
///
1756
/// #[derive(FromZeroes, FromBytes)]
1757
/// #[repr(u8)]
1758
/// enum MyEnum {
1759
/// #   V00, V01, V02, V03, V04, V05, V06, V07, V08, V09, V0A, V0B, V0C, V0D, V0E,
1760
/// #   V0F, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V1A, V1B, V1C, V1D,
1761
/// #   V1E, V1F, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V2A, V2B, V2C,
1762
/// #   V2D, V2E, V2F, V30, V31, V32, V33, V34, V35, V36, V37, V38, V39, V3A, V3B,
1763
/// #   V3C, V3D, V3E, V3F, V40, V41, V42, V43, V44, V45, V46, V47, V48, V49, V4A,
1764
/// #   V4B, V4C, V4D, V4E, V4F, V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
1765
/// #   V5A, V5B, V5C, V5D, V5E, V5F, V60, V61, V62, V63, V64, V65, V66, V67, V68,
1766
/// #   V69, V6A, V6B, V6C, V6D, V6E, V6F, V70, V71, V72, V73, V74, V75, V76, V77,
1767
/// #   V78, V79, V7A, V7B, V7C, V7D, V7E, V7F, V80, V81, V82, V83, V84, V85, V86,
1768
/// #   V87, V88, V89, V8A, V8B, V8C, V8D, V8E, V8F, V90, V91, V92, V93, V94, V95,
1769
/// #   V96, V97, V98, V99, V9A, V9B, V9C, V9D, V9E, V9F, VA0, VA1, VA2, VA3, VA4,
1770
/// #   VA5, VA6, VA7, VA8, VA9, VAA, VAB, VAC, VAD, VAE, VAF, VB0, VB1, VB2, VB3,
1771
/// #   VB4, VB5, VB6, VB7, VB8, VB9, VBA, VBB, VBC, VBD, VBE, VBF, VC0, VC1, VC2,
1772
/// #   VC3, VC4, VC5, VC6, VC7, VC8, VC9, VCA, VCB, VCC, VCD, VCE, VCF, VD0, VD1,
1773
/// #   VD2, VD3, VD4, VD5, VD6, VD7, VD8, VD9, VDA, VDB, VDC, VDD, VDE, VDF, VE0,
1774
/// #   VE1, VE2, VE3, VE4, VE5, VE6, VE7, VE8, VE9, VEA, VEB, VEC, VED, VEE, VEF,
1775
/// #   VF0, VF1, VF2, VF3, VF4, VF5, VF6, VF7, VF8, VF9, VFA, VFB, VFC, VFD, VFE,
1776
/// #   VFF,
1777
/// # /*
1778
///     ...
1779
/// # */
1780
/// }
1781
///
1782
/// #[derive(FromZeroes, FromBytes)]
1783
/// union MyUnion {
1784
/// #   variant: u8,
1785
/// # /*
1786
///     ...
1787
/// # */
1788
/// }
1789
/// ```
1790
///
1791
/// This derive performs a sophisticated, compile-time safety analysis to
1792
/// determine whether a type is `FromBytes`.
1793
///
1794
/// # Safety
1795
///
1796
/// *This section describes what is required in order for `T: FromBytes`, and
1797
/// what unsafe code may assume of such types. If you don't plan on implementing
1798
/// `FromBytes` manually, and you don't plan on writing unsafe code that
1799
/// operates on `FromBytes` types, then you don't need to read this section.*
1800
///
1801
/// If `T: FromBytes`, then unsafe code may assume that:
1802
/// - It is sound to treat any initialized sequence of bytes of length
1803
///   `size_of::<T>()` as a `T`.
1804
/// - Given `b: &[u8]` where `b.len() == size_of::<T>()`, `b` is aligned to
1805
///   `align_of::<T>()` it is sound to construct a `t: &T` at the same address
1806
///   as `b`, and it is sound for both `b` and `t` to be live at the same time.
1807
///
1808
/// If a type is marked as `FromBytes` which violates this contract, it may
1809
/// cause undefined behavior.
1810
///
1811
/// `#[derive(FromBytes)]` only permits [types which satisfy these
1812
/// requirements][derive-analysis].
1813
///
1814
#[cfg_attr(
1815
    feature = "derive",
1816
    doc = "[derive]: zerocopy_derive::FromBytes",
1817
    doc = "[derive-analysis]: zerocopy_derive::FromBytes#analysis"
1818
)]
1819
#[cfg_attr(
1820
    not(feature = "derive"),
1821
    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromBytes.html"),
1822
    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromBytes.html#analysis"),
1823
)]
1824
pub unsafe trait FromBytes: FromZeroes {
1825
    // The `Self: Sized` bound makes it so that `FromBytes` is still object
1826
    // safe.
1827
    #[doc(hidden)]
1828
    fn only_derive_is_allowed_to_implement_this_trait()
1829
    where
1830
        Self: Sized;
1831
1832
    /// Interprets the given `bytes` as a `&Self` without copying.
1833
    ///
1834
    /// If `bytes.len() != size_of::<Self>()` or `bytes` is not aligned to
1835
    /// `align_of::<Self>()`, this returns `None`.
1836
    ///
1837
    /// # Examples
1838
    ///
1839
    /// ```
1840
    /// use zerocopy::FromBytes;
1841
    /// # use zerocopy_derive::*;
1842
    ///
1843
    /// #[derive(FromZeroes, FromBytes)]
1844
    /// #[repr(C)]
1845
    /// struct PacketHeader {
1846
    ///     src_port: [u8; 2],
1847
    ///     dst_port: [u8; 2],
1848
    ///     length: [u8; 2],
1849
    ///     checksum: [u8; 2],
1850
    /// }
1851
    ///
1852
    /// // These bytes encode a `PacketHeader`.
1853
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7].as_slice();
1854
    ///
1855
    /// let header = PacketHeader::ref_from(bytes).unwrap();
1856
    ///
1857
    /// assert_eq!(header.src_port, [0, 1]);
1858
    /// assert_eq!(header.dst_port, [2, 3]);
1859
    /// assert_eq!(header.length, [4, 5]);
1860
    /// assert_eq!(header.checksum, [6, 7]);
1861
    /// ```
1862
    #[inline]
1863
0
    fn ref_from(bytes: &[u8]) -> Option<&Self>
1864
0
    where
1865
0
        Self: Sized,
1866
0
    {
1867
0
        Ref::<&[u8], Self>::new(bytes).map(Ref::into_ref)
1868
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes8ref_fromB5_
1869
1870
    /// Interprets the prefix of the given `bytes` as a `&Self` without copying.
1871
    ///
1872
    /// `ref_from_prefix` returns a reference to the first `size_of::<Self>()`
1873
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or `bytes` is not
1874
    /// aligned to `align_of::<Self>()`, this returns `None`.
1875
    ///
1876
    /// To also access the prefix bytes, use [`Ref::new_from_prefix`]. Then, use
1877
    /// [`Ref::into_ref`] to get a `&Self` with the same lifetime.
1878
    ///
1879
    /// # Examples
1880
    ///
1881
    /// ```
1882
    /// use zerocopy::FromBytes;
1883
    /// # use zerocopy_derive::*;
1884
    ///
1885
    /// #[derive(FromZeroes, FromBytes)]
1886
    /// #[repr(C)]
1887
    /// struct PacketHeader {
1888
    ///     src_port: [u8; 2],
1889
    ///     dst_port: [u8; 2],
1890
    ///     length: [u8; 2],
1891
    ///     checksum: [u8; 2],
1892
    /// }
1893
    ///
1894
    /// // These are more bytes than are needed to encode a `PacketHeader`.
1895
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
1896
    ///
1897
    /// let header = PacketHeader::ref_from_prefix(bytes).unwrap();
1898
    ///
1899
    /// assert_eq!(header.src_port, [0, 1]);
1900
    /// assert_eq!(header.dst_port, [2, 3]);
1901
    /// assert_eq!(header.length, [4, 5]);
1902
    /// assert_eq!(header.checksum, [6, 7]);
1903
    /// ```
1904
    #[inline]
1905
0
    fn ref_from_prefix(bytes: &[u8]) -> Option<&Self>
1906
0
    where
1907
0
        Self: Sized,
1908
0
    {
1909
0
        Ref::<&[u8], Self>::new_from_prefix(bytes).map(|(r, _)| r.into_ref())
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefix0B7_
1910
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_prefixB5_
1911
1912
    /// Interprets the suffix of the given `bytes` as a `&Self` without copying.
1913
    ///
1914
    /// `ref_from_suffix` returns a reference to the last `size_of::<Self>()`
1915
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or the suffix of
1916
    /// `bytes` is not aligned to `align_of::<Self>()`, this returns `None`.
1917
    ///
1918
    /// To also access the suffix bytes, use [`Ref::new_from_suffix`]. Then, use
1919
    /// [`Ref::into_ref`] to get a `&Self` with the same lifetime.
1920
    ///
1921
    /// # Examples
1922
    ///
1923
    /// ```
1924
    /// use zerocopy::FromBytes;
1925
    /// # use zerocopy_derive::*;
1926
    ///
1927
    /// #[derive(FromZeroes, FromBytes)]
1928
    /// #[repr(C)]
1929
    /// struct PacketTrailer {
1930
    ///     frame_check_sequence: [u8; 4],
1931
    /// }
1932
    ///
1933
    /// // These are more bytes than are needed to encode a `PacketTrailer`.
1934
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
1935
    ///
1936
    /// let trailer = PacketTrailer::ref_from_suffix(bytes).unwrap();
1937
    ///
1938
    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
1939
    /// ```
1940
    #[inline]
1941
0
    fn ref_from_suffix(bytes: &[u8]) -> Option<&Self>
1942
0
    where
1943
0
        Self: Sized,
1944
0
    {
1945
0
        Ref::<&[u8], Self>::new_from_suffix(bytes).map(|(_, r)| r.into_ref())
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffix0B7_
1946
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes15ref_from_suffixB5_
1947
1948
    /// Interprets the given `bytes` as a `&mut Self` without copying.
1949
    ///
1950
    /// If `bytes.len() != size_of::<Self>()` or `bytes` is not aligned to
1951
    /// `align_of::<Self>()`, this returns `None`.
1952
    ///
1953
    /// # Examples
1954
    ///
1955
    /// ```
1956
    /// use zerocopy::FromBytes;
1957
    /// # use zerocopy_derive::*;
1958
    ///
1959
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
1960
    /// #[repr(C)]
1961
    /// struct PacketHeader {
1962
    ///     src_port: [u8; 2],
1963
    ///     dst_port: [u8; 2],
1964
    ///     length: [u8; 2],
1965
    ///     checksum: [u8; 2],
1966
    /// }
1967
    ///
1968
    /// // These bytes encode a `PacketHeader`.
1969
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7][..];
1970
    ///
1971
    /// let header = PacketHeader::mut_from(bytes).unwrap();
1972
    ///
1973
    /// assert_eq!(header.src_port, [0, 1]);
1974
    /// assert_eq!(header.dst_port, [2, 3]);
1975
    /// assert_eq!(header.length, [4, 5]);
1976
    /// assert_eq!(header.checksum, [6, 7]);
1977
    ///
1978
    /// header.checksum = [0, 0];
1979
    ///
1980
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0]);
1981
    /// ```
1982
    #[inline]
1983
0
    fn mut_from(bytes: &mut [u8]) -> Option<&mut Self>
1984
0
    where
1985
0
        Self: Sized + AsBytes,
1986
0
    {
1987
0
        Ref::<&mut [u8], Self>::new(bytes).map(Ref::into_mut)
1988
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes8mut_fromB5_
1989
1990
    /// Interprets the prefix of the given `bytes` as a `&mut Self` without
1991
    /// copying.
1992
    ///
1993
    /// `mut_from_prefix` returns a reference to the first `size_of::<Self>()`
1994
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or `bytes` is not
1995
    /// aligned to `align_of::<Self>()`, this returns `None`.
1996
    ///
1997
    /// To also access the prefix bytes, use [`Ref::new_from_prefix`]. Then, use
1998
    /// [`Ref::into_mut`] to get a `&mut Self` with the same lifetime.
1999
    ///
2000
    /// # Examples
2001
    ///
2002
    /// ```
2003
    /// use zerocopy::FromBytes;
2004
    /// # use zerocopy_derive::*;
2005
    ///
2006
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2007
    /// #[repr(C)]
2008
    /// struct PacketHeader {
2009
    ///     src_port: [u8; 2],
2010
    ///     dst_port: [u8; 2],
2011
    ///     length: [u8; 2],
2012
    ///     checksum: [u8; 2],
2013
    /// }
2014
    ///
2015
    /// // These are more bytes than are needed to encode a `PacketHeader`.
2016
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2017
    ///
2018
    /// let header = PacketHeader::mut_from_prefix(bytes).unwrap();
2019
    ///
2020
    /// assert_eq!(header.src_port, [0, 1]);
2021
    /// assert_eq!(header.dst_port, [2, 3]);
2022
    /// assert_eq!(header.length, [4, 5]);
2023
    /// assert_eq!(header.checksum, [6, 7]);
2024
    ///
2025
    /// header.checksum = [0, 0];
2026
    ///
2027
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0, 8, 9]);
2028
    /// ```
2029
    #[inline]
2030
0
    fn mut_from_prefix(bytes: &mut [u8]) -> Option<&mut Self>
2031
0
    where
2032
0
        Self: Sized + AsBytes,
2033
0
    {
2034
0
        Ref::<&mut [u8], Self>::new_from_prefix(bytes).map(|(r, _)| r.into_mut())
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefix0B7_
2035
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_prefixB5_
2036
2037
    /// Interprets the suffix of the given `bytes` as a `&mut Self` without copying.
2038
    ///
2039
    /// `mut_from_suffix` returns a reference to the last `size_of::<Self>()`
2040
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or the suffix of
2041
    /// `bytes` is not aligned to `align_of::<Self>()`, this returns `None`.
2042
    ///
2043
    /// To also access the suffix bytes, use [`Ref::new_from_suffix`]. Then,
2044
    /// use [`Ref::into_mut`] to get a `&mut Self` with the same lifetime.
2045
    ///
2046
    /// # Examples
2047
    ///
2048
    /// ```
2049
    /// use zerocopy::FromBytes;
2050
    /// # use zerocopy_derive::*;
2051
    ///
2052
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2053
    /// #[repr(C)]
2054
    /// struct PacketTrailer {
2055
    ///     frame_check_sequence: [u8; 4],
2056
    /// }
2057
    ///
2058
    /// // These are more bytes than are needed to encode a `PacketTrailer`.
2059
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2060
    ///
2061
    /// let trailer = PacketTrailer::mut_from_suffix(bytes).unwrap();
2062
    ///
2063
    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
2064
    ///
2065
    /// trailer.frame_check_sequence = [0, 0, 0, 0];
2066
    ///
2067
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0, 0, 0]);
2068
    /// ```
2069
    #[inline]
2070
0
    fn mut_from_suffix(bytes: &mut [u8]) -> Option<&mut Self>
2071
0
    where
2072
0
        Self: Sized + AsBytes,
2073
0
    {
2074
0
        Ref::<&mut [u8], Self>::new_from_suffix(bytes).map(|(_, r)| r.into_mut())
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffix0B7_
2075
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes15mut_from_suffixB5_
2076
2077
    /// Interprets the given `bytes` as a `&[Self]` without copying.
2078
    ///
2079
    /// If `bytes.len() % size_of::<Self>() != 0` or `bytes` is not aligned to
2080
    /// `align_of::<Self>()`, this returns `None`.
2081
    ///
2082
    /// If you need to convert a specific number of slice elements, see
2083
    /// [`slice_from_prefix`](FromBytes::slice_from_prefix) or
2084
    /// [`slice_from_suffix`](FromBytes::slice_from_suffix).
2085
    ///
2086
    /// # Panics
2087
    ///
2088
    /// If `Self` is a zero-sized type.
2089
    ///
2090
    /// # Examples
2091
    ///
2092
    /// ```
2093
    /// use zerocopy::FromBytes;
2094
    /// # use zerocopy_derive::*;
2095
    ///
2096
    /// # #[derive(Debug, PartialEq, Eq)]
2097
    /// #[derive(FromZeroes, FromBytes)]
2098
    /// #[repr(C)]
2099
    /// struct Pixel {
2100
    ///     r: u8,
2101
    ///     g: u8,
2102
    ///     b: u8,
2103
    ///     a: u8,
2104
    /// }
2105
    ///
2106
    /// // These bytes encode two `Pixel`s.
2107
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7].as_slice();
2108
    ///
2109
    /// let pixels = Pixel::slice_from(bytes).unwrap();
2110
    ///
2111
    /// assert_eq!(pixels, &[
2112
    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2113
    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2114
    /// ]);
2115
    /// ```
2116
    #[inline]
2117
0
    fn slice_from(bytes: &[u8]) -> Option<&[Self]>
2118
0
    where
2119
0
        Self: Sized,
2120
0
    {
2121
0
        Ref::<_, [Self]>::new_slice(bytes).map(|r| r.into_slice())
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_from0B7_
2122
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes10slice_fromB5_
2123
2124
    /// Interprets the prefix of the given `bytes` as a `&[Self]` with length
2125
    /// equal to `count` without copying.
2126
    ///
2127
    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2128
    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2129
    /// first `size_of::<T>() * count` bytes from `bytes` to construct a
2130
    /// `&[Self]`, and returns the remaining bytes to the caller. It also
2131
    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2132
    /// If any of the length, alignment, or overflow checks fail, it returns
2133
    /// `None`.
2134
    ///
2135
    /// # Panics
2136
    ///
2137
    /// If `T` is a zero-sized type.
2138
    ///
2139
    /// # Examples
2140
    ///
2141
    /// ```
2142
    /// use zerocopy::FromBytes;
2143
    /// # use zerocopy_derive::*;
2144
    ///
2145
    /// # #[derive(Debug, PartialEq, Eq)]
2146
    /// #[derive(FromZeroes, FromBytes)]
2147
    /// #[repr(C)]
2148
    /// struct Pixel {
2149
    ///     r: u8,
2150
    ///     g: u8,
2151
    ///     b: u8,
2152
    ///     a: u8,
2153
    /// }
2154
    ///
2155
    /// // These are more bytes than are needed to encode two `Pixel`s.
2156
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2157
    ///
2158
    /// let (pixels, rest) = Pixel::slice_from_prefix(bytes, 2).unwrap();
2159
    ///
2160
    /// assert_eq!(pixels, &[
2161
    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2162
    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2163
    /// ]);
2164
    ///
2165
    /// assert_eq!(rest, &[8, 9]);
2166
    /// ```
2167
    #[inline]
2168
0
    fn slice_from_prefix(bytes: &[u8], count: usize) -> Option<(&[Self], &[u8])>
2169
0
    where
2170
0
        Self: Sized,
2171
0
    {
2172
0
        Ref::<_, [Self]>::new_slice_from_prefix(bytes, count).map(|(r, b)| (r.into_slice(), b))
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefix0B7_
2173
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_prefixB5_
2174
2175
    /// Interprets the suffix of the given `bytes` as a `&[Self]` with length
2176
    /// equal to `count` without copying.
2177
    ///
2178
    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2179
    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2180
    /// last `size_of::<T>() * count` bytes from `bytes` to construct a
2181
    /// `&[Self]`, and returns the preceding bytes to the caller. It also
2182
    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2183
    /// If any of the length, alignment, or overflow checks fail, it returns
2184
    /// `None`.
2185
    ///
2186
    /// # Panics
2187
    ///
2188
    /// If `T` is a zero-sized type.
2189
    ///
2190
    /// # Examples
2191
    ///
2192
    /// ```
2193
    /// use zerocopy::FromBytes;
2194
    /// # use zerocopy_derive::*;
2195
    ///
2196
    /// # #[derive(Debug, PartialEq, Eq)]
2197
    /// #[derive(FromZeroes, FromBytes)]
2198
    /// #[repr(C)]
2199
    /// struct Pixel {
2200
    ///     r: u8,
2201
    ///     g: u8,
2202
    ///     b: u8,
2203
    ///     a: u8,
2204
    /// }
2205
    ///
2206
    /// // These are more bytes than are needed to encode two `Pixel`s.
2207
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2208
    ///
2209
    /// let (rest, pixels) = Pixel::slice_from_suffix(bytes, 2).unwrap();
2210
    ///
2211
    /// assert_eq!(rest, &[0, 1]);
2212
    ///
2213
    /// assert_eq!(pixels, &[
2214
    ///     Pixel { r: 2, g: 3, b: 4, a: 5 },
2215
    ///     Pixel { r: 6, g: 7, b: 8, a: 9 },
2216
    /// ]);
2217
    /// ```
2218
    #[inline]
2219
0
    fn slice_from_suffix(bytes: &[u8], count: usize) -> Option<(&[u8], &[Self])>
2220
0
    where
2221
0
        Self: Sized,
2222
0
    {
2223
0
        Ref::<_, [Self]>::new_slice_from_suffix(bytes, count).map(|(b, r)| (b, r.into_slice()))
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffix0B7_
2224
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes17slice_from_suffixB5_
2225
2226
    /// Interprets the given `bytes` as a `&mut [Self]` without copying.
2227
    ///
2228
    /// If `bytes.len() % size_of::<T>() != 0` or `bytes` is not aligned to
2229
    /// `align_of::<T>()`, this returns `None`.
2230
    ///
2231
    /// If you need to convert a specific number of slice elements, see
2232
    /// [`mut_slice_from_prefix`](FromBytes::mut_slice_from_prefix) or
2233
    /// [`mut_slice_from_suffix`](FromBytes::mut_slice_from_suffix).
2234
    ///
2235
    /// # Panics
2236
    ///
2237
    /// If `T` is a zero-sized type.
2238
    ///
2239
    /// # Examples
2240
    ///
2241
    /// ```
2242
    /// use zerocopy::FromBytes;
2243
    /// # use zerocopy_derive::*;
2244
    ///
2245
    /// # #[derive(Debug, PartialEq, Eq)]
2246
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2247
    /// #[repr(C)]
2248
    /// struct Pixel {
2249
    ///     r: u8,
2250
    ///     g: u8,
2251
    ///     b: u8,
2252
    ///     a: u8,
2253
    /// }
2254
    ///
2255
    /// // These bytes encode two `Pixel`s.
2256
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7][..];
2257
    ///
2258
    /// let pixels = Pixel::mut_slice_from(bytes).unwrap();
2259
    ///
2260
    /// assert_eq!(pixels, &[
2261
    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2262
    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2263
    /// ]);
2264
    ///
2265
    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
2266
    ///
2267
    /// assert_eq!(bytes, [0, 1, 2, 3, 0, 0, 0, 0]);
2268
    /// ```
2269
    #[inline]
2270
0
    fn mut_slice_from(bytes: &mut [u8]) -> Option<&mut [Self]>
2271
0
    where
2272
0
        Self: Sized + AsBytes,
2273
0
    {
2274
0
        Ref::<_, [Self]>::new_slice(bytes).map(|r| r.into_mut_slice())
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_from0B7_
2275
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes14mut_slice_fromB5_
2276
2277
    /// Interprets the prefix of the given `bytes` as a `&mut [Self]` with length
2278
    /// equal to `count` without copying.
2279
    ///
2280
    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2281
    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2282
    /// first `size_of::<T>() * count` bytes from `bytes` to construct a
2283
    /// `&[Self]`, and returns the remaining bytes to the caller. It also
2284
    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2285
    /// If any of the length, alignment, or overflow checks fail, it returns
2286
    /// `None`.
2287
    ///
2288
    /// # Panics
2289
    ///
2290
    /// If `T` is a zero-sized type.
2291
    ///
2292
    /// # Examples
2293
    ///
2294
    /// ```
2295
    /// use zerocopy::FromBytes;
2296
    /// # use zerocopy_derive::*;
2297
    ///
2298
    /// # #[derive(Debug, PartialEq, Eq)]
2299
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2300
    /// #[repr(C)]
2301
    /// struct Pixel {
2302
    ///     r: u8,
2303
    ///     g: u8,
2304
    ///     b: u8,
2305
    ///     a: u8,
2306
    /// }
2307
    ///
2308
    /// // These are more bytes than are needed to encode two `Pixel`s.
2309
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2310
    ///
2311
    /// let (pixels, rest) = Pixel::mut_slice_from_prefix(bytes, 2).unwrap();
2312
    ///
2313
    /// assert_eq!(pixels, &[
2314
    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2315
    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2316
    /// ]);
2317
    ///
2318
    /// assert_eq!(rest, &[8, 9]);
2319
    ///
2320
    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
2321
    ///
2322
    /// assert_eq!(bytes, [0, 1, 2, 3, 0, 0, 0, 0, 8, 9]);
2323
    /// ```
2324
    #[inline]
2325
0
    fn mut_slice_from_prefix(bytes: &mut [u8], count: usize) -> Option<(&mut [Self], &mut [u8])>
2326
0
    where
2327
0
        Self: Sized + AsBytes,
2328
0
    {
2329
0
        Ref::<_, [Self]>::new_slice_from_prefix(bytes, count).map(|(r, b)| (r.into_mut_slice(), b))
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefix0B7_
2330
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_prefixB5_
2331
2332
    /// Interprets the suffix of the given `bytes` as a `&mut [Self]` with length
2333
    /// equal to `count` without copying.
2334
    ///
2335
    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2336
    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2337
    /// last `size_of::<T>() * count` bytes from `bytes` to construct a
2338
    /// `&[Self]`, and returns the preceding bytes to the caller. It also
2339
    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2340
    /// If any of the length, alignment, or overflow checks fail, it returns
2341
    /// `None`.
2342
    ///
2343
    /// # Panics
2344
    ///
2345
    /// If `T` is a zero-sized type.
2346
    ///
2347
    /// # Examples
2348
    ///
2349
    /// ```
2350
    /// use zerocopy::FromBytes;
2351
    /// # use zerocopy_derive::*;
2352
    ///
2353
    /// # #[derive(Debug, PartialEq, Eq)]
2354
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2355
    /// #[repr(C)]
2356
    /// struct Pixel {
2357
    ///     r: u8,
2358
    ///     g: u8,
2359
    ///     b: u8,
2360
    ///     a: u8,
2361
    /// }
2362
    ///
2363
    /// // These are more bytes than are needed to encode two `Pixel`s.
2364
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2365
    ///
2366
    /// let (rest, pixels) = Pixel::mut_slice_from_suffix(bytes, 2).unwrap();
2367
    ///
2368
    /// assert_eq!(rest, &[0, 1]);
2369
    ///
2370
    /// assert_eq!(pixels, &[
2371
    ///     Pixel { r: 2, g: 3, b: 4, a: 5 },
2372
    ///     Pixel { r: 6, g: 7, b: 8, a: 9 },
2373
    /// ]);
2374
    ///
2375
    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
2376
    ///
2377
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0, 0, 0]);
2378
    /// ```
2379
    #[inline]
2380
0
    fn mut_slice_from_suffix(bytes: &mut [u8], count: usize) -> Option<(&mut [u8], &mut [Self])>
2381
0
    where
2382
0
        Self: Sized + AsBytes,
2383
0
    {
2384
0
        Ref::<_, [Self]>::new_slice_from_suffix(bytes, count).map(|(b, r)| (b, r.into_mut_slice()))
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffix0B7_
2385
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes21mut_slice_from_suffixB5_
2386
2387
    /// Reads a copy of `Self` from `bytes`.
2388
    ///
2389
    /// If `bytes.len() != size_of::<Self>()`, `read_from` returns `None`.
2390
    ///
2391
    /// # Examples
2392
    ///
2393
    /// ```
2394
    /// use zerocopy::FromBytes;
2395
    /// # use zerocopy_derive::*;
2396
    ///
2397
    /// #[derive(FromZeroes, FromBytes)]
2398
    /// #[repr(C)]
2399
    /// struct PacketHeader {
2400
    ///     src_port: [u8; 2],
2401
    ///     dst_port: [u8; 2],
2402
    ///     length: [u8; 2],
2403
    ///     checksum: [u8; 2],
2404
    /// }
2405
    ///
2406
    /// // These bytes encode a `PacketHeader`.
2407
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7].as_slice();
2408
    ///
2409
    /// let header = PacketHeader::read_from(bytes).unwrap();
2410
    ///
2411
    /// assert_eq!(header.src_port, [0, 1]);
2412
    /// assert_eq!(header.dst_port, [2, 3]);
2413
    /// assert_eq!(header.length, [4, 5]);
2414
    /// assert_eq!(header.checksum, [6, 7]);
2415
    /// ```
2416
    #[inline]
2417
0
    fn read_from(bytes: &[u8]) -> Option<Self>
2418
0
    where
2419
0
        Self: Sized,
2420
0
    {
2421
0
        Ref::<_, Unalign<Self>>::new_unaligned(bytes).map(|r| r.read().into_inner())
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes9read_from0B7_
2422
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes9read_fromB5_
2423
2424
    /// Reads a copy of `Self` from the prefix of `bytes`.
2425
    ///
2426
    /// `read_from_prefix` reads a `Self` from the first `size_of::<Self>()`
2427
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()`, it returns
2428
    /// `None`.
2429
    ///
2430
    /// # Examples
2431
    ///
2432
    /// ```
2433
    /// use zerocopy::FromBytes;
2434
    /// # use zerocopy_derive::*;
2435
    ///
2436
    /// #[derive(FromZeroes, FromBytes)]
2437
    /// #[repr(C)]
2438
    /// struct PacketHeader {
2439
    ///     src_port: [u8; 2],
2440
    ///     dst_port: [u8; 2],
2441
    ///     length: [u8; 2],
2442
    ///     checksum: [u8; 2],
2443
    /// }
2444
    ///
2445
    /// // These are more bytes than are needed to encode a `PacketHeader`.
2446
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2447
    ///
2448
    /// let header = PacketHeader::read_from_prefix(bytes).unwrap();
2449
    ///
2450
    /// assert_eq!(header.src_port, [0, 1]);
2451
    /// assert_eq!(header.dst_port, [2, 3]);
2452
    /// assert_eq!(header.length, [4, 5]);
2453
    /// assert_eq!(header.checksum, [6, 7]);
2454
    /// ```
2455
    #[inline]
2456
0
    fn read_from_prefix(bytes: &[u8]) -> Option<Self>
2457
0
    where
2458
0
        Self: Sized,
2459
0
    {
2460
0
        Ref::<_, Unalign<Self>>::new_unaligned_from_prefix(bytes)
2461
0
            .map(|(r, _)| r.read().into_inner())
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefix0B7_
2462
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_prefixB5_
2463
2464
    /// Reads a copy of `Self` from the suffix of `bytes`.
2465
    ///
2466
    /// `read_from_suffix` reads a `Self` from the last `size_of::<Self>()`
2467
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()`, it returns
2468
    /// `None`.
2469
    ///
2470
    /// # Examples
2471
    ///
2472
    /// ```
2473
    /// use zerocopy::FromBytes;
2474
    /// # use zerocopy_derive::*;
2475
    ///
2476
    /// #[derive(FromZeroes, FromBytes)]
2477
    /// #[repr(C)]
2478
    /// struct PacketTrailer {
2479
    ///     frame_check_sequence: [u8; 4],
2480
    /// }
2481
    ///
2482
    /// // These are more bytes than are needed to encode a `PacketTrailer`.
2483
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2484
    ///
2485
    /// let trailer = PacketTrailer::read_from_suffix(bytes).unwrap();
2486
    ///
2487
    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
2488
    /// ```
2489
    #[inline]
2490
0
    fn read_from_suffix(bytes: &[u8]) -> Option<Self>
2491
0
    where
2492
0
        Self: Sized,
2493
0
    {
2494
0
        Ref::<_, Unalign<Self>>::new_unaligned_from_suffix(bytes)
2495
0
            .map(|(_, r)| r.read().into_inner())
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB9_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B1f_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0BR_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0BS_
Unexecuted instantiation: _RNCNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0BS_
Unexecuted instantiation: _RNCNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
Unexecuted instantiation: _RNCNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffix0B7_
2496
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB1d_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy9FromBytes16read_from_suffixB5_
2497
}
2498
2499
/// Analyzes whether a type is [`AsBytes`].
2500
///
2501
/// This derive analyzes, at compile time, whether the annotated type satisfies
2502
/// the [safety conditions] of `AsBytes` and implements `AsBytes` if it is
2503
/// sound to do so. This derive can be applied to structs, enums, and unions;
2504
/// e.g.:
2505
///
2506
/// ```
2507
/// # use zerocopy_derive::{AsBytes};
2508
/// #[derive(AsBytes)]
2509
/// #[repr(C)]
2510
/// struct MyStruct {
2511
/// # /*
2512
///     ...
2513
/// # */
2514
/// }
2515
///
2516
/// #[derive(AsBytes)]
2517
/// #[repr(u8)]
2518
/// enum MyEnum {
2519
/// #   Variant,
2520
/// # /*
2521
///     ...
2522
/// # */
2523
/// }
2524
///
2525
/// #[derive(AsBytes)]
2526
/// #[repr(C)]
2527
/// union MyUnion {
2528
/// #   variant: u8,
2529
/// # /*
2530
///     ...
2531
/// # */
2532
/// }
2533
/// ```
2534
///
2535
/// [safety conditions]: trait@AsBytes#safety
2536
///
2537
/// # Error Messages
2538
///
2539
/// Due to the way that the custom derive for `AsBytes` is implemented, you may
2540
/// get an error like this:
2541
///
2542
/// ```text
2543
/// error[E0277]: the trait bound `HasPadding<Foo, true>: ShouldBe<false>` is not satisfied
2544
///   --> lib.rs:23:10
2545
///    |
2546
///  1 | #[derive(AsBytes)]
2547
///    |          ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<Foo, true>`
2548
///    |
2549
///    = help: the trait `ShouldBe<VALUE>` is implemented for `HasPadding<T, VALUE>`
2550
/// ```
2551
///
2552
/// This error indicates that the type being annotated has padding bytes, which
2553
/// is illegal for `AsBytes` types. Consider reducing the alignment of some
2554
/// fields by using types in the [`byteorder`] module, adding explicit struct
2555
/// fields where those padding bytes would be, or using `#[repr(packed)]`. See
2556
/// the Rust Reference's page on [type layout] for more information
2557
/// about type layout and padding.
2558
///
2559
/// [type layout]: https://doc.rust-lang.org/reference/type-layout.html
2560
///
2561
/// # Analysis
2562
///
2563
/// *This section describes, roughly, the analysis performed by this derive to
2564
/// determine whether it is sound to implement `AsBytes` for a given type.
2565
/// Unless you are modifying the implementation of this derive, or attempting to
2566
/// manually implement `AsBytes` for a type yourself, you don't need to read
2567
/// this section.*
2568
///
2569
/// If a type has the following properties, then this derive can implement
2570
/// `AsBytes` for that type:
2571
///
2572
/// - If the type is a struct:
2573
///   - It must have a defined representation (`repr(C)`, `repr(transparent)`,
2574
///     or `repr(packed)`).
2575
///   - All of its fields must be `AsBytes`.
2576
///   - Its layout must have no padding. This is always true for
2577
///     `repr(transparent)` and `repr(packed)`. For `repr(C)`, see the layout
2578
///     algorithm described in the [Rust Reference].
2579
/// - If the type is an enum:
2580
///   - It must be a C-like enum (meaning that all variants have no fields).
2581
///   - It must have a defined representation (`repr`s `C`, `u8`, `u16`, `u32`,
2582
///     `u64`, `usize`, `i8`, `i16`, `i32`, `i64`, or `isize`).
2583
/// - The type must not contain any [`UnsafeCell`]s (this is required in order
2584
///   for it to be sound to construct a `&[u8]` and a `&T` to the same region of
2585
///   memory). The type may contain references or pointers to `UnsafeCell`s so
2586
///   long as those values can themselves be initialized from zeroes (`AsBytes`
2587
///   is not currently implemented for, e.g., `Option<&UnsafeCell<_>>`, but it
2588
///   could be one day).
2589
///
2590
/// [`UnsafeCell`]: core::cell::UnsafeCell
2591
///
2592
/// This analysis is subject to change. Unsafe code may *only* rely on the
2593
/// documented [safety conditions] of `FromBytes`, and must *not* rely on the
2594
/// implementation details of this derive.
2595
///
2596
/// [Rust Reference]: https://doc.rust-lang.org/reference/type-layout.html
2597
#[cfg(any(feature = "derive", test))]
2598
#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
2599
pub use zerocopy_derive::AsBytes;
2600
2601
/// Types that can be viewed as an immutable slice of initialized bytes.
2602
///
2603
/// Any `AsBytes` type can be viewed as a slice of initialized bytes of the same
2604
/// size. This is useful for efficiently serializing structured data as raw
2605
/// bytes.
2606
///
2607
/// # Implementation
2608
///
2609
/// **Do not implement this trait yourself!** Instead, use
2610
/// [`#[derive(AsBytes)]`][derive] (requires the `derive` Cargo feature); e.g.:
2611
///
2612
/// ```
2613
/// # use zerocopy_derive::AsBytes;
2614
/// #[derive(AsBytes)]
2615
/// #[repr(C)]
2616
/// struct MyStruct {
2617
/// # /*
2618
///     ...
2619
/// # */
2620
/// }
2621
///
2622
/// #[derive(AsBytes)]
2623
/// #[repr(u8)]
2624
/// enum MyEnum {
2625
/// #   Variant0,
2626
/// # /*
2627
///     ...
2628
/// # */
2629
/// }
2630
///
2631
/// #[derive(AsBytes)]
2632
/// #[repr(C)]
2633
/// union MyUnion {
2634
/// #   variant: u8,
2635
/// # /*
2636
///     ...
2637
/// # */
2638
/// }
2639
/// ```
2640
///
2641
/// This derive performs a sophisticated, compile-time safety analysis to
2642
/// determine whether a type is `AsBytes`. See the [derive
2643
/// documentation][derive] for guidance on how to interpret error messages
2644
/// produced by the derive's analysis.
2645
///
2646
/// # Safety
2647
///
2648
/// *This section describes what is required in order for `T: AsBytes`, and
2649
/// what unsafe code may assume of such types. If you don't plan on implementing
2650
/// `AsBytes` manually, and you don't plan on writing unsafe code that
2651
/// operates on `AsBytes` types, then you don't need to read this section.*
2652
///
2653
/// If `T: AsBytes`, then unsafe code may assume that:
2654
/// - It is sound to treat any `t: T` as an immutable `[u8]` of length
2655
///   `size_of_val(t)`.
2656
/// - Given `t: &T`, it is sound to construct a `b: &[u8]` where `b.len() ==
2657
///   size_of_val(t)` at the same address as `t`, and it is sound for both `b`
2658
///   and `t` to be live at the same time.
2659
///
2660
/// If a type is marked as `AsBytes` which violates this contract, it may cause
2661
/// undefined behavior.
2662
///
2663
/// `#[derive(AsBytes)]` only permits [types which satisfy these
2664
/// requirements][derive-analysis].
2665
///
2666
#[cfg_attr(
2667
    feature = "derive",
2668
    doc = "[derive]: zerocopy_derive::AsBytes",
2669
    doc = "[derive-analysis]: zerocopy_derive::AsBytes#analysis"
2670
)]
2671
#[cfg_attr(
2672
    not(feature = "derive"),
2673
    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.AsBytes.html"),
2674
    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.AsBytes.html#analysis"),
2675
)]
2676
pub unsafe trait AsBytes {
2677
    // The `Self: Sized` bound makes it so that this function doesn't prevent
2678
    // `AsBytes` from being object safe. Note that other `AsBytes` methods
2679
    // prevent object safety, but those provide a benefit in exchange for object
2680
    // safety. If at some point we remove those methods, change their type
2681
    // signatures, or move them out of this trait so that `AsBytes` is object
2682
    // safe again, it's important that this function not prevent object safety.
2683
    #[doc(hidden)]
2684
    fn only_derive_is_allowed_to_implement_this_trait()
2685
    where
2686
        Self: Sized;
2687
2688
    /// Gets the bytes of this value.
2689
    ///
2690
    /// `as_bytes` provides access to the bytes of this value as an immutable
2691
    /// byte slice.
2692
    ///
2693
    /// # Examples
2694
    ///
2695
    /// ```
2696
    /// use zerocopy::AsBytes;
2697
    /// # use zerocopy_derive::*;
2698
    ///
2699
    /// #[derive(AsBytes)]
2700
    /// #[repr(C)]
2701
    /// struct PacketHeader {
2702
    ///     src_port: [u8; 2],
2703
    ///     dst_port: [u8; 2],
2704
    ///     length: [u8; 2],
2705
    ///     checksum: [u8; 2],
2706
    /// }
2707
    ///
2708
    /// let header = PacketHeader {
2709
    ///     src_port: [0, 1],
2710
    ///     dst_port: [2, 3],
2711
    ///     length: [4, 5],
2712
    ///     checksum: [6, 7],
2713
    /// };
2714
    ///
2715
    /// let bytes = header.as_bytes();
2716
    ///
2717
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
2718
    /// ```
2719
    #[inline(always)]
2720
0
    fn as_bytes(&self) -> &[u8] {
2721
0
        // Note that this method does not have a `Self: Sized` bound;
2722
0
        // `size_of_val` works for unsized values too.
2723
0
        let len = mem::size_of_val(self);
2724
0
        let slf: *const Self = self;
2725
0
2726
0
        // SAFETY:
2727
0
        // - `slf.cast::<u8>()` is valid for reads for `len *
2728
0
        //   mem::size_of::<u8>()` many bytes because...
2729
0
        //   - `slf` is the same pointer as `self`, and `self` is a reference
2730
0
        //     which points to an object whose size is `len`. Thus...
2731
0
        //     - The entire region of `len` bytes starting at `slf` is contained
2732
0
        //       within a single allocation.
2733
0
        //     - `slf` is non-null.
2734
0
        //   - `slf` is trivially aligned to `align_of::<u8>() == 1`.
2735
0
        // - `Self: AsBytes` ensures that all of the bytes of `slf` are
2736
0
        //   initialized.
2737
0
        // - Since `slf` is derived from `self`, and `self` is an immutable
2738
0
        //   reference, the only other references to this memory region that
2739
0
        //   could exist are other immutable references, and those don't allow
2740
0
        //   mutation. `AsBytes` prohibits types which contain `UnsafeCell`s,
2741
0
        //   which are the only types for which this rule wouldn't be sufficient.
2742
0
        // - The total size of the resulting slice is no larger than
2743
0
        //   `isize::MAX` because no allocation produced by safe code can be
2744
0
        //   larger than `isize::MAX`.
2745
0
        //
2746
0
        // TODO(#429): Add references to docs and quotes.
2747
0
        unsafe { slice::from_raw_parts(slf.cast::<u8>(), len) }
2748
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB1d_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYbNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYcNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYeNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy7AsBytes8as_bytesB5_
2749
2750
    /// Gets the bytes of this value mutably.
2751
    ///
2752
    /// `as_bytes_mut` provides access to the bytes of this value as a mutable
2753
    /// byte slice.
2754
    ///
2755
    /// # Examples
2756
    ///
2757
    /// ```
2758
    /// use zerocopy::AsBytes;
2759
    /// # use zerocopy_derive::*;
2760
    ///
2761
    /// # #[derive(Eq, PartialEq, Debug)]
2762
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2763
    /// #[repr(C)]
2764
    /// struct PacketHeader {
2765
    ///     src_port: [u8; 2],
2766
    ///     dst_port: [u8; 2],
2767
    ///     length: [u8; 2],
2768
    ///     checksum: [u8; 2],
2769
    /// }
2770
    ///
2771
    /// let mut header = PacketHeader {
2772
    ///     src_port: [0, 1],
2773
    ///     dst_port: [2, 3],
2774
    ///     length: [4, 5],
2775
    ///     checksum: [6, 7],
2776
    /// };
2777
    ///
2778
    /// let bytes = header.as_bytes_mut();
2779
    ///
2780
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
2781
    ///
2782
    /// bytes.reverse();
2783
    ///
2784
    /// assert_eq!(header, PacketHeader {
2785
    ///     src_port: [7, 6],
2786
    ///     dst_port: [5, 4],
2787
    ///     length: [3, 2],
2788
    ///     checksum: [1, 0],
2789
    /// });
2790
    /// ```
2791
    #[inline(always)]
2792
    fn as_bytes_mut(&mut self) -> &mut [u8]
2793
    where
2794
        Self: FromBytes,
2795
    {
2796
        // Note that this method does not have a `Self: Sized` bound;
2797
        // `size_of_val` works for unsized values too.
2798
        let len = mem::size_of_val(self);
2799
        let slf: *mut Self = self;
2800
2801
        // SAFETY:
2802
        // - `slf.cast::<u8>()` is valid for reads and writes for `len *
2803
        //   mem::size_of::<u8>()` many bytes because...
2804
        //   - `slf` is the same pointer as `self`, and `self` is a reference
2805
        //     which points to an object whose size is `len`. Thus...
2806
        //     - The entire region of `len` bytes starting at `slf` is contained
2807
        //       within a single allocation.
2808
        //     - `slf` is non-null.
2809
        //   - `slf` is trivially aligned to `align_of::<u8>() == 1`.
2810
        // - `Self: AsBytes` ensures that all of the bytes of `slf` are
2811
        //   initialized.
2812
        // - `Self: FromBytes` ensures that no write to this memory region
2813
        //   could result in it containing an invalid `Self`.
2814
        // - Since `slf` is derived from `self`, and `self` is a mutable
2815
        //   reference, no other references to this memory region can exist.
2816
        // - The total size of the resulting slice is no larger than
2817
        //   `isize::MAX` because no allocation produced by safe code can be
2818
        //   larger than `isize::MAX`.
2819
        //
2820
        // TODO(#429): Add references to docs and quotes.
2821
        unsafe { slice::from_raw_parts_mut(slf.cast::<u8>(), len) }
2822
    }
2823
2824
    /// Writes a copy of `self` to `bytes`.
2825
    ///
2826
    /// If `bytes.len() != size_of_val(self)`, `write_to` returns `None`.
2827
    ///
2828
    /// # Examples
2829
    ///
2830
    /// ```
2831
    /// use zerocopy::AsBytes;
2832
    /// # use zerocopy_derive::*;
2833
    ///
2834
    /// #[derive(AsBytes)]
2835
    /// #[repr(C)]
2836
    /// struct PacketHeader {
2837
    ///     src_port: [u8; 2],
2838
    ///     dst_port: [u8; 2],
2839
    ///     length: [u8; 2],
2840
    ///     checksum: [u8; 2],
2841
    /// }
2842
    ///
2843
    /// let header = PacketHeader {
2844
    ///     src_port: [0, 1],
2845
    ///     dst_port: [2, 3],
2846
    ///     length: [4, 5],
2847
    ///     checksum: [6, 7],
2848
    /// };
2849
    ///
2850
    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0];
2851
    ///
2852
    /// header.write_to(&mut bytes[..]);
2853
    ///
2854
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
2855
    /// ```
2856
    ///
2857
    /// If too many or too few target bytes are provided, `write_to` returns
2858
    /// `None` and leaves the target bytes unmodified:
2859
    ///
2860
    /// ```
2861
    /// # use zerocopy::AsBytes;
2862
    /// # let header = u128::MAX;
2863
    /// let mut excessive_bytes = &mut [0u8; 128][..];
2864
    ///
2865
    /// let write_result = header.write_to(excessive_bytes);
2866
    ///
2867
    /// assert!(write_result.is_none());
2868
    /// assert_eq!(excessive_bytes, [0u8; 128]);
2869
    /// ```
2870
    #[inline]
2871
0
    fn write_to(&self, bytes: &mut [u8]) -> Option<()> {
2872
0
        if bytes.len() != mem::size_of_val(self) {
2873
0
            return None;
2874
0
        }
2875
0
2876
0
        bytes.copy_from_slice(self.as_bytes());
2877
0
        Some(())
2878
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB1d_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYbNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYcNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYeNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy7AsBytes8write_toB5_
2879
2880
    /// Writes a copy of `self` to the prefix of `bytes`.
2881
    ///
2882
    /// `write_to_prefix` writes `self` to the first `size_of_val(self)` bytes
2883
    /// of `bytes`. If `bytes.len() < size_of_val(self)`, it returns `None`.
2884
    ///
2885
    /// # Examples
2886
    ///
2887
    /// ```
2888
    /// use zerocopy::AsBytes;
2889
    /// # use zerocopy_derive::*;
2890
    ///
2891
    /// #[derive(AsBytes)]
2892
    /// #[repr(C)]
2893
    /// struct PacketHeader {
2894
    ///     src_port: [u8; 2],
2895
    ///     dst_port: [u8; 2],
2896
    ///     length: [u8; 2],
2897
    ///     checksum: [u8; 2],
2898
    /// }
2899
    ///
2900
    /// let header = PacketHeader {
2901
    ///     src_port: [0, 1],
2902
    ///     dst_port: [2, 3],
2903
    ///     length: [4, 5],
2904
    ///     checksum: [6, 7],
2905
    /// };
2906
    ///
2907
    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2908
    ///
2909
    /// header.write_to_prefix(&mut bytes[..]);
2910
    ///
2911
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7, 0, 0]);
2912
    /// ```
2913
    ///
2914
    /// If insufficient target bytes are provided, `write_to_prefix` returns
2915
    /// `None` and leaves the target bytes unmodified:
2916
    ///
2917
    /// ```
2918
    /// # use zerocopy::AsBytes;
2919
    /// # let header = u128::MAX;
2920
    /// let mut insufficent_bytes = &mut [0, 0][..];
2921
    ///
2922
    /// let write_result = header.write_to_suffix(insufficent_bytes);
2923
    ///
2924
    /// assert!(write_result.is_none());
2925
    /// assert_eq!(insufficent_bytes, [0, 0]);
2926
    /// ```
2927
    #[inline]
2928
0
    fn write_to_prefix(&self, bytes: &mut [u8]) -> Option<()> {
2929
0
        let size = mem::size_of_val(self);
2930
0
        bytes.get_mut(..size)?.copy_from_slice(self.as_bytes());
2931
0
        Some(())
2932
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB1d_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYbNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYcNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYeNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_prefixB5_
2933
2934
    /// Writes a copy of `self` to the suffix of `bytes`.
2935
    ///
2936
    /// `write_to_suffix` writes `self` to the last `size_of_val(self)` bytes of
2937
    /// `bytes`. If `bytes.len() < size_of_val(self)`, it returns `None`.
2938
    ///
2939
    /// # Examples
2940
    ///
2941
    /// ```
2942
    /// use zerocopy::AsBytes;
2943
    /// # use zerocopy_derive::*;
2944
    ///
2945
    /// #[derive(AsBytes)]
2946
    /// #[repr(C)]
2947
    /// struct PacketHeader {
2948
    ///     src_port: [u8; 2],
2949
    ///     dst_port: [u8; 2],
2950
    ///     length: [u8; 2],
2951
    ///     checksum: [u8; 2],
2952
    /// }
2953
    ///
2954
    /// let header = PacketHeader {
2955
    ///     src_port: [0, 1],
2956
    ///     dst_port: [2, 3],
2957
    ///     length: [4, 5],
2958
    ///     checksum: [6, 7],
2959
    /// };
2960
    ///
2961
    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2962
    ///
2963
    /// header.write_to_suffix(&mut bytes[..]);
2964
    ///
2965
    /// assert_eq!(bytes, [0, 0, 0, 1, 2, 3, 4, 5, 6, 7]);
2966
    ///
2967
    /// let mut insufficent_bytes = &mut [0, 0][..];
2968
    ///
2969
    /// let write_result = header.write_to_suffix(insufficent_bytes);
2970
    ///
2971
    /// assert!(write_result.is_none());
2972
    /// assert_eq!(insufficent_bytes, [0, 0]);
2973
    /// ```
2974
    ///
2975
    /// If insufficient target bytes are provided, `write_to_suffix` returns
2976
    /// `None` and leaves the target bytes unmodified:
2977
    ///
2978
    /// ```
2979
    /// # use zerocopy::AsBytes;
2980
    /// # let header = u128::MAX;
2981
    /// let mut insufficent_bytes = &mut [0, 0][..];
2982
    ///
2983
    /// let write_result = header.write_to_suffix(insufficent_bytes);
2984
    ///
2985
    /// assert!(write_result.is_none());
2986
    /// assert_eq!(insufficent_bytes, [0, 0]);
2987
    /// ```
2988
    #[inline]
2989
0
    fn write_to_suffix(&self, bytes: &mut [u8]) -> Option<()> {
2990
0
        let start = bytes.len().checked_sub(mem::size_of_val(self))?;
2991
0
        bytes
2992
0
            .get_mut(start..)
2993
0
            .expect("`start` should be in-bounds of `bytes`")
2994
0
            .copy_from_slice(self.as_bytes());
2995
0
        Some(())
2996
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroaEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerohEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroiEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerojEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerolEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeromEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeronEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerooEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerosEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZerotEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroxEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB7_3num7nonzero7NonZeroyEENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB1d_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBP_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixBQ_
Unexecuted instantiation: _RNvYaNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYbNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYcNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYdNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYeNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYfNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYhNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYiNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYjNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYlNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYmNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYnNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYoNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYsNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYtNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYuNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYxNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
Unexecuted instantiation: _RNvYyNtCsiAAEnE8327y_8zerocopy7AsBytes15write_to_suffixB5_
2997
}
2998
2999
/// Types with no alignment requirement.
3000
///
3001
/// WARNING: Do not implement this trait yourself! Instead, use
3002
/// `#[derive(Unaligned)]` (requires the `derive` Cargo feature).
3003
///
3004
/// If `T: Unaligned`, then `align_of::<T>() == 1`.
3005
///
3006
/// # Safety
3007
///
3008
/// *This section describes what is required in order for `T: Unaligned`, and
3009
/// what unsafe code may assume of such types. `#[derive(Unaligned)]` only
3010
/// permits types which satisfy these requirements. If you don't plan on
3011
/// implementing `Unaligned` manually, and you don't plan on writing unsafe code
3012
/// that operates on `Unaligned` types, then you don't need to read this
3013
/// section.*
3014
///
3015
/// If `T: Unaligned`, then unsafe code may assume that it is sound to produce a
3016
/// reference to `T` at any memory location regardless of alignment. If a type
3017
/// is marked as `Unaligned` which violates this contract, it may cause
3018
/// undefined behavior.
3019
pub unsafe trait Unaligned {
3020
    // The `Self: Sized` bound makes it so that `Unaligned` is still object
3021
    // safe.
3022
    #[doc(hidden)]
3023
    fn only_derive_is_allowed_to_implement_this_trait()
3024
    where
3025
        Self: Sized;
3026
}
3027
3028
safety_comment! {
3029
    /// SAFETY:
3030
    /// Per the reference [1], "the unit tuple (`()`) ... is guaranteed as a
3031
    /// zero-sized type to have a size of 0 and an alignment of 1."
3032
    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`: There
3033
    ///   is only one possible sequence of 0 bytes, and `()` is inhabited.
3034
    /// - `AsBytes`: Since `()` has size 0, it contains no padding bytes.
3035
    /// - `Unaligned`: `()` has alignment 1.
3036
    ///
3037
    /// [1] https://doc.rust-lang.org/reference/type-layout.html#tuple-layout
3038
    unsafe_impl!((): TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3039
    assert_unaligned!(());
3040
}
3041
3042
safety_comment! {
3043
    /// SAFETY:
3044
    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`: all bit
3045
    ///   patterns are valid for numeric types [1]
3046
    /// - `AsBytes`: numeric types have no padding bytes [1]
3047
    /// - `Unaligned` (`u8` and `i8` only): The reference [2] specifies the size
3048
    ///   of `u8` and `i8` as 1 byte. We also know that:
3049
    ///   - Alignment is >= 1 [3]
3050
    ///   - Size is an integer multiple of alignment [4]
3051
    ///   - The only value >= 1 for which 1 is an integer multiple is 1
3052
    ///   Therefore, the only possible alignment for `u8` and `i8` is 1.
3053
    ///
3054
    /// [1] Per https://doc.rust-lang.org/beta/reference/types/numeric.html#bit-validity:
3055
    ///
3056
    ///     For every numeric type, `T`, the bit validity of `T` is equivalent to
3057
    ///     the bit validity of `[u8; size_of::<T>()]`. An uninitialized byte is
3058
    ///     not a valid `u8`.
3059
    ///
3060
    /// TODO(https://github.com/rust-lang/reference/pull/1392): Once this text
3061
    /// is available on the Stable docs, cite those instead.
3062
    ///
3063
    /// [2] https://doc.rust-lang.org/reference/type-layout.html#primitive-data-layout
3064
    ///
3065
    /// [3] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
3066
    ///
3067
    ///     Alignment is measured in bytes, and must be at least 1.
3068
    ///
3069
    /// [4] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
3070
    ///
3071
    ///     The size of a value is always a multiple of its alignment.
3072
    ///
3073
    /// TODO(#278): Once we've updated the trait docs to refer to `u8`s rather
3074
    /// than bits or bytes, update this comment, especially the reference to
3075
    /// [1].
3076
    unsafe_impl!(u8: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3077
    unsafe_impl!(i8: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3078
    assert_unaligned!(u8, i8);
3079
    unsafe_impl!(u16: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3080
    unsafe_impl!(i16: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3081
    unsafe_impl!(u32: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3082
    unsafe_impl!(i32: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3083
    unsafe_impl!(u64: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3084
    unsafe_impl!(i64: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3085
    unsafe_impl!(u128: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3086
    unsafe_impl!(i128: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3087
    unsafe_impl!(usize: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3088
    unsafe_impl!(isize: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3089
    unsafe_impl!(f32: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3090
    unsafe_impl!(f64: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3091
}
3092
3093
safety_comment! {
3094
    /// SAFETY:
3095
    /// - `FromZeroes`: Valid since "[t]he value false has the bit pattern
3096
    ///   0x00" [1].
3097
    /// - `AsBytes`: Since "the boolean type has a size and alignment of 1 each"
3098
    ///   and "The value false has the bit pattern 0x00 and the value true has
3099
    ///   the bit pattern 0x01" [1]. Thus, the only byte of the bool is always
3100
    ///   initialized.
3101
    /// - `Unaligned`: Per the reference [1], "[a]n object with the boolean type
3102
    ///   has a size and alignment of 1 each."
3103
    ///
3104
    /// [1] https://doc.rust-lang.org/reference/types/boolean.html
3105
    unsafe_impl!(bool: FromZeroes, AsBytes, Unaligned);
3106
    assert_unaligned!(bool);
3107
    /// SAFETY:
3108
    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3109
    ///   closure:
3110
    ///   - Given `t: *mut bool` and `let r = *mut u8`, `r` refers to an object
3111
    ///     of the same size as that referred to by `t`. This is true because
3112
    ///     `bool` and `u8` have the same size (1 byte) [1].
3113
    ///   - Since the closure takes a `&u8` argument, given a `Ptr<'a, bool>`
3114
    ///     which satisfies the preconditions of
3115
    ///     `TryFromBytes::<bool>::is_bit_valid`, it must be guaranteed that the
3116
    ///     memory referenced by that `Ptr` always contains a valid `u8`. Since
3117
    ///     `bool`'s single byte is always initialized, `is_bit_valid`'s
3118
    ///     precondition requires that the same is true of its argument. Since
3119
    ///     `u8`'s only bit validity invariant is that its single byte must be
3120
    ///     initialized, this memory is guaranteed to contain a valid `u8`.
3121
    ///   - The alignment of `bool` is equal to the alignment of `u8`. [1] [2]
3122
    ///   - The impl must only return `true` for its argument if the original
3123
    ///     `Ptr<bool>` refers to a valid `bool`. We only return true if the
3124
    ///     `u8` value is 0 or 1, and both of these are valid values for `bool`.
3125
    ///     [3]
3126
    ///
3127
    /// [1] Per https://doc.rust-lang.org/reference/type-layout.html#primitive-data-layout:
3128
    ///
3129
    ///   The size of most primitives is given in this table.
3130
    ///
3131
    ///   | Type      | `size_of::<Type>() ` |
3132
    ///   |-----------|----------------------|
3133
    ///   | `bool`    | 1                    |
3134
    ///   | `u8`/`i8` | 1                    |
3135
    ///
3136
    /// [2] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
3137
    ///
3138
    ///   The size of a value is always a multiple of its alignment.
3139
    ///
3140
    /// [3] Per https://doc.rust-lang.org/reference/types/boolean.html:
3141
    ///
3142
    ///   The value false has the bit pattern 0x00 and the value true has the
3143
    ///   bit pattern 0x01.
3144
    unsafe_impl!(bool: TryFromBytes; |byte: &u8| *byte < 2);
3145
}
3146
safety_comment! {
3147
    /// SAFETY:
3148
    /// - `FromZeroes`: Per reference [1], "[a] value of type char is a Unicode
3149
    ///   scalar value (i.e. a code point that is not a surrogate), represented
3150
    ///   as a 32-bit unsigned word in the 0x0000 to 0xD7FF or 0xE000 to
3151
    ///   0x10FFFF range" which contains 0x0000.
3152
    /// - `AsBytes`: `char` is per reference [1] "represented as a 32-bit
3153
    ///   unsigned word" (`u32`) which is `AsBytes`. Note that unlike `u32`, not
3154
    ///   all bit patterns are valid for `char`.
3155
    ///
3156
    /// [1] https://doc.rust-lang.org/reference/types/textual.html
3157
    unsafe_impl!(char: FromZeroes, AsBytes);
3158
    /// SAFETY:
3159
    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3160
    ///   closure:
3161
    ///   - Given `t: *mut char` and `let r = *mut u32`, `r` refers to an object
3162
    ///     of the same size as that referred to by `t`. This is true because
3163
    ///     `char` and `u32` have the same size [1].
3164
    ///   - Since the closure takes a `&u32` argument, given a `Ptr<'a, char>`
3165
    ///     which satisfies the preconditions of
3166
    ///     `TryFromBytes::<char>::is_bit_valid`, it must be guaranteed that the
3167
    ///     memory referenced by that `Ptr` always contains a valid `u32`. Since
3168
    ///     `char`'s bytes are always initialized [2], `is_bit_valid`'s
3169
    ///     precondition requires that the same is true of its argument. Since
3170
    ///     `u32`'s only bit validity invariant is that its bytes must be
3171
    ///     initialized, this memory is guaranteed to contain a valid `u32`.
3172
    ///   - The alignment of `char` is equal to the alignment of `u32`. [1]
3173
    ///   - The impl must only return `true` for its argument if the original
3174
    ///     `Ptr<char>` refers to a valid `char`. `char::from_u32` guarantees
3175
    ///     that it returns `None` if its input is not a valid `char`. [3]
3176
    ///
3177
    /// [1] Per https://doc.rust-lang.org/nightly/reference/types/textual.html#layout-and-bit-validity:
3178
    ///
3179
    ///   `char` is guaranteed to have the same size and alignment as `u32` on
3180
    ///   all platforms.
3181
    ///
3182
    /// [2] Per https://doc.rust-lang.org/core/primitive.char.html#method.from_u32:
3183
    ///
3184
    ///   Every byte of a `char` is guaranteed to be initialized.
3185
    ///
3186
    /// [3] Per https://doc.rust-lang.org/core/primitive.char.html#method.from_u32:
3187
    ///
3188
    ///   `from_u32()` will return `None` if the input is not a valid value for
3189
    ///   a `char`.
3190
    unsafe_impl!(char: TryFromBytes; |candidate: &u32| char::from_u32(*candidate).is_some());
3191
}
3192
safety_comment! {
3193
    /// SAFETY:
3194
    /// - `FromZeroes`, `AsBytes`, `Unaligned`: Per the reference [1], `str`
3195
    ///   has the same layout as `[u8]`, and `[u8]` is `FromZeroes`, `AsBytes`,
3196
    ///   and `Unaligned`.
3197
    ///
3198
    /// Note that we don't `assert_unaligned!(str)` because `assert_unaligned!`
3199
    /// uses `align_of`, which only works for `Sized` types.
3200
    ///
3201
    /// TODO(#429): Add quotes from documentation.
3202
    ///
3203
    /// [1] https://doc.rust-lang.org/reference/type-layout.html#str-layout
3204
    unsafe_impl!(str: FromZeroes, AsBytes, Unaligned);
3205
    /// SAFETY:
3206
    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3207
    ///   closure:
3208
    ///   - Given `t: *mut str` and `let r = *mut [u8]`, `r` refers to an object
3209
    ///     of the same size as that referred to by `t`. This is true because
3210
    ///     `str` and `[u8]` have the same representation. [1]
3211
    ///   - Since the closure takes a `&[u8]` argument, given a `Ptr<'a, str>`
3212
    ///     which satisfies the preconditions of
3213
    ///     `TryFromBytes::<str>::is_bit_valid`, it must be guaranteed that the
3214
    ///     memory referenced by that `Ptr` always contains a valid `[u8]`.
3215
    ///     Since `str`'s bytes are always initialized [1], `is_bit_valid`'s
3216
    ///     precondition requires that the same is true of its argument. Since
3217
    ///     `[u8]`'s only bit validity invariant is that its bytes must be
3218
    ///     initialized, this memory is guaranteed to contain a valid `[u8]`.
3219
    ///   - The alignment of `str` is equal to the alignment of `[u8]`. [1]
3220
    ///   - The impl must only return `true` for its argument if the original
3221
    ///     `Ptr<str>` refers to a valid `str`. `str::from_utf8` guarantees that
3222
    ///     it returns `Err` if its input is not a valid `str`. [2]
3223
    ///
3224
    /// [1] Per https://doc.rust-lang.org/reference/types/textual.html:
3225
    ///
3226
    ///   A value of type `str` is represented the same was as `[u8]`.
3227
    ///
3228
    /// [2] Per https://doc.rust-lang.org/core/str/fn.from_utf8.html#errors:
3229
    ///
3230
    ///   Returns `Err` if the slice is not UTF-8.
3231
    unsafe_impl!(str: TryFromBytes; |candidate: &[u8]| core::str::from_utf8(candidate).is_ok());
3232
}
3233
3234
safety_comment! {
3235
    // `NonZeroXxx` is `AsBytes`, but not `FromZeroes` or `FromBytes`.
3236
    //
3237
    /// SAFETY:
3238
    /// - `AsBytes`: `NonZeroXxx` has the same layout as its associated
3239
    ///    primitive. Since it is the same size, this guarantees it has no
3240
    ///    padding - integers have no padding, and there's no room for padding
3241
    ///    if it can represent all of the same values except 0.
3242
    /// - `Unaligned`: `NonZeroU8` and `NonZeroI8` document that
3243
    ///   `Option<NonZeroU8>` and `Option<NonZeroI8>` both have size 1. [1] [2]
3244
    ///   This is worded in a way that makes it unclear whether it's meant as a
3245
    ///   guarantee, but given the purpose of those types, it's virtually
3246
    ///   unthinkable that that would ever change. `Option` cannot be smaller
3247
    ///   than its contained type, which implies that, and `NonZeroX8` are of
3248
    ///   size 1 or 0. `NonZeroX8` can represent multiple states, so they cannot
3249
    ///   be 0 bytes, which means that they must be 1 byte. The only valid
3250
    ///   alignment for a 1-byte type is 1.
3251
    ///
3252
    /// TODO(#429): Add quotes from documentation.
3253
    ///
3254
    /// [1] https://doc.rust-lang.org/stable/std/num/struct.NonZeroU8.html
3255
    /// [2] https://doc.rust-lang.org/stable/std/num/struct.NonZeroI8.html
3256
    /// TODO(https://github.com/rust-lang/rust/pull/104082): Cite documentation
3257
    /// that layout is the same as primitive layout.
3258
    unsafe_impl!(NonZeroU8: AsBytes, Unaligned);
3259
    unsafe_impl!(NonZeroI8: AsBytes, Unaligned);
3260
    assert_unaligned!(NonZeroU8, NonZeroI8);
3261
    unsafe_impl!(NonZeroU16: AsBytes);
3262
    unsafe_impl!(NonZeroI16: AsBytes);
3263
    unsafe_impl!(NonZeroU32: AsBytes);
3264
    unsafe_impl!(NonZeroI32: AsBytes);
3265
    unsafe_impl!(NonZeroU64: AsBytes);
3266
    unsafe_impl!(NonZeroI64: AsBytes);
3267
    unsafe_impl!(NonZeroU128: AsBytes);
3268
    unsafe_impl!(NonZeroI128: AsBytes);
3269
    unsafe_impl!(NonZeroUsize: AsBytes);
3270
    unsafe_impl!(NonZeroIsize: AsBytes);
3271
    /// SAFETY:
3272
    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3273
    ///   closure:
3274
    ///   - Given `t: *mut NonZeroXxx` and `let r = *mut xxx`, `r` refers to an
3275
    ///     object of the same size as that referred to by `t`. This is true
3276
    ///     because `NonZeroXxx` and `xxx` have the same size. [1]
3277
    ///   - Since the closure takes a `&xxx` argument, given a `Ptr<'a,
3278
    ///     NonZeroXxx>` which satisfies the preconditions of
3279
    ///     `TryFromBytes::<NonZeroXxx>::is_bit_valid`, it must be guaranteed
3280
    ///     that the memory referenced by that `Ptr` always contains a valid
3281
    ///     `xxx`. Since `NonZeroXxx`'s bytes are always initialized [1],
3282
    ///     `is_bit_valid`'s precondition requires that the same is true of its
3283
    ///     argument. Since `xxx`'s only bit validity invariant is that its
3284
    ///     bytes must be initialized, this memory is guaranteed to contain a
3285
    ///     valid `xxx`.
3286
    ///   - The alignment of `NonZeroXxx` is equal to the alignment of `xxx`.
3287
    ///     [1]
3288
    ///   - The impl must only return `true` for its argument if the original
3289
    ///     `Ptr<NonZeroXxx>` refers to a valid `NonZeroXxx`. The only `xxx`
3290
    ///     which is not also a valid `NonZeroXxx` is 0. [1]
3291
    ///
3292
    /// [1] Per https://doc.rust-lang.org/core/num/struct.NonZeroU16.html:
3293
    ///
3294
    ///   `NonZeroU16` is guaranteed to have the same layout and bit validity as
3295
    ///   `u16` with the exception that `0` is not a valid instance.
3296
    unsafe_impl!(NonZeroU8: TryFromBytes; |n: &u8| *n != 0);
3297
    unsafe_impl!(NonZeroI8: TryFromBytes; |n: &i8| *n != 0);
3298
    unsafe_impl!(NonZeroU16: TryFromBytes; |n: &u16| *n != 0);
3299
    unsafe_impl!(NonZeroI16: TryFromBytes; |n: &i16| *n != 0);
3300
    unsafe_impl!(NonZeroU32: TryFromBytes; |n: &u32| *n != 0);
3301
    unsafe_impl!(NonZeroI32: TryFromBytes; |n: &i32| *n != 0);
3302
    unsafe_impl!(NonZeroU64: TryFromBytes; |n: &u64| *n != 0);
3303
    unsafe_impl!(NonZeroI64: TryFromBytes; |n: &i64| *n != 0);
3304
    unsafe_impl!(NonZeroU128: TryFromBytes; |n: &u128| *n != 0);
3305
    unsafe_impl!(NonZeroI128: TryFromBytes; |n: &i128| *n != 0);
3306
    unsafe_impl!(NonZeroUsize: TryFromBytes; |n: &usize| *n != 0);
3307
    unsafe_impl!(NonZeroIsize: TryFromBytes; |n: &isize| *n != 0);
3308
}
3309
safety_comment! {
3310
    /// SAFETY:
3311
    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`,
3312
    ///   `AsBytes`: The Rust compiler reuses `0` value to represent `None`, so
3313
    ///   `size_of::<Option<NonZeroXxx>>() == size_of::<xxx>()`; see
3314
    ///   `NonZeroXxx` documentation.
3315
    /// - `Unaligned`: `NonZeroU8` and `NonZeroI8` document that
3316
    ///   `Option<NonZeroU8>` and `Option<NonZeroI8>` both have size 1. [1] [2]
3317
    ///   This is worded in a way that makes it unclear whether it's meant as a
3318
    ///   guarantee, but given the purpose of those types, it's virtually
3319
    ///   unthinkable that that would ever change. The only valid alignment for
3320
    ///   a 1-byte type is 1.
3321
    ///
3322
    /// TODO(#429): Add quotes from documentation.
3323
    ///
3324
    /// [1] https://doc.rust-lang.org/stable/std/num/struct.NonZeroU8.html
3325
    /// [2] https://doc.rust-lang.org/stable/std/num/struct.NonZeroI8.html
3326
    ///
3327
    /// TODO(https://github.com/rust-lang/rust/pull/104082): Cite documentation
3328
    /// for layout guarantees.
3329
    unsafe_impl!(Option<NonZeroU8>: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3330
    unsafe_impl!(Option<NonZeroI8>: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3331
    assert_unaligned!(Option<NonZeroU8>, Option<NonZeroI8>);
3332
    unsafe_impl!(Option<NonZeroU16>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3333
    unsafe_impl!(Option<NonZeroI16>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3334
    unsafe_impl!(Option<NonZeroU32>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3335
    unsafe_impl!(Option<NonZeroI32>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3336
    unsafe_impl!(Option<NonZeroU64>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3337
    unsafe_impl!(Option<NonZeroI64>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3338
    unsafe_impl!(Option<NonZeroU128>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3339
    unsafe_impl!(Option<NonZeroI128>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3340
    unsafe_impl!(Option<NonZeroUsize>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3341
    unsafe_impl!(Option<NonZeroIsize>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3342
}
3343
3344
safety_comment! {
3345
    /// SAFETY:
3346
    /// The following types can be transmuted from `[0u8; size_of::<T>()]`. [1]
3347
    /// None of them contain `UnsafeCell`s, and so they all soundly implement
3348
    /// `FromZeroes`.
3349
    ///
3350
    /// [1] Per
3351
    /// https://doc.rust-lang.org/nightly/core/option/index.html#representation:
3352
    ///
3353
    ///   Rust guarantees to optimize the following types `T` such that
3354
    ///   [`Option<T>`] has the same size and alignment as `T`. In some of these
3355
    ///   cases, Rust further guarantees that `transmute::<_, Option<T>>([0u8;
3356
    ///   size_of::<T>()])` is sound and produces `Option::<T>::None`. These
3357
    ///   cases are identified by the second column:
3358
    ///
3359
    ///   | `T`                   | `transmute::<_, Option<T>>([0u8; size_of::<T>()])` sound? |
3360
    ///   |-----------------------|-----------------------------------------------------------|
3361
    ///   | [`Box<U>`]            | when `U: Sized`                                           |
3362
    ///   | `&U`                  | when `U: Sized`                                           |
3363
    ///   | `&mut U`              | when `U: Sized`                                           |
3364
    ///   | [`ptr::NonNull<U>`]   | when `U: Sized`                                           |
3365
    ///   | `fn`, `extern "C" fn` | always                                                    |
3366
    ///
3367
    /// TODO(#429), TODO(https://github.com/rust-lang/rust/pull/115333): Cite
3368
    /// the Stable docs once they're available.
3369
    #[cfg(feature = "alloc")]
3370
    unsafe_impl!(
3371
        #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
3372
        T => FromZeroes for Option<Box<T>>
3373
    );
3374
    unsafe_impl!(T => FromZeroes for Option<&'_ T>);
3375
    unsafe_impl!(T => FromZeroes for Option<&'_ mut T>);
3376
    unsafe_impl!(T => FromZeroes for Option<NonNull<T>>);
3377
    unsafe_impl_for_power_set!(A, B, C, D, E, F, G, H, I, J, K, L -> M => FromZeroes for opt_fn!(...));
3378
    unsafe_impl_for_power_set!(A, B, C, D, E, F, G, H, I, J, K, L -> M => FromZeroes for opt_extern_c_fn!(...));
3379
}
3380
3381
safety_comment! {
3382
    /// SAFETY:
3383
    /// Per reference [1]:
3384
    /// "For all T, the following are guaranteed:
3385
    /// size_of::<PhantomData<T>>() == 0
3386
    /// align_of::<PhantomData<T>>() == 1".
3387
    /// This gives:
3388
    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`: There
3389
    ///   is only one possible sequence of 0 bytes, and `PhantomData` is
3390
    ///   inhabited.
3391
    /// - `AsBytes`: Since `PhantomData` has size 0, it contains no padding
3392
    ///   bytes.
3393
    /// - `Unaligned`: Per the preceding reference, `PhantomData` has alignment
3394
    ///   1.
3395
    ///
3396
    /// [1] https://doc.rust-lang.org/std/marker/struct.PhantomData.html#layout-1
3397
    unsafe_impl!(T: ?Sized => TryFromBytes for PhantomData<T>);
3398
    unsafe_impl!(T: ?Sized => FromZeroes for PhantomData<T>);
3399
    unsafe_impl!(T: ?Sized => FromBytes for PhantomData<T>);
3400
    unsafe_impl!(T: ?Sized => AsBytes for PhantomData<T>);
3401
    unsafe_impl!(T: ?Sized => Unaligned for PhantomData<T>);
3402
    assert_unaligned!(PhantomData<()>, PhantomData<u8>, PhantomData<u64>);
3403
}
3404
safety_comment! {
3405
    /// SAFETY:
3406
    /// `Wrapping<T>` is guaranteed by its docs [1] to have the same layout and
3407
    /// bit validity as `T`. Also, `Wrapping<T>` is `#[repr(transparent)]`, and
3408
    /// has a single field, which is `pub`. Per the reference [2], this means
3409
    /// that the `#[repr(transparent)]` attribute is "considered part of the
3410
    /// public ABI".
3411
    ///
3412
    /// - `TryFromBytes`: The safety requirements for `unsafe_impl!` with an
3413
    ///   `is_bit_valid` closure:
3414
    ///   - Given `t: *mut Wrapping<T>` and `let r = *mut T`, `r` refers to an
3415
    ///     object of the same size as that referred to by `t`. This is true
3416
    ///     because `Wrapping<T>` and `T` have the same layout
3417
    ///   - The alignment of `Wrapping<T>` is equal to the alignment of `T`.
3418
    ///   - The impl must only return `true` for its argument if the original
3419
    ///     `Ptr<Wrapping<T>>` refers to a valid `Wrapping<T>`. Since
3420
    ///     `Wrapping<T>` has the same bit validity as `T`, and since our impl
3421
    ///     just calls `T::is_bit_valid`, our impl returns `true` exactly when
3422
    ///     its argument contains a valid `Wrapping<T>`.
3423
    /// - `FromBytes`: Since `Wrapping<T>` has the same bit validity as `T`, if
3424
    ///   `T: FromBytes`, then all initialized byte sequences are valid
3425
    ///   instances of `Wrapping<T>`. Similarly, if `T: FromBytes`, then
3426
    ///   `Wrapping<T>` doesn't contain any `UnsafeCell`s. Thus, `impl FromBytes
3427
    ///   for Wrapping<T> where T: FromBytes` is a sound impl.
3428
    /// - `AsBytes`: Since `Wrapping<T>` has the same bit validity as `T`, if
3429
    ///   `T: AsBytes`, then all valid instances of `Wrapping<T>` have all of
3430
    ///   their bytes initialized. Similarly, if `T: AsBytes`, then
3431
    ///   `Wrapping<T>` doesn't contain any `UnsafeCell`s. Thus, `impl AsBytes
3432
    ///   for Wrapping<T> where T: AsBytes` is a valid impl.
3433
    /// - `Unaligned`: Since `Wrapping<T>` has the same layout as `T`,
3434
    ///   `Wrapping<T>` has alignment 1 exactly when `T` does.
3435
    ///
3436
    /// [1] Per https://doc.rust-lang.org/core/num/struct.NonZeroU16.html:
3437
    ///
3438
    ///   `NonZeroU16` is guaranteed to have the same layout and bit validity as
3439
    ///   `u16` with the exception that `0` is not a valid instance.
3440
    ///
3441
    /// TODO(#429): Add quotes from documentation.
3442
    ///
3443
    /// [1] TODO(https://doc.rust-lang.org/nightly/core/num/struct.Wrapping.html#layout-1):
3444
    /// Reference this documentation once it's available on stable.
3445
    ///
3446
    /// [2] https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
3447
    unsafe_impl!(T: TryFromBytes => TryFromBytes for Wrapping<T>; |candidate: Ptr<T>| {
3448
        // SAFETY:
3449
        // - Since `T` and `Wrapping<T>` have the same layout and bit validity
3450
        //   and contain the same fields, `T` contains `UnsafeCell`s exactly
3451
        //   where `Wrapping<T>` does. Thus, all memory and `UnsafeCell`
3452
        //   preconditions of `T::is_bit_valid` hold exactly when the same
3453
        //   preconditions for `Wrapping<T>::is_bit_valid` hold.
3454
        // - By the same token, since `candidate` is guaranteed to have its
3455
        //   bytes initialized where there are always initialized bytes in
3456
        //   `Wrapping<T>`, the same is true for `T`.
3457
        unsafe { T::is_bit_valid(candidate) }
3458
    });
3459
    unsafe_impl!(T: FromZeroes => FromZeroes for Wrapping<T>);
3460
    unsafe_impl!(T: FromBytes => FromBytes for Wrapping<T>);
3461
    unsafe_impl!(T: AsBytes => AsBytes for Wrapping<T>);
3462
    unsafe_impl!(T: Unaligned => Unaligned for Wrapping<T>);
3463
    assert_unaligned!(Wrapping<()>, Wrapping<u8>);
3464
}
3465
safety_comment! {
3466
    // `MaybeUninit<T>` is `FromZeroes` and `FromBytes`, but never `AsBytes`
3467
    // since it may contain uninitialized bytes.
3468
    //
3469
    /// SAFETY:
3470
    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`:
3471
    ///   `MaybeUninit<T>` has no restrictions on its contents. Unfortunately,
3472
    ///   in addition to bit validity, `TryFromBytes`, `FromZeroes` and
3473
    ///   `FromBytes` also require that implementers contain no `UnsafeCell`s.
3474
    ///   Thus, we require `T: Trait` in order to ensure that `T` - and thus
3475
    ///   `MaybeUninit<T>` - contains to `UnsafeCell`s. Thus, requiring that `T`
3476
    ///   implement each of these traits is sufficient.
3477
    /// - `Unaligned`: "MaybeUninit<T> is guaranteed to have the same size,
3478
    ///    alignment, and ABI as T" [1]
3479
    ///
3480
    /// [1] https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#layout-1
3481
    ///
3482
    /// TODO(https://github.com/google/zerocopy/issues/251): If we split
3483
    /// `FromBytes` and `RefFromBytes`, or if we introduce a separate
3484
    /// `NoCell`/`Freeze` trait, we can relax the trait bounds for `FromZeroes`
3485
    /// and `FromBytes`.
3486
    unsafe_impl!(T: TryFromBytes => TryFromBytes for MaybeUninit<T>);
3487
    unsafe_impl!(T: FromZeroes => FromZeroes for MaybeUninit<T>);
3488
    unsafe_impl!(T: FromBytes => FromBytes for MaybeUninit<T>);
3489
    unsafe_impl!(T: Unaligned => Unaligned for MaybeUninit<T>);
3490
    assert_unaligned!(MaybeUninit<()>, MaybeUninit<u8>);
3491
}
3492
safety_comment! {
3493
    /// SAFETY:
3494
    /// `ManuallyDrop` has the same layout and bit validity as `T` [1], and
3495
    /// accessing the inner value is safe (meaning that it's unsound to leave
3496
    /// the inner value uninitialized while exposing the `ManuallyDrop` to safe
3497
    /// code).
3498
    /// - `FromZeroes`, `FromBytes`: Since it has the same layout as `T`, any
3499
    ///   valid `T` is a valid `ManuallyDrop<T>`. If `T: FromZeroes`, a sequence
3500
    ///   of zero bytes is a valid `T`, and thus a valid `ManuallyDrop<T>`. If
3501
    ///   `T: FromBytes`, any sequence of bytes is a valid `T`, and thus a valid
3502
    ///   `ManuallyDrop<T>`.
3503
    /// - `AsBytes`: Since it has the same layout as `T`, and since it's unsound
3504
    ///   to let safe code access a `ManuallyDrop` whose inner value is
3505
    ///   uninitialized, safe code can only ever access a `ManuallyDrop` whose
3506
    ///   contents are a valid `T`. Since `T: AsBytes`, this means that safe
3507
    ///   code can only ever access a `ManuallyDrop` with all initialized bytes.
3508
    /// - `Unaligned`: `ManuallyDrop` has the same layout (and thus alignment)
3509
    ///   as `T`, and `T: Unaligned` guarantees that that alignment is 1.
3510
    ///
3511
    ///   `ManuallyDrop<T>` is guaranteed to have the same layout and bit
3512
    ///   validity as `T`
3513
    ///
3514
    /// [1] Per https://doc.rust-lang.org/nightly/core/mem/struct.ManuallyDrop.html:
3515
    ///
3516
    /// TODO(#429):
3517
    /// - Add quotes from docs.
3518
    /// - Once [1] (added in
3519
    /// https://github.com/rust-lang/rust/pull/115522) is available on stable,
3520
    /// quote the stable docs instead of the nightly docs.
3521
    unsafe_impl!(T: ?Sized + FromZeroes => FromZeroes for ManuallyDrop<T>);
3522
    unsafe_impl!(T: ?Sized + FromBytes => FromBytes for ManuallyDrop<T>);
3523
    unsafe_impl!(T: ?Sized + AsBytes => AsBytes for ManuallyDrop<T>);
3524
    unsafe_impl!(T: ?Sized + Unaligned => Unaligned for ManuallyDrop<T>);
3525
    assert_unaligned!(ManuallyDrop<()>, ManuallyDrop<u8>);
3526
}
3527
safety_comment! {
3528
    /// SAFETY:
3529
    /// Per the reference [1]:
3530
    ///
3531
    ///   An array of `[T; N]` has a size of `size_of::<T>() * N` and the same
3532
    ///   alignment of `T`. Arrays are laid out so that the zero-based `nth`
3533
    ///   element of the array is offset from the start of the array by `n *
3534
    ///   size_of::<T>()` bytes.
3535
    ///
3536
    ///   ...
3537
    ///
3538
    ///   Slices have the same layout as the section of the array they slice.
3539
    ///
3540
    /// In other words, the layout of a `[T]` or `[T; N]` is a sequence of `T`s
3541
    /// laid out back-to-back with no bytes in between. Therefore, `[T]` or `[T;
3542
    /// N]` are `TryFromBytes`, `FromZeroes`, `FromBytes`, and `AsBytes` if `T`
3543
    /// is (respectively). Furthermore, since an array/slice has "the same
3544
    /// alignment of `T`", `[T]` and `[T; N]` are `Unaligned` if `T` is.
3545
    ///
3546
    /// Note that we don't `assert_unaligned!` for slice types because
3547
    /// `assert_unaligned!` uses `align_of`, which only works for `Sized` types.
3548
    ///
3549
    /// [1] https://doc.rust-lang.org/reference/type-layout.html#array-layout
3550
    unsafe_impl!(const N: usize, T: FromZeroes => FromZeroes for [T; N]);
3551
    unsafe_impl!(const N: usize, T: FromBytes => FromBytes for [T; N]);
3552
    unsafe_impl!(const N: usize, T: AsBytes => AsBytes for [T; N]);
3553
    unsafe_impl!(const N: usize, T: Unaligned => Unaligned for [T; N]);
3554
    assert_unaligned!([(); 0], [(); 1], [u8; 0], [u8; 1]);
3555
    unsafe_impl!(T: TryFromBytes => TryFromBytes for [T]; |c: Ptr<[T]>| {
3556
        // SAFETY: Assuming the preconditions of `is_bit_valid` are satisfied,
3557
        // so too will the postcondition: that, if `is_bit_valid(candidate)`
3558
        // returns true, `*candidate` contains a valid `Self`. Per the reference
3559
        // [1]:
3560
        //
3561
        //   An array of `[T; N]` has a size of `size_of::<T>() * N` and the
3562
        //   same alignment of `T`. Arrays are laid out so that the zero-based
3563
        //   `nth` element of the array is offset from the start of the array by
3564
        //   `n * size_of::<T>()` bytes.
3565
        //
3566
        //   ...
3567
        //
3568
        //   Slices have the same layout as the section of the array they slice.
3569
        //
3570
        // In other words, the layout of a `[T] is a sequence of `T`s laid out
3571
        // back-to-back with no bytes in between. If all elements in `candidate`
3572
        // are `is_bit_valid`, so too is `candidate`.
3573
        //
3574
        // Note that any of the below calls may panic, but it would still be
3575
        // sound even if it did. `is_bit_valid` does not promise that it will
3576
        // not panic (in fact, it explicitly warns that it's a possibility), and
3577
        // we have not violated any safety invariants that we must fix before
3578
        // returning.
3579
        c.iter().all(|elem|
3580
            // SAFETY: We uphold the safety contract of `is_bit_valid(elem)`, by
3581
            // precondition on the surrounding call to `is_bit_valid`. The
3582
            // memory referenced by `elem` is contained entirely within `c`, and
3583
            // satisfies the preconditions satisfied by `c`. By axiom, we assume
3584
            // that `Iterator:all` does not invalidate these preconditions
3585
            // (e.g., by writing to `elem`.) Since `elem` is derived from `c`,
3586
            // it is only possible for uninitialized bytes to occur in `elem` at
3587
            // the same bytes they occur within `c`.
3588
0
            unsafe { <T as TryFromBytes>::is_bit_valid(elem) }
3589
        )
3590
    });
3591
    unsafe_impl!(T: FromZeroes => FromZeroes for [T]);
3592
    unsafe_impl!(T: FromBytes => FromBytes for [T]);
3593
    unsafe_impl!(T: AsBytes => AsBytes for [T]);
3594
    unsafe_impl!(T: Unaligned => Unaligned for [T]);
3595
}
3596
safety_comment! {
3597
    /// SAFETY:
3598
    /// - `FromZeroes`: For thin pointers (note that `T: Sized`), the zero
3599
    ///   pointer is considered "null". [1] No operations which require
3600
    ///   provenance are legal on null pointers, so this is not a footgun.
3601
    ///
3602
    /// NOTE(#170): Implementing `FromBytes` and `AsBytes` for raw pointers
3603
    /// would be sound, but carries provenance footguns. We want to support
3604
    /// `FromBytes` and `AsBytes` for raw pointers eventually, but we are
3605
    /// holding off until we can figure out how to address those footguns.
3606
    ///
3607
    /// [1] TODO(https://github.com/rust-lang/rust/pull/116988): Cite the
3608
    /// documentation once this PR lands.
3609
    unsafe_impl!(T => FromZeroes for *const T);
3610
    unsafe_impl!(T => FromZeroes for *mut T);
3611
}
3612
3613
// SIMD support
3614
//
3615
// Per the Unsafe Code Guidelines Reference [1]:
3616
//
3617
//   Packed SIMD vector types are `repr(simd)` homogeneous tuple-structs
3618
//   containing `N` elements of type `T` where `N` is a power-of-two and the
3619
//   size and alignment requirements of `T` are equal:
3620
//
3621
//   ```rust
3622
//   #[repr(simd)]
3623
//   struct Vector<T, N>(T_0, ..., T_(N - 1));
3624
//   ```
3625
//
3626
//   ...
3627
//
3628
//   The size of `Vector` is `N * size_of::<T>()` and its alignment is an
3629
//   implementation-defined function of `T` and `N` greater than or equal to
3630
//   `align_of::<T>()`.
3631
//
3632
//   ...
3633
//
3634
//   Vector elements are laid out in source field order, enabling random access
3635
//   to vector elements by reinterpreting the vector as an array:
3636
//
3637
//   ```rust
3638
//   union U {
3639
//      vec: Vector<T, N>,
3640
//      arr: [T; N]
3641
//   }
3642
//
3643
//   assert_eq!(size_of::<Vector<T, N>>(), size_of::<[T; N]>());
3644
//   assert!(align_of::<Vector<T, N>>() >= align_of::<[T; N]>());
3645
//
3646
//   unsafe {
3647
//     let u = U { vec: Vector<T, N>(t_0, ..., t_(N - 1)) };
3648
//
3649
//     assert_eq!(u.vec.0, u.arr[0]);
3650
//     // ...
3651
//     assert_eq!(u.vec.(N - 1), u.arr[N - 1]);
3652
//   }
3653
//   ```
3654
//
3655
// Given this background, we can observe that:
3656
// - The size and bit pattern requirements of a SIMD type are equivalent to the
3657
//   equivalent array type. Thus, for any SIMD type whose primitive `T` is
3658
//   `TryFromBytes`, `FromZeroes`, `FromBytes`, or `AsBytes`, that SIMD type is
3659
//   also `TryFromBytes`, `FromZeroes`, `FromBytes`, or `AsBytes` respectively.
3660
// - Since no upper bound is placed on the alignment, no SIMD type can be
3661
//   guaranteed to be `Unaligned`.
3662
//
3663
// Also per [1]:
3664
//
3665
//   This chapter represents the consensus from issue #38. The statements in
3666
//   here are not (yet) "guaranteed" not to change until an RFC ratifies them.
3667
//
3668
// See issue #38 [2]. While this behavior is not technically guaranteed, the
3669
// likelihood that the behavior will change such that SIMD types are no longer
3670
// `TryFromBytes`, `FromZeroes`, `FromBytes`, or `AsBytes` is next to zero, as
3671
// that would defeat the entire purpose of SIMD types. Nonetheless, we put this
3672
// behavior behind the `simd` Cargo feature, which requires consumers to opt
3673
// into this stability hazard.
3674
//
3675
// [1] https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html
3676
// [2] https://github.com/rust-lang/unsafe-code-guidelines/issues/38
3677
#[cfg(feature = "simd")]
3678
#[cfg_attr(doc_cfg, doc(cfg(feature = "simd")))]
3679
mod simd {
3680
    /// Defines a module which implements `TryFromBytes`, `FromZeroes`,
3681
    /// `FromBytes`, and `AsBytes` for a set of types from a module in
3682
    /// `core::arch`.
3683
    ///
3684
    /// `$arch` is both the name of the defined module and the name of the
3685
    /// module in `core::arch`, and `$typ` is the list of items from that module
3686
    /// to implement `FromZeroes`, `FromBytes`, and `AsBytes` for.
3687
    #[allow(unused_macros)] // `allow(unused_macros)` is needed because some
3688
                            // target/feature combinations don't emit any impls
3689
                            // and thus don't use this macro.
3690
    macro_rules! simd_arch_mod {
3691
        (#[cfg $cfg:tt] $arch:ident, $mod:ident, $($typ:ident),*) => {
3692
            #[cfg $cfg]
3693
            #[cfg_attr(doc_cfg, doc(cfg $cfg))]
3694
            mod $mod {
3695
                use core::arch::$arch::{$($typ),*};
3696
3697
                use crate::*;
3698
                impl_known_layout!($($typ),*);
3699
                safety_comment! {
3700
                    /// SAFETY:
3701
                    /// See comment on module definition for justification.
3702
                    $( unsafe_impl!($typ: TryFromBytes, FromZeroes, FromBytes, AsBytes); )*
3703
                }
3704
            }
3705
        };
3706
    }
3707
3708
    #[rustfmt::skip]
3709
    const _: () = {
3710
        simd_arch_mod!(
3711
            #[cfg(target_arch = "x86")]
3712
            x86, x86, __m128, __m128d, __m128i, __m256, __m256d, __m256i
3713
        );
3714
        simd_arch_mod!(
3715
            #[cfg(all(feature = "simd-nightly", target_arch = "x86"))]
3716
            x86, x86_nightly, __m512bh, __m512, __m512d, __m512i
3717
        );
3718
        simd_arch_mod!(
3719
            #[cfg(target_arch = "x86_64")]
3720
            x86_64, x86_64, __m128, __m128d, __m128i, __m256, __m256d, __m256i
3721
        );
3722
        simd_arch_mod!(
3723
            #[cfg(all(feature = "simd-nightly", target_arch = "x86_64"))]
3724
            x86_64, x86_64_nightly, __m512bh, __m512, __m512d, __m512i
3725
        );
3726
        simd_arch_mod!(
3727
            #[cfg(target_arch = "wasm32")]
3728
            wasm32, wasm32, v128
3729
        );
3730
        simd_arch_mod!(
3731
            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc"))]
3732
            powerpc, powerpc, vector_bool_long, vector_double, vector_signed_long, vector_unsigned_long
3733
        );
3734
        simd_arch_mod!(
3735
            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc64"))]
3736
            powerpc64, powerpc64, vector_bool_long, vector_double, vector_signed_long, vector_unsigned_long
3737
        );
3738
        simd_arch_mod!(
3739
            #[cfg(target_arch = "aarch64")]
3740
            aarch64, aarch64, float32x2_t, float32x4_t, float64x1_t, float64x2_t, int8x8_t, int8x8x2_t,
3741
            int8x8x3_t, int8x8x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int16x4_t,
3742
            int16x8_t, int32x2_t, int32x4_t, int64x1_t, int64x2_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t,
3743
            poly8x8x4_t, poly8x16_t, poly8x16x2_t, poly8x16x3_t, poly8x16x4_t, poly16x4_t, poly16x8_t,
3744
            poly64x1_t, poly64x2_t, uint8x8_t, uint8x8x2_t, uint8x8x3_t, uint8x8x4_t, uint8x16_t,
3745
            uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint16x4_t, uint16x8_t, uint32x2_t, uint32x4_t,
3746
            uint64x1_t, uint64x2_t
3747
        );
3748
        simd_arch_mod!(
3749
            #[cfg(all(feature = "simd-nightly", target_arch = "arm"))]
3750
            arm, arm, int8x4_t, uint8x4_t
3751
        );
3752
    };
3753
}
3754
3755
/// Safely transmutes a value of one type to a value of another type of the same
3756
/// size.
3757
///
3758
/// The expression `$e` must have a concrete type, `T`, which implements
3759
/// `AsBytes`. The `transmute!` expression must also have a concrete type, `U`
3760
/// (`U` is inferred from the calling context), and `U` must implement
3761
/// `FromBytes`.
3762
///
3763
/// Note that the `T` produced by the expression `$e` will *not* be dropped.
3764
/// Semantically, its bits will be copied into a new value of type `U`, the
3765
/// original `T` will be forgotten, and the value of type `U` will be returned.
3766
///
3767
/// # Examples
3768
///
3769
/// ```
3770
/// # use zerocopy::transmute;
3771
/// let one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
3772
///
3773
/// let two_dimensional: [[u8; 4]; 2] = transmute!(one_dimensional);
3774
///
3775
/// assert_eq!(two_dimensional, [[0, 1, 2, 3], [4, 5, 6, 7]]);
3776
/// ```
3777
#[macro_export]
3778
macro_rules! transmute {
3779
    ($e:expr) => {{
3780
        // NOTE: This must be a macro (rather than a function with trait bounds)
3781
        // because there's no way, in a generic context, to enforce that two
3782
        // types have the same size. `core::mem::transmute` uses compiler magic
3783
        // to enforce this so long as the types are concrete.
3784
3785
        let e = $e;
3786
        if false {
3787
            // This branch, though never taken, ensures that the type of `e` is
3788
            // `AsBytes` and that the type of this macro invocation expression
3789
            // is `FromBytes`.
3790
3791
            struct AssertIsAsBytes<T: $crate::AsBytes>(T);
3792
            let _ = AssertIsAsBytes(e);
3793
3794
            struct AssertIsFromBytes<U: $crate::FromBytes>(U);
3795
            #[allow(unused, unreachable_code)]
3796
            let u = AssertIsFromBytes(loop {});
3797
            u.0
3798
        } else {
3799
            // SAFETY: `core::mem::transmute` ensures that the type of `e` and
3800
            // the type of this macro invocation expression have the same size.
3801
            // We know this transmute is safe thanks to the `AsBytes` and
3802
            // `FromBytes` bounds enforced by the `false` branch.
3803
            //
3804
            // We use this reexport of `core::mem::transmute` because we know it
3805
            // will always be available for crates which are using the 2015
3806
            // edition of Rust. By contrast, if we were to use
3807
            // `std::mem::transmute`, this macro would not work for such crates
3808
            // in `no_std` contexts, and if we were to use
3809
            // `core::mem::transmute`, this macro would not work in `std`
3810
            // contexts in which `core` was not manually imported. This is not a
3811
            // problem for 2018 edition crates.
3812
            unsafe {
3813
                // Clippy: It's okay to transmute a type to itself.
3814
                #[allow(clippy::useless_transmute, clippy::missing_transmute_annotations)]
3815
                $crate::macro_util::core_reexport::mem::transmute(e)
3816
            }
3817
        }
3818
    }}
3819
}
3820
3821
/// Safely transmutes a mutable or immutable reference of one type to an
3822
/// immutable reference of another type of the same size.
3823
///
3824
/// The expression `$e` must have a concrete type, `&T` or `&mut T`, where `T:
3825
/// Sized + AsBytes`. The `transmute_ref!` expression must also have a concrete
3826
/// type, `&U` (`U` is inferred from the calling context), where `U: Sized +
3827
/// FromBytes`. It must be the case that `align_of::<T>() >= align_of::<U>()`.
3828
///
3829
/// The lifetime of the input type, `&T` or `&mut T`, must be the same as or
3830
/// outlive the lifetime of the output type, `&U`.
3831
///
3832
/// # Examples
3833
///
3834
/// ```
3835
/// # use zerocopy::transmute_ref;
3836
/// let one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
3837
///
3838
/// let two_dimensional: &[[u8; 4]; 2] = transmute_ref!(&one_dimensional);
3839
///
3840
/// assert_eq!(two_dimensional, &[[0, 1, 2, 3], [4, 5, 6, 7]]);
3841
/// ```
3842
///
3843
/// # Alignment increase error message
3844
///
3845
/// Because of limitations on macros, the error message generated when
3846
/// `transmute_ref!` is used to transmute from a type of lower alignment to a
3847
/// type of higher alignment is somewhat confusing. For example, the following
3848
/// code:
3849
///
3850
/// ```compile_fail
3851
/// const INCREASE_ALIGNMENT: &u16 = zerocopy::transmute_ref!(&[0u8; 2]);
3852
/// ```
3853
///
3854
/// ...generates the following error:
3855
///
3856
/// ```text
3857
/// error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
3858
///  --> src/lib.rs:1524:34
3859
///   |
3860
/// 5 | const INCREASE_ALIGNMENT: &u16 = zerocopy::transmute_ref!(&[0u8; 2]);
3861
///   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3862
///   |
3863
///   = note: source type: `AlignOf<[u8; 2]>` (8 bits)
3864
///   = note: target type: `MaxAlignsOf<[u8; 2], u16>` (16 bits)
3865
///   = note: this error originates in the macro `$crate::assert_align_gt_eq` which comes from the expansion of the macro `transmute_ref` (in Nightly builds, run with -Z macro-backtrace for more info)
3866
/// ```
3867
///
3868
/// This is saying that `max(align_of::<T>(), align_of::<U>()) !=
3869
/// align_of::<T>()`, which is equivalent to `align_of::<T>() <
3870
/// align_of::<U>()`.
3871
#[macro_export]
3872
macro_rules! transmute_ref {
3873
    ($e:expr) => {{
3874
        // NOTE: This must be a macro (rather than a function with trait bounds)
3875
        // because there's no way, in a generic context, to enforce that two
3876
        // types have the same size or alignment.
3877
3878
        // Ensure that the source type is a reference or a mutable reference
3879
        // (note that mutable references are implicitly reborrowed here).
3880
        let e: &_ = $e;
3881
3882
        #[allow(unused, clippy::diverging_sub_expression)]
3883
        if false {
3884
            // This branch, though never taken, ensures that the type of `e` is
3885
            // `&T` where `T: 't + Sized + AsBytes`, that the type of this macro
3886
            // expression is `&U` where `U: 'u + Sized + FromBytes`, and that
3887
            // `'t` outlives `'u`.
3888
3889
            struct AssertIsAsBytes<'a, T: ::core::marker::Sized + $crate::AsBytes>(&'a T);
3890
            let _ = AssertIsAsBytes(e);
3891
3892
            struct AssertIsFromBytes<'a, U: ::core::marker::Sized + $crate::FromBytes>(&'a U);
3893
            #[allow(unused, unreachable_code)]
3894
            let u = AssertIsFromBytes(loop {});
3895
            u.0
3896
        } else if false {
3897
            // This branch, though never taken, ensures that `size_of::<T>() ==
3898
            // size_of::<U>()` and that that `align_of::<T>() >=
3899
            // align_of::<U>()`.
3900
3901
            // `t` is inferred to have type `T` because it's assigned to `e` (of
3902
            // type `&T`) as `&t`.
3903
            let mut t = unreachable!();
3904
            e = &t;
3905
3906
            // `u` is inferred to have type `U` because it's used as `&u` as the
3907
            // value returned from this branch.
3908
            let u;
3909
3910
            $crate::assert_size_eq!(t, u);
3911
            $crate::assert_align_gt_eq!(t, u);
3912
3913
            &u
3914
        } else {
3915
            // SAFETY: For source type `Src` and destination type `Dst`:
3916
            // - We know that `Src: AsBytes` and `Dst: FromBytes` thanks to the
3917
            //   uses of `AssertIsAsBytes` and `AssertIsFromBytes` above.
3918
            // - We know that `size_of::<Src>() == size_of::<Dst>()` thanks to
3919
            //   the use of `assert_size_eq!` above.
3920
            // - We know that `align_of::<Src>() >= align_of::<Dst>()` thanks to
3921
            //   the use of `assert_align_gt_eq!` above.
3922
            unsafe { $crate::macro_util::transmute_ref(e) }
3923
        }
3924
    }}
3925
}
3926
3927
/// Safely transmutes a mutable reference of one type to an mutable reference of
3928
/// another type of the same size.
3929
///
3930
/// The expression `$e` must have a concrete type, `&mut T`, where `T: Sized +
3931
/// AsBytes`. The `transmute_mut!` expression must also have a concrete type,
3932
/// `&mut U` (`U` is inferred from the calling context), where `U: Sized +
3933
/// FromBytes`. It must be the case that `align_of::<T>() >= align_of::<U>()`.
3934
///
3935
/// The lifetime of the input type, `&mut T`, must be the same as or outlive the
3936
/// lifetime of the output type, `&mut U`.
3937
///
3938
/// # Examples
3939
///
3940
/// ```
3941
/// # use zerocopy::transmute_mut;
3942
/// let mut one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
3943
///
3944
/// let two_dimensional: &mut [[u8; 4]; 2] = transmute_mut!(&mut one_dimensional);
3945
///
3946
/// assert_eq!(two_dimensional, &[[0, 1, 2, 3], [4, 5, 6, 7]]);
3947
///
3948
/// two_dimensional.reverse();
3949
///
3950
/// assert_eq!(one_dimensional, [4, 5, 6, 7, 0, 1, 2, 3]);
3951
/// ```
3952
///
3953
/// # Alignment increase error message
3954
///
3955
/// Because of limitations on macros, the error message generated when
3956
/// `transmute_mut!` is used to transmute from a type of lower alignment to a
3957
/// type of higher alignment is somewhat confusing. For example, the following
3958
/// code:
3959
///
3960
/// ```compile_fail
3961
/// const INCREASE_ALIGNMENT: &mut u16 = zerocopy::transmute_mut!(&mut [0u8; 2]);
3962
/// ```
3963
///
3964
/// ...generates the following error:
3965
///
3966
/// ```text
3967
/// error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
3968
///  --> src/lib.rs:1524:34
3969
///   |
3970
/// 5 | const INCREASE_ALIGNMENT: &mut u16 = zerocopy::transmute_mut!(&mut [0u8; 2]);
3971
///   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3972
///   |
3973
///   = note: source type: `AlignOf<[u8; 2]>` (8 bits)
3974
///   = note: target type: `MaxAlignsOf<[u8; 2], u16>` (16 bits)
3975
///   = note: this error originates in the macro `$crate::assert_align_gt_eq` which comes from the expansion of the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
3976
/// ```
3977
///
3978
/// This is saying that `max(align_of::<T>(), align_of::<U>()) !=
3979
/// align_of::<T>()`, which is equivalent to `align_of::<T>() <
3980
/// align_of::<U>()`.
3981
#[macro_export]
3982
macro_rules! transmute_mut {
3983
    ($e:expr) => {{
3984
        // NOTE: This must be a macro (rather than a function with trait bounds)
3985
        // because there's no way, in a generic context, to enforce that two
3986
        // types have the same size or alignment.
3987
3988
        // Ensure that the source type is a mutable reference.
3989
        let e: &mut _ = $e;
3990
3991
        #[allow(unused, clippy::diverging_sub_expression)]
3992
        if false {
3993
            // This branch, though never taken, ensures that the type of `e` is
3994
            // `&mut T` where `T: 't + Sized + FromBytes + AsBytes`, that the
3995
            // type of this macro expression is `&mut U` where `U: 'u + Sized +
3996
            // FromBytes + AsBytes`.
3997
3998
            // We use immutable references here rather than mutable so that, if
3999
            // this macro is used in a const context (in which, as of this
4000
            // writing, mutable references are banned), the error message
4001
            // appears to originate in the user's code rather than in the
4002
            // internals of this macro.
4003
            struct AssertSrcIsFromBytes<'a, T: ::core::marker::Sized + $crate::FromBytes>(&'a T);
4004
            struct AssertSrcIsAsBytes<'a, T: ::core::marker::Sized + $crate::AsBytes>(&'a T);
4005
            struct AssertDstIsFromBytes<'a, T: ::core::marker::Sized + $crate::FromBytes>(&'a T);
4006
            struct AssertDstIsAsBytes<'a, T: ::core::marker::Sized + $crate::AsBytes>(&'a T);
4007
4008
            if true {
4009
                let _ = AssertSrcIsFromBytes(&*e);
4010
            } else {
4011
                let _ = AssertSrcIsAsBytes(&*e);
4012
            }
4013
4014
            if true {
4015
                #[allow(unused, unreachable_code)]
4016
                let u = AssertDstIsFromBytes(loop {});
4017
                &mut *u.0
4018
            } else {
4019
                #[allow(unused, unreachable_code)]
4020
                let u = AssertDstIsAsBytes(loop {});
4021
                &mut *u.0
4022
            }
4023
        } else if false {
4024
            // This branch, though never taken, ensures that `size_of::<T>() ==
4025
            // size_of::<U>()` and that that `align_of::<T>() >=
4026
            // align_of::<U>()`.
4027
4028
            // `t` is inferred to have type `T` because it's assigned to `e` (of
4029
            // type `&mut T`) as `&mut t`.
4030
            let mut t = unreachable!();
4031
            e = &mut t;
4032
4033
            // `u` is inferred to have type `U` because it's used as `&mut u` as
4034
            // the value returned from this branch.
4035
            let u;
4036
4037
            $crate::assert_size_eq!(t, u);
4038
            $crate::assert_align_gt_eq!(t, u);
4039
4040
            &mut u
4041
        } else {
4042
            // SAFETY: For source type `Src` and destination type `Dst`:
4043
            // - We know that `Src: FromBytes + AsBytes` and `Dst: FromBytes +
4044
            //   AsBytes` thanks to the uses of `AssertSrcIsFromBytes`,
4045
            //   `AssertSrcIsAsBytes`, `AssertDstIsFromBytes`, and
4046
            //   `AssertDstIsAsBytes` above.
4047
            // - We know that `size_of::<Src>() == size_of::<Dst>()` thanks to
4048
            //   the use of `assert_size_eq!` above.
4049
            // - We know that `align_of::<Src>() >= align_of::<Dst>()` thanks to
4050
            //   the use of `assert_align_gt_eq!` above.
4051
            unsafe { $crate::macro_util::transmute_mut(e) }
4052
        }
4053
    }}
4054
}
4055
4056
/// Includes a file and safely transmutes it to a value of an arbitrary type.
4057
///
4058
/// The file will be included as a byte array, `[u8; N]`, which will be
4059
/// transmuted to another type, `T`. `T` is inferred from the calling context,
4060
/// and must implement [`FromBytes`].
4061
///
4062
/// The file is located relative to the current file (similarly to how modules
4063
/// are found). The provided path is interpreted in a platform-specific way at
4064
/// compile time. So, for instance, an invocation with a Windows path containing
4065
/// backslashes `\` would not compile correctly on Unix.
4066
///
4067
/// `include_value!` is ignorant of byte order. For byte order-aware types, see
4068
/// the [`byteorder`] module.
4069
///
4070
/// # Examples
4071
///
4072
/// Assume there are two files in the same directory with the following
4073
/// contents:
4074
///
4075
/// File `data` (no trailing newline):
4076
///
4077
/// ```text
4078
/// abcd
4079
/// ```
4080
///
4081
/// File `main.rs`:
4082
///
4083
/// ```rust
4084
/// use zerocopy::include_value;
4085
/// # macro_rules! include_value {
4086
/// # ($file:expr) => { zerocopy::include_value!(concat!("../testdata/include_value/", $file)) };
4087
/// # }
4088
///
4089
/// fn main() {
4090
///     let as_u32: u32 = include_value!("data");
4091
///     assert_eq!(as_u32, u32::from_ne_bytes([b'a', b'b', b'c', b'd']));
4092
///     let as_i32: i32 = include_value!("data");
4093
///     assert_eq!(as_i32, i32::from_ne_bytes([b'a', b'b', b'c', b'd']));
4094
/// }
4095
/// ```
4096
#[doc(alias("include_bytes", "include_data", "include_type"))]
4097
#[macro_export]
4098
macro_rules! include_value {
4099
    ($file:expr $(,)?) => {
4100
        $crate::transmute!(*::core::include_bytes!($file))
4101
    };
4102
}
4103
4104
/// A typed reference derived from a byte slice.
4105
///
4106
/// A `Ref<B, T>` is a reference to a `T` which is stored in a byte slice, `B`.
4107
/// Unlike a native reference (`&T` or `&mut T`), `Ref<B, T>` has the same
4108
/// mutability as the byte slice it was constructed from (`B`).
4109
///
4110
/// # Examples
4111
///
4112
/// `Ref` can be used to treat a sequence of bytes as a structured type, and to
4113
/// read and write the fields of that type as if the byte slice reference were
4114
/// simply a reference to that type.
4115
///
4116
/// ```rust
4117
/// # #[cfg(feature = "derive")] { // This example uses derives, and won't compile without them
4118
/// use zerocopy::{AsBytes, ByteSlice, ByteSliceMut, FromBytes, FromZeroes, Ref, Unaligned};
4119
///
4120
/// #[derive(FromZeroes, FromBytes, AsBytes, Unaligned)]
4121
/// #[repr(C)]
4122
/// struct UdpHeader {
4123
///     src_port: [u8; 2],
4124
///     dst_port: [u8; 2],
4125
///     length: [u8; 2],
4126
///     checksum: [u8; 2],
4127
/// }
4128
///
4129
/// struct UdpPacket<B> {
4130
///     header: Ref<B, UdpHeader>,
4131
///     body: B,
4132
/// }
4133
///
4134
/// impl<B: ByteSlice> UdpPacket<B> {
4135
///     pub fn parse(bytes: B) -> Option<UdpPacket<B>> {
4136
///         let (header, body) = Ref::new_unaligned_from_prefix(bytes)?;
4137
///         Some(UdpPacket { header, body })
4138
///     }
4139
///
4140
///     pub fn get_src_port(&self) -> [u8; 2] {
4141
///         self.header.src_port
4142
///     }
4143
/// }
4144
///
4145
/// impl<B: ByteSliceMut> UdpPacket<B> {
4146
///     pub fn set_src_port(&mut self, src_port: [u8; 2]) {
4147
///         self.header.src_port = src_port;
4148
///     }
4149
/// }
4150
/// # }
4151
/// ```
4152
pub struct Ref<B, T: ?Sized>(B, PhantomData<T>);
4153
4154
/// Deprecated: prefer [`Ref`] instead.
4155
#[deprecated(since = "0.7.0", note = "LayoutVerified has been renamed to Ref")]
4156
#[doc(hidden)]
4157
pub type LayoutVerified<B, T> = Ref<B, T>;
4158
4159
impl<B, T> Ref<B, T>
4160
where
4161
    B: ByteSlice,
4162
{
4163
    /// Constructs a new `Ref`.
4164
    ///
4165
    /// `new` verifies that `bytes.len() == size_of::<T>()` and that `bytes` is
4166
    /// aligned to `align_of::<T>()`, and constructs a new `Ref`. If either of
4167
    /// these checks fail, it returns `None`.
4168
    #[inline]
4169
0
    pub fn new(bytes: B) -> Option<Ref<B, T>> {
4170
0
        if bytes.len() != mem::size_of::<T>() || !util::aligned_to::<_, T>(bytes.deref()) {
4171
0
            return None;
4172
0
        }
4173
0
        Some(Ref(bytes, PhantomData))
4174
0
    }
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroaEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerohEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroiEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerojEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerolEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeromEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeronEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerooEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerosEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerotEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroxEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroyEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShaE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShdE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShfE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShhE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShiE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShjE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShlE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShmE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShnE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShoE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShsE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShtE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShuE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShxE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShyE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroaEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerohEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroiEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerojEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerolEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeromEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeronEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerooEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerosEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerotEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroxEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroyEEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignaEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligndEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignfEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignhEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligniEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignjEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignlEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignmEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignnEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignoEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignsEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligntEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignuEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignxEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignyEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroaEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerohEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroiEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerojEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerolEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeromEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeronEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerooEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerosEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerotEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroxEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroyEEE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShaE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShdE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShfE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShhE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShiE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShjE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShlE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShmE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShnE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShoE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShsE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShtE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShuE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShxE3newB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShyE3newB5_
4175
4176
    /// Constructs a new `Ref` from the prefix of a byte slice.
4177
    ///
4178
    /// `new_from_prefix` verifies that `bytes.len() >= size_of::<T>()` and that
4179
    /// `bytes` is aligned to `align_of::<T>()`. It consumes the first
4180
    /// `size_of::<T>()` bytes from `bytes` to construct a `Ref`, and returns
4181
    /// the remaining bytes to the caller. If either the length or alignment
4182
    /// checks fail, it returns `None`.
4183
    #[inline]
4184
0
    pub fn new_from_prefix(bytes: B) -> Option<(Ref<B, T>, B)> {
4185
0
        if bytes.len() < mem::size_of::<T>() || !util::aligned_to::<_, T>(bytes.deref()) {
4186
0
            return None;
4187
0
        }
4188
0
        let (bytes, suffix) = bytes.split_at(mem::size_of::<T>());
4189
0
        Some((Ref(bytes, PhantomData), suffix))
4190
0
    }
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroaEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerohEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroiEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerojEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerolEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeromEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeronEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerooEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerosEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerotEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroxEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroyEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShaE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShdE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShfE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShhE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShiE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShjE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShlE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShmE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShnE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShoE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShsE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShtE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShuE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShxE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShyE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroaEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerohEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroiEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerojEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerolEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeromEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeronEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerooEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerosEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerotEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroxEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroyEEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignaEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligndEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignfEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignhEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligniEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignjEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignlEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignmEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignnEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignoEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignsEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligntEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignuEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignxEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignyEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroaEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerohEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroiEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerojEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerolEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeromEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeronEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerooEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerosEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerotEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroxEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroyEEE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShaE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShdE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShfE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShhE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShiE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShjE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShlE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShmE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShnE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShoE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShsE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShtE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShuE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShxE15new_from_prefixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShyE15new_from_prefixB5_
4191
4192
    /// Constructs a new `Ref` from the suffix of a byte slice.
4193
    ///
4194
    /// `new_from_suffix` verifies that `bytes.len() >= size_of::<T>()` and that
4195
    /// the last `size_of::<T>()` bytes of `bytes` are aligned to
4196
    /// `align_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4197
    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4198
    /// caller. If either the length or alignment checks fail, it returns
4199
    /// `None`.
4200
    #[inline]
4201
0
    pub fn new_from_suffix(bytes: B) -> Option<(B, Ref<B, T>)> {
4202
0
        let bytes_len = bytes.len();
4203
0
        let split_at = bytes_len.checked_sub(mem::size_of::<T>())?;
4204
0
        let (prefix, bytes) = bytes.split_at(split_at);
4205
0
        if !util::aligned_to::<_, T>(bytes.deref()) {
4206
0
            return None;
4207
0
        }
4208
0
        Some((prefix, Ref(bytes, PhantomData)))
4209
0
    }
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroaEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerohEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroiEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerojEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerolEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeromEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeronEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerooEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerosEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerotEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroxEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroyEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShaE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShdE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShfE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShhE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShiE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShjE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShlE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShmE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShnE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShoE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShsE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShtE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShuE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShxE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefQShyE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroaEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerohEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroiEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerojEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerolEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeromEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeronEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerooEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerosEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerotEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroxEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroyEEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignaEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligndEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignfEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignhEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligniEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignjEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignlEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignmEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignnEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignoEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignsEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligntEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignuEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignxEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignyEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroaEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerohEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroiEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerojEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerolEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeromEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeronEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerooEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerosEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerotEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroxEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroyEEE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShaE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShdE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShfE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShhE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShiE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShjE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShlE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShmE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShnE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShoE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShsE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShtE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShuE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShxE15new_from_suffixB5_
Unexecuted instantiation: _RNvMs1_CsiAAEnE8327y_8zerocopyINtB5_3RefRShyE15new_from_suffixB5_
4210
}
4211
4212
impl<B, T> Ref<B, [T]>
4213
where
4214
    B: ByteSlice,
4215
{
4216
    /// Constructs a new `Ref` of a slice type.
4217
    ///
4218
    /// `new_slice` verifies that `bytes.len()` is a multiple of
4219
    /// `size_of::<T>()` and that `bytes` is aligned to `align_of::<T>()`, and
4220
    /// constructs a new `Ref`. If either of these checks fail, it returns
4221
    /// `None`.
4222
    ///
4223
    /// # Panics
4224
    ///
4225
    /// `new_slice` panics if `T` is a zero-sized type.
4226
    #[inline]
4227
0
    pub fn new_slice(bytes: B) -> Option<Ref<B, [T]>> {
4228
0
        let remainder = bytes
4229
0
            .len()
4230
0
            .checked_rem(mem::size_of::<T>())
4231
0
            .expect("Ref::new_slice called on a zero-sized type");
4232
0
        if remainder != 0 || !util::aligned_to::<_, T>(bytes.deref()) {
4233
0
            return None;
4234
0
        }
4235
0
        Some(Ref(bytes, PhantomData))
4236
0
    }
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShBD_E9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroaEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerohEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroiEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerojEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerolEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeromEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeronEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerooEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerosEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerotEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroxEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroyEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSaE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSdE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSfE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSiE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSjE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSlE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSmE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSnE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSoE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSsE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShStE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSuE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSxE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSyE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShBD_E9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroaEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerohEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroiEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerojEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerolEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeromEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeronEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerooEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerosEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerotEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroxEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroyEEE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSaE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSdE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSfE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSiE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSjE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSlE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSmE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSnE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSoE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSsE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShStE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSuE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSxE9new_sliceB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSyE9new_sliceB5_
4237
4238
    /// Constructs a new `Ref` of a slice type from the prefix of a byte slice.
4239
    ///
4240
    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4241
    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4242
    /// first `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4243
    /// and returns the remaining bytes to the caller. It also ensures that
4244
    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4245
    /// length, alignment, or overflow checks fail, it returns `None`.
4246
    ///
4247
    /// # Panics
4248
    ///
4249
    /// `new_slice_from_prefix` panics if `T` is a zero-sized type.
4250
    #[inline]
4251
0
    pub fn new_slice_from_prefix(bytes: B, count: usize) -> Option<(Ref<B, [T]>, B)> {
4252
0
        let expected_len = match mem::size_of::<T>().checked_mul(count) {
4253
0
            Some(len) => len,
4254
0
            None => return None,
4255
        };
4256
0
        if bytes.len() < expected_len {
4257
0
            return None;
4258
0
        }
4259
0
        let (prefix, bytes) = bytes.split_at(expected_len);
4260
0
        Self::new_slice(prefix).map(move |l| (l, bytes))
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShBF_E21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroaEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerohEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroiEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerojEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerolEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeromEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeronEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerooEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerosEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerotEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroxEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroyEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSaE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSdE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSfE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSiE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSjE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSlE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSmE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSnE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSoE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSsE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShStE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSuE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSxE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSyE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShBF_E21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroaEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerohEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroiEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerojEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerolEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeromEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeronEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerooEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerosEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerotEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroxEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroyEEE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSaE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSdE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSfE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSiE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSjE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSlE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSmE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSnE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSoE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSsE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShStE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSuE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSxE21new_slice_from_prefix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSyE21new_slice_from_prefix0B7_
4261
0
    }
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShBD_E21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroaEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerohEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroiEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerojEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerolEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeromEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeronEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerooEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerosEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerotEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroxEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroyEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSaE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSdE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSfE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSiE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSjE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSlE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSmE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSnE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSoE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSsE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShStE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSuE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSxE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSyE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShBD_E21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroaEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerohEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroiEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerojEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerolEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeromEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeronEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerooEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerosEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerotEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroxEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroyEEE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSaE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSdE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSfE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSiE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSjE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSlE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSmE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSnE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSoE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSsE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShStE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSuE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSxE21new_slice_from_prefixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSyE21new_slice_from_prefixB5_
4262
4263
    /// Constructs a new `Ref` of a slice type from the suffix of a byte slice.
4264
    ///
4265
    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4266
    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4267
    /// last `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4268
    /// and returns the preceding bytes to the caller. It also ensures that
4269
    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4270
    /// length, alignment, or overflow checks fail, it returns `None`.
4271
    ///
4272
    /// # Panics
4273
    ///
4274
    /// `new_slice_from_suffix` panics if `T` is a zero-sized type.
4275
    #[inline]
4276
0
    pub fn new_slice_from_suffix(bytes: B, count: usize) -> Option<(B, Ref<B, [T]>)> {
4277
0
        let expected_len = match mem::size_of::<T>().checked_mul(count) {
4278
0
            Some(len) => len,
4279
0
            None => return None,
4280
        };
4281
0
        let split_at = bytes.len().checked_sub(expected_len)?;
4282
0
        let (bytes, suffix) = bytes.split_at(split_at);
4283
0
        Self::new_slice(suffix).map(move |l| (bytes, l))
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShBF_E21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroaEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerohEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroiEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerojEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerolEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeromEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeronEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerooEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerosEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerotEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroxEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroyEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSaE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSdE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSfE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSiE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSjE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSlE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSmE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSnE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSoE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSsE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShStE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSuE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSxE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefQShSyE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShBF_E21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroaEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerohEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroiEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerojEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerolEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeromEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeronEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerooEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerosEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZerotEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroxEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBN_3num7nonzero7NonZeroyEEE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSaE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSdE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSfE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSiE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSjE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSlE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSmE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSnE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSoE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSsE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShStE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSuE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSxE21new_slice_from_suffix0B7_
Unexecuted instantiation: _RNCNvMs2_CsiAAEnE8327y_8zerocopyINtB7_3RefRShSyE21new_slice_from_suffix0B7_
4284
0
    }
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShBD_E21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroaEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerohEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroiEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerojEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerolEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeromEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeronEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerooEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerosEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerotEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroxEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroyEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSaE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSdE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSfE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSiE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSjE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSlE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSmE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSnE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSoE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSsE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShStE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSuE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSxE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSyE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShBD_E21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroaEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerohEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroiEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerojEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerolEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeromEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeronEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerooEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerosEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerotEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroxEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroyEEE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSaE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSdE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSfE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSiE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSjE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSlE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSmE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSnE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSoE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSsE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShStE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSuE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSxE21new_slice_from_suffixB5_
Unexecuted instantiation: _RNvMs2_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSyE21new_slice_from_suffixB5_
4285
}
4286
4287
0
fn map_zeroed<B: ByteSliceMut, T: ?Sized>(opt: Option<Ref<B, T>>) -> Option<Ref<B, T>> {
4288
0
    match opt {
4289
0
        Some(mut r) => {
4290
0
            r.0.fill(0);
4291
0
            Some(r)
4292
        }
4293
0
        None => None,
4294
    }
4295
0
}
4296
4297
0
fn map_prefix_tuple_zeroed<B: ByteSliceMut, T: ?Sized>(
4298
0
    opt: Option<(Ref<B, T>, B)>,
4299
0
) -> Option<(Ref<B, T>, B)> {
4300
0
    match opt {
4301
0
        Some((mut r, rest)) => {
4302
0
            r.0.fill(0);
4303
0
            Some((r, rest))
4304
        }
4305
0
        None => None,
4306
    }
4307
0
}
4308
4309
0
fn map_suffix_tuple_zeroed<B: ByteSliceMut, T: ?Sized>(
4310
0
    opt: Option<(B, Ref<B, T>)>,
4311
0
) -> Option<(B, Ref<B, T>)> {
4312
0
    map_prefix_tuple_zeroed(opt.map(|(a, b)| (b, a))).map(|(a, b)| (b, a))
4313
0
}
4314
4315
impl<B, T> Ref<B, T>
4316
where
4317
    B: ByteSliceMut,
4318
{
4319
    /// Constructs a new `Ref` after zeroing the bytes.
4320
    ///
4321
    /// `new_zeroed` verifies that `bytes.len() == size_of::<T>()` and that
4322
    /// `bytes` is aligned to `align_of::<T>()`, and constructs a new `Ref`. If
4323
    /// either of these checks fail, it returns `None`.
4324
    ///
4325
    /// If the checks succeed, then `bytes` will be initialized to zero. This
4326
    /// can be useful when re-using buffers to ensure that sensitive data
4327
    /// previously stored in the buffer is not leaked.
4328
    #[inline(always)]
4329
0
    pub fn new_zeroed(bytes: B) -> Option<Ref<B, T>> {
4330
0
        map_zeroed(Self::new(bytes))
4331
0
    }
4332
4333
    /// Constructs a new `Ref` from the prefix of a byte slice, zeroing the
4334
    /// prefix.
4335
    ///
4336
    /// `new_from_prefix_zeroed` verifies that `bytes.len() >= size_of::<T>()`
4337
    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the first
4338
    /// `size_of::<T>()` bytes from `bytes` to construct a `Ref`, and returns
4339
    /// the remaining bytes to the caller. If either the length or alignment
4340
    /// checks fail, it returns `None`.
4341
    ///
4342
    /// If the checks succeed, then the prefix which is consumed will be
4343
    /// initialized to zero. This can be useful when re-using buffers to ensure
4344
    /// that sensitive data previously stored in the buffer is not leaked.
4345
    #[inline(always)]
4346
0
    pub fn new_from_prefix_zeroed(bytes: B) -> Option<(Ref<B, T>, B)> {
4347
0
        map_prefix_tuple_zeroed(Self::new_from_prefix(bytes))
4348
0
    }
4349
4350
    /// Constructs a new `Ref` from the suffix of a byte slice, zeroing the
4351
    /// suffix.
4352
    ///
4353
    /// `new_from_suffix_zeroed` verifies that `bytes.len() >= size_of::<T>()`
4354
    /// and that the last `size_of::<T>()` bytes of `bytes` are aligned to
4355
    /// `align_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4356
    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4357
    /// caller. If either the length or alignment checks fail, it returns
4358
    /// `None`.
4359
    ///
4360
    /// If the checks succeed, then the suffix which is consumed will be
4361
    /// initialized to zero. This can be useful when re-using buffers to ensure
4362
    /// that sensitive data previously stored in the buffer is not leaked.
4363
    #[inline(always)]
4364
0
    pub fn new_from_suffix_zeroed(bytes: B) -> Option<(B, Ref<B, T>)> {
4365
0
        map_suffix_tuple_zeroed(Self::new_from_suffix(bytes))
4366
0
    }
4367
}
4368
4369
impl<B, T> Ref<B, [T]>
4370
where
4371
    B: ByteSliceMut,
4372
{
4373
    /// Constructs a new `Ref` of a slice type after zeroing the bytes.
4374
    ///
4375
    /// `new_slice_zeroed` verifies that `bytes.len()` is a multiple of
4376
    /// `size_of::<T>()` and that `bytes` is aligned to `align_of::<T>()`, and
4377
    /// constructs a new `Ref`. If either of these checks fail, it returns
4378
    /// `None`.
4379
    ///
4380
    /// If the checks succeed, then `bytes` will be initialized to zero. This
4381
    /// can be useful when re-using buffers to ensure that sensitive data
4382
    /// previously stored in the buffer is not leaked.
4383
    ///
4384
    /// # Panics
4385
    ///
4386
    /// `new_slice` panics if `T` is a zero-sized type.
4387
    #[inline(always)]
4388
0
    pub fn new_slice_zeroed(bytes: B) -> Option<Ref<B, [T]>> {
4389
0
        map_zeroed(Self::new_slice(bytes))
4390
0
    }
4391
4392
    /// Constructs a new `Ref` of a slice type from the prefix of a byte slice,
4393
    /// after zeroing the bytes.
4394
    ///
4395
    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4396
    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4397
    /// first `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4398
    /// and returns the remaining bytes to the caller. It also ensures that
4399
    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4400
    /// length, alignment, or overflow checks fail, it returns `None`.
4401
    ///
4402
    /// If the checks succeed, then the suffix which is consumed will be
4403
    /// initialized to zero. This can be useful when re-using buffers to ensure
4404
    /// that sensitive data previously stored in the buffer is not leaked.
4405
    ///
4406
    /// # Panics
4407
    ///
4408
    /// `new_slice_from_prefix_zeroed` panics if `T` is a zero-sized type.
4409
    #[inline(always)]
4410
0
    pub fn new_slice_from_prefix_zeroed(bytes: B, count: usize) -> Option<(Ref<B, [T]>, B)> {
4411
0
        map_prefix_tuple_zeroed(Self::new_slice_from_prefix(bytes, count))
4412
0
    }
4413
4414
    /// Constructs a new `Ref` of a slice type from the prefix of a byte slice,
4415
    /// after zeroing the bytes.
4416
    ///
4417
    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4418
    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4419
    /// last `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4420
    /// and returns the preceding bytes to the caller. It also ensures that
4421
    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4422
    /// length, alignment, or overflow checks fail, it returns `None`.
4423
    ///
4424
    /// If the checks succeed, then the consumed suffix will be initialized to
4425
    /// zero. This can be useful when re-using buffers to ensure that sensitive
4426
    /// data previously stored in the buffer is not leaked.
4427
    ///
4428
    /// # Panics
4429
    ///
4430
    /// `new_slice_from_suffix_zeroed` panics if `T` is a zero-sized type.
4431
    #[inline(always)]
4432
0
    pub fn new_slice_from_suffix_zeroed(bytes: B, count: usize) -> Option<(B, Ref<B, [T]>)> {
4433
0
        map_suffix_tuple_zeroed(Self::new_slice_from_suffix(bytes, count))
4434
0
    }
4435
}
4436
4437
impl<B, T> Ref<B, T>
4438
where
4439
    B: ByteSlice,
4440
    T: Unaligned,
4441
{
4442
    /// Constructs a new `Ref` for a type with no alignment requirement.
4443
    ///
4444
    /// `new_unaligned` verifies that `bytes.len() == size_of::<T>()` and
4445
    /// constructs a new `Ref`. If the check fails, it returns `None`.
4446
    #[inline(always)]
4447
0
    pub fn new_unaligned(bytes: B) -> Option<Ref<B, T>> {
4448
0
        Ref::new(bytes)
4449
0
    }
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroaEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerohEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroiEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerojEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerolEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeromEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeronEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerooEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerosEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerotEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroxEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroyEEEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignaEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligndEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignfEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignhEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligniEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignjEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignlEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignmEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignnEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignoEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignsEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligntEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignuEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignxEE13new_unalignedB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignyEE13new_unalignedB5_
4450
4451
    /// Constructs a new `Ref` from the prefix of a byte slice for a type with
4452
    /// no alignment requirement.
4453
    ///
4454
    /// `new_unaligned_from_prefix` verifies that `bytes.len() >=
4455
    /// size_of::<T>()`. It consumes the first `size_of::<T>()` bytes from
4456
    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4457
    /// caller. If the length check fails, it returns `None`.
4458
    #[inline(always)]
4459
0
    pub fn new_unaligned_from_prefix(bytes: B) -> Option<(Ref<B, T>, B)> {
4460
0
        Ref::new_from_prefix(bytes)
4461
0
    }
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroaEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerohEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroiEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerojEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerolEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeromEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeronEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerooEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerosEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerotEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroxEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroyEEEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignaEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligndEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignfEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignhEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligniEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignjEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignlEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignmEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignnEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignoEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignsEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligntEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignuEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignxEE25new_unaligned_from_prefixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignyEE25new_unaligned_from_prefixB5_
4462
4463
    /// Constructs a new `Ref` from the suffix of a byte slice for a type with
4464
    /// no alignment requirement.
4465
    ///
4466
    /// `new_unaligned_from_suffix` verifies that `bytes.len() >=
4467
    /// size_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4468
    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4469
    /// caller. If the length check fails, it returns `None`.
4470
    #[inline(always)]
4471
0
    pub fn new_unaligned_from_suffix(bytes: B) -> Option<(B, Ref<B, T>)> {
4472
0
        Ref::new_from_suffix(bytes)
4473
0
    }
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroaEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerohEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroiEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerojEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerolEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeromEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeronEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerooEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerosEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerotEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroxEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroyEEEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignaEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligndEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignfEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignhEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligniEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignjEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignlEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignmEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignnEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignoEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignsEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligntEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignuEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignxEE25new_unaligned_from_suffixB5_
Unexecuted instantiation: _RNvMs5_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignyEE25new_unaligned_from_suffixB5_
4474
}
4475
4476
impl<B, T> Ref<B, [T]>
4477
where
4478
    B: ByteSlice,
4479
    T: Unaligned,
4480
{
4481
    /// Constructs a new `Ref` of a slice type with no alignment requirement.
4482
    ///
4483
    /// `new_slice_unaligned` verifies that `bytes.len()` is a multiple of
4484
    /// `size_of::<T>()` and constructs a new `Ref`. If the check fails, it
4485
    /// returns `None`.
4486
    ///
4487
    /// # Panics
4488
    ///
4489
    /// `new_slice` panics if `T` is a zero-sized type.
4490
    #[inline(always)]
4491
0
    pub fn new_slice_unaligned(bytes: B) -> Option<Ref<B, [T]>> {
4492
0
        Ref::new_slice(bytes)
4493
0
    }
4494
4495
    /// Constructs a new `Ref` of a slice type with no alignment requirement
4496
    /// from the prefix of a byte slice.
4497
    ///
4498
    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4499
    /// count`. It consumes the first `size_of::<T>() * count` bytes from
4500
    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4501
    /// caller. It also ensures that `sizeof::<T>() * count` does not overflow a
4502
    /// `usize`. If either the length, or overflow checks fail, it returns
4503
    /// `None`.
4504
    ///
4505
    /// # Panics
4506
    ///
4507
    /// `new_slice_unaligned_from_prefix` panics if `T` is a zero-sized type.
4508
    #[inline(always)]
4509
0
    pub fn new_slice_unaligned_from_prefix(bytes: B, count: usize) -> Option<(Ref<B, [T]>, B)> {
4510
0
        Ref::new_slice_from_prefix(bytes, count)
4511
0
    }
4512
4513
    /// Constructs a new `Ref` of a slice type with no alignment requirement
4514
    /// from the suffix of a byte slice.
4515
    ///
4516
    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4517
    /// count`. It consumes the last `size_of::<T>() * count` bytes from `bytes`
4518
    /// to construct a `Ref`, and returns the remaining bytes to the caller. It
4519
    /// also ensures that `sizeof::<T>() * count` does not overflow a `usize`.
4520
    /// If either the length, or overflow checks fail, it returns `None`.
4521
    ///
4522
    /// # Panics
4523
    ///
4524
    /// `new_slice_unaligned_from_suffix` panics if `T` is a zero-sized type.
4525
    #[inline(always)]
4526
0
    pub fn new_slice_unaligned_from_suffix(bytes: B, count: usize) -> Option<(B, Ref<B, [T]>)> {
4527
0
        Ref::new_slice_from_suffix(bytes, count)
4528
0
    }
4529
}
4530
4531
impl<B, T> Ref<B, T>
4532
where
4533
    B: ByteSliceMut,
4534
    T: Unaligned,
4535
{
4536
    /// Constructs a new `Ref` for a type with no alignment requirement, zeroing
4537
    /// the bytes.
4538
    ///
4539
    /// `new_unaligned_zeroed` verifies that `bytes.len() == size_of::<T>()` and
4540
    /// constructs a new `Ref`. If the check fails, it returns `None`.
4541
    ///
4542
    /// If the check succeeds, then `bytes` will be initialized to zero. This
4543
    /// can be useful when re-using buffers to ensure that sensitive data
4544
    /// previously stored in the buffer is not leaked.
4545
    #[inline(always)]
4546
0
    pub fn new_unaligned_zeroed(bytes: B) -> Option<Ref<B, T>> {
4547
0
        map_zeroed(Self::new_unaligned(bytes))
4548
0
    }
4549
4550
    /// Constructs a new `Ref` from the prefix of a byte slice for a type with
4551
    /// no alignment requirement, zeroing the prefix.
4552
    ///
4553
    /// `new_unaligned_from_prefix_zeroed` verifies that `bytes.len() >=
4554
    /// size_of::<T>()`. It consumes the first `size_of::<T>()` bytes from
4555
    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4556
    /// caller. If the length check fails, it returns `None`.
4557
    ///
4558
    /// If the check succeeds, then the prefix which is consumed will be
4559
    /// initialized to zero. This can be useful when re-using buffers to ensure
4560
    /// that sensitive data previously stored in the buffer is not leaked.
4561
    #[inline(always)]
4562
0
    pub fn new_unaligned_from_prefix_zeroed(bytes: B) -> Option<(Ref<B, T>, B)> {
4563
0
        map_prefix_tuple_zeroed(Self::new_unaligned_from_prefix(bytes))
4564
0
    }
4565
4566
    /// Constructs a new `Ref` from the suffix of a byte slice for a type with
4567
    /// no alignment requirement, zeroing the suffix.
4568
    ///
4569
    /// `new_unaligned_from_suffix_zeroed` verifies that `bytes.len() >=
4570
    /// size_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4571
    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4572
    /// caller. If the length check fails, it returns `None`.
4573
    ///
4574
    /// If the check succeeds, then the suffix which is consumed will be
4575
    /// initialized to zero. This can be useful when re-using buffers to ensure
4576
    /// that sensitive data previously stored in the buffer is not leaked.
4577
    #[inline(always)]
4578
0
    pub fn new_unaligned_from_suffix_zeroed(bytes: B) -> Option<(B, Ref<B, T>)> {
4579
0
        map_suffix_tuple_zeroed(Self::new_unaligned_from_suffix(bytes))
4580
0
    }
4581
}
4582
4583
impl<B, T> Ref<B, [T]>
4584
where
4585
    B: ByteSliceMut,
4586
    T: Unaligned,
4587
{
4588
    /// Constructs a new `Ref` for a slice type with no alignment requirement,
4589
    /// zeroing the bytes.
4590
    ///
4591
    /// `new_slice_unaligned_zeroed` verifies that `bytes.len()` is a multiple
4592
    /// of `size_of::<T>()` and constructs a new `Ref`. If the check fails, it
4593
    /// returns `None`.
4594
    ///
4595
    /// If the check succeeds, then `bytes` will be initialized to zero. This
4596
    /// can be useful when re-using buffers to ensure that sensitive data
4597
    /// previously stored in the buffer is not leaked.
4598
    ///
4599
    /// # Panics
4600
    ///
4601
    /// `new_slice` panics if `T` is a zero-sized type.
4602
    #[inline(always)]
4603
0
    pub fn new_slice_unaligned_zeroed(bytes: B) -> Option<Ref<B, [T]>> {
4604
0
        map_zeroed(Self::new_slice_unaligned(bytes))
4605
0
    }
4606
4607
    /// Constructs a new `Ref` of a slice type with no alignment requirement
4608
    /// from the prefix of a byte slice, after zeroing the bytes.
4609
    ///
4610
    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4611
    /// count`. It consumes the first `size_of::<T>() * count` bytes from
4612
    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4613
    /// caller. It also ensures that `sizeof::<T>() * count` does not overflow a
4614
    /// `usize`. If either the length, or overflow checks fail, it returns
4615
    /// `None`.
4616
    ///
4617
    /// If the checks succeed, then the prefix will be initialized to zero. This
4618
    /// can be useful when re-using buffers to ensure that sensitive data
4619
    /// previously stored in the buffer is not leaked.
4620
    ///
4621
    /// # Panics
4622
    ///
4623
    /// `new_slice_unaligned_from_prefix_zeroed` panics if `T` is a zero-sized
4624
    /// type.
4625
    #[inline(always)]
4626
0
    pub fn new_slice_unaligned_from_prefix_zeroed(
4627
0
        bytes: B,
4628
0
        count: usize,
4629
0
    ) -> Option<(Ref<B, [T]>, B)> {
4630
0
        map_prefix_tuple_zeroed(Self::new_slice_unaligned_from_prefix(bytes, count))
4631
0
    }
4632
4633
    /// Constructs a new `Ref` of a slice type with no alignment requirement
4634
    /// from the suffix of a byte slice, after zeroing the bytes.
4635
    ///
4636
    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4637
    /// count`. It consumes the last `size_of::<T>() * count` bytes from `bytes`
4638
    /// to construct a `Ref`, and returns the remaining bytes to the caller. It
4639
    /// also ensures that `sizeof::<T>() * count` does not overflow a `usize`.
4640
    /// If either the length, or overflow checks fail, it returns `None`.
4641
    ///
4642
    /// If the checks succeed, then the suffix will be initialized to zero. This
4643
    /// can be useful when re-using buffers to ensure that sensitive data
4644
    /// previously stored in the buffer is not leaked.
4645
    ///
4646
    /// # Panics
4647
    ///
4648
    /// `new_slice_unaligned_from_suffix_zeroed` panics if `T` is a zero-sized
4649
    /// type.
4650
    #[inline(always)]
4651
0
    pub fn new_slice_unaligned_from_suffix_zeroed(
4652
0
        bytes: B,
4653
0
        count: usize,
4654
0
    ) -> Option<(B, Ref<B, [T]>)> {
4655
0
        map_suffix_tuple_zeroed(Self::new_slice_unaligned_from_suffix(bytes, count))
4656
0
    }
4657
}
4658
4659
impl<'a, B, T> Ref<B, T>
4660
where
4661
    B: 'a + ByteSlice,
4662
    T: FromBytes,
4663
{
4664
    /// Converts this `Ref` into a reference.
4665
    ///
4666
    /// `into_ref` consumes the `Ref`, and returns a reference to `T`.
4667
    #[inline(always)]
4668
0
    pub fn into_ref(self) -> &'a T {
4669
0
        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4670
4671
        // SAFETY: According to the safety preconditions on
4672
        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4673
        // ensures that, given `B: 'a`, it is sound to drop `self` and still
4674
        // access the underlying memory using reads for `'a`.
4675
0
        unsafe { self.deref_helper() }
4676
0
    }
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroaEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerohEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroiEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerojEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerolEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeromEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeronEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerooEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerosEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerotEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroxEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroyEEE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShaE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShdE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShfE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShhE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShiE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShjE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShlE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShmE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShnE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShoE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShsE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShtE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShuE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShxE8into_refB5_
Unexecuted instantiation: _RNvMs9_CsiAAEnE8327y_8zerocopyINtB5_3RefRShyE8into_refB5_
4677
}
4678
4679
impl<'a, B, T> Ref<B, T>
4680
where
4681
    B: 'a + ByteSliceMut,
4682
    T: FromBytes + AsBytes,
4683
{
4684
    /// Converts this `Ref` into a mutable reference.
4685
    ///
4686
    /// `into_mut` consumes the `Ref`, and returns a mutable reference to `T`.
4687
    #[inline(always)]
4688
0
    pub fn into_mut(mut self) -> &'a mut T {
4689
0
        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4690
4691
        // SAFETY: According to the safety preconditions on
4692
        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4693
        // ensures that, given `B: 'a + ByteSliceMut`, it is sound to drop
4694
        // `self` and still access the underlying memory using both reads and
4695
        // writes for `'a`.
4696
0
        unsafe { self.deref_mut_helper() }
4697
0
    }
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroaEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerohEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroiEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerojEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerolEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeromEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeronEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerooEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerosEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerotEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroxEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroyEEE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShaE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShdE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShfE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShhE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShiE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShjE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShlE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShmE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShnE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShoE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShsE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShtE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShuE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShxE8into_mutB5_
Unexecuted instantiation: _RNvMsa_CsiAAEnE8327y_8zerocopyINtB5_3RefQShyE8into_mutB5_
4698
}
4699
4700
impl<'a, B, T> Ref<B, [T]>
4701
where
4702
    B: 'a + ByteSlice,
4703
    T: FromBytes,
4704
{
4705
    /// Converts this `Ref` into a slice reference.
4706
    ///
4707
    /// `into_slice` consumes the `Ref`, and returns a reference to `[T]`.
4708
    #[inline(always)]
4709
0
    pub fn into_slice(self) -> &'a [T] {
4710
0
        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4711
4712
        // SAFETY: According to the safety preconditions on
4713
        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4714
        // ensures that, given `B: 'a`, it is sound to drop `self` and still
4715
        // access the underlying memory using reads for `'a`.
4716
0
        unsafe { self.deref_slice_helper() }
4717
0
    }
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShBD_E10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroaEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerohEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroiEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerojEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerolEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeromEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeronEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerooEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerosEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerotEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroxEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroyEEE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSaE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSdE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSfE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSiE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSjE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSlE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSmE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSnE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSoE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSsE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShStE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSuE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSxE10into_sliceB5_
Unexecuted instantiation: _RNvMsb_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSyE10into_sliceB5_
4718
}
4719
4720
impl<'a, B, T> Ref<B, [T]>
4721
where
4722
    B: 'a + ByteSliceMut,
4723
    T: FromBytes + AsBytes,
4724
{
4725
    /// Converts this `Ref` into a mutable slice reference.
4726
    ///
4727
    /// `into_mut_slice` consumes the `Ref`, and returns a mutable reference to
4728
    /// `[T]`.
4729
    #[inline(always)]
4730
0
    pub fn into_mut_slice(mut self) -> &'a mut [T] {
4731
0
        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4732
4733
        // SAFETY: According to the safety preconditions on
4734
        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4735
        // ensures that, given `B: 'a + ByteSliceMut`, it is sound to drop
4736
        // `self` and still access the underlying memory using both reads and
4737
        // writes for `'a`.
4738
0
        unsafe { self.deref_mut_slice_helper() }
4739
0
    }
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShBD_E14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroaEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerohEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroiEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerojEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerolEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeromEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeronEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerooEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerosEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerotEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroxEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroyEEE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSaE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSdE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSfE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSiE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSjE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSlE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSmE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSnE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSoE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSsE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShStE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSuE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSxE14into_mut_sliceB5_
Unexecuted instantiation: _RNvMsc_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSyE14into_mut_sliceB5_
4740
}
4741
4742
impl<B, T> Ref<B, T>
4743
where
4744
    B: ByteSlice,
4745
    T: FromBytes,
4746
{
4747
    /// Creates an immutable reference to `T` with a specific lifetime.
4748
    ///
4749
    /// # Safety
4750
    ///
4751
    /// The type bounds on this method guarantee that it is safe to create an
4752
    /// immutable reference to `T` from `self`. However, since the lifetime `'a`
4753
    /// is not required to be shorter than the lifetime of the reference to
4754
    /// `self`, the caller must guarantee that the lifetime `'a` is valid for
4755
    /// this reference. In particular, the referent must exist for all of `'a`,
4756
    /// and no mutable references to the same memory may be constructed during
4757
    /// `'a`.
4758
0
    unsafe fn deref_helper<'a>(&self) -> &'a T {
4759
0
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4760
0
        #[allow(clippy::undocumented_unsafe_blocks)]
4761
0
        unsafe {
4762
0
            &*self.0.as_ptr().cast::<T>()
4763
0
        }
4764
0
    }
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroaEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerohEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroiEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerojEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerolEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeromEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeronEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerooEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerosEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerotEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroxEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroyEEE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShaE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShdE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShfE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShhE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShiE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShjE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShlE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShmE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShnE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShoE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShsE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShtE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShuE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShxE12deref_helperB5_
Unexecuted instantiation: _RNvMsd_CsiAAEnE8327y_8zerocopyINtB5_3RefRShyE12deref_helperB5_
4765
}
4766
4767
impl<B, T> Ref<B, T>
4768
where
4769
    B: ByteSliceMut,
4770
    T: FromBytes + AsBytes,
4771
{
4772
    /// Creates a mutable reference to `T` with a specific lifetime.
4773
    ///
4774
    /// # Safety
4775
    ///
4776
    /// The type bounds on this method guarantee that it is safe to create a
4777
    /// mutable reference to `T` from `self`. However, since the lifetime `'a`
4778
    /// is not required to be shorter than the lifetime of the reference to
4779
    /// `self`, the caller must guarantee that the lifetime `'a` is valid for
4780
    /// this reference. In particular, the referent must exist for all of `'a`,
4781
    /// and no other references - mutable or immutable - to the same memory may
4782
    /// be constructed during `'a`.
4783
0
    unsafe fn deref_mut_helper<'a>(&mut self) -> &'a mut T {
4784
0
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4785
0
        #[allow(clippy::undocumented_unsafe_blocks)]
4786
0
        unsafe {
4787
0
            &mut *self.0.as_mut_ptr().cast::<T>()
4788
0
        }
4789
0
    }
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroaEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerohEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroiEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerojEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerolEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeromEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeronEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerooEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerosEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZerotEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroxEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBK_3num7nonzero7NonZeroyEEE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShaE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShdE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShfE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShhE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShiE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShjE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShlE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShmE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShnE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShoE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShsE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShtE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShuE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShxE16deref_mut_helperB5_
Unexecuted instantiation: _RNvMse_CsiAAEnE8327y_8zerocopyINtB5_3RefQShyE16deref_mut_helperB5_
4790
}
4791
4792
impl<B, T> Ref<B, [T]>
4793
where
4794
    B: ByteSlice,
4795
    T: FromBytes,
4796
{
4797
    /// Creates an immutable reference to `[T]` with a specific lifetime.
4798
    ///
4799
    /// # Safety
4800
    ///
4801
    /// `deref_slice_helper` has the same safety requirements as `deref_helper`.
4802
0
    unsafe fn deref_slice_helper<'a>(&self) -> &'a [T] {
4803
0
        let len = self.0.len();
4804
0
        let elem_size = mem::size_of::<T>();
4805
0
        debug_assert_ne!(elem_size, 0);
4806
        // `Ref<_, [T]>` maintains the invariant that `size_of::<T>() > 0`.
4807
        // Thus, neither the mod nor division operations here can panic.
4808
        #[allow(clippy::arithmetic_side_effects)]
4809
0
        let elems = {
4810
0
            debug_assert_eq!(len % elem_size, 0);
4811
0
            len / elem_size
4812
0
        };
4813
0
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4814
0
        #[allow(clippy::undocumented_unsafe_blocks)]
4815
0
        unsafe {
4816
0
            slice::from_raw_parts(self.0.as_ptr().cast::<T>(), elems)
4817
0
        }
4818
0
    }
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShBD_E18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroaEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerohEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroiEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerojEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerolEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeromEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeronEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerooEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerosEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerotEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroxEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroyEEE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSaE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSdE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSfE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSiE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSjE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSlE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSmE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSnE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSoE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSsE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShStE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSuE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSxE18deref_slice_helperB5_
Unexecuted instantiation: _RNvMsf_CsiAAEnE8327y_8zerocopyINtB5_3RefRShSyE18deref_slice_helperB5_
4819
}
4820
4821
impl<B, T> Ref<B, [T]>
4822
where
4823
    B: ByteSliceMut,
4824
    T: FromBytes + AsBytes,
4825
{
4826
    /// Creates a mutable reference to `[T]` with a specific lifetime.
4827
    ///
4828
    /// # Safety
4829
    ///
4830
    /// `deref_mut_slice_helper` has the same safety requirements as
4831
    /// `deref_mut_helper`.
4832
0
    unsafe fn deref_mut_slice_helper<'a>(&mut self) -> &'a mut [T] {
4833
0
        let len = self.0.len();
4834
0
        let elem_size = mem::size_of::<T>();
4835
0
        debug_assert_ne!(elem_size, 0);
4836
        // `Ref<_, [T]>` maintains the invariant that `size_of::<T>() > 0`.
4837
        // Thus, neither the mod nor division operations here can panic.
4838
        #[allow(clippy::arithmetic_side_effects)]
4839
0
        let elems = {
4840
0
            debug_assert_eq!(len % elem_size, 0);
4841
0
            len / elem_size
4842
0
        };
4843
0
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4844
0
        #[allow(clippy::undocumented_unsafe_blocks)]
4845
0
        unsafe {
4846
0
            slice::from_raw_parts_mut(self.0.as_mut_ptr().cast::<T>(), elems)
4847
0
        }
4848
0
    }
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShBD_E22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroaEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerohEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroiEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerojEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerolEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeromEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeronEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerooEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerosEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZerotEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroxEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3num7nonzero7NonZeroyEEE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSaE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSdE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSfE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSiE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSjE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSlE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSmE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSnE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSoE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSsE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShStE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSuE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSxE22deref_mut_slice_helperB5_
Unexecuted instantiation: _RNvMsg_CsiAAEnE8327y_8zerocopyINtB5_3RefQShSyE22deref_mut_slice_helperB5_
4849
}
4850
4851
impl<B, T> Ref<B, T>
4852
where
4853
    B: ByteSlice,
4854
    T: ?Sized,
4855
{
4856
    /// Gets the underlying bytes.
4857
    #[inline]
4858
0
    pub fn bytes(&self) -> &[u8] {
4859
0
        &self.0
4860
0
    }
4861
}
4862
4863
impl<B, T> Ref<B, T>
4864
where
4865
    B: ByteSliceMut,
4866
    T: ?Sized,
4867
{
4868
    /// Gets the underlying bytes mutably.
4869
    #[inline]
4870
0
    pub fn bytes_mut(&mut self) -> &mut [u8] {
4871
0
        &mut self.0
4872
0
    }
4873
}
4874
4875
impl<B, T> Ref<B, T>
4876
where
4877
    B: ByteSlice,
4878
    T: FromBytes,
4879
{
4880
    /// Reads a copy of `T`.
4881
    #[inline]
4882
0
    pub fn read(&self) -> T {
4883
0
        // SAFETY: Because of the invariants on `Ref`, we know that `self.0` is
4884
0
        // at least `size_of::<T>()` bytes long, and that it is at least as
4885
0
        // aligned as `align_of::<T>()`. Because `T: FromBytes`, it is sound to
4886
0
        // interpret these bytes as a `T`.
4887
0
        unsafe { ptr::read(self.0.as_ptr().cast::<T>()) }
4888
0
    }
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroaEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerohEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroiEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerojEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerolEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeromEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeronEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerooEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerosEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZerotEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroxEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB19_3num7nonzero7NonZeroyEEEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignaEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligndEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignfEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignhEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligniEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignjEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignlEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignmEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignnEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignoEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignsEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnaligntEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignuEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignxEE4readB5_
Unexecuted instantiation: _RNvMsj_CsiAAEnE8327y_8zerocopyINtB5_3RefRShINtNtB5_8wrappers7UnalignyEE4readB5_
4889
}
4890
4891
impl<B, T> Ref<B, T>
4892
where
4893
    B: ByteSliceMut,
4894
    T: AsBytes,
4895
{
4896
    /// Writes the bytes of `t` and then forgets `t`.
4897
    #[inline]
4898
0
    pub fn write(&mut self, t: T) {
4899
0
        // SAFETY: Because of the invariants on `Ref`, we know that `self.0` is
4900
0
        // at least `size_of::<T>()` bytes long, and that it is at least as
4901
0
        // aligned as `align_of::<T>()`. Writing `t` to the buffer will allow
4902
0
        // all of the bytes of `t` to be accessed as a `[u8]`, but because `T:
4903
0
        // AsBytes`, we know this is sound.
4904
0
        unsafe { ptr::write(self.0.as_mut_ptr().cast::<T>(), t) }
4905
0
    }
4906
}
4907
4908
impl<B, T> Deref for Ref<B, T>
4909
where
4910
    B: ByteSlice,
4911
    T: FromBytes,
4912
{
4913
    type Target = T;
4914
    #[inline]
4915
0
    fn deref(&self) -> &T {
4916
0
        // SAFETY: This is sound because the lifetime of `self` is the same as
4917
0
        // the lifetime of the return value, meaning that a) the returned
4918
0
        // reference cannot outlive `self` and, b) no mutable methods on `self`
4919
0
        // can be called during the lifetime of the returned reference. See the
4920
0
        // documentation on `deref_helper` for what invariants we are required
4921
0
        // to uphold.
4922
0
        unsafe { self.deref_helper() }
4923
0
    }
4924
}
4925
4926
impl<B, T> DerefMut for Ref<B, T>
4927
where
4928
    B: ByteSliceMut,
4929
    T: FromBytes + AsBytes,
4930
{
4931
    #[inline]
4932
0
    fn deref_mut(&mut self) -> &mut T {
4933
0
        // SAFETY: This is sound because the lifetime of `self` is the same as
4934
0
        // the lifetime of the return value, meaning that a) the returned
4935
0
        // reference cannot outlive `self` and, b) no other methods on `self`
4936
0
        // can be called during the lifetime of the returned reference. See the
4937
0
        // documentation on `deref_mut_helper` for what invariants we are
4938
0
        // required to uphold.
4939
0
        unsafe { self.deref_mut_helper() }
4940
0
    }
4941
}
4942
4943
impl<B, T> Deref for Ref<B, [T]>
4944
where
4945
    B: ByteSlice,
4946
    T: FromBytes,
4947
{
4948
    type Target = [T];
4949
    #[inline]
4950
0
    fn deref(&self) -> &[T] {
4951
0
        // SAFETY: This is sound because the lifetime of `self` is the same as
4952
0
        // the lifetime of the return value, meaning that a) the returned
4953
0
        // reference cannot outlive `self` and, b) no mutable methods on `self`
4954
0
        // can be called during the lifetime of the returned reference. See the
4955
0
        // documentation on `deref_slice_helper` for what invariants we are
4956
0
        // required to uphold.
4957
0
        unsafe { self.deref_slice_helper() }
4958
0
    }
4959
}
4960
4961
impl<B, T> DerefMut for Ref<B, [T]>
4962
where
4963
    B: ByteSliceMut,
4964
    T: FromBytes + AsBytes,
4965
{
4966
    #[inline]
4967
0
    fn deref_mut(&mut self) -> &mut [T] {
4968
0
        // SAFETY: This is sound because the lifetime of `self` is the same as
4969
0
        // the lifetime of the return value, meaning that a) the returned
4970
0
        // reference cannot outlive `self` and, b) no other methods on `self`
4971
0
        // can be called during the lifetime of the returned reference. See the
4972
0
        // documentation on `deref_mut_slice_helper` for what invariants we are
4973
0
        // required to uphold.
4974
0
        unsafe { self.deref_mut_slice_helper() }
4975
0
    }
4976
}
4977
4978
impl<T, B> Display for Ref<B, T>
4979
where
4980
    B: ByteSlice,
4981
    T: FromBytes + Display,
4982
{
4983
    #[inline]
4984
0
    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
4985
0
        let inner: &T = self;
4986
0
        inner.fmt(fmt)
4987
0
    }
4988
}
4989
4990
impl<T, B> Display for Ref<B, [T]>
4991
where
4992
    B: ByteSlice,
4993
    T: FromBytes,
4994
    [T]: Display,
4995
{
4996
    #[inline]
4997
0
    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
4998
0
        let inner: &[T] = self;
4999
0
        inner.fmt(fmt)
5000
0
    }
5001
}
5002
5003
impl<T, B> Debug for Ref<B, T>
5004
where
5005
    B: ByteSlice,
5006
    T: FromBytes + Debug,
5007
{
5008
    #[inline]
5009
0
    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
5010
0
        let inner: &T = self;
5011
0
        fmt.debug_tuple("Ref").field(&inner).finish()
5012
0
    }
5013
}
5014
5015
impl<T, B> Debug for Ref<B, [T]>
5016
where
5017
    B: ByteSlice,
5018
    T: FromBytes + Debug,
5019
{
5020
    #[inline]
5021
0
    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
5022
0
        let inner: &[T] = self;
5023
0
        fmt.debug_tuple("Ref").field(&inner).finish()
5024
0
    }
5025
}
5026
5027
impl<T, B> Eq for Ref<B, T>
5028
where
5029
    B: ByteSlice,
5030
    T: FromBytes + Eq,
5031
{
5032
}
5033
5034
impl<T, B> Eq for Ref<B, [T]>
5035
where
5036
    B: ByteSlice,
5037
    T: FromBytes + Eq,
5038
{
5039
}
5040
5041
impl<T, B> PartialEq for Ref<B, T>
5042
where
5043
    B: ByteSlice,
5044
    T: FromBytes + PartialEq,
5045
{
5046
    #[inline]
5047
0
    fn eq(&self, other: &Self) -> bool {
5048
0
        self.deref().eq(other.deref())
5049
0
    }
5050
}
5051
5052
impl<T, B> PartialEq for Ref<B, [T]>
5053
where
5054
    B: ByteSlice,
5055
    T: FromBytes + PartialEq,
5056
{
5057
    #[inline]
5058
0
    fn eq(&self, other: &Self) -> bool {
5059
0
        self.deref().eq(other.deref())
5060
0
    }
5061
}
5062
5063
impl<T, B> Ord for Ref<B, T>
5064
where
5065
    B: ByteSlice,
5066
    T: FromBytes + Ord,
5067
{
5068
    #[inline]
5069
0
    fn cmp(&self, other: &Self) -> Ordering {
5070
0
        let inner: &T = self;
5071
0
        let other_inner: &T = other;
5072
0
        inner.cmp(other_inner)
5073
0
    }
5074
}
5075
5076
impl<T, B> Ord for Ref<B, [T]>
5077
where
5078
    B: ByteSlice,
5079
    T: FromBytes + Ord,
5080
{
5081
    #[inline]
5082
0
    fn cmp(&self, other: &Self) -> Ordering {
5083
0
        let inner: &[T] = self;
5084
0
        let other_inner: &[T] = other;
5085
0
        inner.cmp(other_inner)
5086
0
    }
5087
}
5088
5089
impl<T, B> PartialOrd for Ref<B, T>
5090
where
5091
    B: ByteSlice,
5092
    T: FromBytes + PartialOrd,
5093
{
5094
    #[inline]
5095
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
5096
0
        let inner: &T = self;
5097
0
        let other_inner: &T = other;
5098
0
        inner.partial_cmp(other_inner)
5099
0
    }
5100
}
5101
5102
impl<T, B> PartialOrd for Ref<B, [T]>
5103
where
5104
    B: ByteSlice,
5105
    T: FromBytes + PartialOrd,
5106
{
5107
    #[inline]
5108
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
5109
0
        let inner: &[T] = self;
5110
0
        let other_inner: &[T] = other;
5111
0
        inner.partial_cmp(other_inner)
5112
0
    }
5113
}
5114
5115
mod sealed {
5116
    pub trait ByteSliceSealed {}
5117
}
5118
5119
// ByteSlice and ByteSliceMut abstract over [u8] references (&[u8], &mut [u8],
5120
// Ref<[u8]>, RefMut<[u8]>, etc). We rely on various behaviors of these
5121
// references such as that a given reference will never changes its length
5122
// between calls to deref() or deref_mut(), and that split_at() works as
5123
// expected. If ByteSlice or ByteSliceMut were not sealed, consumers could
5124
// implement them in a way that violated these behaviors, and would break our
5125
// unsafe code. Thus, we seal them and implement it only for known-good
5126
// reference types. For the same reason, they're unsafe traits.
5127
5128
#[allow(clippy::missing_safety_doc)] // TODO(fxbug.dev/99068)
5129
/// A mutable or immutable reference to a byte slice.
5130
///
5131
/// `ByteSlice` abstracts over the mutability of a byte slice reference, and is
5132
/// implemented for various special reference types such as `Ref<[u8]>` and
5133
/// `RefMut<[u8]>`.
5134
///
5135
/// Note that, while it would be technically possible, `ByteSlice` is not
5136
/// implemented for [`Vec<u8>`], as the only way to implement the [`split_at`]
5137
/// method would involve reallocation, and `split_at` must be a very cheap
5138
/// operation in order for the utilities in this crate to perform as designed.
5139
///
5140
/// [`split_at`]: crate::ByteSlice::split_at
5141
// It may seem overkill to go to this length to ensure that this doc link never
5142
// breaks. We do this because it simplifies CI - it means that generating docs
5143
// always succeeds, so we don't need special logic to only generate docs under
5144
// certain features.
5145
#[cfg_attr(feature = "alloc", doc = "[`Vec<u8>`]: alloc::vec::Vec")]
5146
#[cfg_attr(
5147
    not(feature = "alloc"),
5148
    doc = "[`Vec<u8>`]: https://doc.rust-lang.org/std/vec/struct.Vec.html"
5149
)]
5150
pub unsafe trait ByteSlice: Deref<Target = [u8]> + Sized + sealed::ByteSliceSealed {
5151
    /// Are the [`Ref::into_ref`] and [`Ref::into_mut`] methods sound when used
5152
    /// with `Self`? If not, evaluating this constant must panic at compile
5153
    /// time.
5154
    ///
5155
    /// This exists to work around #716 on versions of zerocopy prior to 0.8.
5156
    ///
5157
    /// # Safety
5158
    ///
5159
    /// This may only be set to true if the following holds: Given the
5160
    /// following:
5161
    /// - `Self: 'a`
5162
    /// - `bytes: Self`
5163
    /// - `let ptr = bytes.as_ptr()`
5164
    ///
5165
    /// ...then:
5166
    /// - Using `ptr` to read the memory previously addressed by `bytes` is
5167
    ///   sound for `'a` even after `bytes` has been dropped.
5168
    /// - If `Self: ByteSliceMut`, using `ptr` to write the memory previously
5169
    ///   addressed by `bytes` is sound for `'a` even after `bytes` has been
5170
    ///   dropped.
5171
    #[doc(hidden)]
5172
    const INTO_REF_INTO_MUT_ARE_SOUND: bool;
5173
5174
    /// Gets a raw pointer to the first byte in the slice.
5175
    #[inline]
5176
0
    fn as_ptr(&self) -> *const u8 {
5177
0
        <[u8]>::as_ptr(self)
5178
0
    }
Unexecuted instantiation: _RNvYRShNtCsiAAEnE8327y_8zerocopy9ByteSlice6as_ptrB7_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core4cell3RefShENtCsiAAEnE8327y_8zerocopy9ByteSlice6as_ptrBE_
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core4cell6RefMutShENtCsiAAEnE8327y_8zerocopy9ByteSlice6as_ptrBH_
Unexecuted instantiation: _RNvYQShNtCsiAAEnE8327y_8zerocopy9ByteSlice6as_ptrB7_
5179
5180
    /// Splits the slice at the midpoint.
5181
    ///
5182
    /// `x.split_at(mid)` returns `x[..mid]` and `x[mid..]`.
5183
    ///
5184
    /// # Panics
5185
    ///
5186
    /// `x.split_at(mid)` panics if `mid > x.len()`.
5187
    fn split_at(self, mid: usize) -> (Self, Self);
5188
}
5189
5190
#[allow(clippy::missing_safety_doc)] // TODO(fxbug.dev/99068)
5191
/// A mutable reference to a byte slice.
5192
///
5193
/// `ByteSliceMut` abstracts over various ways of storing a mutable reference to
5194
/// a byte slice, and is implemented for various special reference types such as
5195
/// `RefMut<[u8]>`.
5196
pub unsafe trait ByteSliceMut: ByteSlice + DerefMut {
5197
    /// Gets a mutable raw pointer to the first byte in the slice.
5198
    #[inline]
5199
0
    fn as_mut_ptr(&mut self) -> *mut u8 {
5200
0
        <[u8]>::as_mut_ptr(self)
5201
0
    }
Unexecuted instantiation: _RNvYINtNtCsbQ8arDwx5Xq_4core4cell6RefMutShENtCsiAAEnE8327y_8zerocopy12ByteSliceMut10as_mut_ptrBH_
Unexecuted instantiation: _RNvYQShNtCsiAAEnE8327y_8zerocopy12ByteSliceMut10as_mut_ptrB7_
5202
}
5203
5204
impl<'a> sealed::ByteSliceSealed for &'a [u8] {}
5205
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5206
#[allow(clippy::undocumented_unsafe_blocks)]
5207
unsafe impl<'a> ByteSlice for &'a [u8] {
5208
    // SAFETY: If `&'b [u8]: 'a`, then the underlying memory is treated as
5209
    // borrowed immutably for `'a` even if the slice itself is dropped.
5210
    const INTO_REF_INTO_MUT_ARE_SOUND: bool = true;
5211
5212
    #[inline]
5213
0
    fn split_at(self, mid: usize) -> (Self, Self) {
5214
0
        <[u8]>::split_at(self, mid)
5215
0
    }
5216
}
5217
5218
impl<'a> sealed::ByteSliceSealed for &'a mut [u8] {}
5219
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5220
#[allow(clippy::undocumented_unsafe_blocks)]
5221
unsafe impl<'a> ByteSlice for &'a mut [u8] {
5222
    // SAFETY: If `&'b mut [u8]: 'a`, then the underlying memory is treated as
5223
    // borrowed mutably for `'a` even if the slice itself is dropped.
5224
    const INTO_REF_INTO_MUT_ARE_SOUND: bool = true;
5225
5226
    #[inline]
5227
0
    fn split_at(self, mid: usize) -> (Self, Self) {
5228
0
        <[u8]>::split_at_mut(self, mid)
5229
0
    }
5230
}
5231
5232
impl<'a> sealed::ByteSliceSealed for cell::Ref<'a, [u8]> {}
5233
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5234
#[allow(clippy::undocumented_unsafe_blocks)]
5235
unsafe impl<'a> ByteSlice for cell::Ref<'a, [u8]> {
5236
    const INTO_REF_INTO_MUT_ARE_SOUND: bool = if !cfg!(doc) {
5237
        panic!("Ref::into_ref and Ref::into_mut are unsound when used with core::cell::Ref; see https://github.com/google/zerocopy/issues/716")
5238
    } else {
5239
        // When compiling documentation, allow the evaluation of this constant
5240
        // to succeed. This doesn't represent a soundness hole - it just delays
5241
        // any error to runtime. The reason we need this is that, otherwise,
5242
        // `rustdoc` will fail when trying to document this item.
5243
        false
5244
    };
5245
5246
    #[inline]
5247
0
    fn split_at(self, mid: usize) -> (Self, Self) {
5248
0
        cell::Ref::map_split(self, |slice| <[u8]>::split_at(slice, mid))
5249
0
    }
5250
}
5251
5252
impl<'a> sealed::ByteSliceSealed for RefMut<'a, [u8]> {}
5253
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5254
#[allow(clippy::undocumented_unsafe_blocks)]
5255
unsafe impl<'a> ByteSlice for RefMut<'a, [u8]> {
5256
    const INTO_REF_INTO_MUT_ARE_SOUND: bool = if !cfg!(doc) {
5257
        panic!("Ref::into_ref and Ref::into_mut are unsound when used with core::cell::RefMut; see https://github.com/google/zerocopy/issues/716")
5258
    } else {
5259
        // When compiling documentation, allow the evaluation of this constant
5260
        // to succeed. This doesn't represent a soundness hole - it just delays
5261
        // any error to runtime. The reason we need this is that, otherwise,
5262
        // `rustdoc` will fail when trying to document this item.
5263
        false
5264
    };
5265
5266
    #[inline]
5267
0
    fn split_at(self, mid: usize) -> (Self, Self) {
5268
0
        RefMut::map_split(self, |slice| <[u8]>::split_at_mut(slice, mid))
5269
0
    }
5270
}
5271
5272
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5273
#[allow(clippy::undocumented_unsafe_blocks)]
5274
unsafe impl<'a> ByteSliceMut for &'a mut [u8] {}
5275
5276
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5277
#[allow(clippy::undocumented_unsafe_blocks)]
5278
unsafe impl<'a> ByteSliceMut for RefMut<'a, [u8]> {}
5279
5280
#[cfg(feature = "alloc")]
5281
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
5282
mod alloc_support {
5283
    use alloc::vec::Vec;
5284
5285
    use super::*;
5286
5287
    /// Extends a `Vec<T>` by pushing `additional` new items onto the end of the
5288
    /// vector. The new items are initialized with zeroes.
5289
    ///
5290
    /// # Panics
5291
    ///
5292
    /// Panics if `Vec::reserve(additional)` fails to reserve enough memory.
5293
    #[inline(always)]
5294
    pub fn extend_vec_zeroed<T: FromZeroes>(v: &mut Vec<T>, additional: usize) {
5295
        insert_vec_zeroed(v, v.len(), additional);
5296
    }
5297
5298
    /// Inserts `additional` new items into `Vec<T>` at `position`.
5299
    /// The new items are initialized with zeroes.
5300
    ///
5301
    /// # Panics
5302
    ///
5303
    /// * Panics if `position > v.len()`.
5304
    /// * Panics if `Vec::reserve(additional)` fails to reserve enough memory.
5305
    #[inline]
5306
    pub fn insert_vec_zeroed<T: FromZeroes>(v: &mut Vec<T>, position: usize, additional: usize) {
5307
        assert!(position <= v.len());
5308
        v.reserve(additional);
5309
        // SAFETY: The `reserve` call guarantees that these cannot overflow:
5310
        // * `ptr.add(position)`
5311
        // * `position + additional`
5312
        // * `v.len() + additional`
5313
        //
5314
        // `v.len() - position` cannot overflow because we asserted that
5315
        // `position <= v.len()`.
5316
        unsafe {
5317
            // This is a potentially overlapping copy.
5318
            let ptr = v.as_mut_ptr();
5319
            #[allow(clippy::arithmetic_side_effects)]
5320
            ptr.add(position).copy_to(ptr.add(position + additional), v.len() - position);
5321
            ptr.add(position).write_bytes(0, additional);
5322
            #[allow(clippy::arithmetic_side_effects)]
5323
            v.set_len(v.len() + additional);
5324
        }
5325
    }
5326
5327
    #[cfg(test)]
5328
    mod tests {
5329
        use core::convert::TryFrom as _;
5330
5331
        use super::*;
5332
5333
        #[test]
5334
        fn test_extend_vec_zeroed() {
5335
            // Test extending when there is an existing allocation.
5336
            let mut v = vec![100u64, 200, 300];
5337
            extend_vec_zeroed(&mut v, 3);
5338
            assert_eq!(v.len(), 6);
5339
            assert_eq!(&*v, &[100, 200, 300, 0, 0, 0]);
5340
            drop(v);
5341
5342
            // Test extending when there is no existing allocation.
5343
            let mut v: Vec<u64> = Vec::new();
5344
            extend_vec_zeroed(&mut v, 3);
5345
            assert_eq!(v.len(), 3);
5346
            assert_eq!(&*v, &[0, 0, 0]);
5347
            drop(v);
5348
        }
5349
5350
        #[test]
5351
        fn test_extend_vec_zeroed_zst() {
5352
            // Test extending when there is an existing (fake) allocation.
5353
            let mut v = vec![(), (), ()];
5354
            extend_vec_zeroed(&mut v, 3);
5355
            assert_eq!(v.len(), 6);
5356
            assert_eq!(&*v, &[(), (), (), (), (), ()]);
5357
            drop(v);
5358
5359
            // Test extending when there is no existing (fake) allocation.
5360
            let mut v: Vec<()> = Vec::new();
5361
            extend_vec_zeroed(&mut v, 3);
5362
            assert_eq!(&*v, &[(), (), ()]);
5363
            drop(v);
5364
        }
5365
5366
        #[test]
5367
        fn test_insert_vec_zeroed() {
5368
            // Insert at start (no existing allocation).
5369
            let mut v: Vec<u64> = Vec::new();
5370
            insert_vec_zeroed(&mut v, 0, 2);
5371
            assert_eq!(v.len(), 2);
5372
            assert_eq!(&*v, &[0, 0]);
5373
            drop(v);
5374
5375
            // Insert at start.
5376
            let mut v = vec![100u64, 200, 300];
5377
            insert_vec_zeroed(&mut v, 0, 2);
5378
            assert_eq!(v.len(), 5);
5379
            assert_eq!(&*v, &[0, 0, 100, 200, 300]);
5380
            drop(v);
5381
5382
            // Insert at middle.
5383
            let mut v = vec![100u64, 200, 300];
5384
            insert_vec_zeroed(&mut v, 1, 1);
5385
            assert_eq!(v.len(), 4);
5386
            assert_eq!(&*v, &[100, 0, 200, 300]);
5387
            drop(v);
5388
5389
            // Insert at end.
5390
            let mut v = vec![100u64, 200, 300];
5391
            insert_vec_zeroed(&mut v, 3, 1);
5392
            assert_eq!(v.len(), 4);
5393
            assert_eq!(&*v, &[100, 200, 300, 0]);
5394
            drop(v);
5395
        }
5396
5397
        #[test]
5398
        fn test_insert_vec_zeroed_zst() {
5399
            // Insert at start (no existing fake allocation).
5400
            let mut v: Vec<()> = Vec::new();
5401
            insert_vec_zeroed(&mut v, 0, 2);
5402
            assert_eq!(v.len(), 2);
5403
            assert_eq!(&*v, &[(), ()]);
5404
            drop(v);
5405
5406
            // Insert at start.
5407
            let mut v = vec![(), (), ()];
5408
            insert_vec_zeroed(&mut v, 0, 2);
5409
            assert_eq!(v.len(), 5);
5410
            assert_eq!(&*v, &[(), (), (), (), ()]);
5411
            drop(v);
5412
5413
            // Insert at middle.
5414
            let mut v = vec![(), (), ()];
5415
            insert_vec_zeroed(&mut v, 1, 1);
5416
            assert_eq!(v.len(), 4);
5417
            assert_eq!(&*v, &[(), (), (), ()]);
5418
            drop(v);
5419
5420
            // Insert at end.
5421
            let mut v = vec![(), (), ()];
5422
            insert_vec_zeroed(&mut v, 3, 1);
5423
            assert_eq!(v.len(), 4);
5424
            assert_eq!(&*v, &[(), (), (), ()]);
5425
            drop(v);
5426
        }
5427
5428
        #[test]
5429
        fn test_new_box_zeroed() {
5430
            assert_eq!(*u64::new_box_zeroed(), 0);
5431
        }
5432
5433
        #[test]
5434
        fn test_new_box_zeroed_array() {
5435
            drop(<[u32; 0x1000]>::new_box_zeroed());
5436
        }
5437
5438
        #[test]
5439
        fn test_new_box_zeroed_zst() {
5440
            // This test exists in order to exercise unsafe code, especially
5441
            // when running under Miri.
5442
            #[allow(clippy::unit_cmp)]
5443
            {
5444
                assert_eq!(*<()>::new_box_zeroed(), ());
5445
            }
5446
        }
5447
5448
        #[test]
5449
        fn test_new_box_slice_zeroed() {
5450
            let mut s: Box<[u64]> = u64::new_box_slice_zeroed(3);
5451
            assert_eq!(s.len(), 3);
5452
            assert_eq!(&*s, &[0, 0, 0]);
5453
            s[1] = 3;
5454
            assert_eq!(&*s, &[0, 3, 0]);
5455
        }
5456
5457
        #[test]
5458
        fn test_new_box_slice_zeroed_empty() {
5459
            let s: Box<[u64]> = u64::new_box_slice_zeroed(0);
5460
            assert_eq!(s.len(), 0);
5461
        }
5462
5463
        #[test]
5464
        fn test_new_box_slice_zeroed_zst() {
5465
            let mut s: Box<[()]> = <()>::new_box_slice_zeroed(3);
5466
            assert_eq!(s.len(), 3);
5467
            assert!(s.get(10).is_none());
5468
            // This test exists in order to exercise unsafe code, especially
5469
            // when running under Miri.
5470
            #[allow(clippy::unit_cmp)]
5471
            {
5472
                assert_eq!(s[1], ());
5473
            }
5474
            s[2] = ();
5475
        }
5476
5477
        #[test]
5478
        fn test_new_box_slice_zeroed_zst_empty() {
5479
            let s: Box<[()]> = <()>::new_box_slice_zeroed(0);
5480
            assert_eq!(s.len(), 0);
5481
        }
5482
5483
        #[test]
5484
        #[should_panic(expected = "mem::size_of::<Self>() * len overflows `usize`")]
5485
        fn test_new_box_slice_zeroed_panics_mul_overflow() {
5486
            let _ = u16::new_box_slice_zeroed(usize::MAX);
5487
        }
5488
5489
        #[test]
5490
        #[should_panic(expected = "assertion failed: size <= max_alloc")]
5491
        fn test_new_box_slice_zeroed_panics_isize_overflow() {
5492
            let max = usize::try_from(isize::MAX).unwrap();
5493
            let _ = u16::new_box_slice_zeroed((max / mem::size_of::<u16>()) + 1);
5494
        }
5495
    }
5496
}
5497
5498
#[cfg(feature = "alloc")]
5499
#[doc(inline)]
5500
pub use alloc_support::*;
5501
5502
#[cfg(test)]
5503
mod tests {
5504
    #![allow(clippy::unreadable_literal)]
5505
5506
    use core::{cell::UnsafeCell, convert::TryInto as _, ops::Deref};
5507
5508
    use static_assertions::assert_impl_all;
5509
5510
    use super::*;
5511
    use crate::util::testutil::*;
5512
5513
    // An unsized type.
5514
    //
5515
    // This is used to test the custom derives of our traits. The `[u8]` type
5516
    // gets a hand-rolled impl, so it doesn't exercise our custom derives.
5517
    #[derive(Debug, Eq, PartialEq, FromZeroes, FromBytes, AsBytes, Unaligned)]
5518
    #[repr(transparent)]
5519
    struct Unsized([u8]);
5520
5521
    impl Unsized {
5522
        fn from_mut_slice(slc: &mut [u8]) -> &mut Unsized {
5523
            // SAFETY: This *probably* sound - since the layouts of `[u8]` and
5524
            // `Unsized` are the same, so are the layouts of `&mut [u8]` and
5525
            // `&mut Unsized`. [1] Even if it turns out that this isn't actually
5526
            // guaranteed by the language spec, we can just change this since
5527
            // it's in test code.
5528
            //
5529
            // [1] https://github.com/rust-lang/unsafe-code-guidelines/issues/375
5530
            unsafe { mem::transmute(slc) }
5531
        }
5532
    }
5533
5534
    /// Tests of when a sized `DstLayout` is extended with a sized field.
5535
    #[allow(clippy::decimal_literal_representation)]
5536
    #[test]
5537
    fn test_dst_layout_extend_sized_with_sized() {
5538
        // This macro constructs a layout corresponding to a `u8` and extends it
5539
        // with a zero-sized trailing field of given alignment `n`. The macro
5540
        // tests that the resulting layout has both size and alignment `min(n,
5541
        // P)` for all valid values of `repr(packed(P))`.
5542
        macro_rules! test_align_is_size {
5543
            ($n:expr) => {
5544
                let base = DstLayout::for_type::<u8>();
5545
                let trailing_field = DstLayout::for_type::<elain::Align<$n>>();
5546
5547
                let packs =
5548
                    core::iter::once(None).chain((0..29).map(|p| NonZeroUsize::new(2usize.pow(p))));
5549
5550
                for pack in packs {
5551
                    let composite = base.extend(trailing_field, pack);
5552
                    let max_align = pack.unwrap_or(DstLayout::CURRENT_MAX_ALIGN);
5553
                    let align = $n.min(max_align.get());
5554
                    assert_eq!(
5555
                        composite,
5556
                        DstLayout {
5557
                            align: NonZeroUsize::new(align).unwrap(),
5558
                            size_info: SizeInfo::Sized { _size: align }
5559
                        }
5560
                    )
5561
                }
5562
            };
5563
        }
5564
5565
        test_align_is_size!(1);
5566
        test_align_is_size!(2);
5567
        test_align_is_size!(4);
5568
        test_align_is_size!(8);
5569
        test_align_is_size!(16);
5570
        test_align_is_size!(32);
5571
        test_align_is_size!(64);
5572
        test_align_is_size!(128);
5573
        test_align_is_size!(256);
5574
        test_align_is_size!(512);
5575
        test_align_is_size!(1024);
5576
        test_align_is_size!(2048);
5577
        test_align_is_size!(4096);
5578
        test_align_is_size!(8192);
5579
        test_align_is_size!(16384);
5580
        test_align_is_size!(32768);
5581
        test_align_is_size!(65536);
5582
        test_align_is_size!(131072);
5583
        test_align_is_size!(262144);
5584
        test_align_is_size!(524288);
5585
        test_align_is_size!(1048576);
5586
        test_align_is_size!(2097152);
5587
        test_align_is_size!(4194304);
5588
        test_align_is_size!(8388608);
5589
        test_align_is_size!(16777216);
5590
        test_align_is_size!(33554432);
5591
        test_align_is_size!(67108864);
5592
        test_align_is_size!(33554432);
5593
        test_align_is_size!(134217728);
5594
        test_align_is_size!(268435456);
5595
    }
5596
5597
    /// Tests of when a sized `DstLayout` is extended with a DST field.
5598
    #[test]
5599
    fn test_dst_layout_extend_sized_with_dst() {
5600
        // Test that for all combinations of real-world alignments and
5601
        // `repr_packed` values, that the extension of a sized `DstLayout`` with
5602
        // a DST field correctly computes the trailing offset in the composite
5603
        // layout.
5604
5605
        let aligns = (0..29).map(|p| NonZeroUsize::new(2usize.pow(p)).unwrap());
5606
        let packs = core::iter::once(None).chain(aligns.clone().map(Some));
5607
5608
        for align in aligns {
5609
            for pack in packs.clone() {
5610
                let base = DstLayout::for_type::<u8>();
5611
                let elem_size = 42;
5612
                let trailing_field_offset = 11;
5613
5614
                let trailing_field = DstLayout {
5615
                    align,
5616
                    size_info: SizeInfo::SliceDst(TrailingSliceLayout {
5617
                        _elem_size: elem_size,
5618
                        _offset: 11,
5619
                    }),
5620
                };
5621
5622
                let composite = base.extend(trailing_field, pack);
5623
5624
                let max_align = pack.unwrap_or(DstLayout::CURRENT_MAX_ALIGN).get();
5625
5626
                let align = align.get().min(max_align);
5627
5628
                assert_eq!(
5629
                    composite,
5630
                    DstLayout {
5631
                        align: NonZeroUsize::new(align).unwrap(),
5632
                        size_info: SizeInfo::SliceDst(TrailingSliceLayout {
5633
                            _elem_size: elem_size,
5634
                            _offset: align + trailing_field_offset,
5635
                        }),
5636
                    }
5637
                )
5638
            }
5639
        }
5640
    }
5641
5642
    /// Tests that calling `pad_to_align` on a sized `DstLayout` adds the
5643
    /// expected amount of trailing padding.
5644
    #[test]
5645
    fn test_dst_layout_pad_to_align_with_sized() {
5646
        // For all valid alignments `align`, construct a one-byte layout aligned
5647
        // to `align`, call `pad_to_align`, and assert that the size of the
5648
        // resulting layout is equal to `align`.
5649
        for align in (0..29).map(|p| NonZeroUsize::new(2usize.pow(p)).unwrap()) {
5650
            let layout = DstLayout { align, size_info: SizeInfo::Sized { _size: 1 } };
5651
5652
            assert_eq!(
5653
                layout.pad_to_align(),
5654
                DstLayout { align, size_info: SizeInfo::Sized { _size: align.get() } }
5655
            );
5656
        }
5657
5658
        // Test explicitly-provided combinations of unpadded and padded
5659
        // counterparts.
5660
5661
        macro_rules! test {
5662
            (unpadded { size: $unpadded_size:expr, align: $unpadded_align:expr }
5663
                => padded { size: $padded_size:expr, align: $padded_align:expr }) => {
5664
                let unpadded = DstLayout {
5665
                    align: NonZeroUsize::new($unpadded_align).unwrap(),
5666
                    size_info: SizeInfo::Sized { _size: $unpadded_size },
5667
                };
5668
                let padded = unpadded.pad_to_align();
5669
5670
                assert_eq!(
5671
                    padded,
5672
                    DstLayout {
5673
                        align: NonZeroUsize::new($padded_align).unwrap(),
5674
                        size_info: SizeInfo::Sized { _size: $padded_size },
5675
                    }
5676
                );
5677
            };
5678
        }
5679
5680
        test!(unpadded { size: 0, align: 4 } => padded { size: 0, align: 4 });
5681
        test!(unpadded { size: 1, align: 4 } => padded { size: 4, align: 4 });
5682
        test!(unpadded { size: 2, align: 4 } => padded { size: 4, align: 4 });
5683
        test!(unpadded { size: 3, align: 4 } => padded { size: 4, align: 4 });
5684
        test!(unpadded { size: 4, align: 4 } => padded { size: 4, align: 4 });
5685
        test!(unpadded { size: 5, align: 4 } => padded { size: 8, align: 4 });
5686
        test!(unpadded { size: 6, align: 4 } => padded { size: 8, align: 4 });
5687
        test!(unpadded { size: 7, align: 4 } => padded { size: 8, align: 4 });
5688
        test!(unpadded { size: 8, align: 4 } => padded { size: 8, align: 4 });
5689
5690
        let current_max_align = DstLayout::CURRENT_MAX_ALIGN.get();
5691
5692
        test!(unpadded { size: 1, align: current_max_align }
5693
            => padded { size: current_max_align, align: current_max_align });
5694
5695
        test!(unpadded { size: current_max_align + 1, align: current_max_align }
5696
            => padded { size: current_max_align * 2, align: current_max_align });
5697
    }
5698
5699
    /// Tests that calling `pad_to_align` on a DST `DstLayout` is a no-op.
5700
    #[test]
5701
    fn test_dst_layout_pad_to_align_with_dst() {
5702
        for align in (0..29).map(|p| NonZeroUsize::new(2usize.pow(p)).unwrap()) {
5703
            for offset in 0..10 {
5704
                for elem_size in 0..10 {
5705
                    let layout = DstLayout {
5706
                        align,
5707
                        size_info: SizeInfo::SliceDst(TrailingSliceLayout {
5708
                            _offset: offset,
5709
                            _elem_size: elem_size,
5710
                        }),
5711
                    };
5712
                    assert_eq!(layout.pad_to_align(), layout);
5713
                }
5714
            }
5715
        }
5716
    }
5717
5718
    // This test takes a long time when running under Miri, so we skip it in
5719
    // that case. This is acceptable because this is a logic test that doesn't
5720
    // attempt to expose UB.
5721
    #[test]
5722
    #[cfg_attr(miri, ignore)]
5723
    fn testvalidate_cast_and_convert_metadata() {
5724
        impl From<usize> for SizeInfo {
5725
            fn from(_size: usize) -> SizeInfo {
5726
                SizeInfo::Sized { _size }
5727
            }
5728
        }
5729
5730
        impl From<(usize, usize)> for SizeInfo {
5731
            fn from((_offset, _elem_size): (usize, usize)) -> SizeInfo {
5732
                SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size })
5733
            }
5734
        }
5735
5736
        fn layout<S: Into<SizeInfo>>(s: S, align: usize) -> DstLayout {
5737
            DstLayout { size_info: s.into(), align: NonZeroUsize::new(align).unwrap() }
5738
        }
5739
5740
        /// This macro accepts arguments in the form of:
5741
        ///
5742
        ///           layout(_, _, _).validate(_, _, _), Ok(Some((_, _)))
5743
        ///                  |  |  |           |  |  |            |  |
5744
        ///    base_size ----+  |  |           |  |  |            |  |
5745
        ///    align -----------+  |           |  |  |            |  |
5746
        ///    trailing_size ------+           |  |  |            |  |
5747
        ///    addr ---------------------------+  |  |            |  |
5748
        ///    bytes_len -------------------------+  |            |  |
5749
        ///    cast_type ----------------------------+            |  |
5750
        ///    elems ---------------------------------------------+  |
5751
        ///    split_at ---------------------------------------------+
5752
        ///
5753
        /// `.validate` is shorthand for `.validate_cast_and_convert_metadata`
5754
        /// for brevity.
5755
        ///
5756
        /// Each argument can either be an iterator or a wildcard. Each
5757
        /// wildcarded variable is implicitly replaced by an iterator over a
5758
        /// representative sample of values for that variable. Each `test!`
5759
        /// invocation iterates over every combination of values provided by
5760
        /// each variable's iterator (ie, the cartesian product) and validates
5761
        /// that the results are expected.
5762
        ///
5763
        /// The final argument uses the same syntax, but it has a different
5764
        /// meaning:
5765
        /// - If it is `Ok(pat)`, then the pattern `pat` is supplied to
5766
        ///   `assert_matches!` to validate the computed result for each
5767
        ///   combination of input values.
5768
        /// - If it is `Err(msg)`, then `test!` validates that the call to
5769
        ///   `validate_cast_and_convert_metadata` panics with the given panic
5770
        ///   message.
5771
        ///
5772
        /// Note that the meta-variables that match these variables have the
5773
        /// `tt` type, and some valid expressions are not valid `tt`s (such as
5774
        /// `a..b`). In this case, wrap the expression in parentheses, and it
5775
        /// will become valid `tt`.
5776
        macro_rules! test {
5777
            ($(:$sizes:expr =>)?
5778
                layout($size:tt, $align:tt)
5779
                .validate($addr:tt, $bytes_len:tt, $cast_type:tt), $expect:pat $(,)?
5780
            ) => {
5781
                itertools::iproduct!(
5782
                    test!(@generate_size $size),
5783
                    test!(@generate_align $align),
5784
                    test!(@generate_usize $addr),
5785
                    test!(@generate_usize $bytes_len),
5786
                    test!(@generate_cast_type $cast_type)
5787
                ).for_each(|(size_info, align, addr, bytes_len, cast_type)| {
5788
                    // Temporarily disable the panic hook installed by the test
5789
                    // harness. If we don't do this, all panic messages will be
5790
                    // kept in an internal log. On its own, this isn't a
5791
                    // problem, but if a non-caught panic ever happens (ie, in
5792
                    // code later in this test not in this macro), all of the
5793
                    // previously-buffered messages will be dumped, hiding the
5794
                    // real culprit.
5795
                    let previous_hook = std::panic::take_hook();
5796
                    // I don't understand why, but this seems to be required in
5797
                    // addition to the previous line.
5798
                    std::panic::set_hook(Box::new(|_| {}));
5799
                    let actual = std::panic::catch_unwind(|| {
5800
                        layout(size_info, align).validate_cast_and_convert_metadata(addr, bytes_len, cast_type)
5801
                    }).map_err(|d| {
5802
                        *d.downcast::<&'static str>().expect("expected string panic message").as_ref()
5803
                    });
5804
                    std::panic::set_hook(previous_hook);
5805
5806
                    assert_matches::assert_matches!(
5807
                        actual, $expect,
5808
                        "layout({size_info:?}, {align}).validate_cast_and_convert_metadata({addr}, {bytes_len}, {cast_type:?})",
5809
                    );
5810
                });
5811
            };
5812
            (@generate_usize _) => { 0..8 };
5813
            // Generate sizes for both Sized and !Sized types.
5814
            (@generate_size _) => {
5815
                test!(@generate_size (_)).chain(test!(@generate_size (_, _)))
5816
            };
5817
            // Generate sizes for both Sized and !Sized types by chaining
5818
            // specified iterators for each.
5819
            (@generate_size ($sized_sizes:tt | $unsized_sizes:tt)) => {
5820
                test!(@generate_size ($sized_sizes)).chain(test!(@generate_size $unsized_sizes))
5821
            };
5822
            // Generate sizes for Sized types.
5823
            (@generate_size (_)) => { test!(@generate_size (0..8)) };
5824
            (@generate_size ($sizes:expr)) => { $sizes.into_iter().map(Into::<SizeInfo>::into) };
5825
            // Generate sizes for !Sized types.
5826
            (@generate_size ($min_sizes:tt, $elem_sizes:tt)) => {
5827
                itertools::iproduct!(
5828
                    test!(@generate_min_size $min_sizes),
5829
                    test!(@generate_elem_size $elem_sizes)
5830
                ).map(Into::<SizeInfo>::into)
5831
            };
5832
            (@generate_fixed_size _) => { (0..8).into_iter().map(Into::<SizeInfo>::into) };
5833
            (@generate_min_size _) => { 0..8 };
5834
            (@generate_elem_size _) => { 1..8 };
5835
            (@generate_align _) => { [1, 2, 4, 8, 16] };
5836
            (@generate_opt_usize _) => { [None].into_iter().chain((0..8).map(Some).into_iter()) };
5837
            (@generate_cast_type _) => { [_CastType::_Prefix, _CastType::_Suffix] };
5838
            (@generate_cast_type $variant:ident) => { [_CastType::$variant] };
5839
            // Some expressions need to be wrapped in parentheses in order to be
5840
            // valid `tt`s (required by the top match pattern). See the comment
5841
            // below for more details. This arm removes these parentheses to
5842
            // avoid generating an `unused_parens` warning.
5843
            (@$_:ident ($vals:expr)) => { $vals };
5844
            (@$_:ident $vals:expr) => { $vals };
5845
        }
5846
5847
        const EVENS: [usize; 8] = [0, 2, 4, 6, 8, 10, 12, 14];
5848
        const ODDS: [usize; 8] = [1, 3, 5, 7, 9, 11, 13, 15];
5849
5850
        // base_size is too big for the memory region.
5851
        test!(layout(((1..8) | ((1..8), (1..8))), _).validate(_, [0], _), Ok(None));
5852
        test!(layout(((2..8) | ((2..8), (2..8))), _).validate(_, [1], _), Ok(None));
5853
5854
        // addr is unaligned for prefix cast
5855
        test!(layout(_, [2]).validate(ODDS, _, _Prefix), Ok(None));
5856
        test!(layout(_, [2]).validate(ODDS, _, _Prefix), Ok(None));
5857
5858
        // addr is aligned, but end of buffer is unaligned for suffix cast
5859
        test!(layout(_, [2]).validate(EVENS, ODDS, _Suffix), Ok(None));
5860
        test!(layout(_, [2]).validate(EVENS, ODDS, _Suffix), Ok(None));
5861
5862
        // Unfortunately, these constants cannot easily be used in the
5863
        // implementation of `validate_cast_and_convert_metadata`, since
5864
        // `panic!` consumes a string literal, not an expression.
5865
        //
5866
        // It's important that these messages be in a separate module. If they
5867
        // were at the function's top level, we'd pass them to `test!` as, e.g.,
5868
        // `Err(TRAILING)`, which would run into a subtle Rust footgun - the
5869
        // `TRAILING` identifier would be treated as a pattern to match rather
5870
        // than a value to check for equality.
5871
        mod msgs {
5872
            pub(super) const TRAILING: &str =
5873
                "attempted to cast to slice type with zero-sized element";
5874
            pub(super) const OVERFLOW: &str = "`addr` + `bytes_len` > usize::MAX";
5875
        }
5876
5877
        // casts with ZST trailing element types are unsupported
5878
        test!(layout((_, [0]), _).validate(_, _, _), Err(msgs::TRAILING),);
5879
5880
        // addr + bytes_len must not overflow usize
5881
        test!(layout(_, _).validate([usize::MAX], (1..100), _), Err(msgs::OVERFLOW));
5882
        test!(layout(_, _).validate((1..100), [usize::MAX], _), Err(msgs::OVERFLOW));
5883
        test!(
5884
            layout(_, _).validate(
5885
                [usize::MAX / 2 + 1, usize::MAX],
5886
                [usize::MAX / 2 + 1, usize::MAX],
5887
                _
5888
            ),
5889
            Err(msgs::OVERFLOW)
5890
        );
5891
5892
        // Validates that `validate_cast_and_convert_metadata` satisfies its own
5893
        // documented safety postconditions, and also a few other properties
5894
        // that aren't documented but we want to guarantee anyway.
5895
        fn validate_behavior(
5896
            (layout, addr, bytes_len, cast_type): (DstLayout, usize, usize, _CastType),
5897
        ) {
5898
            if let Some((elems, split_at)) =
5899
                layout.validate_cast_and_convert_metadata(addr, bytes_len, cast_type)
5900
            {
5901
                let (size_info, align) = (layout.size_info, layout.align);
5902
                let debug_str = format!(
5903
                    "layout({size_info:?}, {align}).validate_cast_and_convert_metadata({addr}, {bytes_len}, {cast_type:?}) => ({elems}, {split_at})",
5904
                );
5905
5906
                // If this is a sized type (no trailing slice), then `elems` is
5907
                // meaningless, but in practice we set it to 0. Callers are not
5908
                // allowed to rely on this, but a lot of math is nicer if
5909
                // they're able to, and some callers might accidentally do that.
5910
                let sized = matches!(layout.size_info, SizeInfo::Sized { .. });
5911
                assert!(!(sized && elems != 0), "{}", debug_str);
5912
5913
                let resulting_size = match layout.size_info {
5914
                    SizeInfo::Sized { _size } => _size,
5915
                    SizeInfo::SliceDst(TrailingSliceLayout {
5916
                        _offset: offset,
5917
                        _elem_size: elem_size,
5918
                    }) => {
5919
                        let padded_size = |elems| {
5920
                            let without_padding = offset + elems * elem_size;
5921
                            without_padding
5922
                                + util::core_layout::padding_needed_for(without_padding, align)
5923
                        };
5924
5925
                        let resulting_size = padded_size(elems);
5926
                        // Test that `validate_cast_and_convert_metadata`
5927
                        // computed the largest possible value that fits in the
5928
                        // given range.
5929
                        assert!(padded_size(elems + 1) > bytes_len, "{}", debug_str);
5930
                        resulting_size
5931
                    }
5932
                };
5933
5934
                // Test safety postconditions guaranteed by
5935
                // `validate_cast_and_convert_metadata`.
5936
                assert!(resulting_size <= bytes_len, "{}", debug_str);
5937
                match cast_type {
5938
                    _CastType::_Prefix => {
5939
                        assert_eq!(addr % align, 0, "{}", debug_str);
5940
                        assert_eq!(resulting_size, split_at, "{}", debug_str);
5941
                    }
5942
                    _CastType::_Suffix => {
5943
                        assert_eq!(split_at, bytes_len - resulting_size, "{}", debug_str);
5944
                        assert_eq!((addr + split_at) % align, 0, "{}", debug_str);
5945
                    }
5946
                }
5947
            } else {
5948
                let min_size = match layout.size_info {
5949
                    SizeInfo::Sized { _size } => _size,
5950
                    SizeInfo::SliceDst(TrailingSliceLayout { _offset, .. }) => {
5951
                        _offset + util::core_layout::padding_needed_for(_offset, layout.align)
5952
                    }
5953
                };
5954
5955
                // If a cast is invalid, it is either because...
5956
                // 1. there are insufficent bytes at the given region for type:
5957
                let insufficient_bytes = bytes_len < min_size;
5958
                // 2. performing the cast would misalign type:
5959
                let base = match cast_type {
5960
                    _CastType::_Prefix => 0,
5961
                    _CastType::_Suffix => bytes_len,
5962
                };
5963
                let misaligned = (base + addr) % layout.align != 0;
5964
5965
                assert!(insufficient_bytes || misaligned);
5966
            }
5967
        }
5968
5969
        let sizes = 0..8;
5970
        let elem_sizes = 1..8;
5971
        let size_infos = sizes
5972
            .clone()
5973
            .map(Into::<SizeInfo>::into)
5974
            .chain(itertools::iproduct!(sizes, elem_sizes).map(Into::<SizeInfo>::into));
5975
        let layouts = itertools::iproduct!(size_infos, [1, 2, 4, 8, 16, 32])
5976
            .filter(|(size_info, align)| !matches!(size_info, SizeInfo::Sized { _size } if _size % align != 0))
5977
            .map(|(size_info, align)| layout(size_info, align));
5978
        itertools::iproduct!(layouts, 0..8, 0..8, [_CastType::_Prefix, _CastType::_Suffix])
5979
            .for_each(validate_behavior);
5980
    }
5981
5982
    #[test]
5983
    #[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
5984
    fn test_validate_rust_layout() {
5985
        use core::ptr::NonNull;
5986
5987
        // This test synthesizes pointers with various metadata and uses Rust's
5988
        // built-in APIs to confirm that Rust makes decisions about type layout
5989
        // which are consistent with what we believe is guaranteed by the
5990
        // language. If this test fails, it doesn't just mean our code is wrong
5991
        // - it means we're misunderstanding the language's guarantees.
5992
5993
        #[derive(Debug)]
5994
        struct MacroArgs {
5995
            offset: usize,
5996
            align: NonZeroUsize,
5997
            elem_size: Option<usize>,
5998
        }
5999
6000
        /// # Safety
6001
        ///
6002
        /// `test` promises to only call `addr_of_slice_field` on a `NonNull<T>`
6003
        /// which points to a valid `T`.
6004
        ///
6005
        /// `with_elems` must produce a pointer which points to a valid `T`.
6006
        fn test<T: ?Sized, W: Fn(usize) -> NonNull<T>>(
6007
            args: MacroArgs,
6008
            with_elems: W,
6009
            addr_of_slice_field: Option<fn(NonNull<T>) -> NonNull<u8>>,
6010
        ) {
6011
            let dst = args.elem_size.is_some();
6012
            let layout = {
6013
                let size_info = match args.elem_size {
6014
                    Some(elem_size) => SizeInfo::SliceDst(TrailingSliceLayout {
6015
                        _offset: args.offset,
6016
                        _elem_size: elem_size,
6017
                    }),
6018
                    None => SizeInfo::Sized {
6019
                        // Rust only supports types whose sizes are a multiple
6020
                        // of their alignment. If the macro created a type like
6021
                        // this:
6022
                        //
6023
                        //   #[repr(C, align(2))]
6024
                        //   struct Foo([u8; 1]);
6025
                        //
6026
                        // ...then Rust will automatically round the type's size
6027
                        // up to 2.
6028
                        _size: args.offset
6029
                            + util::core_layout::padding_needed_for(args.offset, args.align),
6030
                    },
6031
                };
6032
                DstLayout { size_info, align: args.align }
6033
            };
6034
6035
            for elems in 0..128 {
6036
                let ptr = with_elems(elems);
6037
6038
                if let Some(addr_of_slice_field) = addr_of_slice_field {
6039
                    let slc_field_ptr = addr_of_slice_field(ptr).as_ptr();
6040
                    // SAFETY: Both `slc_field_ptr` and `ptr` are pointers to
6041
                    // the same valid Rust object.
6042
                    let offset: usize =
6043
                        unsafe { slc_field_ptr.byte_offset_from(ptr.as_ptr()).try_into().unwrap() };
6044
                    assert_eq!(offset, args.offset);
6045
                }
6046
6047
                // SAFETY: `ptr` points to a valid `T`.
6048
                let (size, align) = unsafe {
6049
                    (mem::size_of_val_raw(ptr.as_ptr()), mem::align_of_val_raw(ptr.as_ptr()))
6050
                };
6051
6052
                // Avoid expensive allocation when running under Miri.
6053
                let assert_msg = if !cfg!(miri) {
6054
                    format!("\n{args:?}\nsize:{size}, align:{align}")
6055
                } else {
6056
                    String::new()
6057
                };
6058
6059
                let without_padding =
6060
                    args.offset + args.elem_size.map(|elem_size| elems * elem_size).unwrap_or(0);
6061
                assert!(size >= without_padding, "{}", assert_msg);
6062
                assert_eq!(align, args.align.get(), "{}", assert_msg);
6063
6064
                // This encodes the most important part of the test: our
6065
                // understanding of how Rust determines the layout of repr(C)
6066
                // types. Sized repr(C) types are trivial, but DST types have
6067
                // some subtlety. Note that:
6068
                // - For sized types, `without_padding` is just the size of the
6069
                //   type that we constructed for `Foo`. Since we may have
6070
                //   requested a larger alignment, `Foo` may actually be larger
6071
                //   than this, hence `padding_needed_for`.
6072
                // - For unsized types, `without_padding` is dynamically
6073
                //   computed from the offset, the element size, and element
6074
                //   count. We expect that the size of the object should be
6075
                //   `offset + elem_size * elems` rounded up to the next
6076
                //   alignment.
6077
                let expected_size = without_padding
6078
                    + util::core_layout::padding_needed_for(without_padding, args.align);
6079
                assert_eq!(expected_size, size, "{}", assert_msg);
6080
6081
                // For zero-sized element types,
6082
                // `validate_cast_and_convert_metadata` just panics, so we skip
6083
                // testing those types.
6084
                if args.elem_size.map(|elem_size| elem_size > 0).unwrap_or(true) {
6085
                    let addr = ptr.addr().get();
6086
                    let (got_elems, got_split_at) = layout
6087
                        .validate_cast_and_convert_metadata(addr, size, _CastType::_Prefix)
6088
                        .unwrap();
6089
                    // Avoid expensive allocation when running under Miri.
6090
                    let assert_msg = if !cfg!(miri) {
6091
                        format!(
6092
                            "{}\nvalidate_cast_and_convert_metadata({addr}, {size})",
6093
                            assert_msg
6094
                        )
6095
                    } else {
6096
                        String::new()
6097
                    };
6098
                    assert_eq!(got_split_at, size, "{}", assert_msg);
6099
                    if dst {
6100
                        assert!(got_elems >= elems, "{}", assert_msg);
6101
                        if got_elems != elems {
6102
                            // If `validate_cast_and_convert_metadata`
6103
                            // returned more elements than `elems`, that
6104
                            // means that `elems` is not the maximum number
6105
                            // of elements that can fit in `size` - in other
6106
                            // words, there is enough padding at the end of
6107
                            // the value to fit at least one more element.
6108
                            // If we use this metadata to synthesize a
6109
                            // pointer, despite having a different element
6110
                            // count, we still expect it to have the same
6111
                            // size.
6112
                            let got_ptr = with_elems(got_elems);
6113
                            // SAFETY: `got_ptr` is a pointer to a valid `T`.
6114
                            let size_of_got_ptr = unsafe { mem::size_of_val_raw(got_ptr.as_ptr()) };
6115
                            assert_eq!(size_of_got_ptr, size, "{}", assert_msg);
6116
                        }
6117
                    } else {
6118
                        // For sized casts, the returned element value is
6119
                        // technically meaningless, and we don't guarantee any
6120
                        // particular value. In practice, it's always zero.
6121
                        assert_eq!(got_elems, 0, "{}", assert_msg)
6122
                    }
6123
                }
6124
            }
6125
        }
6126
6127
        macro_rules! validate_against_rust {
6128
            ($offset:literal, $align:literal $(, $elem_size:literal)?) => {{
6129
                #[repr(C, align($align))]
6130
                struct Foo([u8; $offset]$(, [[u8; $elem_size]])?);
6131
6132
                let args = MacroArgs {
6133
                    offset: $offset,
6134
                    align: $align.try_into().unwrap(),
6135
                    elem_size: {
6136
                        #[allow(unused)]
6137
                        let ret = None::<usize>;
6138
                        $(let ret = Some($elem_size);)?
6139
                        ret
6140
                    }
6141
                };
6142
6143
                #[repr(C, align($align))]
6144
                struct FooAlign;
6145
                // Create an aligned buffer to use in order to synthesize
6146
                // pointers to `Foo`. We don't ever load values from these
6147
                // pointers - we just do arithmetic on them - so having a "real"
6148
                // block of memory as opposed to a validly-aligned-but-dangling
6149
                // pointer is only necessary to make Miri happy since we run it
6150
                // with "strict provenance" checking enabled.
6151
                let aligned_buf = Align::<_, FooAlign>::new([0u8; 1024]);
6152
                let with_elems = |elems| {
6153
                    let slc = NonNull::slice_from_raw_parts(NonNull::from(&aligned_buf.t), elems);
6154
                    #[allow(clippy::as_conversions)]
6155
                    NonNull::new(slc.as_ptr() as *mut Foo).unwrap()
6156
                };
6157
                let addr_of_slice_field = {
6158
                    #[allow(unused)]
6159
                    let f = None::<fn(NonNull<Foo>) -> NonNull<u8>>;
6160
                    $(
6161
                        // SAFETY: `test` promises to only call `f` with a `ptr`
6162
                        // to a valid `Foo`.
6163
                        let f: Option<fn(NonNull<Foo>) -> NonNull<u8>> = Some(|ptr: NonNull<Foo>| unsafe {
6164
                            NonNull::new(ptr::addr_of_mut!((*ptr.as_ptr()).1)).unwrap().cast::<u8>()
6165
                        });
6166
                        let _ = $elem_size;
6167
                    )?
6168
                    f
6169
                };
6170
6171
                test::<Foo, _>(args, with_elems, addr_of_slice_field);
6172
            }};
6173
        }
6174
6175
        // Every permutation of:
6176
        // - offset in [0, 4]
6177
        // - align in [1, 16]
6178
        // - elem_size in [0, 4] (plus no elem_size)
6179
        validate_against_rust!(0, 1);
6180
        validate_against_rust!(0, 1, 0);
6181
        validate_against_rust!(0, 1, 1);
6182
        validate_against_rust!(0, 1, 2);
6183
        validate_against_rust!(0, 1, 3);
6184
        validate_against_rust!(0, 1, 4);
6185
        validate_against_rust!(0, 2);
6186
        validate_against_rust!(0, 2, 0);
6187
        validate_against_rust!(0, 2, 1);
6188
        validate_against_rust!(0, 2, 2);
6189
        validate_against_rust!(0, 2, 3);
6190
        validate_against_rust!(0, 2, 4);
6191
        validate_against_rust!(0, 4);
6192
        validate_against_rust!(0, 4, 0);
6193
        validate_against_rust!(0, 4, 1);
6194
        validate_against_rust!(0, 4, 2);
6195
        validate_against_rust!(0, 4, 3);
6196
        validate_against_rust!(0, 4, 4);
6197
        validate_against_rust!(0, 8);
6198
        validate_against_rust!(0, 8, 0);
6199
        validate_against_rust!(0, 8, 1);
6200
        validate_against_rust!(0, 8, 2);
6201
        validate_against_rust!(0, 8, 3);
6202
        validate_against_rust!(0, 8, 4);
6203
        validate_against_rust!(0, 16);
6204
        validate_against_rust!(0, 16, 0);
6205
        validate_against_rust!(0, 16, 1);
6206
        validate_against_rust!(0, 16, 2);
6207
        validate_against_rust!(0, 16, 3);
6208
        validate_against_rust!(0, 16, 4);
6209
        validate_against_rust!(1, 1);
6210
        validate_against_rust!(1, 1, 0);
6211
        validate_against_rust!(1, 1, 1);
6212
        validate_against_rust!(1, 1, 2);
6213
        validate_against_rust!(1, 1, 3);
6214
        validate_against_rust!(1, 1, 4);
6215
        validate_against_rust!(1, 2);
6216
        validate_against_rust!(1, 2, 0);
6217
        validate_against_rust!(1, 2, 1);
6218
        validate_against_rust!(1, 2, 2);
6219
        validate_against_rust!(1, 2, 3);
6220
        validate_against_rust!(1, 2, 4);
6221
        validate_against_rust!(1, 4);
6222
        validate_against_rust!(1, 4, 0);
6223
        validate_against_rust!(1, 4, 1);
6224
        validate_against_rust!(1, 4, 2);
6225
        validate_against_rust!(1, 4, 3);
6226
        validate_against_rust!(1, 4, 4);
6227
        validate_against_rust!(1, 8);
6228
        validate_against_rust!(1, 8, 0);
6229
        validate_against_rust!(1, 8, 1);
6230
        validate_against_rust!(1, 8, 2);
6231
        validate_against_rust!(1, 8, 3);
6232
        validate_against_rust!(1, 8, 4);
6233
        validate_against_rust!(1, 16);
6234
        validate_against_rust!(1, 16, 0);
6235
        validate_against_rust!(1, 16, 1);
6236
        validate_against_rust!(1, 16, 2);
6237
        validate_against_rust!(1, 16, 3);
6238
        validate_against_rust!(1, 16, 4);
6239
        validate_against_rust!(2, 1);
6240
        validate_against_rust!(2, 1, 0);
6241
        validate_against_rust!(2, 1, 1);
6242
        validate_against_rust!(2, 1, 2);
6243
        validate_against_rust!(2, 1, 3);
6244
        validate_against_rust!(2, 1, 4);
6245
        validate_against_rust!(2, 2);
6246
        validate_against_rust!(2, 2, 0);
6247
        validate_against_rust!(2, 2, 1);
6248
        validate_against_rust!(2, 2, 2);
6249
        validate_against_rust!(2, 2, 3);
6250
        validate_against_rust!(2, 2, 4);
6251
        validate_against_rust!(2, 4);
6252
        validate_against_rust!(2, 4, 0);
6253
        validate_against_rust!(2, 4, 1);
6254
        validate_against_rust!(2, 4, 2);
6255
        validate_against_rust!(2, 4, 3);
6256
        validate_against_rust!(2, 4, 4);
6257
        validate_against_rust!(2, 8);
6258
        validate_against_rust!(2, 8, 0);
6259
        validate_against_rust!(2, 8, 1);
6260
        validate_against_rust!(2, 8, 2);
6261
        validate_against_rust!(2, 8, 3);
6262
        validate_against_rust!(2, 8, 4);
6263
        validate_against_rust!(2, 16);
6264
        validate_against_rust!(2, 16, 0);
6265
        validate_against_rust!(2, 16, 1);
6266
        validate_against_rust!(2, 16, 2);
6267
        validate_against_rust!(2, 16, 3);
6268
        validate_against_rust!(2, 16, 4);
6269
        validate_against_rust!(3, 1);
6270
        validate_against_rust!(3, 1, 0);
6271
        validate_against_rust!(3, 1, 1);
6272
        validate_against_rust!(3, 1, 2);
6273
        validate_against_rust!(3, 1, 3);
6274
        validate_against_rust!(3, 1, 4);
6275
        validate_against_rust!(3, 2);
6276
        validate_against_rust!(3, 2, 0);
6277
        validate_against_rust!(3, 2, 1);
6278
        validate_against_rust!(3, 2, 2);
6279
        validate_against_rust!(3, 2, 3);
6280
        validate_against_rust!(3, 2, 4);
6281
        validate_against_rust!(3, 4);
6282
        validate_against_rust!(3, 4, 0);
6283
        validate_against_rust!(3, 4, 1);
6284
        validate_against_rust!(3, 4, 2);
6285
        validate_against_rust!(3, 4, 3);
6286
        validate_against_rust!(3, 4, 4);
6287
        validate_against_rust!(3, 8);
6288
        validate_against_rust!(3, 8, 0);
6289
        validate_against_rust!(3, 8, 1);
6290
        validate_against_rust!(3, 8, 2);
6291
        validate_against_rust!(3, 8, 3);
6292
        validate_against_rust!(3, 8, 4);
6293
        validate_against_rust!(3, 16);
6294
        validate_against_rust!(3, 16, 0);
6295
        validate_against_rust!(3, 16, 1);
6296
        validate_against_rust!(3, 16, 2);
6297
        validate_against_rust!(3, 16, 3);
6298
        validate_against_rust!(3, 16, 4);
6299
        validate_against_rust!(4, 1);
6300
        validate_against_rust!(4, 1, 0);
6301
        validate_against_rust!(4, 1, 1);
6302
        validate_against_rust!(4, 1, 2);
6303
        validate_against_rust!(4, 1, 3);
6304
        validate_against_rust!(4, 1, 4);
6305
        validate_against_rust!(4, 2);
6306
        validate_against_rust!(4, 2, 0);
6307
        validate_against_rust!(4, 2, 1);
6308
        validate_against_rust!(4, 2, 2);
6309
        validate_against_rust!(4, 2, 3);
6310
        validate_against_rust!(4, 2, 4);
6311
        validate_against_rust!(4, 4);
6312
        validate_against_rust!(4, 4, 0);
6313
        validate_against_rust!(4, 4, 1);
6314
        validate_against_rust!(4, 4, 2);
6315
        validate_against_rust!(4, 4, 3);
6316
        validate_against_rust!(4, 4, 4);
6317
        validate_against_rust!(4, 8);
6318
        validate_against_rust!(4, 8, 0);
6319
        validate_against_rust!(4, 8, 1);
6320
        validate_against_rust!(4, 8, 2);
6321
        validate_against_rust!(4, 8, 3);
6322
        validate_against_rust!(4, 8, 4);
6323
        validate_against_rust!(4, 16);
6324
        validate_against_rust!(4, 16, 0);
6325
        validate_against_rust!(4, 16, 1);
6326
        validate_against_rust!(4, 16, 2);
6327
        validate_against_rust!(4, 16, 3);
6328
        validate_against_rust!(4, 16, 4);
6329
    }
6330
6331
    #[test]
6332
    fn test_known_layout() {
6333
        // Test that `$ty` and `ManuallyDrop<$ty>` have the expected layout.
6334
        // Test that `PhantomData<$ty>` has the same layout as `()` regardless
6335
        // of `$ty`.
6336
        macro_rules! test {
6337
            ($ty:ty, $expect:expr) => {
6338
                let expect = $expect;
6339
                assert_eq!(<$ty as KnownLayout>::LAYOUT, expect);
6340
                assert_eq!(<ManuallyDrop<$ty> as KnownLayout>::LAYOUT, expect);
6341
                assert_eq!(<PhantomData<$ty> as KnownLayout>::LAYOUT, <() as KnownLayout>::LAYOUT);
6342
            };
6343
        }
6344
6345
        let layout = |offset, align, _trailing_slice_elem_size| DstLayout {
6346
            align: NonZeroUsize::new(align).unwrap(),
6347
            size_info: match _trailing_slice_elem_size {
6348
                None => SizeInfo::Sized { _size: offset },
6349
                Some(elem_size) => SizeInfo::SliceDst(TrailingSliceLayout {
6350
                    _offset: offset,
6351
                    _elem_size: elem_size,
6352
                }),
6353
            },
6354
        };
6355
6356
        test!((), layout(0, 1, None));
6357
        test!(u8, layout(1, 1, None));
6358
        // Use `align_of` because `u64` alignment may be smaller than 8 on some
6359
        // platforms.
6360
        test!(u64, layout(8, mem::align_of::<u64>(), None));
6361
        test!(AU64, layout(8, 8, None));
6362
6363
        test!(Option<&'static ()>, usize::LAYOUT);
6364
6365
        test!([()], layout(0, 1, Some(0)));
6366
        test!([u8], layout(0, 1, Some(1)));
6367
        test!(str, layout(0, 1, Some(1)));
6368
    }
6369
6370
    #[cfg(feature = "derive")]
6371
    #[test]
6372
    fn test_known_layout_derive() {
6373
        // In this and other files (`late_compile_pass.rs`,
6374
        // `mid_compile_pass.rs`, and `struct.rs`), we test success and failure
6375
        // modes of `derive(KnownLayout)` for the following combination of
6376
        // properties:
6377
        //
6378
        // +------------+--------------------------------------+-----------+
6379
        // |            |      trailing field properties       |           |
6380
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6381
        // |------------+----------+----------------+----------+-----------|
6382
        // |          N |        N |              N |        N |      KL00 |
6383
        // |          N |        N |              N |        Y |      KL01 |
6384
        // |          N |        N |              Y |        N |      KL02 |
6385
        // |          N |        N |              Y |        Y |      KL03 |
6386
        // |          N |        Y |              N |        N |      KL04 |
6387
        // |          N |        Y |              N |        Y |      KL05 |
6388
        // |          N |        Y |              Y |        N |      KL06 |
6389
        // |          N |        Y |              Y |        Y |      KL07 |
6390
        // |          Y |        N |              N |        N |      KL08 |
6391
        // |          Y |        N |              N |        Y |      KL09 |
6392
        // |          Y |        N |              Y |        N |      KL10 |
6393
        // |          Y |        N |              Y |        Y |      KL11 |
6394
        // |          Y |        Y |              N |        N |      KL12 |
6395
        // |          Y |        Y |              N |        Y |      KL13 |
6396
        // |          Y |        Y |              Y |        N |      KL14 |
6397
        // |          Y |        Y |              Y |        Y |      KL15 |
6398
        // +------------+----------+----------------+----------+-----------+
6399
6400
        struct NotKnownLayout<T = ()> {
6401
            _t: T,
6402
        }
6403
6404
        #[derive(KnownLayout)]
6405
        #[repr(C)]
6406
        struct AlignSize<const ALIGN: usize, const SIZE: usize>
6407
        where
6408
            elain::Align<ALIGN>: elain::Alignment,
6409
        {
6410
            _align: elain::Align<ALIGN>,
6411
            _size: [u8; SIZE],
6412
        }
6413
6414
        type AU16 = AlignSize<2, 2>;
6415
        type AU32 = AlignSize<4, 4>;
6416
6417
        fn _assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
6418
6419
        let sized_layout = |align, size| DstLayout {
6420
            align: NonZeroUsize::new(align).unwrap(),
6421
            size_info: SizeInfo::Sized { _size: size },
6422
        };
6423
6424
        let unsized_layout = |align, elem_size, offset| DstLayout {
6425
            align: NonZeroUsize::new(align).unwrap(),
6426
            size_info: SizeInfo::SliceDst(TrailingSliceLayout {
6427
                _offset: offset,
6428
                _elem_size: elem_size,
6429
            }),
6430
        };
6431
6432
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6433
        // |          N |        N |              N |        Y |      KL01 |
6434
        #[derive(KnownLayout)]
6435
        #[allow(dead_code)] // fields are never read
6436
        struct KL01(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6437
6438
        let expected = DstLayout::for_type::<KL01>();
6439
6440
        assert_eq!(<KL01 as KnownLayout>::LAYOUT, expected);
6441
        assert_eq!(<KL01 as KnownLayout>::LAYOUT, sized_layout(4, 8));
6442
6443
        // ...with `align(N)`:
6444
        #[derive(KnownLayout)]
6445
        #[repr(align(64))]
6446
        #[allow(dead_code)] // fields are never read
6447
        struct KL01Align(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6448
6449
        let expected = DstLayout::for_type::<KL01Align>();
6450
6451
        assert_eq!(<KL01Align as KnownLayout>::LAYOUT, expected);
6452
        assert_eq!(<KL01Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
6453
6454
        // ...with `packed`:
6455
        #[derive(KnownLayout)]
6456
        #[repr(packed)]
6457
        #[allow(dead_code)] // fields are never read
6458
        struct KL01Packed(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6459
6460
        let expected = DstLayout::for_type::<KL01Packed>();
6461
6462
        assert_eq!(<KL01Packed as KnownLayout>::LAYOUT, expected);
6463
        assert_eq!(<KL01Packed as KnownLayout>::LAYOUT, sized_layout(1, 6));
6464
6465
        // ...with `packed(N)`:
6466
        #[derive(KnownLayout)]
6467
        #[repr(packed(2))]
6468
        #[allow(dead_code)] // fields are never read
6469
        struct KL01PackedN(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6470
6471
        assert_impl_all!(KL01PackedN: KnownLayout);
6472
6473
        let expected = DstLayout::for_type::<KL01PackedN>();
6474
6475
        assert_eq!(<KL01PackedN as KnownLayout>::LAYOUT, expected);
6476
        assert_eq!(<KL01PackedN as KnownLayout>::LAYOUT, sized_layout(2, 6));
6477
6478
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6479
        // |          N |        N |              Y |        Y |      KL03 |
6480
        #[derive(KnownLayout)]
6481
        #[allow(dead_code)] // fields are never read
6482
        struct KL03(NotKnownLayout, u8);
6483
6484
        let expected = DstLayout::for_type::<KL03>();
6485
6486
        assert_eq!(<KL03 as KnownLayout>::LAYOUT, expected);
6487
        assert_eq!(<KL03 as KnownLayout>::LAYOUT, sized_layout(1, 1));
6488
6489
        // ... with `align(N)`
6490
        #[derive(KnownLayout)]
6491
        #[repr(align(64))]
6492
        #[allow(dead_code)] // fields are never read
6493
        struct KL03Align(NotKnownLayout<AU32>, u8);
6494
6495
        let expected = DstLayout::for_type::<KL03Align>();
6496
6497
        assert_eq!(<KL03Align as KnownLayout>::LAYOUT, expected);
6498
        assert_eq!(<KL03Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
6499
6500
        // ... with `packed`:
6501
        #[derive(KnownLayout)]
6502
        #[repr(packed)]
6503
        #[allow(dead_code)] // fields are never read
6504
        struct KL03Packed(NotKnownLayout<AU32>, u8);
6505
6506
        let expected = DstLayout::for_type::<KL03Packed>();
6507
6508
        assert_eq!(<KL03Packed as KnownLayout>::LAYOUT, expected);
6509
        assert_eq!(<KL03Packed as KnownLayout>::LAYOUT, sized_layout(1, 5));
6510
6511
        // ... with `packed(N)`
6512
        #[derive(KnownLayout)]
6513
        #[repr(packed(2))]
6514
        #[allow(dead_code)] // fields are never read
6515
        struct KL03PackedN(NotKnownLayout<AU32>, u8);
6516
6517
        assert_impl_all!(KL03PackedN: KnownLayout);
6518
6519
        let expected = DstLayout::for_type::<KL03PackedN>();
6520
6521
        assert_eq!(<KL03PackedN as KnownLayout>::LAYOUT, expected);
6522
        assert_eq!(<KL03PackedN as KnownLayout>::LAYOUT, sized_layout(2, 6));
6523
6524
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6525
        // |          N |        Y |              N |        Y |      KL05 |
6526
        #[derive(KnownLayout)]
6527
        #[allow(dead_code)] // fields are never read
6528
        struct KL05<T>(u8, T);
6529
6530
        fn _test_kl05<T>(t: T) -> impl KnownLayout {
6531
            KL05(0u8, t)
6532
        }
6533
6534
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6535
        // |          N |        Y |              Y |        Y |      KL07 |
6536
        #[derive(KnownLayout)]
6537
        #[allow(dead_code)] // fields are never read
6538
        struct KL07<T: KnownLayout>(u8, T);
6539
6540
        fn _test_kl07<T: KnownLayout>(t: T) -> impl KnownLayout {
6541
            let _ = KL07(0u8, t);
6542
        }
6543
6544
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6545
        // |          Y |        N |              Y |        N |      KL10 |
6546
        #[derive(KnownLayout)]
6547
        #[repr(C)]
6548
        struct KL10(NotKnownLayout<AU32>, [u8]);
6549
6550
        let expected = DstLayout::new_zst(None)
6551
            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), None)
6552
            .extend(<[u8] as KnownLayout>::LAYOUT, None)
6553
            .pad_to_align();
6554
6555
        assert_eq!(<KL10 as KnownLayout>::LAYOUT, expected);
6556
        assert_eq!(<KL10 as KnownLayout>::LAYOUT, unsized_layout(4, 1, 4));
6557
6558
        // ...with `align(N)`:
6559
        #[derive(KnownLayout)]
6560
        #[repr(C, align(64))]
6561
        struct KL10Align(NotKnownLayout<AU32>, [u8]);
6562
6563
        let repr_align = NonZeroUsize::new(64);
6564
6565
        let expected = DstLayout::new_zst(repr_align)
6566
            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), None)
6567
            .extend(<[u8] as KnownLayout>::LAYOUT, None)
6568
            .pad_to_align();
6569
6570
        assert_eq!(<KL10Align as KnownLayout>::LAYOUT, expected);
6571
        assert_eq!(<KL10Align as KnownLayout>::LAYOUT, unsized_layout(64, 1, 4));
6572
6573
        // ...with `packed`:
6574
        #[derive(KnownLayout)]
6575
        #[repr(C, packed)]
6576
        struct KL10Packed(NotKnownLayout<AU32>, [u8]);
6577
6578
        let repr_packed = NonZeroUsize::new(1);
6579
6580
        let expected = DstLayout::new_zst(None)
6581
            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), repr_packed)
6582
            .extend(<[u8] as KnownLayout>::LAYOUT, repr_packed)
6583
            .pad_to_align();
6584
6585
        assert_eq!(<KL10Packed as KnownLayout>::LAYOUT, expected);
6586
        assert_eq!(<KL10Packed as KnownLayout>::LAYOUT, unsized_layout(1, 1, 4));
6587
6588
        // ...with `packed(N)`:
6589
        #[derive(KnownLayout)]
6590
        #[repr(C, packed(2))]
6591
        struct KL10PackedN(NotKnownLayout<AU32>, [u8]);
6592
6593
        let repr_packed = NonZeroUsize::new(2);
6594
6595
        let expected = DstLayout::new_zst(None)
6596
            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), repr_packed)
6597
            .extend(<[u8] as KnownLayout>::LAYOUT, repr_packed)
6598
            .pad_to_align();
6599
6600
        assert_eq!(<KL10PackedN as KnownLayout>::LAYOUT, expected);
6601
        assert_eq!(<KL10PackedN as KnownLayout>::LAYOUT, unsized_layout(2, 1, 4));
6602
6603
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6604
        // |          Y |        N |              Y |        Y |      KL11 |
6605
        #[derive(KnownLayout)]
6606
        #[repr(C)]
6607
        struct KL11(NotKnownLayout<AU64>, u8);
6608
6609
        let expected = DstLayout::new_zst(None)
6610
            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), None)
6611
            .extend(<u8 as KnownLayout>::LAYOUT, None)
6612
            .pad_to_align();
6613
6614
        assert_eq!(<KL11 as KnownLayout>::LAYOUT, expected);
6615
        assert_eq!(<KL11 as KnownLayout>::LAYOUT, sized_layout(8, 16));
6616
6617
        // ...with `align(N)`:
6618
        #[derive(KnownLayout)]
6619
        #[repr(C, align(64))]
6620
        struct KL11Align(NotKnownLayout<AU64>, u8);
6621
6622
        let repr_align = NonZeroUsize::new(64);
6623
6624
        let expected = DstLayout::new_zst(repr_align)
6625
            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), None)
6626
            .extend(<u8 as KnownLayout>::LAYOUT, None)
6627
            .pad_to_align();
6628
6629
        assert_eq!(<KL11Align as KnownLayout>::LAYOUT, expected);
6630
        assert_eq!(<KL11Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
6631
6632
        // ...with `packed`:
6633
        #[derive(KnownLayout)]
6634
        #[repr(C, packed)]
6635
        struct KL11Packed(NotKnownLayout<AU64>, u8);
6636
6637
        let repr_packed = NonZeroUsize::new(1);
6638
6639
        let expected = DstLayout::new_zst(None)
6640
            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), repr_packed)
6641
            .extend(<u8 as KnownLayout>::LAYOUT, repr_packed)
6642
            .pad_to_align();
6643
6644
        assert_eq!(<KL11Packed as KnownLayout>::LAYOUT, expected);
6645
        assert_eq!(<KL11Packed as KnownLayout>::LAYOUT, sized_layout(1, 9));
6646
6647
        // ...with `packed(N)`:
6648
        #[derive(KnownLayout)]
6649
        #[repr(C, packed(2))]
6650
        struct KL11PackedN(NotKnownLayout<AU64>, u8);
6651
6652
        let repr_packed = NonZeroUsize::new(2);
6653
6654
        let expected = DstLayout::new_zst(None)
6655
            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), repr_packed)
6656
            .extend(<u8 as KnownLayout>::LAYOUT, repr_packed)
6657
            .pad_to_align();
6658
6659
        assert_eq!(<KL11PackedN as KnownLayout>::LAYOUT, expected);
6660
        assert_eq!(<KL11PackedN as KnownLayout>::LAYOUT, sized_layout(2, 10));
6661
6662
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6663
        // |          Y |        Y |              Y |        N |      KL14 |
6664
        #[derive(KnownLayout)]
6665
        #[repr(C)]
6666
        struct KL14<T: ?Sized + KnownLayout>(u8, T);
6667
6668
        fn _test_kl14<T: ?Sized + KnownLayout>(kl: &KL14<T>) {
6669
            _assert_kl(kl)
6670
        }
6671
6672
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6673
        // |          Y |        Y |              Y |        Y |      KL15 |
6674
        #[derive(KnownLayout)]
6675
        #[repr(C)]
6676
        struct KL15<T: KnownLayout>(u8, T);
6677
6678
        fn _test_kl15<T: KnownLayout>(t: T) -> impl KnownLayout {
6679
            let _ = KL15(0u8, t);
6680
        }
6681
6682
        // Test a variety of combinations of field types:
6683
        //  - ()
6684
        //  - u8
6685
        //  - AU16
6686
        //  - [()]
6687
        //  - [u8]
6688
        //  - [AU16]
6689
6690
        #[allow(clippy::upper_case_acronyms)]
6691
        #[derive(KnownLayout)]
6692
        #[repr(C)]
6693
        struct KLTU<T, U: ?Sized>(T, U);
6694
6695
        assert_eq!(<KLTU<(), ()> as KnownLayout>::LAYOUT, sized_layout(1, 0));
6696
6697
        assert_eq!(<KLTU<(), u8> as KnownLayout>::LAYOUT, sized_layout(1, 1));
6698
6699
        assert_eq!(<KLTU<(), AU16> as KnownLayout>::LAYOUT, sized_layout(2, 2));
6700
6701
        assert_eq!(<KLTU<(), [()]> as KnownLayout>::LAYOUT, unsized_layout(1, 0, 0));
6702
6703
        assert_eq!(<KLTU<(), [u8]> as KnownLayout>::LAYOUT, unsized_layout(1, 1, 0));
6704
6705
        assert_eq!(<KLTU<(), [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 0));
6706
6707
        assert_eq!(<KLTU<u8, ()> as KnownLayout>::LAYOUT, sized_layout(1, 1));
6708
6709
        assert_eq!(<KLTU<u8, u8> as KnownLayout>::LAYOUT, sized_layout(1, 2));
6710
6711
        assert_eq!(<KLTU<u8, AU16> as KnownLayout>::LAYOUT, sized_layout(2, 4));
6712
6713
        assert_eq!(<KLTU<u8, [()]> as KnownLayout>::LAYOUT, unsized_layout(1, 0, 1));
6714
6715
        assert_eq!(<KLTU<u8, [u8]> as KnownLayout>::LAYOUT, unsized_layout(1, 1, 1));
6716
6717
        assert_eq!(<KLTU<u8, [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 2));
6718
6719
        assert_eq!(<KLTU<AU16, ()> as KnownLayout>::LAYOUT, sized_layout(2, 2));
6720
6721
        assert_eq!(<KLTU<AU16, u8> as KnownLayout>::LAYOUT, sized_layout(2, 4));
6722
6723
        assert_eq!(<KLTU<AU16, AU16> as KnownLayout>::LAYOUT, sized_layout(2, 4));
6724
6725
        assert_eq!(<KLTU<AU16, [()]> as KnownLayout>::LAYOUT, unsized_layout(2, 0, 2));
6726
6727
        assert_eq!(<KLTU<AU16, [u8]> as KnownLayout>::LAYOUT, unsized_layout(2, 1, 2));
6728
6729
        assert_eq!(<KLTU<AU16, [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 2));
6730
6731
        // Test a variety of field counts.
6732
6733
        #[derive(KnownLayout)]
6734
        #[repr(C)]
6735
        struct KLF0;
6736
6737
        assert_eq!(<KLF0 as KnownLayout>::LAYOUT, sized_layout(1, 0));
6738
6739
        #[derive(KnownLayout)]
6740
        #[repr(C)]
6741
        struct KLF1([u8]);
6742
6743
        assert_eq!(<KLF1 as KnownLayout>::LAYOUT, unsized_layout(1, 1, 0));
6744
6745
        #[derive(KnownLayout)]
6746
        #[repr(C)]
6747
        struct KLF2(NotKnownLayout<u8>, [u8]);
6748
6749
        assert_eq!(<KLF2 as KnownLayout>::LAYOUT, unsized_layout(1, 1, 1));
6750
6751
        #[derive(KnownLayout)]
6752
        #[repr(C)]
6753
        struct KLF3(NotKnownLayout<u8>, NotKnownLayout<AU16>, [u8]);
6754
6755
        assert_eq!(<KLF3 as KnownLayout>::LAYOUT, unsized_layout(2, 1, 4));
6756
6757
        #[derive(KnownLayout)]
6758
        #[repr(C)]
6759
        struct KLF4(NotKnownLayout<u8>, NotKnownLayout<AU16>, NotKnownLayout<AU32>, [u8]);
6760
6761
        assert_eq!(<KLF4 as KnownLayout>::LAYOUT, unsized_layout(4, 1, 8));
6762
    }
6763
6764
    #[test]
6765
    fn test_object_safety() {
6766
        fn _takes_from_zeroes(_: &dyn FromZeroes) {}
6767
        fn _takes_from_bytes(_: &dyn FromBytes) {}
6768
        fn _takes_unaligned(_: &dyn Unaligned) {}
6769
    }
6770
6771
    #[test]
6772
    fn test_from_zeroes_only() {
6773
        // Test types that implement `FromZeroes` but not `FromBytes`.
6774
6775
        assert!(!bool::new_zeroed());
6776
        assert_eq!(char::new_zeroed(), '\0');
6777
6778
        #[cfg(feature = "alloc")]
6779
        {
6780
            assert_eq!(bool::new_box_zeroed(), Box::new(false));
6781
            assert_eq!(char::new_box_zeroed(), Box::new('\0'));
6782
6783
            assert_eq!(bool::new_box_slice_zeroed(3).as_ref(), [false, false, false]);
6784
            assert_eq!(char::new_box_slice_zeroed(3).as_ref(), ['\0', '\0', '\0']);
6785
6786
            assert_eq!(bool::new_vec_zeroed(3).as_ref(), [false, false, false]);
6787
            assert_eq!(char::new_vec_zeroed(3).as_ref(), ['\0', '\0', '\0']);
6788
        }
6789
6790
        let mut string = "hello".to_string();
6791
        let s: &mut str = string.as_mut();
6792
        assert_eq!(s, "hello");
6793
        s.zero();
6794
        assert_eq!(s, "\0\0\0\0\0");
6795
    }
6796
6797
    #[test]
6798
    fn test_read_write() {
6799
        const VAL: u64 = 0x12345678;
6800
        #[cfg(target_endian = "big")]
6801
        const VAL_BYTES: [u8; 8] = VAL.to_be_bytes();
6802
        #[cfg(target_endian = "little")]
6803
        const VAL_BYTES: [u8; 8] = VAL.to_le_bytes();
6804
6805
        // Test `FromBytes::{read_from, read_from_prefix, read_from_suffix}`.
6806
6807
        assert_eq!(u64::read_from(&VAL_BYTES[..]), Some(VAL));
6808
        // The first 8 bytes are from `VAL_BYTES` and the second 8 bytes are all
6809
        // zeroes.
6810
        let bytes_with_prefix: [u8; 16] = transmute!([VAL_BYTES, [0; 8]]);
6811
        assert_eq!(u64::read_from_prefix(&bytes_with_prefix[..]), Some(VAL));
6812
        assert_eq!(u64::read_from_suffix(&bytes_with_prefix[..]), Some(0));
6813
        // The first 8 bytes are all zeroes and the second 8 bytes are from
6814
        // `VAL_BYTES`
6815
        let bytes_with_suffix: [u8; 16] = transmute!([[0; 8], VAL_BYTES]);
6816
        assert_eq!(u64::read_from_prefix(&bytes_with_suffix[..]), Some(0));
6817
        assert_eq!(u64::read_from_suffix(&bytes_with_suffix[..]), Some(VAL));
6818
6819
        // Test `AsBytes::{write_to, write_to_prefix, write_to_suffix}`.
6820
6821
        let mut bytes = [0u8; 8];
6822
        assert_eq!(VAL.write_to(&mut bytes[..]), Some(()));
6823
        assert_eq!(bytes, VAL_BYTES);
6824
        let mut bytes = [0u8; 16];
6825
        assert_eq!(VAL.write_to_prefix(&mut bytes[..]), Some(()));
6826
        let want: [u8; 16] = transmute!([VAL_BYTES, [0; 8]]);
6827
        assert_eq!(bytes, want);
6828
        let mut bytes = [0u8; 16];
6829
        assert_eq!(VAL.write_to_suffix(&mut bytes[..]), Some(()));
6830
        let want: [u8; 16] = transmute!([[0; 8], VAL_BYTES]);
6831
        assert_eq!(bytes, want);
6832
    }
6833
6834
    #[test]
6835
    fn test_transmute() {
6836
        // Test that memory is transmuted as expected.
6837
        let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
6838
        let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
6839
        let x: [[u8; 2]; 4] = transmute!(array_of_u8s);
6840
        assert_eq!(x, array_of_arrays);
6841
        let x: [u8; 8] = transmute!(array_of_arrays);
6842
        assert_eq!(x, array_of_u8s);
6843
6844
        // Test that the source expression's value is forgotten rather than
6845
        // dropped.
6846
        #[derive(AsBytes)]
6847
        #[repr(transparent)]
6848
        struct PanicOnDrop(());
6849
        impl Drop for PanicOnDrop {
6850
            fn drop(&mut self) {
6851
                panic!("PanicOnDrop::drop");
6852
            }
6853
        }
6854
        #[allow(clippy::let_unit_value)]
6855
        let _: () = transmute!(PanicOnDrop(()));
6856
6857
        // Test that `transmute!` is legal in a const context.
6858
        const ARRAY_OF_U8S: [u8; 8] = [0u8, 1, 2, 3, 4, 5, 6, 7];
6859
        const ARRAY_OF_ARRAYS: [[u8; 2]; 4] = [[0, 1], [2, 3], [4, 5], [6, 7]];
6860
        const X: [[u8; 2]; 4] = transmute!(ARRAY_OF_U8S);
6861
        assert_eq!(X, ARRAY_OF_ARRAYS);
6862
    }
6863
6864
    #[test]
6865
    fn test_transmute_ref() {
6866
        // Test that memory is transmuted as expected.
6867
        let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
6868
        let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
6869
        let x: &[[u8; 2]; 4] = transmute_ref!(&array_of_u8s);
6870
        assert_eq!(*x, array_of_arrays);
6871
        let x: &[u8; 8] = transmute_ref!(&array_of_arrays);
6872
        assert_eq!(*x, array_of_u8s);
6873
6874
        // Test that `transmute_ref!` is legal in a const context.
6875
        const ARRAY_OF_U8S: [u8; 8] = [0u8, 1, 2, 3, 4, 5, 6, 7];
6876
        const ARRAY_OF_ARRAYS: [[u8; 2]; 4] = [[0, 1], [2, 3], [4, 5], [6, 7]];
6877
        #[allow(clippy::redundant_static_lifetimes)]
6878
        const X: &'static [[u8; 2]; 4] = transmute_ref!(&ARRAY_OF_U8S);
6879
        assert_eq!(*X, ARRAY_OF_ARRAYS);
6880
6881
        // Test that it's legal to transmute a reference while shrinking the
6882
        // lifetime (note that `X` has the lifetime `'static`).
6883
        let x: &[u8; 8] = transmute_ref!(X);
6884
        assert_eq!(*x, ARRAY_OF_U8S);
6885
6886
        // Test that `transmute_ref!` supports decreasing alignment.
6887
        let u = AU64(0);
6888
        let array = [0, 0, 0, 0, 0, 0, 0, 0];
6889
        let x: &[u8; 8] = transmute_ref!(&u);
6890
        assert_eq!(*x, array);
6891
6892
        // Test that a mutable reference can be turned into an immutable one.
6893
        let mut x = 0u8;
6894
        #[allow(clippy::useless_transmute)]
6895
        let y: &u8 = transmute_ref!(&mut x);
6896
        assert_eq!(*y, 0);
6897
    }
6898
6899
    #[test]
6900
    fn test_transmute_mut() {
6901
        // Test that memory is transmuted as expected.
6902
        let mut array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
6903
        let mut array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
6904
        let x: &mut [[u8; 2]; 4] = transmute_mut!(&mut array_of_u8s);
6905
        assert_eq!(*x, array_of_arrays);
6906
        let x: &mut [u8; 8] = transmute_mut!(&mut array_of_arrays);
6907
        assert_eq!(*x, array_of_u8s);
6908
6909
        {
6910
            // Test that it's legal to transmute a reference while shrinking the
6911
            // lifetime.
6912
            let x: &mut [u8; 8] = transmute_mut!(&mut array_of_arrays);
6913
            assert_eq!(*x, array_of_u8s);
6914
        }
6915
        // Test that `transmute_mut!` supports decreasing alignment.
6916
        let mut u = AU64(0);
6917
        let array = [0, 0, 0, 0, 0, 0, 0, 0];
6918
        let x: &[u8; 8] = transmute_mut!(&mut u);
6919
        assert_eq!(*x, array);
6920
6921
        // Test that a mutable reference can be turned into an immutable one.
6922
        let mut x = 0u8;
6923
        #[allow(clippy::useless_transmute)]
6924
        let y: &u8 = transmute_mut!(&mut x);
6925
        assert_eq!(*y, 0);
6926
    }
6927
6928
    #[test]
6929
    fn test_macros_evaluate_args_once() {
6930
        let mut ctr = 0;
6931
        let _: usize = transmute!({
6932
            ctr += 1;
6933
            0usize
6934
        });
6935
        assert_eq!(ctr, 1);
6936
6937
        let mut ctr = 0;
6938
        let _: &usize = transmute_ref!({
6939
            ctr += 1;
6940
            &0usize
6941
        });
6942
        assert_eq!(ctr, 1);
6943
    }
6944
6945
    #[test]
6946
    fn test_include_value() {
6947
        const AS_U32: u32 = include_value!("../testdata/include_value/data");
6948
        assert_eq!(AS_U32, u32::from_ne_bytes([b'a', b'b', b'c', b'd']));
6949
        const AS_I32: i32 = include_value!("../testdata/include_value/data");
6950
        assert_eq!(AS_I32, i32::from_ne_bytes([b'a', b'b', b'c', b'd']));
6951
    }
6952
6953
    #[test]
6954
    fn test_address() {
6955
        // Test that the `Deref` and `DerefMut` implementations return a
6956
        // reference which points to the right region of memory.
6957
6958
        let buf = [0];
6959
        let r = Ref::<_, u8>::new(&buf[..]).unwrap();
6960
        let buf_ptr = buf.as_ptr();
6961
        let deref_ptr: *const u8 = r.deref();
6962
        assert_eq!(buf_ptr, deref_ptr);
6963
6964
        let buf = [0];
6965
        let r = Ref::<_, [u8]>::new_slice(&buf[..]).unwrap();
6966
        let buf_ptr = buf.as_ptr();
6967
        let deref_ptr = r.deref().as_ptr();
6968
        assert_eq!(buf_ptr, deref_ptr);
6969
    }
6970
6971
    // Verify that values written to a `Ref` are properly shared between the
6972
    // typed and untyped representations, that reads via `deref` and `read`
6973
    // behave the same, and that writes via `deref_mut` and `write` behave the
6974
    // same.
6975
    fn test_new_helper(mut r: Ref<&mut [u8], AU64>) {
6976
        // assert that the value starts at 0
6977
        assert_eq!(*r, AU64(0));
6978
        assert_eq!(r.read(), AU64(0));
6979
6980
        // Assert that values written to the typed value are reflected in the
6981
        // byte slice.
6982
        const VAL1: AU64 = AU64(0xFF00FF00FF00FF00);
6983
        *r = VAL1;
6984
        assert_eq!(r.bytes(), &VAL1.to_bytes());
6985
        *r = AU64(0);
6986
        r.write(VAL1);
6987
        assert_eq!(r.bytes(), &VAL1.to_bytes());
6988
6989
        // Assert that values written to the byte slice are reflected in the
6990
        // typed value.
6991
        const VAL2: AU64 = AU64(!VAL1.0); // different from `VAL1`
6992
        r.bytes_mut().copy_from_slice(&VAL2.to_bytes()[..]);
6993
        assert_eq!(*r, VAL2);
6994
        assert_eq!(r.read(), VAL2);
6995
    }
6996
6997
    // Verify that values written to a `Ref` are properly shared between the
6998
    // typed and untyped representations; pass a value with `typed_len` `AU64`s
6999
    // backed by an array of `typed_len * 8` bytes.
7000
    fn test_new_helper_slice(mut r: Ref<&mut [u8], [AU64]>, typed_len: usize) {
7001
        // Assert that the value starts out zeroed.
7002
        assert_eq!(&*r, vec![AU64(0); typed_len].as_slice());
7003
7004
        // Check the backing storage is the exact same slice.
7005
        let untyped_len = typed_len * 8;
7006
        assert_eq!(r.bytes().len(), untyped_len);
7007
        assert_eq!(r.bytes().as_ptr(), r.as_ptr().cast::<u8>());
7008
7009
        // Assert that values written to the typed value are reflected in the
7010
        // byte slice.
7011
        const VAL1: AU64 = AU64(0xFF00FF00FF00FF00);
7012
        for typed in &mut *r {
7013
            *typed = VAL1;
7014
        }
7015
        assert_eq!(r.bytes(), VAL1.0.to_ne_bytes().repeat(typed_len).as_slice());
7016
7017
        // Assert that values written to the byte slice are reflected in the
7018
        // typed value.
7019
        const VAL2: AU64 = AU64(!VAL1.0); // different from VAL1
7020
        r.bytes_mut().copy_from_slice(&VAL2.0.to_ne_bytes().repeat(typed_len));
7021
        assert!(r.iter().copied().all(|x| x == VAL2));
7022
    }
7023
7024
    // Verify that values written to a `Ref` are properly shared between the
7025
    // typed and untyped representations, that reads via `deref` and `read`
7026
    // behave the same, and that writes via `deref_mut` and `write` behave the
7027
    // same.
7028
    fn test_new_helper_unaligned(mut r: Ref<&mut [u8], [u8; 8]>) {
7029
        // assert that the value starts at 0
7030
        assert_eq!(*r, [0; 8]);
7031
        assert_eq!(r.read(), [0; 8]);
7032
7033
        // Assert that values written to the typed value are reflected in the
7034
        // byte slice.
7035
        const VAL1: [u8; 8] = [0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00];
7036
        *r = VAL1;
7037
        assert_eq!(r.bytes(), &VAL1);
7038
        *r = [0; 8];
7039
        r.write(VAL1);
7040
        assert_eq!(r.bytes(), &VAL1);
7041
7042
        // Assert that values written to the byte slice are reflected in the
7043
        // typed value.
7044
        const VAL2: [u8; 8] = [0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF]; // different from VAL1
7045
        r.bytes_mut().copy_from_slice(&VAL2[..]);
7046
        assert_eq!(*r, VAL2);
7047
        assert_eq!(r.read(), VAL2);
7048
    }
7049
7050
    // Verify that values written to a `Ref` are properly shared between the
7051
    // typed and untyped representations; pass a value with `len` `u8`s backed
7052
    // by an array of `len` bytes.
7053
    fn test_new_helper_slice_unaligned(mut r: Ref<&mut [u8], [u8]>, len: usize) {
7054
        // Assert that the value starts out zeroed.
7055
        assert_eq!(&*r, vec![0u8; len].as_slice());
7056
7057
        // Check the backing storage is the exact same slice.
7058
        assert_eq!(r.bytes().len(), len);
7059
        assert_eq!(r.bytes().as_ptr(), r.as_ptr());
7060
7061
        // Assert that values written to the typed value are reflected in the
7062
        // byte slice.
7063
        let mut expected_bytes = [0xFF, 0x00].iter().copied().cycle().take(len).collect::<Vec<_>>();
7064
        r.copy_from_slice(&expected_bytes);
7065
        assert_eq!(r.bytes(), expected_bytes.as_slice());
7066
7067
        // Assert that values written to the byte slice are reflected in the
7068
        // typed value.
7069
        for byte in &mut expected_bytes {
7070
            *byte = !*byte; // different from `expected_len`
7071
        }
7072
        r.bytes_mut().copy_from_slice(&expected_bytes);
7073
        assert_eq!(&*r, expected_bytes.as_slice());
7074
    }
7075
7076
    #[test]
7077
    fn test_new_aligned_sized() {
7078
        // Test that a properly-aligned, properly-sized buffer works for new,
7079
        // new_from_prefix, and new_from_suffix, and that new_from_prefix and
7080
        // new_from_suffix return empty slices. Test that a properly-aligned
7081
        // buffer whose length is a multiple of the element size works for
7082
        // new_slice. Test that xxx_zeroed behaves the same, and zeroes the
7083
        // memory.
7084
7085
        // A buffer with an alignment of 8.
7086
        let mut buf = Align::<[u8; 8], AU64>::default();
7087
        // `buf.t` should be aligned to 8, so this should always succeed.
7088
        test_new_helper(Ref::<_, AU64>::new(&mut buf.t[..]).unwrap());
7089
        let ascending: [u8; 8] = (0..8).collect::<Vec<_>>().try_into().unwrap();
7090
        buf.t = ascending;
7091
        test_new_helper(Ref::<_, AU64>::new_zeroed(&mut buf.t[..]).unwrap());
7092
        {
7093
            // In a block so that `r` and `suffix` don't live too long.
7094
            buf.set_default();
7095
            let (r, suffix) = Ref::<_, AU64>::new_from_prefix(&mut buf.t[..]).unwrap();
7096
            assert!(suffix.is_empty());
7097
            test_new_helper(r);
7098
        }
7099
        {
7100
            buf.t = ascending;
7101
            let (r, suffix) = Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[..]).unwrap();
7102
            assert!(suffix.is_empty());
7103
            test_new_helper(r);
7104
        }
7105
        {
7106
            buf.set_default();
7107
            let (prefix, r) = Ref::<_, AU64>::new_from_suffix(&mut buf.t[..]).unwrap();
7108
            assert!(prefix.is_empty());
7109
            test_new_helper(r);
7110
        }
7111
        {
7112
            buf.t = ascending;
7113
            let (prefix, r) = Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).unwrap();
7114
            assert!(prefix.is_empty());
7115
            test_new_helper(r);
7116
        }
7117
7118
        // A buffer with alignment 8 and length 24. We choose this length very
7119
        // intentionally: if we instead used length 16, then the prefix and
7120
        // suffix lengths would be identical. In the past, we used length 16,
7121
        // which resulted in this test failing to discover the bug uncovered in
7122
        // #506.
7123
        let mut buf = Align::<[u8; 24], AU64>::default();
7124
        // `buf.t` should be aligned to 8 and have a length which is a multiple
7125
        // of `size_of::<AU64>()`, so this should always succeed.
7126
        test_new_helper_slice(Ref::<_, [AU64]>::new_slice(&mut buf.t[..]).unwrap(), 3);
7127
        let ascending: [u8; 24] = (0..24).collect::<Vec<_>>().try_into().unwrap();
7128
        // 16 ascending bytes followed by 8 zeros.
7129
        let mut ascending_prefix = ascending;
7130
        ascending_prefix[16..].copy_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
7131
        // 8 zeros followed by 16 ascending bytes.
7132
        let mut ascending_suffix = ascending;
7133
        ascending_suffix[..8].copy_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
7134
        test_new_helper_slice(Ref::<_, [AU64]>::new_slice_zeroed(&mut buf.t[..]).unwrap(), 3);
7135
7136
        {
7137
            buf.t = ascending_suffix;
7138
            let (r, suffix) = Ref::<_, [AU64]>::new_slice_from_prefix(&mut buf.t[..], 1).unwrap();
7139
            assert_eq!(suffix, &ascending[8..]);
7140
            test_new_helper_slice(r, 1);
7141
        }
7142
        {
7143
            buf.t = ascending_suffix;
7144
            let (r, suffix) =
7145
                Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[..], 1).unwrap();
7146
            assert_eq!(suffix, &ascending[8..]);
7147
            test_new_helper_slice(r, 1);
7148
        }
7149
        {
7150
            buf.t = ascending_prefix;
7151
            let (prefix, r) = Ref::<_, [AU64]>::new_slice_from_suffix(&mut buf.t[..], 1).unwrap();
7152
            assert_eq!(prefix, &ascending[..16]);
7153
            test_new_helper_slice(r, 1);
7154
        }
7155
        {
7156
            buf.t = ascending_prefix;
7157
            let (prefix, r) =
7158
                Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[..], 1).unwrap();
7159
            assert_eq!(prefix, &ascending[..16]);
7160
            test_new_helper_slice(r, 1);
7161
        }
7162
    }
7163
7164
    #[test]
7165
    fn test_new_unaligned_sized() {
7166
        // Test that an unaligned, properly-sized buffer works for
7167
        // `new_unaligned`, `new_unaligned_from_prefix`, and
7168
        // `new_unaligned_from_suffix`, and that `new_unaligned_from_prefix`
7169
        // `new_unaligned_from_suffix` return empty slices. Test that an
7170
        // unaligned buffer whose length is a multiple of the element size works
7171
        // for `new_slice`. Test that `xxx_zeroed` behaves the same, and zeroes
7172
        // the memory.
7173
7174
        let mut buf = [0u8; 8];
7175
        test_new_helper_unaligned(Ref::<_, [u8; 8]>::new_unaligned(&mut buf[..]).unwrap());
7176
        buf = [0xFFu8; 8];
7177
        test_new_helper_unaligned(Ref::<_, [u8; 8]>::new_unaligned_zeroed(&mut buf[..]).unwrap());
7178
        {
7179
            // In a block so that `r` and `suffix` don't live too long.
7180
            buf = [0u8; 8];
7181
            let (r, suffix) = Ref::<_, [u8; 8]>::new_unaligned_from_prefix(&mut buf[..]).unwrap();
7182
            assert!(suffix.is_empty());
7183
            test_new_helper_unaligned(r);
7184
        }
7185
        {
7186
            buf = [0xFFu8; 8];
7187
            let (r, suffix) =
7188
                Ref::<_, [u8; 8]>::new_unaligned_from_prefix_zeroed(&mut buf[..]).unwrap();
7189
            assert!(suffix.is_empty());
7190
            test_new_helper_unaligned(r);
7191
        }
7192
        {
7193
            buf = [0u8; 8];
7194
            let (prefix, r) = Ref::<_, [u8; 8]>::new_unaligned_from_suffix(&mut buf[..]).unwrap();
7195
            assert!(prefix.is_empty());
7196
            test_new_helper_unaligned(r);
7197
        }
7198
        {
7199
            buf = [0xFFu8; 8];
7200
            let (prefix, r) =
7201
                Ref::<_, [u8; 8]>::new_unaligned_from_suffix_zeroed(&mut buf[..]).unwrap();
7202
            assert!(prefix.is_empty());
7203
            test_new_helper_unaligned(r);
7204
        }
7205
7206
        let mut buf = [0u8; 16];
7207
        // `buf.t` should be aligned to 8 and have a length which is a multiple
7208
        // of `size_of::AU64>()`, so this should always succeed.
7209
        test_new_helper_slice_unaligned(
7210
            Ref::<_, [u8]>::new_slice_unaligned(&mut buf[..]).unwrap(),
7211
            16,
7212
        );
7213
        buf = [0xFFu8; 16];
7214
        test_new_helper_slice_unaligned(
7215
            Ref::<_, [u8]>::new_slice_unaligned_zeroed(&mut buf[..]).unwrap(),
7216
            16,
7217
        );
7218
7219
        {
7220
            buf = [0u8; 16];
7221
            let (r, suffix) =
7222
                Ref::<_, [u8]>::new_slice_unaligned_from_prefix(&mut buf[..], 8).unwrap();
7223
            assert_eq!(suffix, [0; 8]);
7224
            test_new_helper_slice_unaligned(r, 8);
7225
        }
7226
        {
7227
            buf = [0xFFu8; 16];
7228
            let (r, suffix) =
7229
                Ref::<_, [u8]>::new_slice_unaligned_from_prefix_zeroed(&mut buf[..], 8).unwrap();
7230
            assert_eq!(suffix, [0xFF; 8]);
7231
            test_new_helper_slice_unaligned(r, 8);
7232
        }
7233
        {
7234
            buf = [0u8; 16];
7235
            let (prefix, r) =
7236
                Ref::<_, [u8]>::new_slice_unaligned_from_suffix(&mut buf[..], 8).unwrap();
7237
            assert_eq!(prefix, [0; 8]);
7238
            test_new_helper_slice_unaligned(r, 8);
7239
        }
7240
        {
7241
            buf = [0xFFu8; 16];
7242
            let (prefix, r) =
7243
                Ref::<_, [u8]>::new_slice_unaligned_from_suffix_zeroed(&mut buf[..], 8).unwrap();
7244
            assert_eq!(prefix, [0xFF; 8]);
7245
            test_new_helper_slice_unaligned(r, 8);
7246
        }
7247
    }
7248
7249
    #[test]
7250
    fn test_new_oversized() {
7251
        // Test that a properly-aligned, overly-sized buffer works for
7252
        // `new_from_prefix` and `new_from_suffix`, and that they return the
7253
        // remainder and prefix of the slice respectively. Test that
7254
        // `xxx_zeroed` behaves the same, and zeroes the memory.
7255
7256
        let mut buf = Align::<[u8; 16], AU64>::default();
7257
        {
7258
            // In a block so that `r` and `suffix` don't live too long. `buf.t`
7259
            // should be aligned to 8, so this should always succeed.
7260
            let (r, suffix) = Ref::<_, AU64>::new_from_prefix(&mut buf.t[..]).unwrap();
7261
            assert_eq!(suffix.len(), 8);
7262
            test_new_helper(r);
7263
        }
7264
        {
7265
            buf.t = [0xFFu8; 16];
7266
            // `buf.t` should be aligned to 8, so this should always succeed.
7267
            let (r, suffix) = Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[..]).unwrap();
7268
            // Assert that the suffix wasn't zeroed.
7269
            assert_eq!(suffix, &[0xFFu8; 8]);
7270
            test_new_helper(r);
7271
        }
7272
        {
7273
            buf.set_default();
7274
            // `buf.t` should be aligned to 8, so this should always succeed.
7275
            let (prefix, r) = Ref::<_, AU64>::new_from_suffix(&mut buf.t[..]).unwrap();
7276
            assert_eq!(prefix.len(), 8);
7277
            test_new_helper(r);
7278
        }
7279
        {
7280
            buf.t = [0xFFu8; 16];
7281
            // `buf.t` should be aligned to 8, so this should always succeed.
7282
            let (prefix, r) = Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).unwrap();
7283
            // Assert that the prefix wasn't zeroed.
7284
            assert_eq!(prefix, &[0xFFu8; 8]);
7285
            test_new_helper(r);
7286
        }
7287
    }
7288
7289
    #[test]
7290
    fn test_new_unaligned_oversized() {
7291
        // Test than an unaligned, overly-sized buffer works for
7292
        // `new_unaligned_from_prefix` and `new_unaligned_from_suffix`, and that
7293
        // they return the remainder and prefix of the slice respectively. Test
7294
        // that `xxx_zeroed` behaves the same, and zeroes the memory.
7295
7296
        let mut buf = [0u8; 16];
7297
        {
7298
            // In a block so that `r` and `suffix` don't live too long.
7299
            let (r, suffix) = Ref::<_, [u8; 8]>::new_unaligned_from_prefix(&mut buf[..]).unwrap();
7300
            assert_eq!(suffix.len(), 8);
7301
            test_new_helper_unaligned(r);
7302
        }
7303
        {
7304
            buf = [0xFFu8; 16];
7305
            let (r, suffix) =
7306
                Ref::<_, [u8; 8]>::new_unaligned_from_prefix_zeroed(&mut buf[..]).unwrap();
7307
            // Assert that the suffix wasn't zeroed.
7308
            assert_eq!(suffix, &[0xFF; 8]);
7309
            test_new_helper_unaligned(r);
7310
        }
7311
        {
7312
            buf = [0u8; 16];
7313
            let (prefix, r) = Ref::<_, [u8; 8]>::new_unaligned_from_suffix(&mut buf[..]).unwrap();
7314
            assert_eq!(prefix.len(), 8);
7315
            test_new_helper_unaligned(r);
7316
        }
7317
        {
7318
            buf = [0xFFu8; 16];
7319
            let (prefix, r) =
7320
                Ref::<_, [u8; 8]>::new_unaligned_from_suffix_zeroed(&mut buf[..]).unwrap();
7321
            // Assert that the prefix wasn't zeroed.
7322
            assert_eq!(prefix, &[0xFF; 8]);
7323
            test_new_helper_unaligned(r);
7324
        }
7325
    }
7326
7327
    #[test]
7328
    fn test_ref_from_mut_from() {
7329
        // Test `FromBytes::{ref_from, mut_from}{,_prefix,_suffix}` success cases
7330
        // Exhaustive coverage for these methods is covered by the `Ref` tests above,
7331
        // which these helper methods defer to.
7332
7333
        let mut buf =
7334
            Align::<[u8; 16], AU64>::new([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
7335
7336
        assert_eq!(
7337
            AU64::ref_from(&buf.t[8..]).unwrap().0.to_ne_bytes(),
7338
            [8, 9, 10, 11, 12, 13, 14, 15]
7339
        );
7340
        let suffix = AU64::mut_from(&mut buf.t[8..]).unwrap();
7341
        suffix.0 = 0x0101010101010101;
7342
        // The `[u8:9]` is a non-half size of the full buffer, which would catch
7343
        // `from_prefix` having the same implementation as `from_suffix` (issues #506, #511).
7344
        assert_eq!(<[u8; 9]>::ref_from_suffix(&buf.t[..]).unwrap(), &[7u8, 1, 1, 1, 1, 1, 1, 1, 1]);
7345
        let suffix = AU64::mut_from_suffix(&mut buf.t[1..]).unwrap();
7346
        suffix.0 = 0x0202020202020202;
7347
        <[u8; 10]>::mut_from_suffix(&mut buf.t[..]).unwrap()[0] = 42;
7348
        assert_eq!(<[u8; 9]>::ref_from_prefix(&buf.t[..]).unwrap(), &[0, 1, 2, 3, 4, 5, 42, 7, 2]);
7349
        <[u8; 2]>::mut_from_prefix(&mut buf.t[..]).unwrap()[1] = 30;
7350
        assert_eq!(buf.t, [0, 30, 2, 3, 4, 5, 42, 7, 2, 2, 2, 2, 2, 2, 2, 2]);
7351
    }
7352
7353
    #[test]
7354
    fn test_ref_from_mut_from_error() {
7355
        // Test `FromBytes::{ref_from, mut_from}{,_prefix,_suffix}` error cases.
7356
7357
        // Fail because the buffer is too large.
7358
        let mut buf = Align::<[u8; 16], AU64>::default();
7359
        // `buf.t` should be aligned to 8, so only the length check should fail.
7360
        assert!(AU64::ref_from(&buf.t[..]).is_none());
7361
        assert!(AU64::mut_from(&mut buf.t[..]).is_none());
7362
        assert!(<[u8; 8]>::ref_from(&buf.t[..]).is_none());
7363
        assert!(<[u8; 8]>::mut_from(&mut buf.t[..]).is_none());
7364
7365
        // Fail because the buffer is too small.
7366
        let mut buf = Align::<[u8; 4], AU64>::default();
7367
        assert!(AU64::ref_from(&buf.t[..]).is_none());
7368
        assert!(AU64::mut_from(&mut buf.t[..]).is_none());
7369
        assert!(<[u8; 8]>::ref_from(&buf.t[..]).is_none());
7370
        assert!(<[u8; 8]>::mut_from(&mut buf.t[..]).is_none());
7371
        assert!(AU64::ref_from_prefix(&buf.t[..]).is_none());
7372
        assert!(AU64::mut_from_prefix(&mut buf.t[..]).is_none());
7373
        assert!(AU64::ref_from_suffix(&buf.t[..]).is_none());
7374
        assert!(AU64::mut_from_suffix(&mut buf.t[..]).is_none());
7375
        assert!(<[u8; 8]>::ref_from_prefix(&buf.t[..]).is_none());
7376
        assert!(<[u8; 8]>::mut_from_prefix(&mut buf.t[..]).is_none());
7377
        assert!(<[u8; 8]>::ref_from_suffix(&buf.t[..]).is_none());
7378
        assert!(<[u8; 8]>::mut_from_suffix(&mut buf.t[..]).is_none());
7379
7380
        // Fail because the alignment is insufficient.
7381
        let mut buf = Align::<[u8; 13], AU64>::default();
7382
        assert!(AU64::ref_from(&buf.t[1..]).is_none());
7383
        assert!(AU64::mut_from(&mut buf.t[1..]).is_none());
7384
        assert!(AU64::ref_from(&buf.t[1..]).is_none());
7385
        assert!(AU64::mut_from(&mut buf.t[1..]).is_none());
7386
        assert!(AU64::ref_from_prefix(&buf.t[1..]).is_none());
7387
        assert!(AU64::mut_from_prefix(&mut buf.t[1..]).is_none());
7388
        assert!(AU64::ref_from_suffix(&buf.t[..]).is_none());
7389
        assert!(AU64::mut_from_suffix(&mut buf.t[..]).is_none());
7390
    }
7391
7392
    #[test]
7393
    #[allow(clippy::cognitive_complexity)]
7394
    fn test_new_error() {
7395
        // Fail because the buffer is too large.
7396
7397
        // A buffer with an alignment of 8.
7398
        let mut buf = Align::<[u8; 16], AU64>::default();
7399
        // `buf.t` should be aligned to 8, so only the length check should fail.
7400
        assert!(Ref::<_, AU64>::new(&buf.t[..]).is_none());
7401
        assert!(Ref::<_, AU64>::new_zeroed(&mut buf.t[..]).is_none());
7402
        assert!(Ref::<_, [u8; 8]>::new_unaligned(&buf.t[..]).is_none());
7403
        assert!(Ref::<_, [u8; 8]>::new_unaligned_zeroed(&mut buf.t[..]).is_none());
7404
7405
        // Fail because the buffer is too small.
7406
7407
        // A buffer with an alignment of 8.
7408
        let mut buf = Align::<[u8; 4], AU64>::default();
7409
        // `buf.t` should be aligned to 8, so only the length check should fail.
7410
        assert!(Ref::<_, AU64>::new(&buf.t[..]).is_none());
7411
        assert!(Ref::<_, AU64>::new_zeroed(&mut buf.t[..]).is_none());
7412
        assert!(Ref::<_, [u8; 8]>::new_unaligned(&buf.t[..]).is_none());
7413
        assert!(Ref::<_, [u8; 8]>::new_unaligned_zeroed(&mut buf.t[..]).is_none());
7414
        assert!(Ref::<_, AU64>::new_from_prefix(&buf.t[..]).is_none());
7415
        assert!(Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[..]).is_none());
7416
        assert!(Ref::<_, AU64>::new_from_suffix(&buf.t[..]).is_none());
7417
        assert!(Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).is_none());
7418
        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_prefix(&buf.t[..]).is_none());
7419
        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_prefix_zeroed(&mut buf.t[..]).is_none());
7420
        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_suffix(&buf.t[..]).is_none());
7421
        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_suffix_zeroed(&mut buf.t[..]).is_none());
7422
7423
        // Fail because the length is not a multiple of the element size.
7424
7425
        let mut buf = Align::<[u8; 12], AU64>::default();
7426
        // `buf.t` has length 12, but element size is 8.
7427
        assert!(Ref::<_, [AU64]>::new_slice(&buf.t[..]).is_none());
7428
        assert!(Ref::<_, [AU64]>::new_slice_zeroed(&mut buf.t[..]).is_none());
7429
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned(&buf.t[..]).is_none());
7430
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_zeroed(&mut buf.t[..]).is_none());
7431
7432
        // Fail because the buffer is too short.
7433
        let mut buf = Align::<[u8; 12], AU64>::default();
7434
        // `buf.t` has length 12, but the element size is 8 (and we're expecting
7435
        // two of them).
7436
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix(&buf.t[..], 2).is_none());
7437
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[..], 2).is_none());
7438
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix(&buf.t[..], 2).is_none());
7439
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[..], 2).is_none());
7440
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix(&buf.t[..], 2).is_none());
7441
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix_zeroed(&mut buf.t[..], 2)
7442
            .is_none());
7443
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix(&buf.t[..], 2).is_none());
7444
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix_zeroed(&mut buf.t[..], 2)
7445
            .is_none());
7446
7447
        // Fail because the alignment is insufficient.
7448
7449
        // A buffer with an alignment of 8. An odd buffer size is chosen so that
7450
        // the last byte of the buffer has odd alignment.
7451
        let mut buf = Align::<[u8; 13], AU64>::default();
7452
        // Slicing from 1, we get a buffer with size 12 (so the length check
7453
        // should succeed) but an alignment of only 1, which is insufficient.
7454
        assert!(Ref::<_, AU64>::new(&buf.t[1..]).is_none());
7455
        assert!(Ref::<_, AU64>::new_zeroed(&mut buf.t[1..]).is_none());
7456
        assert!(Ref::<_, AU64>::new_from_prefix(&buf.t[1..]).is_none());
7457
        assert!(Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[1..]).is_none());
7458
        assert!(Ref::<_, [AU64]>::new_slice(&buf.t[1..]).is_none());
7459
        assert!(Ref::<_, [AU64]>::new_slice_zeroed(&mut buf.t[1..]).is_none());
7460
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix(&buf.t[1..], 1).is_none());
7461
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[1..], 1).is_none());
7462
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix(&buf.t[1..], 1).is_none());
7463
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[1..], 1).is_none());
7464
        // Slicing is unnecessary here because `new_from_suffix[_zeroed]` use
7465
        // the suffix of the slice, which has odd alignment.
7466
        assert!(Ref::<_, AU64>::new_from_suffix(&buf.t[..]).is_none());
7467
        assert!(Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).is_none());
7468
7469
        // Fail due to arithmetic overflow.
7470
7471
        let mut buf = Align::<[u8; 16], AU64>::default();
7472
        let unreasonable_len = usize::MAX / mem::size_of::<AU64>() + 1;
7473
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix(&buf.t[..], unreasonable_len).is_none());
7474
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[..], unreasonable_len)
7475
            .is_none());
7476
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix(&buf.t[..], unreasonable_len).is_none());
7477
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[..], unreasonable_len)
7478
            .is_none());
7479
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix(&buf.t[..], unreasonable_len)
7480
            .is_none());
7481
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix_zeroed(
7482
            &mut buf.t[..],
7483
            unreasonable_len
7484
        )
7485
        .is_none());
7486
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix(&buf.t[..], unreasonable_len)
7487
            .is_none());
7488
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix_zeroed(
7489
            &mut buf.t[..],
7490
            unreasonable_len
7491
        )
7492
        .is_none());
7493
    }
7494
7495
    // Tests for ensuring that, if a ZST is passed into a slice-like function,
7496
    // we always panic. Since these tests need to be separate per-function, and
7497
    // they tend to take up a lot of space, we generate them using a macro in a
7498
    // submodule instead. The submodule ensures that we can just re-use the name
7499
    // of the function under test for the name of the test itself.
7500
    mod test_zst_panics {
7501
        macro_rules! zst_test {
7502
            ($name:ident($($tt:tt)*), $constructor_in_panic_msg:tt) => {
7503
                #[test]
7504
                #[should_panic = concat!("Ref::", $constructor_in_panic_msg, " called on a zero-sized type")]
7505
                fn $name() {
7506
                    let mut buffer = [0u8];
7507
                    let r = $crate::Ref::<_, [()]>::$name(&mut buffer[..], $($tt)*);
7508
                    unreachable!("should have panicked, got {:?}", r);
7509
                }
7510
            }
7511
        }
7512
        zst_test!(new_slice(), "new_slice");
7513
        zst_test!(new_slice_zeroed(), "new_slice");
7514
        zst_test!(new_slice_from_prefix(1), "new_slice");
7515
        zst_test!(new_slice_from_prefix_zeroed(1), "new_slice");
7516
        zst_test!(new_slice_from_suffix(1), "new_slice");
7517
        zst_test!(new_slice_from_suffix_zeroed(1), "new_slice");
7518
        zst_test!(new_slice_unaligned(), "new_slice_unaligned");
7519
        zst_test!(new_slice_unaligned_zeroed(), "new_slice_unaligned");
7520
        zst_test!(new_slice_unaligned_from_prefix(1), "new_slice_unaligned");
7521
        zst_test!(new_slice_unaligned_from_prefix_zeroed(1), "new_slice_unaligned");
7522
        zst_test!(new_slice_unaligned_from_suffix(1), "new_slice_unaligned");
7523
        zst_test!(new_slice_unaligned_from_suffix_zeroed(1), "new_slice_unaligned");
7524
    }
7525
7526
    #[test]
7527
    fn test_as_bytes_methods() {
7528
        /// Run a series of tests by calling `AsBytes` methods on `t`.
7529
        ///
7530
        /// `bytes` is the expected byte sequence returned from `t.as_bytes()`
7531
        /// before `t` has been modified. `post_mutation` is the expected
7532
        /// sequence returned from `t.as_bytes()` after `t.as_bytes_mut()[0]`
7533
        /// has had its bits flipped (by applying `^= 0xFF`).
7534
        ///
7535
        /// `N` is the size of `t` in bytes.
7536
        fn test<T: FromBytes + AsBytes + Debug + Eq + ?Sized, const N: usize>(
7537
            t: &mut T,
7538
            bytes: &[u8],
7539
            post_mutation: &T,
7540
        ) {
7541
            // Test that we can access the underlying bytes, and that we get the
7542
            // right bytes and the right number of bytes.
7543
            assert_eq!(t.as_bytes(), bytes);
7544
7545
            // Test that changes to the underlying byte slices are reflected in
7546
            // the original object.
7547
            t.as_bytes_mut()[0] ^= 0xFF;
7548
            assert_eq!(t, post_mutation);
7549
            t.as_bytes_mut()[0] ^= 0xFF;
7550
7551
            // `write_to` rejects slices that are too small or too large.
7552
            assert_eq!(t.write_to(&mut vec![0; N - 1][..]), None);
7553
            assert_eq!(t.write_to(&mut vec![0; N + 1][..]), None);
7554
7555
            // `write_to` works as expected.
7556
            let mut bytes = [0; N];
7557
            assert_eq!(t.write_to(&mut bytes[..]), Some(()));
7558
            assert_eq!(bytes, t.as_bytes());
7559
7560
            // `write_to_prefix` rejects slices that are too small.
7561
            assert_eq!(t.write_to_prefix(&mut vec![0; N - 1][..]), None);
7562
7563
            // `write_to_prefix` works with exact-sized slices.
7564
            let mut bytes = [0; N];
7565
            assert_eq!(t.write_to_prefix(&mut bytes[..]), Some(()));
7566
            assert_eq!(bytes, t.as_bytes());
7567
7568
            // `write_to_prefix` works with too-large slices, and any bytes past
7569
            // the prefix aren't modified.
7570
            let mut too_many_bytes = vec![0; N + 1];
7571
            too_many_bytes[N] = 123;
7572
            assert_eq!(t.write_to_prefix(&mut too_many_bytes[..]), Some(()));
7573
            assert_eq!(&too_many_bytes[..N], t.as_bytes());
7574
            assert_eq!(too_many_bytes[N], 123);
7575
7576
            // `write_to_suffix` rejects slices that are too small.
7577
            assert_eq!(t.write_to_suffix(&mut vec![0; N - 1][..]), None);
7578
7579
            // `write_to_suffix` works with exact-sized slices.
7580
            let mut bytes = [0; N];
7581
            assert_eq!(t.write_to_suffix(&mut bytes[..]), Some(()));
7582
            assert_eq!(bytes, t.as_bytes());
7583
7584
            // `write_to_suffix` works with too-large slices, and any bytes
7585
            // before the suffix aren't modified.
7586
            let mut too_many_bytes = vec![0; N + 1];
7587
            too_many_bytes[0] = 123;
7588
            assert_eq!(t.write_to_suffix(&mut too_many_bytes[..]), Some(()));
7589
            assert_eq!(&too_many_bytes[1..], t.as_bytes());
7590
            assert_eq!(too_many_bytes[0], 123);
7591
        }
7592
7593
        #[derive(Debug, Eq, PartialEq, FromZeroes, FromBytes, AsBytes)]
7594
        #[repr(C)]
7595
        struct Foo {
7596
            a: u32,
7597
            b: Wrapping<u32>,
7598
            c: Option<NonZeroU32>,
7599
        }
7600
7601
        let expected_bytes: Vec<u8> = if cfg!(target_endian = "little") {
7602
            vec![1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]
7603
        } else {
7604
            vec![0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0]
7605
        };
7606
        let post_mutation_expected_a =
7607
            if cfg!(target_endian = "little") { 0x00_00_00_FE } else { 0xFF_00_00_01 };
7608
        test::<_, 12>(
7609
            &mut Foo { a: 1, b: Wrapping(2), c: None },
7610
            expected_bytes.as_bytes(),
7611
            &Foo { a: post_mutation_expected_a, b: Wrapping(2), c: None },
7612
        );
7613
        test::<_, 3>(
7614
            Unsized::from_mut_slice(&mut [1, 2, 3]),
7615
            &[1, 2, 3],
7616
            Unsized::from_mut_slice(&mut [0xFE, 2, 3]),
7617
        );
7618
    }
7619
7620
    #[test]
7621
    fn test_array() {
7622
        #[derive(FromZeroes, FromBytes, AsBytes)]
7623
        #[repr(C)]
7624
        struct Foo {
7625
            a: [u16; 33],
7626
        }
7627
7628
        let foo = Foo { a: [0xFFFF; 33] };
7629
        let expected = [0xFFu8; 66];
7630
        assert_eq!(foo.as_bytes(), &expected[..]);
7631
    }
7632
7633
    #[test]
7634
    fn test_display_debug() {
7635
        let buf = Align::<[u8; 8], u64>::default();
7636
        let r = Ref::<_, u64>::new(&buf.t[..]).unwrap();
7637
        assert_eq!(format!("{}", r), "0");
7638
        assert_eq!(format!("{:?}", r), "Ref(0)");
7639
7640
        let buf = Align::<[u8; 8], u64>::default();
7641
        let r = Ref::<_, [u64]>::new_slice(&buf.t[..]).unwrap();
7642
        assert_eq!(format!("{:?}", r), "Ref([0])");
7643
    }
7644
7645
    #[test]
7646
    fn test_eq() {
7647
        let buf1 = 0_u64;
7648
        let r1 = Ref::<_, u64>::new(buf1.as_bytes()).unwrap();
7649
        let buf2 = 0_u64;
7650
        let r2 = Ref::<_, u64>::new(buf2.as_bytes()).unwrap();
7651
        assert_eq!(r1, r2);
7652
    }
7653
7654
    #[test]
7655
    fn test_ne() {
7656
        let buf1 = 0_u64;
7657
        let r1 = Ref::<_, u64>::new(buf1.as_bytes()).unwrap();
7658
        let buf2 = 1_u64;
7659
        let r2 = Ref::<_, u64>::new(buf2.as_bytes()).unwrap();
7660
        assert_ne!(r1, r2);
7661
    }
7662
7663
    #[test]
7664
    fn test_ord() {
7665
        let buf1 = 0_u64;
7666
        let r1 = Ref::<_, u64>::new(buf1.as_bytes()).unwrap();
7667
        let buf2 = 1_u64;
7668
        let r2 = Ref::<_, u64>::new(buf2.as_bytes()).unwrap();
7669
        assert!(r1 < r2);
7670
    }
7671
7672
    #[test]
7673
    fn test_new_zeroed() {
7674
        assert!(!bool::new_zeroed());
7675
        assert_eq!(u64::new_zeroed(), 0);
7676
        // This test exists in order to exercise unsafe code, especially when
7677
        // running under Miri.
7678
        #[allow(clippy::unit_cmp)]
7679
        {
7680
            assert_eq!(<()>::new_zeroed(), ());
7681
        }
7682
    }
7683
7684
    #[test]
7685
    fn test_transparent_packed_generic_struct() {
7686
        #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
7687
        #[repr(transparent)]
7688
        #[allow(dead_code)] // for the unused fields
7689
        struct Foo<T> {
7690
            _t: T,
7691
            _phantom: PhantomData<()>,
7692
        }
7693
7694
        assert_impl_all!(Foo<u32>: FromZeroes, FromBytes, AsBytes);
7695
        assert_impl_all!(Foo<u8>: Unaligned);
7696
7697
        #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
7698
        #[repr(packed)]
7699
        #[allow(dead_code)] // for the unused fields
7700
        struct Bar<T, U> {
7701
            _t: T,
7702
            _u: U,
7703
        }
7704
7705
        assert_impl_all!(Bar<u8, AU64>: FromZeroes, FromBytes, AsBytes, Unaligned);
7706
    }
7707
7708
    #[test]
7709
    fn test_impls() {
7710
        use core::borrow::Borrow;
7711
7712
        // A type that can supply test cases for testing
7713
        // `TryFromBytes::is_bit_valid`. All types passed to `assert_impls!`
7714
        // must implement this trait; that macro uses it to generate runtime
7715
        // tests for `TryFromBytes` impls.
7716
        //
7717
        // All `T: FromBytes` types are provided with a blanket impl. Other
7718
        // types must implement `TryFromBytesTestable` directly (ie using
7719
        // `impl_try_from_bytes_testable!`).
7720
        trait TryFromBytesTestable {
7721
            fn with_passing_test_cases<F: Fn(&Self)>(f: F);
7722
            fn with_failing_test_cases<F: Fn(&[u8])>(f: F);
7723
        }
7724
7725
        impl<T: FromBytes> TryFromBytesTestable for T {
7726
            fn with_passing_test_cases<F: Fn(&Self)>(f: F) {
7727
                // Test with a zeroed value.
7728
                f(&Self::new_zeroed());
7729
7730
                let ffs = {
7731
                    let mut t = Self::new_zeroed();
7732
                    let ptr: *mut T = &mut t;
7733
                    // SAFETY: `T: FromBytes`
7734
                    unsafe { ptr::write_bytes(ptr.cast::<u8>(), 0xFF, mem::size_of::<T>()) };
7735
                    t
7736
                };
7737
7738
                // Test with a value initialized with 0xFF.
7739
                f(&ffs);
7740
            }
7741
7742
            fn with_failing_test_cases<F: Fn(&[u8])>(_f: F) {}
7743
        }
7744
7745
        // Implements `TryFromBytesTestable`.
7746
        macro_rules! impl_try_from_bytes_testable {
7747
            // Base case for recursion (when the list of types has run out).
7748
            (=> @success $($success_case:expr),* $(, @failure $($failure_case:expr),*)?) => {};
7749
            // Implements for type(s) with no type parameters.
7750
            ($ty:ty $(,$tys:ty)* => @success $($success_case:expr),* $(, @failure $($failure_case:expr),*)?) => {
7751
                impl TryFromBytesTestable for $ty {
7752
                    impl_try_from_bytes_testable!(
7753
                        @methods     @success $($success_case),*
7754
                                 $(, @failure $($failure_case),*)?
7755
                    );
7756
                }
7757
                impl_try_from_bytes_testable!($($tys),* => @success $($success_case),* $(, @failure $($failure_case),*)?);
7758
            };
7759
            // Implements for multiple types with no type parameters.
7760
            ($($($ty:ty),* => @success $($success_case:expr), * $(, @failure $($failure_case:expr),*)?;)*) => {
7761
                $(
7762
                    impl_try_from_bytes_testable!($($ty),* => @success $($success_case),* $(, @failure $($failure_case),*)*);
7763
                )*
7764
            };
7765
            // Implements only the methods; caller must invoke this from inside
7766
            // an impl block.
7767
            (@methods @success $($success_case:expr),* $(, @failure $($failure_case:expr),*)?) => {
7768
                fn with_passing_test_cases<F: Fn(&Self)>(_f: F) {
7769
                    $(
7770
                        _f($success_case.borrow());
7771
                    )*
7772
                }
7773
7774
                fn with_failing_test_cases<F: Fn(&[u8])>(_f: F) {
7775
                    $($(
7776
                        let case = $failure_case.as_bytes();
7777
                        _f(case.as_bytes());
7778
                    )*)?
7779
                }
7780
            };
7781
        }
7782
7783
        // Note that these impls are only for types which are not `FromBytes`.
7784
        // `FromBytes` types are covered by a preceding blanket impl.
7785
        impl_try_from_bytes_testable!(
7786
            bool => @success true, false,
7787
                    @failure 2u8, 3u8, 0xFFu8;
7788
            char => @success '\u{0}', '\u{D7FF}', '\u{E000}', '\u{10FFFF}',
7789
                    @failure 0xD800u32, 0xDFFFu32, 0x110000u32;
7790
            str  => @success "", "hello", "❤️🧡💛💚💙💜",
7791
                    @failure [0, 159, 146, 150];
7792
            [u8] => @success [], [0, 1, 2];
7793
            NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32,
7794
            NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128,
7795
            NonZeroUsize, NonZeroIsize
7796
                 => @success Self::new(1).unwrap(),
7797
                    // Doing this instead of `0` ensures that we always satisfy
7798
                    // the size and alignment requirements of `Self` (whereas
7799
                    // `0` may be any integer type with a different size or
7800
                    // alignment than some `NonZeroXxx` types).
7801
                    @failure Option::<Self>::None;
7802
            [bool]
7803
                => @success [true, false], [false, true],
7804
                    @failure [2u8], [3u8], [0xFFu8], [0u8, 1u8, 2u8];
7805
        );
7806
7807
        // Asserts that `$ty` implements any `$trait` and doesn't implement any
7808
        // `!$trait`. Note that all `$trait`s must come before any `!$trait`s.
7809
        //
7810
        // For `T: TryFromBytes`, uses `TryFromBytesTestable` to test success
7811
        // and failure cases for `TryFromBytes::is_bit_valid`.
7812
        macro_rules! assert_impls {
7813
            ($ty:ty: TryFromBytes) => {
7814
                <$ty as TryFromBytesTestable>::with_passing_test_cases(|val| {
7815
                    let c = Ptr::from(val);
7816
                    // SAFETY:
7817
                    // - Since `val` is a normal reference, `c` is guranteed to
7818
                    //   be aligned, to point to a single allocation, and to
7819
                    //   have a size which doesn't overflow `isize`.
7820
                    // - Since `val` is a valid `$ty`, `c`'s referent satisfies
7821
                    //   the bit validity constraints of `is_bit_valid`, which
7822
                    //   are a superset of the bit validity constraints of
7823
                    //   `$ty`.
7824
                    let res = unsafe { <$ty as TryFromBytes>::is_bit_valid(c) };
7825
                    assert!(res, "{}::is_bit_valid({:?}): got false, expected true", stringify!($ty), val);
7826
7827
                    // TODO(#5): In addition to testing `is_bit_valid`, test the
7828
                    // methods built on top of it. This would both allow us to
7829
                    // test their implementations and actually convert the bytes
7830
                    // to `$ty`, giving Miri a chance to catch if this is
7831
                    // unsound (ie, if our `is_bit_valid` impl is buggy).
7832
                    //
7833
                    // The following code was tried, but it doesn't work because
7834
                    // a) some types are not `AsBytes` and, b) some types are
7835
                    // not `Sized`.
7836
                    //
7837
                    //   let r = <$ty as TryFromBytes>::try_from_ref(val.as_bytes()).unwrap();
7838
                    //   assert_eq!(r, &val);
7839
                    //   let r = <$ty as TryFromBytes>::try_from_mut(val.as_bytes_mut()).unwrap();
7840
                    //   assert_eq!(r, &mut val);
7841
                    //   let v = <$ty as TryFromBytes>::try_read_from(val.as_bytes()).unwrap();
7842
                    //   assert_eq!(v, val);
7843
                });
7844
                #[allow(clippy::as_conversions)]
7845
                <$ty as TryFromBytesTestable>::with_failing_test_cases(|c| {
7846
                    let res = <$ty as TryFromBytes>::try_from_ref(c);
7847
                    assert!(res.is_none(), "{}::is_bit_valid({:?}): got true, expected false", stringify!($ty), c);
7848
                });
7849
7850
                #[allow(dead_code)]
7851
                const _: () = { static_assertions::assert_impl_all!($ty: TryFromBytes); };
7852
            };
7853
            ($ty:ty: $trait:ident) => {
7854
                #[allow(dead_code)]
7855
                const _: () = { static_assertions::assert_impl_all!($ty: $trait); };
7856
            };
7857
            ($ty:ty: !$trait:ident) => {
7858
                #[allow(dead_code)]
7859
                const _: () = { static_assertions::assert_not_impl_any!($ty: $trait); };
7860
            };
7861
            ($ty:ty: $($trait:ident),* $(,)? $(!$negative_trait:ident),*) => {
7862
                $(
7863
                    assert_impls!($ty: $trait);
7864
                )*
7865
7866
                $(
7867
                    assert_impls!($ty: !$negative_trait);
7868
                )*
7869
            };
7870
        }
7871
7872
        // NOTE: The negative impl assertions here are not necessarily
7873
        // prescriptive. They merely serve as change detectors to make sure
7874
        // we're aware of what trait impls are getting added with a given
7875
        // change. Of course, some impls would be invalid (e.g., `bool:
7876
        // FromBytes`), and so this change detection is very important.
7877
7878
        assert_impls!((): KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7879
        assert_impls!(u8: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7880
        assert_impls!(i8: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7881
        assert_impls!(u16: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7882
        assert_impls!(i16: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7883
        assert_impls!(u32: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7884
        assert_impls!(i32: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7885
        assert_impls!(u64: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7886
        assert_impls!(i64: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7887
        assert_impls!(u128: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7888
        assert_impls!(i128: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7889
        assert_impls!(usize: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7890
        assert_impls!(isize: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7891
        assert_impls!(f32: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7892
        assert_impls!(f64: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7893
7894
        assert_impls!(bool: KnownLayout, TryFromBytes, FromZeroes, AsBytes, Unaligned, !FromBytes);
7895
        assert_impls!(char: KnownLayout, TryFromBytes, FromZeroes, AsBytes, !FromBytes, !Unaligned);
7896
        assert_impls!(str: KnownLayout, TryFromBytes, FromZeroes, AsBytes, Unaligned, !FromBytes);
7897
7898
        assert_impls!(NonZeroU8: KnownLayout, TryFromBytes, AsBytes, Unaligned, !FromZeroes, !FromBytes);
7899
        assert_impls!(NonZeroI8: KnownLayout, TryFromBytes, AsBytes, Unaligned, !FromZeroes, !FromBytes);
7900
        assert_impls!(NonZeroU16: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7901
        assert_impls!(NonZeroI16: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7902
        assert_impls!(NonZeroU32: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7903
        assert_impls!(NonZeroI32: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7904
        assert_impls!(NonZeroU64: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7905
        assert_impls!(NonZeroI64: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7906
        assert_impls!(NonZeroU128: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7907
        assert_impls!(NonZeroI128: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7908
        assert_impls!(NonZeroUsize: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7909
        assert_impls!(NonZeroIsize: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7910
7911
        assert_impls!(Option<NonZeroU8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7912
        assert_impls!(Option<NonZeroI8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7913
        assert_impls!(Option<NonZeroU16>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7914
        assert_impls!(Option<NonZeroI16>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7915
        assert_impls!(Option<NonZeroU32>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7916
        assert_impls!(Option<NonZeroI32>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7917
        assert_impls!(Option<NonZeroU64>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7918
        assert_impls!(Option<NonZeroI64>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7919
        assert_impls!(Option<NonZeroU128>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7920
        assert_impls!(Option<NonZeroI128>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7921
        assert_impls!(Option<NonZeroUsize>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7922
        assert_impls!(Option<NonZeroIsize>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7923
7924
        // Implements none of the ZC traits.
7925
        struct NotZerocopy;
7926
7927
        #[rustfmt::skip]
7928
        type FnManyArgs = fn(
7929
            NotZerocopy, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
7930
        ) -> (NotZerocopy, NotZerocopy);
7931
7932
        // Allowed, because we're not actually using this type for FFI.
7933
        #[allow(improper_ctypes_definitions)]
7934
        #[rustfmt::skip]
7935
        type ECFnManyArgs = extern "C" fn(
7936
            NotZerocopy, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
7937
        ) -> (NotZerocopy, NotZerocopy);
7938
7939
        #[cfg(feature = "alloc")]
7940
        assert_impls!(Option<Box<UnsafeCell<NotZerocopy>>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7941
        assert_impls!(Option<Box<[UnsafeCell<NotZerocopy>]>>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7942
        assert_impls!(Option<&'static UnsafeCell<NotZerocopy>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7943
        assert_impls!(Option<&'static [UnsafeCell<NotZerocopy>]>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7944
        assert_impls!(Option<&'static mut UnsafeCell<NotZerocopy>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7945
        assert_impls!(Option<&'static mut [UnsafeCell<NotZerocopy>]>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7946
        assert_impls!(Option<NonNull<UnsafeCell<NotZerocopy>>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7947
        assert_impls!(Option<NonNull<[UnsafeCell<NotZerocopy>]>>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7948
        assert_impls!(Option<fn()>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7949
        assert_impls!(Option<FnManyArgs>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7950
        assert_impls!(Option<extern "C" fn()>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7951
        assert_impls!(Option<ECFnManyArgs>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7952
7953
        assert_impls!(PhantomData<NotZerocopy>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7954
        assert_impls!(PhantomData<[u8]>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7955
7956
        assert_impls!(ManuallyDrop<u8>: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7957
        assert_impls!(ManuallyDrop<[u8]>: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7958
        assert_impls!(ManuallyDrop<NotZerocopy>: !TryFromBytes, !KnownLayout, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7959
        assert_impls!(ManuallyDrop<[NotZerocopy]>: !TryFromBytes, !KnownLayout, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7960
7961
        assert_impls!(MaybeUninit<u8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, Unaligned, !AsBytes);
7962
        assert_impls!(MaybeUninit<NotZerocopy>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7963
7964
        assert_impls!(Wrapping<u8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7965
        assert_impls!(Wrapping<NotZerocopy>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7966
7967
        assert_impls!(Unalign<u8>: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7968
        assert_impls!(Unalign<NotZerocopy>: Unaligned, !KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes);
7969
7970
        assert_impls!([u8]: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7971
        assert_impls!([bool]: KnownLayout, TryFromBytes, FromZeroes, AsBytes, Unaligned, !FromBytes);
7972
        assert_impls!([NotZerocopy]: !KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7973
        assert_impls!([u8; 0]: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7974
        assert_impls!([NotZerocopy; 0]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7975
        assert_impls!([u8; 1]: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7976
        assert_impls!([NotZerocopy; 1]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7977
7978
        assert_impls!(*const NotZerocopy: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7979
        assert_impls!(*mut NotZerocopy: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7980
        assert_impls!(*const [NotZerocopy]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7981
        assert_impls!(*mut [NotZerocopy]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7982
        assert_impls!(*const dyn Debug: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7983
        assert_impls!(*mut dyn Debug: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7984
7985
        #[cfg(feature = "simd")]
7986
        {
7987
            #[allow(unused_macros)]
7988
            macro_rules! test_simd_arch_mod {
7989
                ($arch:ident, $($typ:ident),*) => {
7990
                    {
7991
                        use core::arch::$arch::{$($typ),*};
7992
                        use crate::*;
7993
                        $( assert_impls!($typ: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned); )*
7994
                    }
7995
                };
7996
            }
7997
            #[cfg(target_arch = "x86")]
7998
            test_simd_arch_mod!(x86, __m128, __m128d, __m128i, __m256, __m256d, __m256i);
7999
8000
            #[cfg(all(feature = "simd-nightly", target_arch = "x86"))]
8001
            test_simd_arch_mod!(x86, __m512bh, __m512, __m512d, __m512i);
8002
8003
            #[cfg(target_arch = "x86_64")]
8004
            test_simd_arch_mod!(x86_64, __m128, __m128d, __m128i, __m256, __m256d, __m256i);
8005
8006
            #[cfg(all(feature = "simd-nightly", target_arch = "x86_64"))]
8007
            test_simd_arch_mod!(x86_64, __m512bh, __m512, __m512d, __m512i);
8008
8009
            #[cfg(target_arch = "wasm32")]
8010
            test_simd_arch_mod!(wasm32, v128);
8011
8012
            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc"))]
8013
            test_simd_arch_mod!(
8014
                powerpc,
8015
                vector_bool_long,
8016
                vector_double,
8017
                vector_signed_long,
8018
                vector_unsigned_long
8019
            );
8020
8021
            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc64"))]
8022
            test_simd_arch_mod!(
8023
                powerpc64,
8024
                vector_bool_long,
8025
                vector_double,
8026
                vector_signed_long,
8027
                vector_unsigned_long
8028
            );
8029
            #[cfg(target_arch = "aarch64")]
8030
            #[rustfmt::skip]
8031
            test_simd_arch_mod!(
8032
                aarch64, float32x2_t, float32x4_t, float64x1_t, float64x2_t, int8x8_t, int8x8x2_t,
8033
                int8x8x3_t, int8x8x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int16x4_t,
8034
                int16x8_t, int32x2_t, int32x4_t, int64x1_t, int64x2_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t,
8035
                poly8x8x4_t, poly8x16_t, poly8x16x2_t, poly8x16x3_t, poly8x16x4_t, poly16x4_t, poly16x8_t,
8036
                poly64x1_t, poly64x2_t, uint8x8_t, uint8x8x2_t, uint8x8x3_t, uint8x8x4_t, uint8x16_t,
8037
                uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint16x4_t, uint16x8_t, uint32x2_t, uint32x4_t,
8038
                uint64x1_t, uint64x2_t
8039
            );
8040
            #[cfg(all(feature = "simd-nightly", target_arch = "arm"))]
8041
            #[rustfmt::skip]
8042
            test_simd_arch_mod!(arm, int8x4_t, uint8x4_t);
8043
        }
8044
    }
8045
}
8046
8047
#[cfg(kani)]
8048
mod proofs {
8049
    use super::*;
8050
8051
    impl kani::Arbitrary for DstLayout {
8052
        fn any() -> Self {
8053
            let align: NonZeroUsize = kani::any();
8054
            let size_info: SizeInfo = kani::any();
8055
8056
            kani::assume(align.is_power_of_two());
8057
            kani::assume(align < DstLayout::THEORETICAL_MAX_ALIGN);
8058
8059
            // For testing purposes, we most care about instantiations of
8060
            // `DstLayout` that can correspond to actual Rust types. We use
8061
            // `Layout` to verify that our `DstLayout` satisfies the validity
8062
            // conditions of Rust layouts.
8063
            kani::assume(
8064
                match size_info {
8065
                    SizeInfo::Sized { _size } => Layout::from_size_align(_size, align.get()),
8066
                    SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size }) => {
8067
                        // `SliceDst`` cannot encode an exact size, but we know
8068
                        // it is at least `_offset` bytes.
8069
                        Layout::from_size_align(_offset, align.get())
8070
                    }
8071
                }
8072
                .is_ok(),
8073
            );
8074
8075
            Self { align: align, size_info: size_info }
8076
        }
8077
    }
8078
8079
    impl kani::Arbitrary for SizeInfo {
8080
        fn any() -> Self {
8081
            let is_sized: bool = kani::any();
8082
8083
            match is_sized {
8084
                true => {
8085
                    let size: usize = kani::any();
8086
8087
                    kani::assume(size <= isize::MAX as _);
8088
8089
                    SizeInfo::Sized { _size: size }
8090
                }
8091
                false => SizeInfo::SliceDst(kani::any()),
8092
            }
8093
        }
8094
    }
8095
8096
    impl kani::Arbitrary for TrailingSliceLayout {
8097
        fn any() -> Self {
8098
            let elem_size: usize = kani::any();
8099
            let offset: usize = kani::any();
8100
8101
            kani::assume(elem_size < isize::MAX as _);
8102
            kani::assume(offset < isize::MAX as _);
8103
8104
            TrailingSliceLayout { _elem_size: elem_size, _offset: offset }
8105
        }
8106
    }
8107
8108
    #[kani::proof]
8109
    fn prove_dst_layout_extend() {
8110
        use crate::util::{core_layout::padding_needed_for, max, min};
8111
8112
        let base: DstLayout = kani::any();
8113
        let field: DstLayout = kani::any();
8114
        let packed: Option<NonZeroUsize> = kani::any();
8115
8116
        if let Some(max_align) = packed {
8117
            kani::assume(max_align.is_power_of_two());
8118
            kani::assume(base.align <= max_align);
8119
        }
8120
8121
        // The base can only be extended if it's sized.
8122
        kani::assume(matches!(base.size_info, SizeInfo::Sized { .. }));
8123
        let base_size = if let SizeInfo::Sized { _size: size } = base.size_info {
8124
            size
8125
        } else {
8126
            unreachable!();
8127
        };
8128
8129
        // Under the above conditions, `DstLayout::extend` will not panic.
8130
        let composite = base.extend(field, packed);
8131
8132
        // The field's alignment is clamped by `max_align` (i.e., the
8133
        // `packed` attribute, if any) [1].
8134
        //
8135
        // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
8136
        //
8137
        //   The alignments of each field, for the purpose of positioning
8138
        //   fields, is the smaller of the specified alignment and the
8139
        //   alignment of the field's type.
8140
        let field_align = min(field.align, packed.unwrap_or(DstLayout::THEORETICAL_MAX_ALIGN));
8141
8142
        // The struct's alignment is the maximum of its previous alignment and
8143
        // `field_align`.
8144
        assert_eq!(composite.align, max(base.align, field_align));
8145
8146
        // Compute the minimum amount of inter-field padding needed to
8147
        // satisfy the field's alignment, and offset of the trailing field.
8148
        // [1]
8149
        //
8150
        // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
8151
        //
8152
        //   Inter-field padding is guaranteed to be the minimum required in
8153
        //   order to satisfy each field's (possibly altered) alignment.
8154
        let padding = padding_needed_for(base_size, field_align);
8155
        let offset = base_size + padding;
8156
8157
        // For testing purposes, we'll also construct `alloc::Layout`
8158
        // stand-ins for `DstLayout`, and show that `extend` behaves
8159
        // comparably on both types.
8160
        let base_analog = Layout::from_size_align(base_size, base.align.get()).unwrap();
8161
8162
        match field.size_info {
8163
            SizeInfo::Sized { _size: field_size } => {
8164
                if let SizeInfo::Sized { _size: composite_size } = composite.size_info {
8165
                    // If the trailing field is sized, the resulting layout
8166
                    // will be sized. Its size will be the sum of the
8167
                    // preceeding layout, the size of the new field, and the
8168
                    // size of inter-field padding between the two.
8169
                    assert_eq!(composite_size, offset + field_size);
8170
8171
                    let field_analog =
8172
                        Layout::from_size_align(field_size, field_align.get()).unwrap();
8173
8174
                    if let Ok((actual_composite, actual_offset)) = base_analog.extend(field_analog)
8175
                    {
8176
                        assert_eq!(actual_offset, offset);
8177
                        assert_eq!(actual_composite.size(), composite_size);
8178
                        assert_eq!(actual_composite.align(), composite.align.get());
8179
                    } else {
8180
                        // An error here reflects that composite of `base`
8181
                        // and `field` cannot correspond to a real Rust type
8182
                        // fragment, because such a fragment would violate
8183
                        // the basic invariants of a valid Rust layout. At
8184
                        // the time of writing, `DstLayout` is a little more
8185
                        // permissive than `Layout`, so we don't assert
8186
                        // anything in this branch (e.g., unreachability).
8187
                    }
8188
                } else {
8189
                    panic!("The composite of two sized layouts must be sized.")
8190
                }
8191
            }
8192
            SizeInfo::SliceDst(TrailingSliceLayout {
8193
                _offset: field_offset,
8194
                _elem_size: field_elem_size,
8195
            }) => {
8196
                if let SizeInfo::SliceDst(TrailingSliceLayout {
8197
                    _offset: composite_offset,
8198
                    _elem_size: composite_elem_size,
8199
                }) = composite.size_info
8200
                {
8201
                    // The offset of the trailing slice component is the sum
8202
                    // of the offset of the trailing field and the trailing
8203
                    // slice offset within that field.
8204
                    assert_eq!(composite_offset, offset + field_offset);
8205
                    // The elem size is unchanged.
8206
                    assert_eq!(composite_elem_size, field_elem_size);
8207
8208
                    let field_analog =
8209
                        Layout::from_size_align(field_offset, field_align.get()).unwrap();
8210
8211
                    if let Ok((actual_composite, actual_offset)) = base_analog.extend(field_analog)
8212
                    {
8213
                        assert_eq!(actual_offset, offset);
8214
                        assert_eq!(actual_composite.size(), composite_offset);
8215
                        assert_eq!(actual_composite.align(), composite.align.get());
8216
                    } else {
8217
                        // An error here reflects that composite of `base`
8218
                        // and `field` cannot correspond to a real Rust type
8219
                        // fragment, because such a fragment would violate
8220
                        // the basic invariants of a valid Rust layout. At
8221
                        // the time of writing, `DstLayout` is a little more
8222
                        // permissive than `Layout`, so we don't assert
8223
                        // anything in this branch (e.g., unreachability).
8224
                    }
8225
                } else {
8226
                    panic!("The extension of a layout with a DST must result in a DST.")
8227
                }
8228
            }
8229
        }
8230
    }
8231
8232
    #[kani::proof]
8233
    #[kani::should_panic]
8234
    fn prove_dst_layout_extend_dst_panics() {
8235
        let base: DstLayout = kani::any();
8236
        let field: DstLayout = kani::any();
8237
        let packed: Option<NonZeroUsize> = kani::any();
8238
8239
        if let Some(max_align) = packed {
8240
            kani::assume(max_align.is_power_of_two());
8241
            kani::assume(base.align <= max_align);
8242
        }
8243
8244
        kani::assume(matches!(base.size_info, SizeInfo::SliceDst(..)));
8245
8246
        let _ = base.extend(field, packed);
8247
    }
8248
8249
    #[kani::proof]
8250
    fn prove_dst_layout_pad_to_align() {
8251
        use crate::util::core_layout::padding_needed_for;
8252
8253
        let layout: DstLayout = kani::any();
8254
8255
        let padded: DstLayout = layout.pad_to_align();
8256
8257
        // Calling `pad_to_align` does not alter the `DstLayout`'s alignment.
8258
        assert_eq!(padded.align, layout.align);
8259
8260
        if let SizeInfo::Sized { _size: unpadded_size } = layout.size_info {
8261
            if let SizeInfo::Sized { _size: padded_size } = padded.size_info {
8262
                // If the layout is sized, it will remain sized after padding is
8263
                // added. Its sum will be its unpadded size and the size of the
8264
                // trailing padding needed to satisfy its alignment
8265
                // requirements.
8266
                let padding = padding_needed_for(unpadded_size, layout.align);
8267
                assert_eq!(padded_size, unpadded_size + padding);
8268
8269
                // Prove that calling `DstLayout::pad_to_align` behaves
8270
                // identically to `Layout::pad_to_align`.
8271
                let layout_analog =
8272
                    Layout::from_size_align(unpadded_size, layout.align.get()).unwrap();
8273
                let padded_analog = layout_analog.pad_to_align();
8274
                assert_eq!(padded_analog.align(), layout.align.get());
8275
                assert_eq!(padded_analog.size(), padded_size);
8276
            } else {
8277
                panic!("The padding of a sized layout must result in a sized layout.")
8278
            }
8279
        } else {
8280
            // If the layout is a DST, padding cannot be statically added.
8281
            assert_eq!(padded.size_info, layout.size_info);
8282
        }
8283
    }
8284
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zerocopy-0.7.35/src/macro_util.rs
Line
Count
Source
1
// Copyright 2022 The Fuchsia Authors
2
//
3
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6
// This file may not be copied, modified, or distributed except according to
7
// those terms.
8
9
//! Utilities used by macros and by `zerocopy-derive`.
10
//!
11
//! These are defined here `zerocopy` rather than in code generated by macros or
12
//! by `zerocopy-derive` so that they can be compiled once rather than
13
//! recompiled for every invocation (e.g., if they were defined in generated
14
//! code, then deriving `AsBytes` and `FromBytes` on three different types would
15
//! result in the code in question being emitted and compiled six different
16
//! times).
17
18
#![allow(missing_debug_implementations)]
19
20
use core::{marker::PhantomData, mem::ManuallyDrop};
21
22
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove this
23
// `cfg` when `size_of_val_raw` is stabilized.
24
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
25
use core::ptr::{self, NonNull};
26
27
/// A compile-time check that should be one particular value.
28
pub trait ShouldBe<const VALUE: bool> {}
29
30
/// A struct for checking whether `T` contains padding.
31
pub struct HasPadding<T: ?Sized, const VALUE: bool>(PhantomData<T>);
32
33
impl<T: ?Sized, const VALUE: bool> ShouldBe<VALUE> for HasPadding<T, VALUE> {}
34
35
/// A type whose size is equal to `align_of::<T>()`.
36
#[repr(C)]
37
pub struct AlignOf<T> {
38
    // This field ensures that:
39
    // - The size is always at least 1 (the minimum possible alignment).
40
    // - If the alignment is greater than 1, Rust has to round up to the next
41
    //   multiple of it in order to make sure that `Align`'s size is a multiple
42
    //   of that alignment. Without this field, its size could be 0, which is a
43
    //   valid multiple of any alignment.
44
    _u: u8,
45
    _a: [T; 0],
46
}
47
48
impl<T> AlignOf<T> {
49
    #[inline(never)] // Make `missing_inline_in_public_items` happy.
50
0
    pub fn into_t(self) -> T {
51
0
        unreachable!()
52
    }
53
}
54
55
/// A type whose size is equal to `max(align_of::<T>(), align_of::<U>())`.
56
#[repr(C)]
57
pub union MaxAlignsOf<T, U> {
58
    _t: ManuallyDrop<AlignOf<T>>,
59
    _u: ManuallyDrop<AlignOf<U>>,
60
}
61
62
impl<T, U> MaxAlignsOf<T, U> {
63
    #[inline(never)] // Make `missing_inline_in_public_items` happy.
64
0
    pub fn new(_t: T, _u: U) -> MaxAlignsOf<T, U> {
65
0
        unreachable!()
66
    }
67
}
68
69
const _64K: usize = 1 << 16;
70
71
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove this
72
// `cfg` when `size_of_val_raw` is stabilized.
73
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
74
#[repr(C, align(65536))]
75
struct Aligned64kAllocation([u8; _64K]);
76
77
/// A pointer to an aligned allocation of size 2^16.
78
///
79
/// # Safety
80
///
81
/// `ALIGNED_64K_ALLOCATION` is guaranteed to point to the entirety of an
82
/// allocation with size and alignment 2^16, and to have valid provenance.
83
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove this
84
// `cfg` when `size_of_val_raw` is stabilized.
85
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
86
pub const ALIGNED_64K_ALLOCATION: NonNull<[u8]> = {
87
    const REF: &Aligned64kAllocation = &Aligned64kAllocation([0; _64K]);
88
    let ptr: *const Aligned64kAllocation = REF;
89
    let ptr: *const [u8] = ptr::slice_from_raw_parts(ptr.cast(), _64K);
90
    // SAFETY:
91
    // - `ptr` is derived from a Rust reference, which is guaranteed to be
92
    //   non-null.
93
    // - `ptr` is derived from an `&Aligned64kAllocation`, which has size and
94
    //   alignment `_64K` as promised. Its length is initialized to `_64K`,
95
    //   which means that it refers to the entire allocation.
96
    // - `ptr` is derived from a Rust reference, which is guaranteed to have
97
    //   valid provenance.
98
    //
99
    // TODO(#429): Once `NonNull::new_unchecked` docs document that it preserves
100
    // provenance, cite those docs.
101
    // TODO: Replace this `as` with `ptr.cast_mut()` once our MSRV >= 1.65
102
    #[allow(clippy::as_conversions)]
103
    unsafe {
104
        NonNull::new_unchecked(ptr as *mut _)
105
    }
106
};
107
108
/// Computes the offset of the base of the field `$trailing_field_name` within
109
/// the type `$ty`.
110
///
111
/// `trailing_field_offset!` produces code which is valid in a `const` context.
112
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove this
113
// `cfg` when `size_of_val_raw` is stabilized.
114
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
115
#[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
116
#[macro_export]
117
macro_rules! trailing_field_offset {
118
    ($ty:ty, $trailing_field_name:tt) => {{
119
        let min_size = {
120
            let zero_elems: *const [()] =
121
                $crate::macro_util::core_reexport::ptr::slice_from_raw_parts(
122
                    $crate::macro_util::core_reexport::ptr::NonNull::<()>::dangling()
123
                        .as_ptr()
124
                        .cast_const(),
125
                    0,
126
                );
127
            // SAFETY:
128
            // - If `$ty` is `Sized`, `size_of_val_raw` is always safe to call.
129
            // - Otherwise:
130
            //   - If `$ty` is not a slice DST, this pointer conversion will
131
            //     fail due to "mismatched vtable kinds", and compilation will
132
            //     fail.
133
            //   - If `$ty` is a slice DST, the safety requirement is that "the
134
            //     length of the slice tail must be an initialized integer, and
135
            //     the size of the entire value (dynamic tail length +
136
            //     statically sized prefix) must fit in isize." The length is
137
            //     initialized to 0 above, and Rust guarantees that no type's
138
            //     minimum size may overflow `isize`. [1]
139
            //
140
            // [1] TODO(#429),
141
            // TODO(https://github.com/rust-lang/unsafe-code-guidelines/issues/465#issuecomment-1782206516):
142
            // Citation for this?
143
            unsafe {
144
                #[allow(clippy::as_conversions)]
145
                $crate::macro_util::core_reexport::mem::size_of_val_raw(zero_elems as *const $ty)
146
            }
147
        };
148
149
        assert!(min_size <= _64K);
150
151
        #[allow(clippy::as_conversions)]
152
        let ptr = ALIGNED_64K_ALLOCATION.as_ptr() as *const $ty;
153
154
        // SAFETY:
155
        // - Thanks to the preceding `assert!`, we know that the value with zero
156
        //   elements fits in `_64K` bytes, and thus in the allocation addressed
157
        //   by `ALIGNED_64K_ALLOCATION`. The offset of the trailing field is
158
        //   guaranteed to be no larger than this size, so this field projection
159
        //   is guaranteed to remain in-bounds of its allocation.
160
        // - Because the minimum size is no larger than `_64K` bytes, and
161
        //   because an object's size must always be a multiple of its alignment
162
        //   [1], we know that `$ty`'s alignment is no larger than `_64K`. The
163
        //   allocation addressed by `ALIGNED_64K_ALLOCATION` is guaranteed to
164
        //   be aligned to `_64K`, so `ptr` is guaranteed to satisfy `$ty`'s
165
        //   alignment.
166
        //
167
        //   Note that, as of [2], this requirement is technically unnecessary
168
        //   for Rust versions >= 1.75.0, but no harm in guaranteeing it anyway
169
        //   until we bump our MSRV.
170
        //
171
        // [1] Per https://doc.rust-lang.org/reference/type-layout.html:
172
        //
173
        //   The size of a value is always a multiple of its alignment.
174
        //
175
        // [2] https://github.com/rust-lang/reference/pull/1387
176
        let field = unsafe {
177
            $crate::macro_util::core_reexport::ptr::addr_of!((*ptr).$trailing_field_name)
178
        };
179
        // SAFETY:
180
        // - Both `ptr` and `field` are derived from the same allocated object.
181
        // - By the preceding safety comment, `field` is in bounds of that
182
        //   allocated object.
183
        // - The distance, in bytes, between `ptr` and `field` is required to be
184
        //   a multiple of the size of `u8`, which is trivially true because
185
        //   `u8`'s size is 1.
186
        // - The distance, in bytes, cannot overflow `isize`. This is guaranteed
187
        //   because no allocated object can have a size larger than can fit in
188
        //   `isize`. [1]
189
        // - The distance being in-bounds cannot rely on wrapping around the
190
        //   address space. This is guaranteed because the same is guaranteed of
191
        //   allocated objects. [1]
192
        //
193
        // [1] TODO(#429), TODO(https://github.com/rust-lang/rust/pull/116675):
194
        //     Once these are guaranteed in the Reference, cite it.
195
        let offset = unsafe { field.cast::<u8>().offset_from(ptr.cast::<u8>()) };
196
        // Guaranteed not to be lossy: `field` comes after `ptr`, so the offset
197
        // from `ptr` to `field` is guaranteed to be positive.
198
        assert!(offset >= 0);
199
        Some(
200
            #[allow(clippy::as_conversions)]
201
            {
202
                offset as usize
203
            },
204
        )
205
    }};
206
}
207
208
/// Computes alignment of `$ty: ?Sized`.
209
///
210
/// `align_of!` produces code which is valid in a `const` context.
211
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove this
212
// `cfg` when `size_of_val_raw` is stabilized.
213
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
214
#[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
215
#[macro_export]
216
macro_rules! align_of {
217
    ($ty:ty) => {{
218
        // SAFETY: `OffsetOfTrailingIsAlignment` is `repr(C)`, and its layout is
219
        // guaranteed [1] to begin with the single-byte layout for `_byte`,
220
        // followed by the padding needed to align `_trailing`, then the layout
221
        // for `_trailing`, and finally any trailing padding bytes needed to
222
        // correctly-align the entire struct.
223
        //
224
        // This macro computes the alignment of `$ty` by counting the number of
225
        // bytes preceeding `_trailing`. For instance, if the alignment of `$ty`
226
        // is `1`, then no padding is required align `_trailing` and it will be
227
        // located immediately after `_byte` at offset 1. If the alignment of
228
        // `$ty` is 2, then a single padding byte is required before
229
        // `_trailing`, and `_trailing` will be located at offset 2.
230
231
        // This correspondence between offset and alignment holds for all valid
232
        // Rust alignments, and we confirm this exhaustively (or, at least up to
233
        // the maximum alignment supported by `trailing_field_offset!`) in
234
        // `test_align_of_dst`.
235
        //
236
        // [1]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprc
237
238
        #[repr(C)]
239
        struct OffsetOfTrailingIsAlignment {
240
            _byte: u8,
241
            _trailing: $ty,
242
        }
243
244
        trailing_field_offset!(OffsetOfTrailingIsAlignment, _trailing)
245
    }};
246
}
247
248
/// Does the struct type `$t` have padding?
249
///
250
/// `$ts` is the list of the type of every field in `$t`. `$t` must be a
251
/// struct type, or else `struct_has_padding!`'s result may be meaningless.
252
///
253
/// Note that `struct_has_padding!`'s results are independent of `repr` since
254
/// they only consider the size of the type and the sizes of the fields.
255
/// Whatever the repr, the size of the type already takes into account any
256
/// padding that the compiler has decided to add. Structs with well-defined
257
/// representations (such as `repr(C)`) can use this macro to check for padding.
258
/// Note that while this may yield some consistent value for some `repr(Rust)`
259
/// structs, it is not guaranteed across platforms or compilations.
260
#[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
261
#[macro_export]
262
macro_rules! struct_has_padding {
263
    ($t:ty, $($ts:ty),*) => {
264
        core::mem::size_of::<$t>() > 0 $(+ core::mem::size_of::<$ts>())*
265
    };
266
}
267
268
/// Does the union type `$t` have padding?
269
///
270
/// `$ts` is the list of the type of every field in `$t`. `$t` must be a
271
/// union type, or else `union_has_padding!`'s result may be meaningless.
272
///
273
/// Note that `union_has_padding!`'s results are independent of `repr` since
274
/// they only consider the size of the type and the sizes of the fields.
275
/// Whatever the repr, the size of the type already takes into account any
276
/// padding that the compiler has decided to add. Unions with well-defined
277
/// representations (such as `repr(C)`) can use this macro to check for padding.
278
/// Note that while this may yield some consistent value for some `repr(Rust)`
279
/// unions, it is not guaranteed across platforms or compilations.
280
#[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
281
#[macro_export]
282
macro_rules! union_has_padding {
283
    ($t:ty, $($ts:ty),*) => {
284
        false $(|| core::mem::size_of::<$t>() != core::mem::size_of::<$ts>())*
285
    };
286
}
287
288
/// Does `t` have alignment greater than or equal to `u`?  If not, this macro
289
/// produces a compile error. It must be invoked in a dead codepath. This is
290
/// used in `transmute_ref!` and `transmute_mut!`.
291
#[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
292
#[macro_export]
293
macro_rules! assert_align_gt_eq {
294
    ($t:ident, $u: ident) => {{
295
        // The comments here should be read in the context of this macro's
296
        // invocations in `transmute_ref!` and `transmute_mut!`.
297
        #[allow(clippy::missing_transmute_annotations)]
298
        if false {
299
            // The type wildcard in this bound is inferred to be `T` because
300
            // `align_of.into_t()` is assigned to `t` (which has type `T`).
301
            let align_of: $crate::macro_util::AlignOf<_> = unreachable!();
302
            $t = align_of.into_t();
303
            // `max_aligns` is inferred to have type `MaxAlignsOf<T, U>` because
304
            // of the inferred types of `t` and `u`.
305
            let mut max_aligns = $crate::macro_util::MaxAlignsOf::new($t, $u);
306
307
            // This transmute will only compile successfully if
308
            // `align_of::<T>() == max(align_of::<T>(), align_of::<U>())` - in
309
            // other words, if `align_of::<T>() >= align_of::<U>()`.
310
            //
311
            // SAFETY: This code is never run.
312
            max_aligns = unsafe { $crate::macro_util::core_reexport::mem::transmute(align_of) };
313
        } else {
314
            loop {}
315
        }
316
    }};
317
}
318
319
/// Do `t` and `u` have the same size?  If not, this macro produces a compile
320
/// error. It must be invoked in a dead codepath. This is used in
321
/// `transmute_ref!` and `transmute_mut!`.
322
#[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
323
#[macro_export]
324
macro_rules! assert_size_eq {
325
    ($t:ident, $u: ident) => {{
326
        // The comments here should be read in the context of this macro's
327
        // invocations in `transmute_ref!` and `transmute_mut!`.
328
        if false {
329
            // SAFETY: This code is never run.
330
            $u = unsafe {
331
                // Clippy: It's okay to transmute a type to itself.
332
                #[allow(clippy::useless_transmute, clippy::missing_transmute_annotations)]
333
                $crate::macro_util::core_reexport::mem::transmute($t)
334
            };
335
        } else {
336
            loop {}
337
        }
338
    }};
339
}
340
341
/// Transmutes a reference of one type to a reference of another type.
342
///
343
/// # Safety
344
///
345
/// The caller must guarantee that:
346
/// - `Src: AsBytes`
347
/// - `Dst: FromBytes`
348
/// - `size_of::<Src>() == size_of::<Dst>()`
349
/// - `align_of::<Src>() >= align_of::<Dst>()`
350
#[inline(always)]
351
0
pub const unsafe fn transmute_ref<'dst, 'src: 'dst, Src: 'src, Dst: 'dst>(
352
0
    src: &'src Src,
353
0
) -> &'dst Dst {
354
0
    let src: *const Src = src;
355
0
    let dst = src.cast::<Dst>();
356
0
    // SAFETY:
357
0
    // - We know that it is sound to view the target type of the input reference
358
0
    //   (`Src`) as the target type of the output reference (`Dst`) because the
359
0
    //   caller has guaranteed that `Src: AsBytes`, `Dst: FromBytes`, and
360
0
    //   `size_of::<Src>() == size_of::<Dst>()`.
361
0
    // - We know that there are no `UnsafeCell`s, and thus we don't have to
362
0
    //   worry about `UnsafeCell` overlap, because `Src: AsBytes` and `Dst:
363
0
    //   FromBytes` both forbid `UnsafeCell`s.
364
0
    // - The caller has guaranteed that alignment is not increased.
365
0
    // - We know that the returned lifetime will not outlive the input lifetime
366
0
    //   thanks to the lifetime bounds on this function.
367
0
    unsafe { &*dst }
368
0
}
369
370
/// Transmutes a mutable reference of one type to a mutable reference of another
371
/// type.
372
///
373
/// # Safety
374
///
375
/// The caller must guarantee that:
376
/// - `Src: FromBytes + AsBytes`
377
/// - `Dst: FromBytes + AsBytes`
378
/// - `size_of::<Src>() == size_of::<Dst>()`
379
/// - `align_of::<Src>() >= align_of::<Dst>()`
380
#[inline(always)]
381
0
pub unsafe fn transmute_mut<'dst, 'src: 'dst, Src: 'src, Dst: 'dst>(
382
0
    src: &'src mut Src,
383
0
) -> &'dst mut Dst {
384
0
    let src: *mut Src = src;
385
0
    let dst = src.cast::<Dst>();
386
0
    // SAFETY:
387
0
    // - We know that it is sound to view the target type of the input reference
388
0
    //   (`Src`) as the target type of the output reference (`Dst`) and
389
0
    //   vice-versa because the caller has guaranteed that `Src: FromBytes +
390
0
    //   AsBytes`, `Dst: FromBytes + AsBytes`, and `size_of::<Src>() ==
391
0
    //   size_of::<Dst>()`.
392
0
    // - We know that there are no `UnsafeCell`s, and thus we don't have to
393
0
    //   worry about `UnsafeCell` overlap, because `Src: FromBytes + AsBytes`
394
0
    //   and `Dst: FromBytes + AsBytes` forbid `UnsafeCell`s.
395
0
    // - The caller has guaranteed that alignment is not increased.
396
0
    // - We know that the returned lifetime will not outlive the input lifetime
397
0
    //   thanks to the lifetime bounds on this function.
398
0
    unsafe { &mut *dst }
399
0
}
400
401
// NOTE: We can't change this to a `pub use core as core_reexport` until [1] is
402
// fixed or we update to a semver-breaking version (as of this writing, 0.8.0)
403
// on the `main` branch.
404
//
405
// [1] https://github.com/obi1kenobi/cargo-semver-checks/issues/573
406
pub mod core_reexport {
407
    pub use core::*;
408
409
    pub mod mem {
410
        pub use core::mem::*;
411
    }
412
}
413
414
#[cfg(test)]
415
mod tests {
416
    use core::mem;
417
418
    use super::*;
419
    use crate::util::testutil::*;
420
421
    #[test]
422
    fn test_align_of() {
423
        macro_rules! test {
424
            ($ty:ty) => {
425
                assert_eq!(mem::size_of::<AlignOf<$ty>>(), mem::align_of::<$ty>());
426
            };
427
        }
428
429
        test!(());
430
        test!(u8);
431
        test!(AU64);
432
        test!([AU64; 2]);
433
    }
434
435
    #[test]
436
    fn test_max_aligns_of() {
437
        macro_rules! test {
438
            ($t:ty, $u:ty) => {
439
                assert_eq!(
440
                    mem::size_of::<MaxAlignsOf<$t, $u>>(),
441
                    core::cmp::max(mem::align_of::<$t>(), mem::align_of::<$u>())
442
                );
443
            };
444
        }
445
446
        test!(u8, u8);
447
        test!(u8, AU64);
448
        test!(AU64, u8);
449
    }
450
451
    #[test]
452
    fn test_typed_align_check() {
453
        // Test that the type-based alignment check used in
454
        // `assert_align_gt_eq!` behaves as expected.
455
456
        macro_rules! assert_t_align_gteq_u_align {
457
            ($t:ty, $u:ty, $gteq:expr) => {
458
                assert_eq!(
459
                    mem::size_of::<MaxAlignsOf<$t, $u>>() == mem::size_of::<AlignOf<$t>>(),
460
                    $gteq
461
                );
462
            };
463
        }
464
465
        assert_t_align_gteq_u_align!(u8, u8, true);
466
        assert_t_align_gteq_u_align!(AU64, AU64, true);
467
        assert_t_align_gteq_u_align!(AU64, u8, true);
468
        assert_t_align_gteq_u_align!(u8, AU64, false);
469
    }
470
471
    // TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove
472
    // this `cfg` when `size_of_val_raw` is stabilized.
473
    #[allow(clippy::decimal_literal_representation)]
474
    #[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
475
    #[test]
476
    fn test_trailing_field_offset() {
477
        assert_eq!(mem::align_of::<Aligned64kAllocation>(), _64K);
478
479
        macro_rules! test {
480
            (#[$cfg:meta] ($($ts:ty),* ; $trailing_field_ty:ty) => $expect:expr) => {{
481
                #[$cfg]
482
                #[allow(dead_code)] // fields are never read
483
                struct Test($($ts,)* $trailing_field_ty);
484
                assert_eq!(test!(@offset $($ts),* ; $trailing_field_ty), $expect);
485
            }};
486
            (#[$cfg:meta] $(#[$cfgs:meta])* ($($ts:ty),* ; $trailing_field_ty:ty) => $expect:expr) => {
487
                test!(#[$cfg] ($($ts),* ; $trailing_field_ty) => $expect);
488
                test!($(#[$cfgs])* ($($ts),* ; $trailing_field_ty) => $expect);
489
            };
490
            (@offset ; $_trailing:ty) => { trailing_field_offset!(Test, 0) };
491
            (@offset $_t:ty ; $_trailing:ty) => { trailing_field_offset!(Test, 1) };
492
        }
493
494
        test!(#[repr(C)] #[repr(transparent)] #[repr(packed)](; u8) => Some(0));
495
        test!(#[repr(C)] #[repr(transparent)] #[repr(packed)](; [u8]) => Some(0));
496
        test!(#[repr(C)] #[repr(C, packed)] (u8; u8) => Some(1));
497
        test!(#[repr(C)] (; AU64) => Some(0));
498
        test!(#[repr(C)] (; [AU64]) => Some(0));
499
        test!(#[repr(C)] (u8; AU64) => Some(8));
500
        test!(#[repr(C)] (u8; [AU64]) => Some(8));
501
        test!(#[repr(C)] (; Nested<u8, AU64>) => Some(0));
502
        test!(#[repr(C)] (; Nested<u8, [AU64]>) => Some(0));
503
        test!(#[repr(C)] (u8; Nested<u8, AU64>) => Some(8));
504
        test!(#[repr(C)] (u8; Nested<u8, [AU64]>) => Some(8));
505
506
        // Test that `packed(N)` limits the offset of the trailing field.
507
        test!(#[repr(C, packed(        1))] (u8; elain::Align<        2>) => Some(        1));
508
        test!(#[repr(C, packed(        2))] (u8; elain::Align<        4>) => Some(        2));
509
        test!(#[repr(C, packed(        4))] (u8; elain::Align<        8>) => Some(        4));
510
        test!(#[repr(C, packed(        8))] (u8; elain::Align<       16>) => Some(        8));
511
        test!(#[repr(C, packed(       16))] (u8; elain::Align<       32>) => Some(       16));
512
        test!(#[repr(C, packed(       32))] (u8; elain::Align<       64>) => Some(       32));
513
        test!(#[repr(C, packed(       64))] (u8; elain::Align<      128>) => Some(       64));
514
        test!(#[repr(C, packed(      128))] (u8; elain::Align<      256>) => Some(      128));
515
        test!(#[repr(C, packed(      256))] (u8; elain::Align<      512>) => Some(      256));
516
        test!(#[repr(C, packed(      512))] (u8; elain::Align<     1024>) => Some(      512));
517
        test!(#[repr(C, packed(     1024))] (u8; elain::Align<     2048>) => Some(     1024));
518
        test!(#[repr(C, packed(     2048))] (u8; elain::Align<     4096>) => Some(     2048));
519
        test!(#[repr(C, packed(     4096))] (u8; elain::Align<     8192>) => Some(     4096));
520
        test!(#[repr(C, packed(     8192))] (u8; elain::Align<    16384>) => Some(     8192));
521
        test!(#[repr(C, packed(    16384))] (u8; elain::Align<    32768>) => Some(    16384));
522
        test!(#[repr(C, packed(    32768))] (u8; elain::Align<    65536>) => Some(    32768));
523
        test!(#[repr(C, packed(    65536))] (u8; elain::Align<   131072>) => Some(    65536));
524
        /* Alignments above 65536 are not yet supported.
525
        test!(#[repr(C, packed(   131072))] (u8; elain::Align<   262144>) => Some(   131072));
526
        test!(#[repr(C, packed(   262144))] (u8; elain::Align<   524288>) => Some(   262144));
527
        test!(#[repr(C, packed(   524288))] (u8; elain::Align<  1048576>) => Some(   524288));
528
        test!(#[repr(C, packed(  1048576))] (u8; elain::Align<  2097152>) => Some(  1048576));
529
        test!(#[repr(C, packed(  2097152))] (u8; elain::Align<  4194304>) => Some(  2097152));
530
        test!(#[repr(C, packed(  4194304))] (u8; elain::Align<  8388608>) => Some(  4194304));
531
        test!(#[repr(C, packed(  8388608))] (u8; elain::Align< 16777216>) => Some(  8388608));
532
        test!(#[repr(C, packed( 16777216))] (u8; elain::Align< 33554432>) => Some( 16777216));
533
        test!(#[repr(C, packed( 33554432))] (u8; elain::Align< 67108864>) => Some( 33554432));
534
        test!(#[repr(C, packed( 67108864))] (u8; elain::Align< 33554432>) => Some( 67108864));
535
        test!(#[repr(C, packed( 33554432))] (u8; elain::Align<134217728>) => Some( 33554432));
536
        test!(#[repr(C, packed(134217728))] (u8; elain::Align<268435456>) => Some(134217728));
537
        test!(#[repr(C, packed(268435456))] (u8; elain::Align<268435456>) => Some(268435456));
538
        */
539
540
        // Test that `align(N)` does not limit the offset of the trailing field.
541
        test!(#[repr(C, align(        1))] (u8; elain::Align<        2>) => Some(        2));
542
        test!(#[repr(C, align(        2))] (u8; elain::Align<        4>) => Some(        4));
543
        test!(#[repr(C, align(        4))] (u8; elain::Align<        8>) => Some(        8));
544
        test!(#[repr(C, align(        8))] (u8; elain::Align<       16>) => Some(       16));
545
        test!(#[repr(C, align(       16))] (u8; elain::Align<       32>) => Some(       32));
546
        test!(#[repr(C, align(       32))] (u8; elain::Align<       64>) => Some(       64));
547
        test!(#[repr(C, align(       64))] (u8; elain::Align<      128>) => Some(      128));
548
        test!(#[repr(C, align(      128))] (u8; elain::Align<      256>) => Some(      256));
549
        test!(#[repr(C, align(      256))] (u8; elain::Align<      512>) => Some(      512));
550
        test!(#[repr(C, align(      512))] (u8; elain::Align<     1024>) => Some(     1024));
551
        test!(#[repr(C, align(     1024))] (u8; elain::Align<     2048>) => Some(     2048));
552
        test!(#[repr(C, align(     2048))] (u8; elain::Align<     4096>) => Some(     4096));
553
        test!(#[repr(C, align(     4096))] (u8; elain::Align<     8192>) => Some(     8192));
554
        test!(#[repr(C, align(     8192))] (u8; elain::Align<    16384>) => Some(    16384));
555
        test!(#[repr(C, align(    16384))] (u8; elain::Align<    32768>) => Some(    32768));
556
        test!(#[repr(C, align(    32768))] (u8; elain::Align<    65536>) => Some(    65536));
557
        /* Alignments above 65536 are not yet supported.
558
        test!(#[repr(C, align(    65536))] (u8; elain::Align<   131072>) => Some(   131072));
559
        test!(#[repr(C, align(   131072))] (u8; elain::Align<   262144>) => Some(   262144));
560
        test!(#[repr(C, align(   262144))] (u8; elain::Align<   524288>) => Some(   524288));
561
        test!(#[repr(C, align(   524288))] (u8; elain::Align<  1048576>) => Some(  1048576));
562
        test!(#[repr(C, align(  1048576))] (u8; elain::Align<  2097152>) => Some(  2097152));
563
        test!(#[repr(C, align(  2097152))] (u8; elain::Align<  4194304>) => Some(  4194304));
564
        test!(#[repr(C, align(  4194304))] (u8; elain::Align<  8388608>) => Some(  8388608));
565
        test!(#[repr(C, align(  8388608))] (u8; elain::Align< 16777216>) => Some( 16777216));
566
        test!(#[repr(C, align( 16777216))] (u8; elain::Align< 33554432>) => Some( 33554432));
567
        test!(#[repr(C, align( 33554432))] (u8; elain::Align< 67108864>) => Some( 67108864));
568
        test!(#[repr(C, align( 67108864))] (u8; elain::Align< 33554432>) => Some( 33554432));
569
        test!(#[repr(C, align( 33554432))] (u8; elain::Align<134217728>) => Some(134217728));
570
        test!(#[repr(C, align(134217728))] (u8; elain::Align<268435456>) => Some(268435456));
571
        */
572
    }
573
574
    // TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove
575
    // this `cfg` when `size_of_val_raw` is stabilized.
576
    #[allow(clippy::decimal_literal_representation)]
577
    #[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
578
    #[test]
579
    fn test_align_of_dst() {
580
        // Test that `align_of!` correctly computes the alignment of DSTs.
581
        assert_eq!(align_of!([elain::Align<1>]), Some(1));
582
        assert_eq!(align_of!([elain::Align<2>]), Some(2));
583
        assert_eq!(align_of!([elain::Align<4>]), Some(4));
584
        assert_eq!(align_of!([elain::Align<8>]), Some(8));
585
        assert_eq!(align_of!([elain::Align<16>]), Some(16));
586
        assert_eq!(align_of!([elain::Align<32>]), Some(32));
587
        assert_eq!(align_of!([elain::Align<64>]), Some(64));
588
        assert_eq!(align_of!([elain::Align<128>]), Some(128));
589
        assert_eq!(align_of!([elain::Align<256>]), Some(256));
590
        assert_eq!(align_of!([elain::Align<512>]), Some(512));
591
        assert_eq!(align_of!([elain::Align<1024>]), Some(1024));
592
        assert_eq!(align_of!([elain::Align<2048>]), Some(2048));
593
        assert_eq!(align_of!([elain::Align<4096>]), Some(4096));
594
        assert_eq!(align_of!([elain::Align<8192>]), Some(8192));
595
        assert_eq!(align_of!([elain::Align<16384>]), Some(16384));
596
        assert_eq!(align_of!([elain::Align<32768>]), Some(32768));
597
        assert_eq!(align_of!([elain::Align<65536>]), Some(65536));
598
        /* Alignments above 65536 are not yet supported.
599
        assert_eq!(align_of!([elain::Align<131072>]), Some(131072));
600
        assert_eq!(align_of!([elain::Align<262144>]), Some(262144));
601
        assert_eq!(align_of!([elain::Align<524288>]), Some(524288));
602
        assert_eq!(align_of!([elain::Align<1048576>]), Some(1048576));
603
        assert_eq!(align_of!([elain::Align<2097152>]), Some(2097152));
604
        assert_eq!(align_of!([elain::Align<4194304>]), Some(4194304));
605
        assert_eq!(align_of!([elain::Align<8388608>]), Some(8388608));
606
        assert_eq!(align_of!([elain::Align<16777216>]), Some(16777216));
607
        assert_eq!(align_of!([elain::Align<33554432>]), Some(33554432));
608
        assert_eq!(align_of!([elain::Align<67108864>]), Some(67108864));
609
        assert_eq!(align_of!([elain::Align<33554432>]), Some(33554432));
610
        assert_eq!(align_of!([elain::Align<134217728>]), Some(134217728));
611
        assert_eq!(align_of!([elain::Align<268435456>]), Some(268435456));
612
        */
613
    }
614
615
    #[test]
616
    fn test_struct_has_padding() {
617
        // Test that, for each provided repr, `struct_has_padding!` reports the
618
        // expected value.
619
        macro_rules! test {
620
            (#[$cfg:meta] ($($ts:ty),*) => $expect:expr) => {{
621
                #[$cfg]
622
                #[allow(dead_code)] // fields are never read
623
                struct Test($($ts),*);
624
                assert_eq!(struct_has_padding!(Test, $($ts),*), $expect);
625
            }};
626
            (#[$cfg:meta] $(#[$cfgs:meta])* ($($ts:ty),*) => $expect:expr) => {
627
                test!(#[$cfg] ($($ts),*) => $expect);
628
                test!($(#[$cfgs])* ($($ts),*) => $expect);
629
            };
630
        }
631
632
        test!(#[repr(C)] #[repr(transparent)] #[repr(packed)] () => false);
633
        test!(#[repr(C)] #[repr(transparent)] #[repr(packed)] (u8) => false);
634
        test!(#[repr(C)] #[repr(transparent)] #[repr(packed)] (u8, ()) => false);
635
        test!(#[repr(C)] #[repr(packed)] (u8, u8) => false);
636
637
        test!(#[repr(C)] (u8, AU64) => true);
638
        // Rust won't let you put `#[repr(packed)]` on a type which contains a
639
        // `#[repr(align(n > 1))]` type (`AU64`), so we have to use `u64` here.
640
        // It's not ideal, but it definitely has align > 1 on /some/ of our CI
641
        // targets, and this isn't a particularly complex macro we're testing
642
        // anyway.
643
        test!(#[repr(packed)] (u8, u64) => false);
644
    }
645
646
    #[test]
647
    fn test_union_has_padding() {
648
        // Test that, for each provided repr, `union_has_padding!` reports the
649
        // expected value.
650
        macro_rules! test {
651
            (#[$cfg:meta] {$($fs:ident: $ts:ty),*} => $expect:expr) => {{
652
                #[$cfg]
653
                #[allow(unused)] // fields are never read
654
                union Test{ $($fs: $ts),* }
655
                assert_eq!(union_has_padding!(Test, $($ts),*), $expect);
656
            }};
657
            (#[$cfg:meta] $(#[$cfgs:meta])* {$($fs:ident: $ts:ty),*} => $expect:expr) => {
658
                test!(#[$cfg] {$($fs: $ts),*} => $expect);
659
                test!($(#[$cfgs])* {$($fs: $ts),*} => $expect);
660
            };
661
        }
662
663
        test!(#[repr(C)] #[repr(packed)] {a: u8} => false);
664
        test!(#[repr(C)] #[repr(packed)] {a: u8, b: u8} => false);
665
666
        // Rust won't let you put `#[repr(packed)]` on a type which contains a
667
        // `#[repr(align(n > 1))]` type (`AU64`), so we have to use `u64` here.
668
        // It's not ideal, but it definitely has align > 1 on /some/ of our CI
669
        // targets, and this isn't a particularly complex macro we're testing
670
        // anyway.
671
        test!(#[repr(C)] #[repr(packed)] {a: u8, b: u64} => true);
672
    }
673
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zerocopy-0.7.35/src/macros.rs
Line
Count
Source
1
// Copyright 2023 The Fuchsia Authors
2
//
3
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6
// This file may not be copied, modified, or distributed except according to
7
// those terms.
8
9
/// Documents multiple unsafe blocks with a single safety comment.
10
///
11
/// Invoked as:
12
///
13
/// ```rust,ignore
14
/// safety_comment! {
15
///     // Non-doc comments come first.
16
///     /// SAFETY:
17
///     /// Safety comment starts on its own line.
18
///     macro_1!(args);
19
///     macro_2! { args };
20
///     /// SAFETY:
21
///     /// Subsequent safety comments are allowed but not required.
22
///     macro_3! { args };
23
/// }
24
/// ```
25
///
26
/// The macro invocations are emitted, each decorated with the following
27
/// attribute: `#[allow(clippy::undocumented_unsafe_blocks)]`.
28
macro_rules! safety_comment {
29
    (#[doc = r" SAFETY:"] $($(#[$attr:meta])* $macro:ident!$args:tt;)*) => {
30
        #[allow(clippy::undocumented_unsafe_blocks, unused_attributes)]
31
        const _: () = { $($(#[$attr])* $macro!$args;)* };
32
    }
33
}
34
35
/// Unsafely implements trait(s) for a type.
36
///
37
/// # Safety
38
///
39
/// The trait impl must be sound.
40
///
41
/// When implementing `TryFromBytes`:
42
/// - If no `is_bit_valid` impl is provided, then it must be valid for
43
///   `is_bit_valid` to unconditionally return `true`. In other words, it must
44
///   be the case that any initialized sequence of bytes constitutes a valid
45
///   instance of `$ty`.
46
/// - If an `is_bit_valid` impl is provided, then:
47
///   - Regardless of whether the provided closure takes a `Ptr<$repr>` or
48
///     `&$repr` argument, it must be the case that, given `t: *mut $ty` and
49
///     `let r = t as *mut $repr`, `r` refers to an object of equal or lesser
50
///     size than the object referred to by `t`.
51
///   - If the provided closure takes a `&$repr` argument, then given a `Ptr<'a,
52
///     $ty>` which satisfies the preconditions of
53
///     `TryFromBytes::<$ty>::is_bit_valid`, it must be guaranteed that the
54
///     memory referenced by that `Ptr` always contains a valid `$repr`.
55
///   - The alignment of `$repr` is less than or equal to the alignment of
56
///     `$ty`.
57
///   - The impl of `is_bit_valid` must only return `true` for its argument
58
///     `Ptr<$repr>` if the original `Ptr<$ty>` refers to a valid `$ty`.
59
macro_rules! unsafe_impl {
60
    // Implement `$trait` for `$ty` with no bounds.
61
    ($(#[$attr:meta])* $ty:ty: $trait:ident $(; |$candidate:ident: &$repr:ty| $is_bit_valid:expr)?) => {
62
        $(#[$attr])*
63
        unsafe impl $trait for $ty {
64
            unsafe_impl!(@method $trait $(; |$candidate: &$repr| $is_bit_valid)?);
65
        }
66
    };
67
    // Implement all `$traits` for `$ty` with no bounds.
68
    ($ty:ty: $($traits:ident),*) => {
69
        $( unsafe_impl!($ty: $traits); )*
70
    };
71
    // This arm is identical to the following one, except it contains a
72
    // preceding `const`. If we attempt to handle these with a single arm, there
73
    // is an inherent ambiguity between `const` (the keyword) and `const` (the
74
    // ident match for `$tyvar:ident`).
75
    //
76
    // To explain how this works, consider the following invocation:
77
    //
78
    //   unsafe_impl!(const N: usize, T: ?Sized + Copy => Clone for Foo<T>);
79
    //
80
    // In this invocation, here are the assignments to meta-variables:
81
    //
82
    //   |---------------|------------|
83
    //   | Meta-variable | Assignment |
84
    //   |---------------|------------|
85
    //   | $constname    |  N         |
86
    //   | $constty      |  usize     |
87
    //   | $tyvar        |  T         |
88
    //   | $optbound     |  Sized     |
89
    //   | $bound        |  Copy      |
90
    //   | $trait        |  Clone     |
91
    //   | $ty           |  Foo<T>    |
92
    //   |---------------|------------|
93
    //
94
    // The following arm has the same behavior with the exception of the lack of
95
    // support for a leading `const` parameter.
96
    (
97
        $(#[$attr:meta])*
98
        const $constname:ident : $constty:ident $(,)?
99
        $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
100
        => $trait:ident for $ty:ty $(; |$candidate:ident $(: &$ref_repr:ty)? $(: Ptr<$ptr_repr:ty>)?| $is_bit_valid:expr)?
101
    ) => {
102
        unsafe_impl!(
103
            @inner
104
            $(#[$attr])*
105
            @const $constname: $constty,
106
            $($tyvar $(: $(? $optbound +)* + $($bound +)*)?,)*
107
            => $trait for $ty $(; |$candidate $(: &$ref_repr)? $(: Ptr<$ptr_repr>)?| $is_bit_valid)?
108
        );
109
    };
110
    (
111
        $(#[$attr:meta])*
112
        $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
113
        => $trait:ident for $ty:ty $(; |$candidate:ident $(: &$ref_repr:ty)? $(: Ptr<$ptr_repr:ty>)?| $is_bit_valid:expr)?
114
    ) => {
115
        unsafe_impl!(
116
            @inner
117
            $(#[$attr])*
118
            $($tyvar $(: $(? $optbound +)* + $($bound +)*)?,)*
119
            => $trait for $ty $(; |$candidate $(: &$ref_repr)? $(: Ptr<$ptr_repr>)?| $is_bit_valid)?
120
        );
121
    };
122
    (
123
        @inner
124
        $(#[$attr:meta])*
125
        $(@const $constname:ident : $constty:ident,)*
126
        $($tyvar:ident $(: $(? $optbound:ident +)* + $($bound:ident +)* )?,)*
127
        => $trait:ident for $ty:ty $(; |$candidate:ident $(: &$ref_repr:ty)? $(: Ptr<$ptr_repr:ty>)?| $is_bit_valid:expr)?
128
    ) => {
129
        $(#[$attr])*
130
        unsafe impl<$(const $constname: $constty,)* $($tyvar $(: $(? $optbound +)* $($bound +)*)?),*> $trait for $ty {
131
            unsafe_impl!(@method $trait $(; |$candidate: $(&$ref_repr)? $(Ptr<$ptr_repr>)?| $is_bit_valid)?);
132
        }
133
    };
134
135
    (@method TryFromBytes ; |$candidate:ident: &$repr:ty| $is_bit_valid:expr) => {
136
        #[inline]
137
0
        unsafe fn is_bit_valid(candidate: Ptr<'_, Self>) -> bool {
138
0
            // SAFETY:
139
0
            // - The argument to `cast_unsized` is `|p| p as *mut _` as required
140
0
            //   by that method's safety precondition.
141
0
            // - The caller has promised that the cast results in an object of
142
0
            //   equal or lesser size.
143
0
            // - The caller has promised that `$repr`'s alignment is less than
144
0
            //   or equal to `Self`'s alignment.
145
0
            #[allow(clippy::as_conversions)]
146
0
            let candidate = unsafe { candidate.cast_unsized::<$repr, _>(|p| p as *mut _) };
Unexecuted instantiation: _RNCNvXs1_NvCsiAAEnE8327y_8zerocopysB_1__bNtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXs0_NvCsiAAEnE8327y_8zerocopysC_1__cNtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXs1_NvCsiAAEnE8327y_8zerocopysD_1__eNtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXsc_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXsd_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXse_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXsf_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXsg_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXsh_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXsi_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXsj_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXsk_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXsl_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXsm_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXsn_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtB9_12TryFromBytes12is_bit_valid0B9_
147
0
            // SAFETY:
148
0
            // - The caller has promised that the referenced memory region will
149
0
            //   contain a valid `$repr` for `'a`.
150
0
            // - The memory may not be referenced by any mutable references.
151
0
            //   This is a precondition of `is_bit_valid`.
152
0
            // - The memory may not be mutated even via `UnsafeCell`s. This is a
153
0
            //   precondition of `is_bit_valid`.
154
0
            // - There must not exist any references to the same memory region
155
0
            //   which contain `UnsafeCell`s at byte ranges which are not
156
0
            //   identical to the byte ranges at which `T` contains
157
0
            //   `UnsafeCell`s. This is a precondition of `is_bit_valid`.
158
0
            let $candidate: &$repr = unsafe { candidate.as_ref() };
159
0
            $is_bit_valid
160
0
        }
Unexecuted instantiation: _RNvXs1_NvCsiAAEnE8327y_8zerocopysB_1__bNtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXs0_NvCsiAAEnE8327y_8zerocopysC_1__cNtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXs1_NvCsiAAEnE8327y_8zerocopysD_1__eNtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXsc_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXsd_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXse_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXsf_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXsg_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXsh_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXsi_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXsj_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXsk_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXsl_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXsm_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXsn_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtB7_12TryFromBytes12is_bit_validB7_
161
    };
162
    (@method TryFromBytes ; |$candidate:ident: Ptr<$repr:ty>| $is_bit_valid:expr) => {
163
        #[inline]
164
0
        unsafe fn is_bit_valid(candidate: Ptr<'_, Self>) -> bool {
165
0
            // SAFETY:
166
0
            // - The argument to `cast_unsized` is `|p| p as *mut _` as required
167
0
            //   by that method's safety precondition.
168
0
            // - The caller has promised that the cast results in an object of
169
0
            //   equal or lesser size.
170
0
            // - The caller has promised that `$repr`'s alignment is less than
171
0
            //   or equal to `Self`'s alignment.
172
0
            #[allow(clippy::as_conversions)]
173
0
            let $candidate = unsafe { candidate.cast_unsized::<$repr, _>(|p| p as *mut _) };
Unexecuted instantiation: _RNCNvXININvCsiAAEnE8327y_8zerocopysI_1__0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB9_12TryFromBytes12is_bit_valid0B9_
Unexecuted instantiation: _RNCNvXININvCsiAAEnE8327y_8zerocopysL_1__s2_0pESpNtB9_12TryFromBytes12is_bit_valid0B9_
174
0
            $is_bit_valid
175
0
        }
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysI_1__0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysL_1__s2_0pESpNtB7_12TryFromBytes12is_bit_validB7_
176
    };
177
0
    (@method TryFromBytes) => { #[inline(always)] unsafe fn is_bit_valid(_: Ptr<'_, Self>) -> bool { true } };
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysz_1__uNtB4_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysA_1__hNtB4_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXs3_NvCsiAAEnE8327y_8zerocopysA_1__aNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXs8_NvCsiAAEnE8327y_8zerocopysA_1__tNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsc_NvCsiAAEnE8327y_8zerocopysA_1__sNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsg_NvCsiAAEnE8327y_8zerocopysA_1__mNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsk_NvCsiAAEnE8327y_8zerocopysA_1__lNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXso_NvCsiAAEnE8327y_8zerocopysA_1__yNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXss_NvCsiAAEnE8327y_8zerocopysA_1__xNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsw_NvCsiAAEnE8327y_8zerocopysA_1__oNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsA_NvCsiAAEnE8327y_8zerocopysA_1__nNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsE_NvCsiAAEnE8327y_8zerocopysA_1__jNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsI_NvCsiAAEnE8327y_8zerocopysA_1__iNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsM_NvCsiAAEnE8327y_8zerocopysA_1__fNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsQ_NvCsiAAEnE8327y_8zerocopysA_1__dNtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZerohEENtB4_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXs3_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroaEENtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXs8_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerotEENtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsc_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerosEENtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsg_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeromEENtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsk_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerolEENtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXso_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroyEENtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXss_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroxEENtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsw_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerooEENtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsA_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeronEENtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsE_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerojEENtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsI_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroiEENtB7_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtBa_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXs2_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtBd_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXs6_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtBd_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsa_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtBd_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXse_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtBd_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXsi_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtBd_12TryFromBytes12is_bit_valid
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysH_1__0pEINtNtCsbQ8arDwx5Xq_4core6marker11PhantomDatapENtB7_12TryFromBytes12is_bit_validB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysJ_1__0pEINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninitpENtB7_12TryFromBytes12is_bit_validB7_
178
    (@method $trait:ident) => {
179
        #[allow(clippy::missing_inline_in_public_items)]
180
0
        fn only_derive_is_allowed_to_implement_this_trait() {}
Unexecuted instantiation: _RNvXs_NvCsiAAEnE8327y_8zerocopysz_1__uNtB6_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB6_
Unexecuted instantiation: _RNvXs0_NvCsiAAEnE8327y_8zerocopysz_1__uNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs1_NvCsiAAEnE8327y_8zerocopysz_1__uNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs2_NvCsiAAEnE8327y_8zerocopysz_1__uNtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs_NvCsiAAEnE8327y_8zerocopysA_1__hNtB6_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB6_
Unexecuted instantiation: _RNvXs0_NvCsiAAEnE8327y_8zerocopysA_1__hNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs1_NvCsiAAEnE8327y_8zerocopysA_1__hNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs2_NvCsiAAEnE8327y_8zerocopysA_1__hNtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs4_NvCsiAAEnE8327y_8zerocopysA_1__aNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs5_NvCsiAAEnE8327y_8zerocopysA_1__aNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs6_NvCsiAAEnE8327y_8zerocopysA_1__aNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs7_NvCsiAAEnE8327y_8zerocopysA_1__aNtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs9_NvCsiAAEnE8327y_8zerocopysA_1__tNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsa_NvCsiAAEnE8327y_8zerocopysA_1__tNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsb_NvCsiAAEnE8327y_8zerocopysA_1__tNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsd_NvCsiAAEnE8327y_8zerocopysA_1__sNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXse_NvCsiAAEnE8327y_8zerocopysA_1__sNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsf_NvCsiAAEnE8327y_8zerocopysA_1__sNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsh_NvCsiAAEnE8327y_8zerocopysA_1__mNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsi_NvCsiAAEnE8327y_8zerocopysA_1__mNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsj_NvCsiAAEnE8327y_8zerocopysA_1__mNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsl_NvCsiAAEnE8327y_8zerocopysA_1__lNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsm_NvCsiAAEnE8327y_8zerocopysA_1__lNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsn_NvCsiAAEnE8327y_8zerocopysA_1__lNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsp_NvCsiAAEnE8327y_8zerocopysA_1__yNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsq_NvCsiAAEnE8327y_8zerocopysA_1__yNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsr_NvCsiAAEnE8327y_8zerocopysA_1__yNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXst_NvCsiAAEnE8327y_8zerocopysA_1__xNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsu_NvCsiAAEnE8327y_8zerocopysA_1__xNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsv_NvCsiAAEnE8327y_8zerocopysA_1__xNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsx_NvCsiAAEnE8327y_8zerocopysA_1__oNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsy_NvCsiAAEnE8327y_8zerocopysA_1__oNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsz_NvCsiAAEnE8327y_8zerocopysA_1__oNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsB_NvCsiAAEnE8327y_8zerocopysA_1__nNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsC_NvCsiAAEnE8327y_8zerocopysA_1__nNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsD_NvCsiAAEnE8327y_8zerocopysA_1__nNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsF_NvCsiAAEnE8327y_8zerocopysA_1__jNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsG_NvCsiAAEnE8327y_8zerocopysA_1__jNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsH_NvCsiAAEnE8327y_8zerocopysA_1__jNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsJ_NvCsiAAEnE8327y_8zerocopysA_1__iNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsK_NvCsiAAEnE8327y_8zerocopysA_1__iNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsL_NvCsiAAEnE8327y_8zerocopysA_1__iNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsN_NvCsiAAEnE8327y_8zerocopysA_1__fNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsO_NvCsiAAEnE8327y_8zerocopysA_1__fNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsP_NvCsiAAEnE8327y_8zerocopysA_1__fNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsR_NvCsiAAEnE8327y_8zerocopysA_1__dNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsS_NvCsiAAEnE8327y_8zerocopysA_1__dNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsT_NvCsiAAEnE8327y_8zerocopysA_1__dNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysB_1__bNtB4_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXs_NvCsiAAEnE8327y_8zerocopysB_1__bNtB6_7AsBytes46only_derive_is_allowed_to_implement_this_traitB6_
Unexecuted instantiation: _RNvXs0_NvCsiAAEnE8327y_8zerocopysB_1__bNtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysC_1__cNtB4_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXs_NvCsiAAEnE8327y_8zerocopysC_1__cNtB6_7AsBytes46only_derive_is_allowed_to_implement_this_traitB6_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysD_1__eNtB4_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXs_NvCsiAAEnE8327y_8zerocopysD_1__eNtB6_7AsBytes46only_derive_is_allowed_to_implement_this_traitB6_
Unexecuted instantiation: _RNvXs0_NvCsiAAEnE8327y_8zerocopysD_1__eNtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtB4_7AsBytes46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXs_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtB6_9Unaligned46only_derive_is_allowed_to_implement_this_traitB6_
Unexecuted instantiation: _RNvXs0_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs1_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs2_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs3_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs4_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs5_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs6_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs7_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs8_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs9_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsa_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsb_NvCsiAAEnE8327y_8zerocopysE_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBE_3num7nonzero7NonZerohEENtB6_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB6_
Unexecuted instantiation: _RNvXs0_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerohEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs1_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerohEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs2_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerohEENtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs4_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroaEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs5_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroaEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs6_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroaEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs7_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroaEENtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs9_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerotEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsa_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerotEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsb_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerotEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsd_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerosEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXse_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerosEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsf_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerosEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsh_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeromEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsi_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeromEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsj_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeromEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsl_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerolEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsm_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerolEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsn_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerolEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsp_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroyEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsq_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroyEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsr_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroyEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXst_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroxEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsu_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroxEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsv_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroxEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsx_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerooEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsy_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerooEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsz_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerooEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsB_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeronEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsC_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeronEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsD_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeronEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsF_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerojEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsG_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerojEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsH_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZerojEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsJ_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroiEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsK_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroiEENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXsL_NvCsiAAEnE8327y_8zerocopysF_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBF_3num7nonzero7NonZeroiEENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXs_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtBc_10FromZeroes46only_derive_is_allowed_to_implement_this_traitBc_
Unexecuted instantiation: _RNvXs0_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtBd_9FromBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXs1_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtBd_7AsBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXs3_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtBd_10FromZeroes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXs4_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtBd_9FromBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXs5_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtBd_7AsBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXs7_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtBd_10FromZeroes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXs8_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtBd_9FromBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXs9_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtBd_7AsBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXsb_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtBd_10FromZeroes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXsc_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtBd_9FromBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXsd_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtBd_7AsBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXsf_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtBd_10FromZeroes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXsg_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtBd_9FromBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXsh_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtBd_7AsBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXsj_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtBd_10FromZeroes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXsk_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtBd_9FromBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXsl_NvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s4_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtBd_7AsBytes46only_derive_is_allowed_to_implement_this_traitBd_
Unexecuted instantiation: _RNvXININvNvNtCsiAAEnE8327y_8zerocopy8wrapperss_1__1__0pEINtB9_7UnalignpENtBb_9Unaligned46only_derive_is_allowed_to_implement_this_traitBb_
Unexecuted instantiation: _RNvXININvNvNtCsiAAEnE8327y_8zerocopy8wrapperss_1__s_1__0pEINtB9_7UnalignpENtBb_10FromZeroes46only_derive_is_allowed_to_implement_this_traitBb_
Unexecuted instantiation: _RNvXININvNvNtCsiAAEnE8327y_8zerocopy8wrapperss_1__s0_1__0pEINtB9_7UnalignpENtBb_9FromBytes46only_derive_is_allowed_to_implement_this_traitBb_
Unexecuted instantiation: _RNvXININvNvNtCsiAAEnE8327y_8zerocopy8wrapperss_1__s1_1__0pEINtB9_7UnalignpENtBb_7AsBytes46only_derive_is_allowed_to_implement_this_traitBb_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionRpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__s_0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionQpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__s0_0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBL_3ptr8non_null7NonNullpEENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysH_1__s_0pEINtNtCsbQ8arDwx5Xq_4core6marker11PhantomDatapENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysH_1__s0_0pEINtNtCsbQ8arDwx5Xq_4core6marker11PhantomDatapENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysH_1__s1_0pEINtNtCsbQ8arDwx5Xq_4core6marker11PhantomDatapENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysH_1__s2_0pEINtNtCsbQ8arDwx5Xq_4core6marker11PhantomDatapENtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysI_1__s_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysI_1__s0_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysI_1__s1_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysI_1__s2_0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysJ_1__s_0pEINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninitpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysJ_1__s0_0pEINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninitpENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysJ_1__s1_0pEINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninitpENtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysK_1__0pEINtNtNtCsbQ8arDwx5Xq_4core3mem13manually_drop12ManuallyDroppENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysK_1__s_0pEINtNtNtCsbQ8arDwx5Xq_4core3mem13manually_drop12ManuallyDroppENtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysK_1__s0_0pEINtNtNtCsbQ8arDwx5Xq_4core3mem13manually_drop12ManuallyDroppENtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysK_1__s1_0pEINtNtNtCsbQ8arDwx5Xq_4core3mem13manually_drop12ManuallyDroppENtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysL_1__0KppEAppNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysL_1__s_0KppEAppNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysL_1__s0_0KppEAppNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysL_1__s1_0KppEAppNtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysL_1__s3_0pESpNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysL_1__s4_0pESpNtB7_9FromBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysL_1__s5_0pESpNtB7_7AsBytes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysL_1__s6_0pESpNtB7_9Unaligned46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysM_1__0pEPpNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysM_1__s_0pEOpNtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
181
    };
182
    (@method $trait:ident; |$_candidate:ident $(: &$_ref_repr:ty)? $(: NonNull<$_ptr_repr:ty>)?| $_is_bit_valid:expr) => {
183
        compile_error!("Can't provide `is_bit_valid` impl for trait other than `TryFromBytes`");
184
    };
185
}
186
187
/// Implements a trait for a type, bounding on each memeber of the power set of
188
/// a set of type variables. This is useful for implementing traits for tuples
189
/// or `fn` types.
190
///
191
/// The last argument is the name of a macro which will be called in every
192
/// `impl` block, and is expected to expand to the name of the type for which to
193
/// implement the trait.
194
///
195
/// For example, the invocation:
196
/// ```ignore
197
/// unsafe_impl_for_power_set!(A, B => Foo for type!(...))
198
/// ```
199
/// ...expands to:
200
/// ```ignore
201
/// unsafe impl       Foo for type!()     { ... }
202
/// unsafe impl<B>    Foo for type!(B)    { ... }
203
/// unsafe impl<A, B> Foo for type!(A, B) { ... }
204
/// ```
205
macro_rules! unsafe_impl_for_power_set {
206
    ($first:ident $(, $rest:ident)* $(-> $ret:ident)? => $trait:ident for $macro:ident!(...)) => {
207
        unsafe_impl_for_power_set!($($rest),* $(-> $ret)? => $trait for $macro!(...));
208
        unsafe_impl_for_power_set!(@impl $first $(, $rest)* $(-> $ret)? => $trait for $macro!(...));
209
    };
210
    ($(-> $ret:ident)? => $trait:ident for $macro:ident!(...)) => {
211
        unsafe_impl_for_power_set!(@impl $(-> $ret)? => $trait for $macro!(...));
212
    };
213
    (@impl $($vars:ident),* $(-> $ret:ident)? => $trait:ident for $macro:ident!(...)) => {
214
        unsafe impl<$($vars,)* $($ret)?> $trait for $macro!($($vars),* $(-> $ret)?) {
215
            #[allow(clippy::missing_inline_in_public_items)]
216
0
            fn only_derive_is_allowed_to_implement_this_trait() {}
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__s1_0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionFEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__s2_0ppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFpEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__s3_0pppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__s4_0ppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFpppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__s5_0pppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__s6_0ppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFpppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__s7_0pppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__s8_0ppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFpppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__s9_0pppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFppppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sa_0ppppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFpppppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sb_0pppppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFppppppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sc_0ppppppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFpppppppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sd_0pppppppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFppppppppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__se_0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sf_0ppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCpEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sg_0pppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sh_0ppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCpppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__si_0pppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sj_0ppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCpppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sk_0pppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sl_0ppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCpppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sm_0pppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCppppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sn_0ppppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCpppppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__so_0pppppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCppppppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sp_0ppppppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCpppppppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysG_1__sq_0pppppppppppppEINtNtCsbQ8arDwx5Xq_4core6option6OptionFKCppppppppppppEpENtB7_10FromZeroes46only_derive_is_allowed_to_implement_this_traitB7_
217
        }
218
    };
219
}
220
221
/// Expands to an `Option<extern "C" fn>` type with the given argument types and
222
/// return type. Designed for use with `unsafe_impl_for_power_set`.
223
macro_rules! opt_extern_c_fn {
224
    ($($args:ident),* -> $ret:ident) => { Option<extern "C" fn($($args),*) -> $ret> };
225
}
226
227
/// Expands to a `Option<fn>` type with the given argument types and return
228
/// type. Designed for use with `unsafe_impl_for_power_set`.
229
macro_rules! opt_fn {
230
    ($($args:ident),* -> $ret:ident) => { Option<fn($($args),*) -> $ret> };
231
}
232
233
/// Implements trait(s) for a type or verifies the given implementation by
234
/// referencing an existing (derived) implementation.
235
///
236
/// This macro exists so that we can provide zerocopy-derive as an optional
237
/// dependency and still get the benefit of using its derives to validate that
238
/// our trait impls are sound.
239
///
240
/// When compiling without `--cfg 'feature = "derive"` and without `--cfg test`,
241
/// `impl_or_verify!` emits the provided trait impl. When compiling with either
242
/// of those cfgs, it is expected that the type in question is deriving the
243
/// traits instead. In this case, `impl_or_verify!` emits code which validates
244
/// that the given trait impl is at least as restrictive as the the impl emitted
245
/// by the custom derive. This has the effect of confirming that the impl which
246
/// is emitted when the `derive` feature is disabled is actually sound (on the
247
/// assumption that the impl emitted by the custom derive is sound).
248
///
249
/// The caller is still required to provide a safety comment (e.g. using the
250
/// `safety_comment!` macro) . The reason for this restriction is that, while
251
/// `impl_or_verify!` can guarantee that the provided impl is sound when it is
252
/// compiled with the appropriate cfgs, there is no way to guarantee that it is
253
/// ever compiled with those cfgs. In particular, it would be possible to
254
/// accidentally place an `impl_or_verify!` call in a context that is only ever
255
/// compiled when the `derive` feature is disabled. If that were to happen,
256
/// there would be nothing to prevent an unsound trait impl from being emitted.
257
/// Requiring a safety comment reduces the likelihood of emitting an unsound
258
/// impl in this case, and also provides useful documentation for readers of the
259
/// code.
260
///
261
/// ## Example
262
///
263
/// ```rust,ignore
264
/// // Note that these derives are gated by `feature = "derive"`
265
/// #[cfg_attr(any(feature = "derive", test), derive(FromZeroes, FromBytes, AsBytes, Unaligned))]
266
/// #[repr(transparent)]
267
/// struct Wrapper<T>(T);
268
///
269
/// safety_comment! {
270
///     /// SAFETY:
271
///     /// `Wrapper<T>` is `repr(transparent)`, so it is sound to implement any
272
///     /// zerocopy trait if `T` implements that trait.
273
///     impl_or_verify!(T: FromZeroes => FromZeroes for Wrapper<T>);
274
///     impl_or_verify!(T: FromBytes => FromBytes for Wrapper<T>);
275
///     impl_or_verify!(T: AsBytes => AsBytes for Wrapper<T>);
276
///     impl_or_verify!(T: Unaligned => Unaligned for Wrapper<T>);
277
/// }
278
/// ```
279
macro_rules! impl_or_verify {
280
    // The following two match arms follow the same pattern as their
281
    // counterparts in `unsafe_impl!`; see the documentation on those arms for
282
    // more details.
283
    (
284
        const $constname:ident : $constty:ident $(,)?
285
        $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
286
        => $trait:ident for $ty:ty
287
    ) => {
288
        impl_or_verify!(@impl { unsafe_impl!(
289
            const $constname: $constty, $($tyvar $(: $(? $optbound +)* $($bound +)*)?),* => $trait for $ty
290
        ); });
291
        impl_or_verify!(@verify $trait, {
292
            impl<const $constname: $constty, $($tyvar $(: $(? $optbound +)* $($bound +)*)?),*> Subtrait for $ty {}
293
        });
294
    };
295
    (
296
        $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
297
        => $trait:ident for $ty:ty
298
    ) => {
299
        impl_or_verify!(@impl { unsafe_impl!(
300
            $($tyvar $(: $(? $optbound +)* $($bound +)*)?),* => $trait for $ty
301
        ); });
302
        impl_or_verify!(@verify $trait, {
303
            impl<$($tyvar $(: $(? $optbound +)* $($bound +)*)?),*> Subtrait for $ty {}
304
        });
305
    };
306
    (
307
        $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
308
        => $trait:ident for $ty:ty
309
    ) => {
310
        unsafe_impl!(
311
            @inner
312
            $($tyvar $(: $(? $optbound +)* + $($bound +)*)?,)*
313
            => $trait for $ty
314
        );
315
    };
316
    (@impl $impl_block:tt) => {
317
        #[cfg(not(any(feature = "derive", test)))]
318
        const _: () = { $impl_block };
319
    };
320
    (@verify $trait:ident, $impl_block:tt) => {
321
        #[cfg(any(feature = "derive", test))]
322
        const _: () = {
323
            trait Subtrait: $trait {}
324
            $impl_block
325
        };
326
    };
327
}
328
329
/// Implements `KnownLayout` for a sized type.
330
macro_rules! impl_known_layout {
331
    ($(const $constvar:ident : $constty:ty, $tyvar:ident $(: ?$optbound:ident)? => $ty:ty),* $(,)?) => {
332
        $(impl_known_layout!(@inner const $constvar: $constty, $tyvar $(: ?$optbound)? => $ty);)*
333
    };
334
    ($($tyvar:ident $(: ?$optbound:ident)? => $ty:ty),* $(,)?) => {
335
        $(impl_known_layout!(@inner , $tyvar $(: ?$optbound)? => $ty);)*
336
    };
337
    ($($ty:ty),*) => { $(impl_known_layout!(@inner , => $ty);)* };
338
    (@inner $(const $constvar:ident : $constty:ty)? , $($tyvar:ident $(: ?$optbound:ident)?)? => $ty:ty) => {
339
        const _: () = {
340
            use core::ptr::NonNull;
341
342
            // SAFETY: Delegates safety to `DstLayout::for_type`.
343
            unsafe impl<$(const $constvar : $constty,)? $($tyvar $(: ?$optbound)?)?> KnownLayout for $ty {
344
                #[allow(clippy::missing_inline_in_public_items)]
345
0
                fn only_derive_is_allowed_to_implement_this_trait() where Self: Sized {}
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopy1__uNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys_1__hNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys0_1__aNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys1_1__tNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys2_1__sNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys3_1__mNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys4_1__lNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys5_1__yNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys6_1__xNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys7_1__oNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys8_1__nNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys9_1__jNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysa_1__iNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysb_1__fNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysc_1__dNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysd_1__bNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopyse_1__cNtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysf_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysg_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysh_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysi_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysj_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysk_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysl_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysm_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysn_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopyso_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysp_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysq_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtB4_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB4_
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_641__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtBa_11KnownLayout46only_derive_is_allowed_to_implement_this_traitBa_
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtBa_11KnownLayout46only_derive_is_allowed_to_implement_this_traitBa_
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s0_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtBa_11KnownLayout46only_derive_is_allowed_to_implement_this_traitBa_
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s1_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtBa_11KnownLayout46only_derive_is_allowed_to_implement_this_traitBa_
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s2_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtBa_11KnownLayout46only_derive_is_allowed_to_implement_this_traitBa_
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s3_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtBa_11KnownLayout46only_derive_is_allowed_to_implement_this_traitBa_
Unexecuted instantiation: _RNvXININvNtCsiAAEnE8327y_8zerocopy8wrappers1__0pEINtB7_7UnalignpENtB9_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB9_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysr_1__0pEINtNtCsbQ8arDwx5Xq_4core6option6OptionpENtB7_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopyss_1__0pEINtNtCsbQ8arDwx5Xq_4core6marker11PhantomDatapENtB7_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopyst_1__0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB7_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysu_1__0pEINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninitpENtB7_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysv_1__0pEPpNtB7_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysw_1__0pEOpNtB7_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysx_1__0KppEAppNtB7_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB7_
346
347
                const LAYOUT: DstLayout = DstLayout::for_type::<$ty>();
348
349
                // SAFETY: `.cast` preserves address and provenance.
350
                //
351
                // TODO(#429): Add documentation to `.cast` that promises that
352
                // it preserves provenance.
353
                #[inline(always)]
354
0
                fn raw_from_ptr_len(bytes: NonNull<u8>, _elems: usize) -> NonNull<Self> {
355
0
                    bytes.cast::<Self>()
356
0
                }
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopy1__uNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys_1__hNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys0_1__aNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys1_1__tNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys2_1__sNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys3_1__mNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys4_1__lNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys5_1__yNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys6_1__xNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys7_1__oNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys8_1__nNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopys9_1__jNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysa_1__iNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysb_1__fNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysc_1__dNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysd_1__bNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopyse_1__cNtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysf_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysg_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysh_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysi_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysj_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysk_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysl_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysm_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysn_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopyso_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysp_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysq_1__INtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtB4_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZeroaEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZerohEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZeroiEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZerojEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZerolEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZeromEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZeronEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZerooEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZerosEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZerotEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZeroxEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvCsiAAEnE8327y_8zerocopysr_1__INtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBC_3num7nonzero7NonZeroyEENtB4_11KnownLayout16raw_from_ptr_lenB4_
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_641__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtBa_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtBa_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s0_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtBa_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s1_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtBa_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s2_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtBa_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXNvNtNvNtCsiAAEnE8327y_8zerocopy4simd1__6x86_64s3_1__NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtBa_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXININvNtCsiAAEnE8327y_8zerocopy8wrappers1__0pEINtB7_7UnalignpENtB9_11KnownLayout16raw_from_ptr_lenB9_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopyss_1__0pEINtNtCsbQ8arDwx5Xq_4core6marker11PhantomDatapENtB7_11KnownLayout16raw_from_ptr_lenB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopyst_1__0pEINtNtNtCsbQ8arDwx5Xq_4core3num8wrapping8WrappingpENtB7_11KnownLayout16raw_from_ptr_lenB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysu_1__0pEINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninitpENtB7_11KnownLayout16raw_from_ptr_lenB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysv_1__0pEPpNtB7_11KnownLayout16raw_from_ptr_lenB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysw_1__0pEOpNtB7_11KnownLayout16raw_from_ptr_lenB7_
Unexecuted instantiation: _RNvXININvCsiAAEnE8327y_8zerocopysx_1__0KppEAppNtB7_11KnownLayout16raw_from_ptr_lenB7_
357
            }
358
        };
359
    };
360
}
361
362
/// Implements `KnownLayout` for a type in terms of the implementation of
363
/// another type with the same representation.
364
///
365
/// # Safety
366
///
367
/// - `$ty` and `$repr` must have the same:
368
///   - Fixed prefix size
369
///   - Alignment
370
///   - (For DSTs) trailing slice element size
371
/// - It must be valid to perform an `as` cast from `*mut $repr` to `*mut $ty`,
372
///   and this operation must preserve referent size (ie, `size_of_val_raw`).
373
macro_rules! unsafe_impl_known_layout {
374
    ($($tyvar:ident: ?Sized + KnownLayout =>)? #[repr($repr:ty)] $ty:ty) => {
375
        const _: () = {
376
            use core::ptr::NonNull;
377
378
            unsafe impl<$($tyvar: ?Sized + KnownLayout)?> KnownLayout for $ty {
379
                #[allow(clippy::missing_inline_in_public_items)]
380
0
                fn only_derive_is_allowed_to_implement_this_trait() {}
Unexecuted instantiation: _RNvXNvNvCsiAAEnE8327y_8zerocopysy_1__1__eNtB6_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB6_
Unexecuted instantiation: _RNvXININvNvCsiAAEnE8327y_8zerocopysy_1__s_1__0pEINtNtNtCsbQ8arDwx5Xq_4core3mem13manually_drop12ManuallyDroppENtB9_11KnownLayout46only_derive_is_allowed_to_implement_this_traitB9_
381
382
                const LAYOUT: DstLayout = <$repr as KnownLayout>::LAYOUT;
383
384
                // SAFETY: All operations preserve address and provenance.
385
                // Caller has promised that the `as` cast preserves size.
386
                //
387
                // TODO(#429): Add documentation to `NonNull::new_unchecked`
388
                // that it preserves provenance.
389
                #[inline(always)]
390
0
                fn raw_from_ptr_len(bytes: NonNull<u8>, elems: usize) -> NonNull<Self> {
391
0
                    #[allow(clippy::as_conversions)]
392
0
                    let ptr = <$repr>::raw_from_ptr_len(bytes, elems).as_ptr() as *mut Self;
393
0
                    // SAFETY: `ptr` was converted from `bytes`, which is non-null.
394
0
                    unsafe { NonNull::new_unchecked(ptr) }
395
0
                }
Unexecuted instantiation: _RNvXNvNvCsiAAEnE8327y_8zerocopysy_1__1__eNtB6_11KnownLayout16raw_from_ptr_len
Unexecuted instantiation: _RNvXININvNvCsiAAEnE8327y_8zerocopysy_1__s_1__0pEINtNtNtCsbQ8arDwx5Xq_4core3mem13manually_drop12ManuallyDroppENtB9_11KnownLayout16raw_from_ptr_lenB9_
396
            }
397
        };
398
    };
399
}
400
401
/// Uses `align_of` to confirm that a type or set of types have alignment 1.
402
///
403
/// Note that `align_of<T>` requires `T: Sized`, so this macro doesn't work for
404
/// unsized types.
405
macro_rules! assert_unaligned {
406
    ($ty:ty) => {
407
        // We only compile this assertion under `cfg(test)` to avoid taking an
408
        // extra non-dev dependency (and making this crate more expensive to
409
        // compile for our dependents).
410
        #[cfg(test)]
411
        static_assertions::const_assert_eq!(core::mem::align_of::<$ty>(), 1);
412
    };
413
    ($($ty:ty),*) => {
414
        $(assert_unaligned!($ty);)*
415
    };
416
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zerocopy-0.7.35/src/third_party/rust/layout.rs
Line
Count
Source
1
use core::num::NonZeroUsize;
2
3
/// Returns the amount of padding we must insert after `len` bytes to ensure
4
/// that the following address will satisfy `align` (measured in bytes).
5
///
6
/// e.g., if `len` is 9, then `padding_needed_for(len, 4)` returns 3, because
7
/// that is the minimum number of bytes of padding required to get a 4-aligned
8
/// address (assuming that the corresponding memory block starts at a 4-aligned
9
/// address).
10
///
11
/// The return value of this function has no meaning if `align` is not a
12
/// power-of-two.
13
///
14
/// # Panics
15
///
16
/// May panic if `align` is not a power of two.
17
//
18
// TODO(#419): Replace `len` with a witness type for region size.
19
#[allow(unused)]
20
#[inline(always)]
21
0
pub(crate) const fn padding_needed_for(len: usize, align: NonZeroUsize) -> usize {
22
0
    // Rounded up value is:
23
0
    //   len_rounded_up = (len + align - 1) & !(align - 1);
24
0
    // and then we return the padding difference: `len_rounded_up - len`.
25
0
    //
26
0
    // We use modular arithmetic throughout:
27
0
    //
28
0
    // 1. align is guaranteed to be > 0, so align - 1 is always
29
0
    //    valid.
30
0
    //
31
0
    // 2. `len + align - 1` can overflow by at most `align - 1`,
32
0
    //    so the &-mask with `!(align - 1)` will ensure that in the
33
0
    //    case of overflow, `len_rounded_up` will itself be 0.
34
0
    //    Thus the returned padding, when added to `len`, yields 0,
35
0
    //    which trivially satisfies the alignment `align`.
36
0
    //
37
0
    // (Of course, attempts to allocate blocks of memory whose
38
0
    // size and padding overflow in the above manner should cause
39
0
    // the allocator to yield an error anyway.)
40
0
41
0
    let align = align.get();
42
0
    debug_assert!(align.is_power_of_two());
43
0
    let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
44
0
    len_rounded_up.wrapping_sub(len)
45
0
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zerocopy-0.7.35/src/util.rs
Line
Count
Source
1
// Copyright 2023 The Fuchsia Authors
2
//
3
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6
// This file may not be copied, modified, or distributed except according to
7
// those terms.
8
9
#[path = "third_party/rust/layout.rs"]
10
pub(crate) mod core_layout;
11
12
use core::{mem, num::NonZeroUsize};
13
14
pub(crate) mod ptr {
15
    use core::{
16
        fmt::{Debug, Formatter},
17
        marker::PhantomData,
18
        ptr::NonNull,
19
    };
20
21
    use crate::{util::AsAddress, KnownLayout, _CastType};
22
23
    /// A raw pointer with more restrictions.
24
    ///
25
    /// `Ptr<T>` is similar to `NonNull<T>`, but it is more restrictive in the
26
    /// following ways:
27
    /// - It must derive from a valid allocation
28
    /// - It must reference a byte range which is contained inside the
29
    ///   allocation from which it derives
30
    ///   - As a consequence, the byte range it references must have a size
31
    ///     which does not overflow `isize`
32
    /// - It must satisfy `T`'s alignment requirement
33
    ///
34
    /// Thanks to these restrictions, it is easier to prove the soundness of
35
    /// some operations using `Ptr`s.
36
    ///
37
    /// `Ptr<'a, T>` is [covariant] in `'a` and `T`.
38
    ///
39
    /// [covariant]: https://doc.rust-lang.org/reference/subtyping.html
40
    pub struct Ptr<'a, T: 'a + ?Sized> {
41
        // INVARIANTS:
42
        // 1. `ptr` is derived from some valid Rust allocation, `A`
43
        // 2. `ptr` has the same provenance as `A`
44
        // 3. `ptr` addresses a byte range which is entirely contained in `A`
45
        // 4. `ptr` addresses a byte range whose length fits in an `isize`
46
        // 5. `ptr` addresses a byte range which does not wrap around the address
47
        //     space
48
        // 6. `ptr` is validly-aligned for `T`
49
        // 7. `A` is guaranteed to live for at least `'a`
50
        // 8. `T: 'a`
51
        ptr: NonNull<T>,
52
        _lifetime: PhantomData<&'a ()>,
53
    }
54
55
    impl<'a, T: ?Sized> Copy for Ptr<'a, T> {}
56
    impl<'a, T: ?Sized> Clone for Ptr<'a, T> {
57
        #[inline]
58
0
        fn clone(&self) -> Self {
59
0
            *self
60
0
        }
61
    }
62
63
    impl<'a, T: ?Sized> Ptr<'a, T> {
64
        /// Returns a shared reference to the value.
65
        ///
66
        /// # Safety
67
        ///
68
        /// For the duration of `'a`:
69
        /// - The referenced memory must contain a validly-initialized `T` for
70
        ///   the duration of `'a`.
71
        /// - The referenced memory must not also be referenced by any mutable
72
        ///   references.
73
        /// - The referenced memory must not be mutated, even via an
74
        ///   [`UnsafeCell`].
75
        /// - There must not exist any references to the same memory region
76
        ///   which contain `UnsafeCell`s at byte ranges which are not identical
77
        ///   to the byte ranges at which `T` contains `UnsafeCell`s.
78
        ///
79
        /// [`UnsafeCell`]: core::cell::UnsafeCell
80
        // TODO(#429): The safety requirements are likely overly-restrictive.
81
        // Notably, mutation via `UnsafeCell`s is probably fine. Once the rules
82
        // are more clearly defined, we should relax the safety requirements.
83
        // For an example of why this is subtle, see:
84
        // https://github.com/rust-lang/unsafe-code-guidelines/issues/463#issuecomment-1736771593
85
        #[allow(unused)]
86
0
        pub(crate) unsafe fn as_ref(&self) -> &'a T {
87
0
            // SAFETY:
88
0
            // - By invariant, `self.ptr` is properly-aligned for `T`.
89
0
            // - By invariant, `self.ptr` is "dereferenceable" in that it points
90
0
            //   to a single allocation.
91
0
            // - By invariant, the allocation is live for `'a`.
92
0
            // - The caller promises that no mutable references exist to this
93
0
            //   region during `'a`.
94
0
            // - The caller promises that `UnsafeCell`s match exactly.
95
0
            // - The caller promises that no mutation will happen during `'a`,
96
0
            //   even via `UnsafeCell`s.
97
0
            // - The caller promises that the memory region contains a
98
0
            //   validly-intialized `T`.
99
0
            unsafe { self.ptr.as_ref() }
100
0
        }
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZeroaEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZerohEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZeroiEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZerojEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZerolEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZeromEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZeronEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZerooEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZerosEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZerotEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZeroxEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBU_3num7nonzero7NonZeroyEEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyEE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtraE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrbE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrcE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrdE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtreE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrfE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrhE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtriE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrjE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrlE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrmE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrnE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtroE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrsE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrtE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtruE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrxE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtryE6as_refB9_
Unexecuted instantiation: _RNvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB5_3PtrShE6as_refB9_
101
102
        /// Casts to a different (unsized) target type.
103
        ///
104
        /// # Safety
105
        ///
106
        /// The caller promises that
107
        /// - `cast(p)` is implemented exactly as follows: `|p: *mut T| p as
108
        ///   *mut U`.
109
        /// - The size of the object referenced by the resulting pointer is less
110
        ///   than or equal to the size of the object referenced by `self`.
111
        /// - The alignment of `U` is less than or equal to the alignment of
112
        ///   `T`.
113
0
        pub(crate) unsafe fn cast_unsized<U: 'a + ?Sized, F: FnOnce(*mut T) -> *mut U>(
114
0
            self,
115
0
            cast: F,
116
0
        ) -> Ptr<'a, U> {
117
0
            let ptr = cast(self.ptr.as_ptr());
118
0
            // SAFETY: Caller promises that `cast` is just an `as` cast. We call
119
0
            // `cast` on `self.ptr.as_ptr()`, which is non-null by construction.
120
0
            let ptr = unsafe { NonNull::new_unchecked(ptr) };
121
0
            // SAFETY:
122
0
            // - By invariant, `self.ptr` is derived from some valid Rust
123
0
            //   allocation, and since `ptr` is just `self.ptr as *mut U`, so is
124
0
            //   `ptr`.
125
0
            // - By invariant, `self.ptr` has the same provenance as `A`, and so
126
0
            //   the same is true of `ptr`.
127
0
            // - By invariant, `self.ptr` addresses a byte range which is
128
0
            //   entirely contained in `A`, and so the same is true of `ptr`.
129
0
            // - By invariant, `self.ptr` addresses a byte range whose length
130
0
            //   fits in an `isize`, and so the same is true of `ptr`.
131
0
            // - By invariant, `self.ptr` addresses a byte range which does not
132
0
            //   wrap around the address space, and so the same is true of
133
0
            //   `ptr`.
134
0
            // - By invariant, `self.ptr` is validly-aligned for `T`. Since
135
0
            //   `ptr` has the same address, and since the caller promises that
136
0
            //   the alignment of `U` is less than or equal to the alignment of
137
0
            //   `T`, `ptr` is validly-aligned for `U`.
138
0
            // - By invariant, `A` is guaranteed to live for at least `'a`.
139
0
            // - `U: 'a`
140
0
            Ptr { ptr, _lifetime: PhantomData }
141
0
        }
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaEE12cast_unsizedaNCNvXsd_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohEE12cast_unsizedhNCNvXsc_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiEE12cast_unsizediNCNvXsn_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojEE12cast_unsizedjNCNvXsm_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolEE12cast_unsizedlNCNvXsh_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromEE12cast_unsizedmNCNvXsg_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronEE12cast_unsizednNCNvXsl_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooEE12cast_unsizedoNCNvXsk_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosEE12cast_unsizedsNCNvXsf_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotEE12cast_unsizedtNCNvXse_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxEE12cast_unsizedxNCNvXsj_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyEE12cast_unsizedyNCNvXsi_NvBa_sE_1__BQ_NtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrbE12cast_unsizedhNCNvXs1_NvBa_sB_1__bNtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrcE12cast_unsizedmNCNvXs0_NvBa_sC_1__cNtBa_12TryFromBytes12is_bit_valid0EBa_
Unexecuted instantiation: _RINvMs0_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtreE12cast_unsizedShNCNvXs1_NvBa_sD_1__eNtBa_12TryFromBytes12is_bit_valid0EBa_
142
    }
143
144
    impl<'a> Ptr<'a, [u8]> {
145
        /// Attempts to cast `self` to a `U` using the given cast type.
146
        ///
147
        /// Returns `None` if the resulting `U` would be invalidly-aligned or if
148
        /// no `U` can fit in `self`. On success, returns a pointer to the
149
        /// largest-possible `U` which fits in `self`.
150
        ///
151
        /// # Safety
152
        ///
153
        /// The caller may assume that this implementation is correct, and may
154
        /// rely on that assumption for the soundness of their code. In
155
        /// particular, the caller may assume that, if `try_cast_into` returns
156
        /// `Some((ptr, split_at))`, then:
157
        /// - If this is a prefix cast, `ptr` refers to the byte range `[0,
158
        ///   split_at)` in `self`.
159
        /// - If this is a suffix cast, `ptr` refers to the byte range
160
        ///   `[split_at, self.len())` in `self`.
161
        ///
162
        /// # Panics
163
        ///
164
        /// Panics if `U` is a DST whose trailing slice element is zero-sized.
165
0
        pub(crate) fn try_cast_into<U: 'a + ?Sized + KnownLayout>(
166
0
            &self,
167
0
            cast_type: _CastType,
168
0
        ) -> Option<(Ptr<'a, U>, usize)> {
169
            // PANICS: By invariant, the byte range addressed by `self.ptr` does
170
            // not wrap around the address space. This implies that the sum of
171
            // the address (represented as a `usize`) and length do not overflow
172
            // `usize`, as required by `validate_cast_and_convert_metadata`.
173
            // Thus, this call to `validate_cast_and_convert_metadata` won't
174
            // panic.
175
0
            let (elems, split_at) = U::LAYOUT.validate_cast_and_convert_metadata(
176
0
                AsAddress::addr(self.ptr.as_ptr()),
177
0
                self.len(),
178
0
                cast_type,
179
0
            )?;
180
0
            let offset = match cast_type {
181
0
                _CastType::_Prefix => 0,
182
0
                _CastType::_Suffix => split_at,
183
            };
184
185
0
            let ptr = self.ptr.cast::<u8>().as_ptr();
186
0
            // SAFETY: `offset` is either `0` or `split_at`.
187
0
            // `validate_cast_and_convert_metadata` promises that `split_at` is
188
0
            // in the range `[0, self.len()]`. Thus, in both cases, `offset` is
189
0
            // in `[0, self.len()]`. Thus:
190
0
            // - The resulting pointer is in or one byte past the end of the
191
0
            //   same byte range as `self.ptr`. Since, by invariant, `self.ptr`
192
0
            //   addresses a byte range entirely contained within a single
193
0
            //   allocation, the pointer resulting from this operation is within
194
0
            //   or one byte past the end of that same allocation.
195
0
            // - By invariant, `self.len() <= isize::MAX`. Since `offset <=
196
0
            //   self.len()`, `offset <= isize::MAX`.
197
0
            // - By invariant, `self.ptr` addresses a byte range which does not
198
0
            //   wrap around the address space. This means that the base pointer
199
0
            //   plus the `self.len()` does not overflow `usize`. Since `offset
200
0
            //   <= self.len()`, this addition does not overflow `usize`.
201
0
            let base = unsafe { ptr.add(offset) };
202
0
            // SAFETY: Since `add` is not allowed to wrap around, the preceding line
203
0
            // produces a pointer whose address is greater than or equal to that of
204
0
            // `ptr`. Since `ptr` is a `NonNull`, `base` is also non-null.
205
0
            let base = unsafe { NonNull::new_unchecked(base) };
206
0
            let ptr = U::raw_from_ptr_len(base, elems);
207
0
            // SAFETY:
208
0
            // - By invariant, `self.ptr` is derived from some valid Rust
209
0
            //   allocation, `A`, and has the same provenance as `A`. All
210
0
            //   operations performed on `self.ptr` and values derived from it
211
0
            //   in this method preserve provenance, so:
212
0
            //   - `ptr` is derived from a valid Rust allocation, `A`.
213
0
            //   - `ptr` has the same provenance as `A`.
214
0
            // - `validate_cast_and_convert_metadata` promises that the object
215
0
            //   described by `elems` and `split_at` lives at a byte range which
216
0
            //   is a subset of the input byte range. Thus:
217
0
            //   - Since, by invariant, `self.ptr` addresses a byte range
218
0
            //     entirely contained in `A`, so does `ptr`.
219
0
            //   - Since, by invariant, `self.ptr` addresses a range whose
220
0
            //     length is not longer than `isize::MAX` bytes, so does `ptr`.
221
0
            //   - Since, by invariant, `self.ptr` addresses a range which does
222
0
            //     not wrap around the address space, so does `ptr`.
223
0
            // - `validate_cast_and_convert_metadata` promises that the object
224
0
            //   described by `split_at` is validly-aligned for `U`.
225
0
            // - By invariant on `self`, `A` is guaranteed to live for at least
226
0
            //   `'a`.
227
0
            // - `U: 'a` by trait bound.
228
0
            Some((Ptr { ptr, _lifetime: PhantomData }, split_at))
229
0
        }
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZeroaEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZerohEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZeroiEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZerojEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZerolEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZeromEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZeronEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZerooEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZerosEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZerotEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZeroxEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1d_3num7nonzero7NonZeroyEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoaEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intobEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intocEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intodEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoeEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intofEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intohEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoiEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intojEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intolEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intomEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intonEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intooEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intosEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intotEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intouEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoxEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE13try_cast_intoyEBa_
230
231
        /// Attempts to cast `self` into a `U`, failing if all of the bytes of
232
        /// `self` cannot be treated as a `U`.
233
        ///
234
        /// In particular, this method fails if `self` is not validly-aligned
235
        /// for `U` or if `self`'s size is not a valid size for `U`.
236
        ///
237
        /// # Safety
238
        ///
239
        /// On success, the caller may assume that the returned pointer
240
        /// references the same byte range as `self`.
241
        #[allow(unused)]
242
        #[inline(always)]
243
0
        pub(crate) fn try_cast_into_no_leftover<U: 'a + ?Sized + KnownLayout>(
244
0
            &self,
245
0
        ) -> Option<Ptr<'a, U>> {
246
0
            // TODO(#67): Remove this allow. See NonNulSlicelExt for more
247
0
            // details.
248
0
            #[allow(unstable_name_collisions)]
249
0
            match self.try_cast_into(_CastType::_Prefix) {
250
0
                Some((slf, split_at)) if split_at == self.len() => Some(slf),
251
0
                Some(_) | None => None,
252
            }
253
0
        }
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZeroaEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZerohEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZeroiEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZerojEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZerolEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZeromEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZeronEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZerooEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZerosEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZerotEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZeroxEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1p_3num7nonzero7NonZeroyEEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyEEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoveraEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverbEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftovercEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverdEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftovereEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverfEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverhEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoveriEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverjEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverlEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftovermEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftovernEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoveroEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoversEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftovertEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoveruEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoverxEBa_
Unexecuted instantiation: _RINvMs1_NtNtCsiAAEnE8327y_8zerocopy4util3ptrINtB6_3PtrShE25try_cast_into_no_leftoveryEBa_
254
    }
255
256
    impl<'a, T> Ptr<'a, [T]> {
257
        /// The number of slice elements referenced by `self`.
258
        ///
259
        /// # Safety
260
        ///
261
        /// Unsafe code my rely on `len` satisfying the above contract.
262
0
        fn len(&self) -> usize {
263
0
            #[allow(clippy::as_conversions)]
264
0
            let slc = self.ptr.as_ptr() as *const [()];
265
0
            // SAFETY:
266
0
            // - `()` has alignment 1, so `slc` is trivially aligned.
267
0
            // - `slc` was derived from a non-null pointer.
268
0
            // - The size is 0 regardless of the length, so it is sound to
269
0
            //   materialize a reference regardless of location.
270
0
            // - By invariant, `self.ptr` has valid provenance.
271
0
            let slc = unsafe { &*slc };
272
0
            // This is correct because the preceding `as` cast preserves the
273
0
            // number of slice elements. Per
274
0
            // https://doc.rust-lang.org/nightly/reference/expressions/operator-expr.html#slice-dst-pointer-to-pointer-cast:
275
0
            //
276
0
            //   For slice types like `[T]` and `[U]`, the raw pointer types
277
0
            //   `*const [T]`, `*mut [T]`, `*const [U]`, and `*mut [U]` encode
278
0
            //   the number of elements in this slice. Casts between these raw
279
0
            //   pointer types preserve the number of elements. Note that, as a
280
0
            //   consequence, such casts do *not* necessarily preserve the size
281
0
            //   of the pointer's referent (e.g., casting `*const [u16]` to
282
0
            //   `*const [u8]` will result in a raw pointer which refers to an
283
0
            //   object of half the size of the original). The same holds for
284
0
            //   `str` and any compound type whose unsized tail is a slice type,
285
0
            //   such as struct `Foo(i32, [u8])` or `(u64, Foo)`.
286
0
            //
287
0
            // TODO(#429),
288
0
            // TODO(https://github.com/rust-lang/reference/pull/1417): Once this
289
0
            // text is available on the Stable docs, cite those instead of the
290
0
            // Nightly docs.
291
0
            slc.len()
292
0
        }
293
294
0
        pub(crate) fn iter(&self) -> impl Iterator<Item = Ptr<'a, T>> {
295
0
            // TODO(#429): Once `NonNull::cast` documents that it preserves
296
0
            // provenance, cite those docs.
297
0
            let base = self.ptr.cast::<T>().as_ptr();
298
0
            (0..self.len()).map(move |i| {
299
0
                // TODO(https://github.com/rust-lang/rust/issues/74265): Use
300
0
                // `NonNull::get_unchecked_mut`.
301
0
302
0
                // SAFETY: If the following conditions are not satisfied
303
0
                // `pointer::cast` may induce Undefined Behavior [1]:
304
0
                // > 1. Both the starting and resulting pointer must be either
305
0
                // >    in bounds or one byte past the end of the same allocated
306
0
                // >    object.
307
0
                // > 2. The computed offset, in bytes, cannot overflow an
308
0
                // >    `isize`.
309
0
                // > 3. The offset being in bounds cannot rely on “wrapping
310
0
                // >    around” the address space. That is, the
311
0
                // >    infinite-precision sum must fit in a `usize`.
312
0
                //
313
0
                // [1] https://doc.rust-lang.org/std/primitive.pointer.html#method.add
314
0
                //
315
0
                // We satisfy all three of these conditions here:
316
0
                // 1. `base` (by invariant on `self`) points to an allocated
317
0
                //    object. By contract, `self.len()` accurately reflects the
318
0
                //    number of elements in the slice. `i` is in bounds of
319
0
                //   `c.len()` by construction, and so the result of this
320
0
                //   addition cannot overflow past the end of the allocation
321
0
                //   referred to by `c`.
322
0
                // 2. By invariant on `Ptr`, `self` addresses a byte range whose
323
0
                //    length fits in an `isize`. Since `elem` is contained in
324
0
                //    `self`, the computed offset of `elem` must fit within
325
0
                //    `isize.`
326
0
                // 3. By invariant on `Ptr`, `self` addresses a byte range which
327
0
                //    does not wrap around the address space. Since `elem` is
328
0
                //    contained in `self`, the computed offset of `elem` must
329
0
                //    wrap around the address space.
330
0
                //
331
0
                // TODO(#429): Once `pointer::add` documents that it preserves
332
0
                // provenance, cite those docs.
333
0
                let elem = unsafe { base.add(i) };
334
0
335
0
                // SAFETY:
336
0
                //  - `elem` must not be null. `base` is constructed from a
337
0
                //    `NonNull` pointer, and the addition that produces `elem`
338
0
                //    must not overflow or wrap around, so `elem >= base > 0`.
339
0
                //
340
0
                // TODO(#429): Once `NonNull::new_unchecked` documents that it
341
0
                // preserves provenance, cite those docs.
342
0
                let elem = unsafe { NonNull::new_unchecked(elem) };
343
0
344
0
                // SAFETY: The safety invariants of `Ptr` (see definition) are
345
0
                // satisfied:
346
0
                // 1. `elem` is derived from a valid Rust allocation, because
347
0
                //    `self` is derived from a valid Rust allocation, by
348
0
                //    invariant on `Ptr`
349
0
                // 2. `elem` has the same provenance as `self`, because it
350
0
                //    derived from `self` using a series of
351
0
                //    provenance-preserving operations
352
0
                // 3. `elem` is entirely contained in the allocation of `self`
353
0
                //    (see above)
354
0
                // 4. `elem` addresses a byte range whose length fits in an
355
0
                //    `isize` (see above)
356
0
                // 5. `elem` addresses a byte range which does not wrap around
357
0
                //    the address space (see above)
358
0
                // 6. `elem` is validly-aligned for `T`. `self`, which
359
0
                //    represents a `[T]` is validly aligned for `T`, and `elem`
360
0
                //    is an element within that `[T]`
361
0
                // 7. The allocation of `elem` is guaranteed to live for at
362
0
                //    least `'a`, because `elem` is entirely contained in
363
0
                //    `self`, which lives for at least `'a` by invariant on
364
0
                //    `Ptr`.
365
0
                // 8. `T: 'a`, because `elem` is an element within `[T]`, and
366
0
                //    `[T]: 'a` by invariant on `Ptr`
367
0
                Ptr { ptr: elem, _lifetime: PhantomData }
368
0
            })
369
0
        }
370
    }
371
372
    impl<'a, T: 'a + ?Sized> From<&'a T> for Ptr<'a, T> {
373
        #[inline(always)]
374
0
        fn from(t: &'a T) -> Ptr<'a, T> {
375
0
            // SAFETY: `t` points to a valid Rust allocation, `A`, by
376
0
            // construction. Thus:
377
0
            // - `ptr` is derived from `A`
378
0
            // - Since we use `NonNull::from`, which preserves provenance, `ptr`
379
0
            //   has the same provenance as `A`
380
0
            // - Since `NonNull::from` creates a pointer which addresses the
381
0
            //   same bytes as `t`, `ptr` addresses a byte range entirely
382
0
            //   contained in (in this case, identical to) `A`
383
0
            // - Since `t: &T`, it addresses no more than `isize::MAX` bytes [1]
384
0
            // - Since `t: &T`, it addresses a byte range which does not wrap
385
0
            //   around the address space [2]
386
0
            // - Since it is constructed from a valid `&T`, `ptr` is
387
0
            //   validly-aligned for `T`
388
0
            // - Since `t: &'a T`, the allocation `A` is guaranteed to live for
389
0
            //   at least `'a`
390
0
            // - `T: 'a` by trait bound
391
0
            //
392
0
            // TODO(#429),
393
0
            // TODO(https://github.com/rust-lang/rust/issues/116181): Once it's
394
0
            // documented, reference the guarantee that `NonNull::from`
395
0
            // preserves provenance.
396
0
            //
397
0
            // TODO(#429),
398
0
            // TODO(https://github.com/rust-lang/unsafe-code-guidelines/issues/465):
399
0
            // - [1] Where does the reference document that allocations fit in
400
0
            //   `isize`?
401
0
            // - [2] Where does the reference document that allocations don't
402
0
            //   wrap around the address space?
403
0
            Ptr { ptr: NonNull::from(t), _lifetime: PhantomData }
404
0
        }
405
    }
406
407
    impl<'a, T: 'a + ?Sized> Debug for Ptr<'a, T> {
408
        #[inline]
409
0
        fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
410
0
            self.ptr.fmt(f)
411
0
        }
412
    }
413
414
    #[cfg(test)]
415
    mod tests {
416
        use core::mem::{self, MaybeUninit};
417
418
        use super::*;
419
        use crate::{util::testutil::AU64, FromBytes};
420
421
        #[test]
422
        fn test_ptrtry_cast_into_soundness() {
423
            // This test is designed so that if `Ptr::try_cast_into_xxx` are
424
            // buggy, it will manifest as unsoundness that Miri can detect.
425
426
            // - If `size_of::<T>() == 0`, `N == 4`
427
            // - Else, `N == 4 * size_of::<T>()`
428
            fn test<const N: usize, T: ?Sized + KnownLayout + FromBytes>() {
429
                let mut bytes = [MaybeUninit::<u8>::uninit(); N];
430
                let initialized = [MaybeUninit::new(0u8); N];
431
                for start in 0..=bytes.len() {
432
                    for end in start..=bytes.len() {
433
                        // Set all bytes to uninitialized other than those in
434
                        // the range we're going to pass to `try_cast_from`.
435
                        // This allows Miri to detect out-of-bounds reads
436
                        // because they read uninitialized memory. Without this,
437
                        // some out-of-bounds reads would still be in-bounds of
438
                        // `bytes`, and so might spuriously be accepted.
439
                        bytes = [MaybeUninit::<u8>::uninit(); N];
440
                        let bytes = &mut bytes[start..end];
441
                        // Initialize only the byte range we're going to pass to
442
                        // `try_cast_from`.
443
                        bytes.copy_from_slice(&initialized[start..end]);
444
445
                        let bytes = {
446
                            let bytes: *const [MaybeUninit<u8>] = bytes;
447
                            #[allow(clippy::as_conversions)]
448
                            let bytes = bytes as *const [u8];
449
                            // SAFETY: We just initialized these bytes to valid
450
                            // `u8`s.
451
                            unsafe { &*bytes }
452
                        };
453
454
                        /// # Safety
455
                        ///
456
                        /// - `slf` must reference a byte range which is
457
                        ///   entirely initialized.
458
                        /// - `slf` must reference a byte range which is only
459
                        ///   referenced by shared references which do not
460
                        ///   contain `UnsafeCell`s during its lifetime.
461
                        unsafe fn validate_and_get_len<T: ?Sized + KnownLayout + FromBytes>(
462
                            slf: Ptr<'_, T>,
463
                        ) -> usize {
464
                            // SAFETY:
465
                            // - Since all bytes in `slf` are initialized and
466
                            //   `T: FromBytes`, `slf` contains a valid `T`.
467
                            // - The caller promises that the referenced memory
468
                            //   is not also referenced by any mutable
469
                            //   references.
470
                            // - The caller promises that the referenced memory
471
                            //   is not also referenced as a type which contains
472
                            //   `UnsafeCell`s.
473
                            let t = unsafe { slf.as_ref() };
474
475
                            let bytes = {
476
                                let len = mem::size_of_val(t);
477
                                let t: *const T = t;
478
                                // SAFETY:
479
                                // - We know `t`'s bytes are all initialized
480
                                //   because we just read it from `slf`, which
481
                                //   points to an initialized range of bytes. If
482
                                //   there's a bug and this doesn't hold, then
483
                                //   that's exactly what we're hoping Miri will
484
                                //   catch!
485
                                // - Since `T: FromBytes`, `T` doesn't contain
486
                                //   any `UnsafeCell`s, so it's okay for `t: T`
487
                                //   and a `&[u8]` to the same memory to be
488
                                //   alive concurrently.
489
                                unsafe { core::slice::from_raw_parts(t.cast::<u8>(), len) }
490
                            };
491
492
                            // This assertion ensures that `t`'s bytes are read
493
                            // and compared to another value, which in turn
494
                            // ensures that Miri gets a chance to notice if any
495
                            // of `t`'s bytes are uninitialized, which they
496
                            // shouldn't be (see the comment above).
497
                            assert_eq!(bytes, vec![0u8; bytes.len()]);
498
499
                            mem::size_of_val(t)
500
                        }
501
502
                        for cast_type in [_CastType::_Prefix, _CastType::_Suffix] {
503
                            if let Some((slf, split_at)) =
504
                                Ptr::from(bytes).try_cast_into::<T>(cast_type)
505
                            {
506
                                // SAFETY: All bytes in `bytes` have been
507
                                // initialized.
508
                                let len = unsafe { validate_and_get_len(slf) };
509
                                match cast_type {
510
                                    _CastType::_Prefix => assert_eq!(split_at, len),
511
                                    _CastType::_Suffix => assert_eq!(split_at, bytes.len() - len),
512
                                }
513
                            }
514
                        }
515
516
                        if let Some(slf) = Ptr::from(bytes).try_cast_into_no_leftover::<T>() {
517
                            // SAFETY: All bytes in `bytes` have been
518
                            // initialized.
519
                            let len = unsafe { validate_and_get_len(slf) };
520
                            assert_eq!(len, bytes.len());
521
                        }
522
                    }
523
                }
524
            }
525
526
            macro_rules! test {
527
            ($($ty:ty),*) => {
528
                $({
529
                    const S: usize = core::mem::size_of::<$ty>();
530
                    const N: usize = if S == 0 { 4 } else { S * 4 };
531
                    test::<N, $ty>();
532
                    // We don't support casting into DSTs whose trailing slice
533
                    // element is a ZST.
534
                    if S > 0 {
535
                        test::<N, [$ty]>();
536
                    }
537
                    // TODO: Test with a slice DST once we have any that
538
                    // implement `KnownLayout + FromBytes`.
539
                })*
540
            };
541
        }
542
543
            test!(());
544
            test!(u8, u16, u32, u64, u128, usize, AU64);
545
            test!(i8, i16, i32, i64, i128, isize);
546
            test!(f32, f64);
547
        }
548
    }
549
}
550
551
pub(crate) trait AsAddress {
552
    fn addr(self) -> usize;
553
}
554
555
impl<'a, T: ?Sized> AsAddress for &'a T {
556
    #[inline(always)]
557
0
    fn addr(self) -> usize {
558
0
        let ptr: *const T = self;
559
0
        AsAddress::addr(ptr)
560
0
    }
561
}
562
563
impl<'a, T: ?Sized> AsAddress for &'a mut T {
564
    #[inline(always)]
565
0
    fn addr(self) -> usize {
566
0
        let ptr: *const T = self;
567
0
        AsAddress::addr(ptr)
568
0
    }
569
}
570
571
impl<T: ?Sized> AsAddress for *const T {
572
    #[inline(always)]
573
0
    fn addr(self) -> usize {
574
0
        // TODO(#181), TODO(https://github.com/rust-lang/rust/issues/95228): Use
575
0
        // `.addr()` instead of `as usize` once it's stable, and get rid of this
576
0
        // `allow`. Currently, `as usize` is the only way to accomplish this.
577
0
        #[allow(clippy::as_conversions)]
578
0
        #[cfg_attr(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS, allow(lossy_provenance_casts))]
579
0
        return self.cast::<()>() as usize;
580
0
    }
581
}
582
583
impl<T: ?Sized> AsAddress for *mut T {
584
    #[inline(always)]
585
0
    fn addr(self) -> usize {
586
0
        let ptr: *const T = self;
587
0
        AsAddress::addr(ptr)
588
0
    }
589
}
590
591
/// Is `t` aligned to `mem::align_of::<U>()`?
592
#[inline(always)]
593
0
pub(crate) fn aligned_to<T: AsAddress, U>(t: T) -> bool {
594
0
    // `mem::align_of::<U>()` is guaranteed to return a non-zero value, which in
595
0
    // turn guarantees that this mod operation will not panic.
596
0
    #[allow(clippy::arithmetic_side_effects)]
597
0
    let remainder = t.addr() % mem::align_of::<U>();
598
0
    remainder == 0
599
0
}
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZeroaEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZerohEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZeroiEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZerojEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZerolEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZeromEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZeronEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZerooEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZerosEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZerotEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZeroxEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBQ_3num7nonzero7NonZeroyEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShaEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShdEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShfEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShhEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShiEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShjEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShlEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShmEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShnEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShoEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShsEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShtEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShuEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShxEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShyEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZeroaEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZerohEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZeroiEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZerojEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZerolEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZeromEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZeronEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZerooEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZerosEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZerotEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZeroxEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtB1f_3num7nonzero7NonZeroyEEEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignaEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnaligndEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignfEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignhEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnaligniEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignjEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignlEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignmEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignnEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignoEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignsEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnaligntEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignuEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignxEEB4_
Unexecuted instantiation: _RINvNtCsiAAEnE8327y_8zerocopy4util10aligned_toRShINtNtB4_8wrappers7UnalignyEEB4_
600
601
/// Round `n` down to the largest value `m` such that `m <= n` and `m % align ==
602
/// 0`.
603
///
604
/// # Panics
605
///
606
/// May panic if `align` is not a power of two. Even if it doesn't panic in this
607
/// case, it will produce nonsense results.
608
#[inline(always)]
609
0
pub(crate) const fn round_down_to_next_multiple_of_alignment(
610
0
    n: usize,
611
0
    align: NonZeroUsize,
612
0
) -> usize {
613
0
    let align = align.get();
614
0
    debug_assert!(align.is_power_of_two());
615
616
    // Subtraction can't underflow because `align.get() >= 1`.
617
    #[allow(clippy::arithmetic_side_effects)]
618
0
    let mask = !(align - 1);
619
0
    n & mask
620
0
}
621
622
0
pub(crate) const fn max(a: NonZeroUsize, b: NonZeroUsize) -> NonZeroUsize {
623
0
    if a.get() < b.get() {
624
0
        b
625
    } else {
626
0
        a
627
    }
628
0
}
629
630
0
pub(crate) const fn min(a: NonZeroUsize, b: NonZeroUsize) -> NonZeroUsize {
631
0
    if a.get() > b.get() {
632
0
        b
633
    } else {
634
0
        a
635
    }
636
0
}
637
638
/// Since we support multiple versions of Rust, there are often features which
639
/// have been stabilized in the most recent stable release which do not yet
640
/// exist (stably) on our MSRV. This module provides polyfills for those
641
/// features so that we can write more "modern" code, and just remove the
642
/// polyfill once our MSRV supports the corresponding feature. Without this,
643
/// we'd have to write worse/more verbose code and leave TODO comments sprinkled
644
/// throughout the codebase to update to the new pattern once it's stabilized.
645
///
646
/// Each trait is imported as `_` at the crate root; each polyfill should "just
647
/// work" at usage sites.
648
pub(crate) mod polyfills {
649
    use core::ptr::{self, NonNull};
650
651
    // A polyfill for `NonNull::slice_from_raw_parts` that we can use before our
652
    // MSRV is 1.70, when that function was stabilized.
653
    //
654
    // TODO(#67): Once our MSRV is 1.70, remove this.
655
    #[allow(unused)]
656
    pub(crate) trait NonNullExt<T> {
657
        fn slice_from_raw_parts(data: Self, len: usize) -> NonNull<[T]>;
658
    }
659
660
    #[allow(unused)]
661
    impl<T> NonNullExt<T> for NonNull<T> {
662
        #[inline(always)]
663
0
        fn slice_from_raw_parts(data: Self, len: usize) -> NonNull<[T]> {
664
0
            let ptr = ptr::slice_from_raw_parts_mut(data.as_ptr(), len);
665
0
            // SAFETY: `ptr` is converted from `data`, which is non-null.
666
0
            unsafe { NonNull::new_unchecked(ptr) }
667
0
        }
668
    }
669
}
670
671
#[cfg(test)]
672
pub(crate) mod testutil {
673
    use core::fmt::{self, Display, Formatter};
674
675
    use crate::*;
676
677
    /// A `T` which is aligned to at least `align_of::<A>()`.
678
    #[derive(Default)]
679
    pub(crate) struct Align<T, A> {
680
        pub(crate) t: T,
681
        _a: [A; 0],
682
    }
683
684
    impl<T: Default, A> Align<T, A> {
685
        pub(crate) fn set_default(&mut self) {
686
            self.t = T::default();
687
        }
688
    }
689
690
    impl<T, A> Align<T, A> {
691
        pub(crate) const fn new(t: T) -> Align<T, A> {
692
            Align { t, _a: [] }
693
        }
694
    }
695
696
    // A `u64` with alignment 8.
697
    //
698
    // Though `u64` has alignment 8 on some platforms, it's not guaranteed.
699
    // By contrast, `AU64` is guaranteed to have alignment 8.
700
    #[derive(
701
        KnownLayout,
702
        FromZeroes,
703
        FromBytes,
704
        AsBytes,
705
        Eq,
706
        PartialEq,
707
        Ord,
708
        PartialOrd,
709
        Default,
710
        Debug,
711
        Copy,
712
        Clone,
713
    )]
714
    #[repr(C, align(8))]
715
    pub(crate) struct AU64(pub(crate) u64);
716
717
    impl AU64 {
718
        // Converts this `AU64` to bytes using this platform's endianness.
719
        pub(crate) fn to_bytes(self) -> [u8; 8] {
720
            crate::transmute!(self)
721
        }
722
    }
723
724
    impl Display for AU64 {
725
        fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
726
            Display::fmt(&self.0, f)
727
        }
728
    }
729
730
    #[derive(
731
        FromZeroes, FromBytes, Eq, PartialEq, Ord, PartialOrd, Default, Debug, Copy, Clone,
732
    )]
733
    #[repr(C)]
734
    pub(crate) struct Nested<T, U: ?Sized> {
735
        _t: T,
736
        _u: U,
737
    }
738
}
739
740
#[cfg(test)]
741
mod tests {
742
    use super::*;
743
744
    #[test]
745
    fn test_round_down_to_next_multiple_of_alignment() {
746
        fn alt_impl(n: usize, align: NonZeroUsize) -> usize {
747
            let mul = n / align.get();
748
            mul * align.get()
749
        }
750
751
        for align in [1, 2, 4, 8, 16] {
752
            for n in 0..256 {
753
                let align = NonZeroUsize::new(align).unwrap();
754
                let want = alt_impl(n, align);
755
                let got = round_down_to_next_multiple_of_alignment(n, align);
756
                assert_eq!(got, want, "round_down_to_next_multiple_of_alignment({n}, {align})");
757
            }
758
        }
759
    }
760
}
761
762
#[cfg(kani)]
763
mod proofs {
764
    use super::*;
765
766
    #[kani::proof]
767
    fn prove_round_down_to_next_multiple_of_alignment() {
768
        fn model_impl(n: usize, align: NonZeroUsize) -> usize {
769
            assert!(align.get().is_power_of_two());
770
            let mul = n / align.get();
771
            mul * align.get()
772
        }
773
774
        let align: NonZeroUsize = kani::any();
775
        kani::assume(align.get().is_power_of_two());
776
        let n: usize = kani::any();
777
778
        let expected = model_impl(n, align);
779
        let actual = round_down_to_next_multiple_of_alignment(n, align);
780
        assert_eq!(expected, actual, "round_down_to_next_multiple_of_alignment({n}, {align})");
781
    }
782
783
    // Restricted to nightly since we use the unstable `usize::next_multiple_of`
784
    // in our model implementation.
785
    #[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
786
    #[kani::proof]
787
    fn prove_padding_needed_for() {
788
        fn model_impl(len: usize, align: NonZeroUsize) -> usize {
789
            let padded = len.next_multiple_of(align.get());
790
            let padding = padded - len;
791
            padding
792
        }
793
794
        let align: NonZeroUsize = kani::any();
795
        kani::assume(align.get().is_power_of_two());
796
        let len: usize = kani::any();
797
        // Constrain `len` to valid Rust lengths, since our model implementation
798
        // isn't robust to overflow.
799
        kani::assume(len <= isize::MAX as usize);
800
        kani::assume(align.get() < 1 << 29);
801
802
        let expected = model_impl(len, align);
803
        let actual = core_layout::padding_needed_for(len, align);
804
        assert_eq!(expected, actual, "padding_needed_for({len}, {align})");
805
806
        let padded_len = actual + len;
807
        assert_eq!(padded_len % align, 0);
808
        assert!(padded_len / align >= len / align);
809
    }
810
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zerocopy-0.7.35/src/wrappers.rs
Line
Count
Source
1
// Copyright 2023 The Fuchsia Authors
2
//
3
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6
// This file may not be copied, modified, or distributed except according to
7
// those terms.
8
9
use core::{
10
    cmp::Ordering,
11
    fmt::{self, Debug, Display, Formatter},
12
    hash::Hash,
13
    mem::{self, ManuallyDrop},
14
    ops::{Deref, DerefMut},
15
    ptr,
16
};
17
18
use super::*;
19
20
/// A type with no alignment requirement.
21
///
22
/// An `Unalign` wraps a `T`, removing any alignment requirement. `Unalign<T>`
23
/// has the same size and bit validity as `T`, but not necessarily the same
24
/// alignment [or ABI]. This is useful if a type with an alignment requirement
25
/// needs to be read from a chunk of memory which provides no alignment
26
/// guarantees.
27
///
28
/// Since `Unalign` has no alignment requirement, the inner `T` may not be
29
/// properly aligned in memory. There are five ways to access the inner `T`:
30
/// - by value, using [`get`] or [`into_inner`]
31
/// - by reference inside of a callback, using [`update`]
32
/// - fallibly by reference, using [`try_deref`] or [`try_deref_mut`]; these can
33
///   fail if the `Unalign` does not satisfy `T`'s alignment requirement at
34
///   runtime
35
/// - unsafely by reference, using [`deref_unchecked`] or
36
///   [`deref_mut_unchecked`]; it is the caller's responsibility to ensure that
37
///   the `Unalign` satisfies `T`'s alignment requirement
38
/// - (where `T: Unaligned`) infallibly by reference, using [`Deref::deref`] or
39
///   [`DerefMut::deref_mut`]
40
///
41
/// [or ABI]: https://github.com/google/zerocopy/issues/164
42
/// [`get`]: Unalign::get
43
/// [`into_inner`]: Unalign::into_inner
44
/// [`update`]: Unalign::update
45
/// [`try_deref`]: Unalign::try_deref
46
/// [`try_deref_mut`]: Unalign::try_deref_mut
47
/// [`deref_unchecked`]: Unalign::deref_unchecked
48
/// [`deref_mut_unchecked`]: Unalign::deref_mut_unchecked
49
// NOTE: This type is sound to use with types that need to be dropped. The
50
// reason is that the compiler-generated drop code automatically moves all
51
// values to aligned memory slots before dropping them in-place. This is not
52
// well-documented, but it's hinted at in places like [1] and [2]. However, this
53
// also means that `T` must be `Sized`; unless something changes, we can never
54
// support unsized `T`. [3]
55
//
56
// [1] https://github.com/rust-lang/rust/issues/54148#issuecomment-420529646
57
// [2] https://github.com/google/zerocopy/pull/126#discussion_r1018512323
58
// [3] https://github.com/google/zerocopy/issues/209
59
#[allow(missing_debug_implementations)]
60
#[derive(Default, Copy)]
61
#[cfg_attr(
62
    any(feature = "derive", test),
63
    derive(KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned)
64
)]
65
#[repr(C, packed)]
66
pub struct Unalign<T>(T);
67
68
#[cfg(not(any(feature = "derive", test)))]
69
impl_known_layout!(T => Unalign<T>);
70
71
safety_comment! {
72
    /// SAFETY:
73
    /// - `Unalign<T>` is `repr(packed)`, so it is unaligned regardless of the
74
    ///   alignment of `T`, and so we don't require that `T: Unaligned`
75
    /// - `Unalign<T>` has the same bit validity as `T`, and so it is
76
    ///   `FromZeroes`, `FromBytes`, or `AsBytes` exactly when `T` is as well.
77
    impl_or_verify!(T => Unaligned for Unalign<T>);
78
    impl_or_verify!(T: FromZeroes => FromZeroes for Unalign<T>);
79
    impl_or_verify!(T: FromBytes => FromBytes for Unalign<T>);
80
    impl_or_verify!(T: AsBytes => AsBytes for Unalign<T>);
81
}
82
83
// Note that `Unalign: Clone` only if `T: Copy`. Since the inner `T` may not be
84
// aligned, there's no way to safely call `T::clone`, and so a `T: Clone` bound
85
// is not sufficient to implement `Clone` for `Unalign`.
86
impl<T: Copy> Clone for Unalign<T> {
87
    #[inline(always)]
88
0
    fn clone(&self) -> Unalign<T> {
89
0
        *self
90
0
    }
91
}
92
93
impl<T> Unalign<T> {
94
    /// Constructs a new `Unalign`.
95
    #[inline(always)]
96
0
    pub const fn new(val: T) -> Unalign<T> {
97
0
        Unalign(val)
98
0
    }
99
100
    /// Consumes `self`, returning the inner `T`.
101
    #[inline(always)]
102
0
    pub const fn into_inner(self) -> T {
103
        // Use this instead of `mem::transmute` since the latter can't tell
104
        // that `Unalign<T>` and `T` have the same size.
105
        #[repr(C)]
106
        union Transmute<T> {
107
            u: ManuallyDrop<Unalign<T>>,
108
            t: ManuallyDrop<T>,
109
        }
110
111
        // SAFETY: Since `Unalign` is `#[repr(C, packed)]`, it has the same
112
        // layout as `T`. `ManuallyDrop<U>` is guaranteed to have the same
113
        // layout as `U`, and so `ManuallyDrop<Unalign<T>>` has the same layout
114
        // as `ManuallyDrop<T>`. Since `Transmute<T>` is `#[repr(C)]`, its `t`
115
        // and `u` fields both start at the same offset (namely, 0) within the
116
        // union.
117
        //
118
        // We do this instead of just destructuring in order to prevent
119
        // `Unalign`'s `Drop::drop` from being run, since dropping is not
120
        // supported in `const fn`s.
121
        //
122
        // TODO(https://github.com/rust-lang/rust/issues/73255): Destructure
123
        // instead of using unsafe.
124
0
        unsafe { ManuallyDrop::into_inner(Transmute { u: ManuallyDrop::new(self) }.t) }
125
0
    }
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZeroaEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZerohEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZeroiEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZerojEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZerolEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZeromEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZeronEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZerooEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZerosEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZerotEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZeroxEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignINtNtCsbQ8arDwx5Xq_4core6option6OptionINtNtNtBV_3num7nonzero7NonZeroyEEE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128E10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256E10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignaE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnaligndE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignfE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignhE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnaligniE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignjE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignlE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignmE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignnE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignoE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignsE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnaligntE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignuE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignxE10into_innerB6_
Unexecuted instantiation: _RNvMs_NtCsiAAEnE8327y_8zerocopy8wrappersINtB4_7UnalignyE10into_innerB6_
126
127
    /// Attempts to return a reference to the wrapped `T`, failing if `self` is
128
    /// not properly aligned.
129
    ///
130
    /// If `self` does not satisfy `mem::align_of::<T>()`, then it is unsound to
131
    /// return a reference to the wrapped `T`, and `try_deref` returns `None`.
132
    ///
133
    /// If `T: Unaligned`, then `Unalign<T>` implements [`Deref`], and callers
134
    /// may prefer [`Deref::deref`], which is infallible.
135
    #[inline(always)]
136
0
    pub fn try_deref(&self) -> Option<&T> {
137
0
        if !util::aligned_to::<_, T>(self) {
138
0
            return None;
139
0
        }
140
0
141
0
        // SAFETY: `deref_unchecked`'s safety requirement is that `self` is
142
0
        // aligned to `align_of::<T>()`, which we just checked.
143
0
        unsafe { Some(self.deref_unchecked()) }
144
0
    }
145
146
    /// Attempts to return a mutable reference to the wrapped `T`, failing if
147
    /// `self` is not properly aligned.
148
    ///
149
    /// If `self` does not satisfy `mem::align_of::<T>()`, then it is unsound to
150
    /// return a reference to the wrapped `T`, and `try_deref_mut` returns
151
    /// `None`.
152
    ///
153
    /// If `T: Unaligned`, then `Unalign<T>` implements [`DerefMut`], and
154
    /// callers may prefer [`DerefMut::deref_mut`], which is infallible.
155
    #[inline(always)]
156
0
    pub fn try_deref_mut(&mut self) -> Option<&mut T> {
157
0
        if !util::aligned_to::<_, T>(&*self) {
158
0
            return None;
159
0
        }
160
0
161
0
        // SAFETY: `deref_mut_unchecked`'s safety requirement is that `self` is
162
0
        // aligned to `align_of::<T>()`, which we just checked.
163
0
        unsafe { Some(self.deref_mut_unchecked()) }
164
0
    }
165
166
    /// Returns a reference to the wrapped `T` without checking alignment.
167
    ///
168
    /// If `T: Unaligned`, then `Unalign<T>` implements[ `Deref`], and callers
169
    /// may prefer [`Deref::deref`], which is safe.
170
    ///
171
    /// # Safety
172
    ///
173
    /// If `self` does not satisfy `mem::align_of::<T>()`, then
174
    /// `self.deref_unchecked()` may cause undefined behavior.
175
    #[inline(always)]
176
0
    pub const unsafe fn deref_unchecked(&self) -> &T {
177
0
        // SAFETY: `Unalign<T>` is `repr(transparent)`, so there is a valid `T`
178
0
        // at the same memory location as `self`. It has no alignment guarantee,
179
0
        // but the caller has promised that `self` is properly aligned, so we
180
0
        // know that it is sound to create a reference to `T` at this memory
181
0
        // location.
182
0
        //
183
0
        // We use `mem::transmute` instead of `&*self.get_ptr()` because
184
0
        // dereferencing pointers is not stable in `const` on our current MSRV
185
0
        // (1.56 as of this writing).
186
0
        unsafe { mem::transmute(self) }
187
0
    }
188
189
    /// Returns a mutable reference to the wrapped `T` without checking
190
    /// alignment.
191
    ///
192
    /// If `T: Unaligned`, then `Unalign<T>` implements[ `DerefMut`], and
193
    /// callers may prefer [`DerefMut::deref_mut`], which is safe.
194
    ///
195
    /// # Safety
196
    ///
197
    /// If `self` does not satisfy `mem::align_of::<T>()`, then
198
    /// `self.deref_mut_unchecked()` may cause undefined behavior.
199
    #[inline(always)]
200
0
    pub unsafe fn deref_mut_unchecked(&mut self) -> &mut T {
201
0
        // SAFETY: `self.get_mut_ptr()` returns a raw pointer to a valid `T` at
202
0
        // the same memory location as `self`. It has no alignment guarantee,
203
0
        // but the caller has promised that `self` is properly aligned, so we
204
0
        // know that the pointer itself is aligned, and thus that it is sound to
205
0
        // create a reference to a `T` at this memory location.
206
0
        unsafe { &mut *self.get_mut_ptr() }
207
0
    }
208
209
    /// Gets an unaligned raw pointer to the inner `T`.
210
    ///
211
    /// # Safety
212
    ///
213
    /// The returned raw pointer is not necessarily aligned to
214
    /// `align_of::<T>()`. Most functions which operate on raw pointers require
215
    /// those pointers to be aligned, so calling those functions with the result
216
    /// of `get_ptr` will be undefined behavior if alignment is not guaranteed
217
    /// using some out-of-band mechanism. In general, the only functions which
218
    /// are safe to call with this pointer are those which are explicitly
219
    /// documented as being sound to use with an unaligned pointer, such as
220
    /// [`read_unaligned`].
221
    ///
222
    /// [`read_unaligned`]: core::ptr::read_unaligned
223
    #[inline(always)]
224
0
    pub const fn get_ptr(&self) -> *const T {
225
0
        ptr::addr_of!(self.0)
226
0
    }
227
228
    /// Gets an unaligned mutable raw pointer to the inner `T`.
229
    ///
230
    /// # Safety
231
    ///
232
    /// The returned raw pointer is not necessarily aligned to
233
    /// `align_of::<T>()`. Most functions which operate on raw pointers require
234
    /// those pointers to be aligned, so calling those functions with the result
235
    /// of `get_ptr` will be undefined behavior if alignment is not guaranteed
236
    /// using some out-of-band mechanism. In general, the only functions which
237
    /// are safe to call with this pointer are those which are explicitly
238
    /// documented as being sound to use with an unaligned pointer, such as
239
    /// [`read_unaligned`].
240
    ///
241
    /// [`read_unaligned`]: core::ptr::read_unaligned
242
    // TODO(https://github.com/rust-lang/rust/issues/57349): Make this `const`.
243
    #[inline(always)]
244
0
    pub fn get_mut_ptr(&mut self) -> *mut T {
245
0
        ptr::addr_of_mut!(self.0)
246
0
    }
247
248
    /// Sets the inner `T`, dropping the previous value.
249
    // TODO(https://github.com/rust-lang/rust/issues/57349): Make this `const`.
250
    #[inline(always)]
251
0
    pub fn set(&mut self, t: T) {
252
0
        *self = Unalign::new(t);
253
0
    }
254
255
    /// Updates the inner `T` by calling a function on it.
256
    ///
257
    /// If [`T: Unaligned`], then `Unalign<T>` implements [`DerefMut`], and that
258
    /// impl should be preferred over this method when performing updates, as it
259
    /// will usually be faster and more ergonomic.
260
    ///
261
    /// For large types, this method may be expensive, as it requires copying
262
    /// `2 * size_of::<T>()` bytes. \[1\]
263
    ///
264
    /// \[1\] Since the inner `T` may not be aligned, it would not be sound to
265
    /// invoke `f` on it directly. Instead, `update` moves it into a
266
    /// properly-aligned location in the local stack frame, calls `f` on it, and
267
    /// then moves it back to its original location in `self`.
268
    ///
269
    /// [`T: Unaligned`]: Unaligned
270
    #[inline]
271
0
    pub fn update<O, F: FnOnce(&mut T) -> O>(&mut self, f: F) -> O {
272
        // On drop, this moves `copy` out of itself and uses `ptr::write` to
273
        // overwrite `slf`.
274
        struct WriteBackOnDrop<T> {
275
            copy: ManuallyDrop<T>,
276
            slf: *mut Unalign<T>,
277
        }
278
279
        impl<T> Drop for WriteBackOnDrop<T> {
280
0
            fn drop(&mut self) {
281
0
                // SAFETY: We never use `copy` again as required by
282
0
                // `ManuallyDrop::take`.
283
0
                let copy = unsafe { ManuallyDrop::take(&mut self.copy) };
284
0
                // SAFETY: `slf` is the raw pointer value of `self`. We know it
285
0
                // is valid for writes and properly aligned because `self` is a
286
0
                // mutable reference, which guarantees both of these properties.
287
0
                unsafe { ptr::write(self.slf, Unalign::new(copy)) };
288
0
            }
289
        }
290
291
        // SAFETY: We know that `self` is valid for reads, properly aligned, and
292
        // points to an initialized `Unalign<T>` because it is a mutable
293
        // reference, which guarantees all of these properties.
294
        //
295
        // Since `T: !Copy`, it would be unsound in the general case to allow
296
        // both the original `Unalign<T>` and the copy to be used by safe code.
297
        // We guarantee that the copy is used to overwrite the original in the
298
        // `Drop::drop` impl of `WriteBackOnDrop`. So long as this `drop` is
299
        // called before any other safe code executes, soundness is upheld.
300
        // While this method can terminate in two ways (by returning normally or
301
        // by unwinding due to a panic in `f`), in both cases, `write_back` is
302
        // dropped - and its `drop` called - before any other safe code can
303
        // execute.
304
0
        let copy = unsafe { ptr::read(self) }.into_inner();
305
0
        let mut write_back = WriteBackOnDrop { copy: ManuallyDrop::new(copy), slf: self };
306
0
307
0
        let ret = f(&mut write_back.copy);
308
0
309
0
        drop(write_back);
310
0
        ret
311
0
    }
312
}
313
314
impl<T: Copy> Unalign<T> {
315
    /// Gets a copy of the inner `T`.
316
    // TODO(https://github.com/rust-lang/rust/issues/57349): Make this `const`.
317
    #[inline(always)]
318
0
    pub fn get(&self) -> T {
319
0
        let Unalign(val) = *self;
320
0
        val
321
0
    }
322
}
323
324
impl<T: Unaligned> Deref for Unalign<T> {
325
    type Target = T;
326
327
    #[inline(always)]
328
0
    fn deref(&self) -> &T {
329
0
        // SAFETY: `deref_unchecked`'s safety requirement is that `self` is
330
0
        // aligned to `align_of::<T>()`. `T: Unaligned` guarantees that
331
0
        // `align_of::<T>() == 1`, and all pointers are one-aligned because all
332
0
        // addresses are divisible by 1.
333
0
        unsafe { self.deref_unchecked() }
334
0
    }
335
}
336
337
impl<T: Unaligned> DerefMut for Unalign<T> {
338
    #[inline(always)]
339
0
    fn deref_mut(&mut self) -> &mut T {
340
0
        // SAFETY: `deref_mut_unchecked`'s safety requirement is that `self` is
341
0
        // aligned to `align_of::<T>()`. `T: Unaligned` guarantees that
342
0
        // `align_of::<T>() == 1`, and all pointers are one-aligned because all
343
0
        // addresses are divisible by 1.
344
0
        unsafe { self.deref_mut_unchecked() }
345
0
    }
346
}
347
348
impl<T: Unaligned + PartialOrd> PartialOrd<Unalign<T>> for Unalign<T> {
349
    #[inline(always)]
350
0
    fn partial_cmp(&self, other: &Unalign<T>) -> Option<Ordering> {
351
0
        PartialOrd::partial_cmp(self.deref(), other.deref())
352
0
    }
353
}
354
355
impl<T: Unaligned + Ord> Ord for Unalign<T> {
356
    #[inline(always)]
357
0
    fn cmp(&self, other: &Unalign<T>) -> Ordering {
358
0
        Ord::cmp(self.deref(), other.deref())
359
0
    }
360
}
361
362
impl<T: Unaligned + PartialEq> PartialEq<Unalign<T>> for Unalign<T> {
363
    #[inline(always)]
364
0
    fn eq(&self, other: &Unalign<T>) -> bool {
365
0
        PartialEq::eq(self.deref(), other.deref())
366
0
    }
367
}
368
369
impl<T: Unaligned + Eq> Eq for Unalign<T> {}
370
371
impl<T: Unaligned + Hash> Hash for Unalign<T> {
372
    #[inline(always)]
373
0
    fn hash<H>(&self, state: &mut H)
374
0
    where
375
0
        H: Hasher,
376
0
    {
377
0
        self.deref().hash(state);
378
0
    }
379
}
380
381
impl<T: Unaligned + Debug> Debug for Unalign<T> {
382
    #[inline(always)]
383
0
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
384
0
        Debug::fmt(self.deref(), f)
385
0
    }
386
}
387
388
impl<T: Unaligned + Display> Display for Unalign<T> {
389
    #[inline(always)]
390
0
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
391
0
        Display::fmt(self.deref(), f)
392
0
    }
393
}
394
395
#[cfg(test)]
396
mod tests {
397
    use core::panic::AssertUnwindSafe;
398
399
    use super::*;
400
    use crate::util::testutil::*;
401
402
    /// A `T` which is guaranteed not to satisfy `align_of::<A>()`.
403
    ///
404
    /// It must be the case that `align_of::<T>() < align_of::<A>()` in order
405
    /// fot this type to work properly.
406
    #[repr(C)]
407
    struct ForceUnalign<T, A> {
408
        // The outer struct is aligned to `A`, and, thanks to `repr(C)`, `t` is
409
        // placed at the minimum offset that guarantees its alignment. If
410
        // `align_of::<T>() < align_of::<A>()`, then that offset will be
411
        // guaranteed *not* to satisfy `align_of::<A>()`.
412
        _u: u8,
413
        t: T,
414
        _a: [A; 0],
415
    }
416
417
    impl<T, A> ForceUnalign<T, A> {
418
        const fn new(t: T) -> ForceUnalign<T, A> {
419
            ForceUnalign { _u: 0, t, _a: [] }
420
        }
421
    }
422
423
    #[test]
424
    fn test_unalign() {
425
        // Test methods that don't depend on alignment.
426
        let mut u = Unalign::new(AU64(123));
427
        assert_eq!(u.get(), AU64(123));
428
        assert_eq!(u.into_inner(), AU64(123));
429
        assert_eq!(u.get_ptr(), <*const _>::cast::<AU64>(&u));
430
        assert_eq!(u.get_mut_ptr(), <*mut _>::cast::<AU64>(&mut u));
431
        u.set(AU64(321));
432
        assert_eq!(u.get(), AU64(321));
433
434
        // Test methods that depend on alignment (when alignment is satisfied).
435
        let mut u: Align<_, AU64> = Align::new(Unalign::new(AU64(123)));
436
        assert_eq!(u.t.try_deref(), Some(&AU64(123)));
437
        assert_eq!(u.t.try_deref_mut(), Some(&mut AU64(123)));
438
        // SAFETY: The `Align<_, AU64>` guarantees proper alignment.
439
        assert_eq!(unsafe { u.t.deref_unchecked() }, &AU64(123));
440
        // SAFETY: The `Align<_, AU64>` guarantees proper alignment.
441
        assert_eq!(unsafe { u.t.deref_mut_unchecked() }, &mut AU64(123));
442
        *u.t.try_deref_mut().unwrap() = AU64(321);
443
        assert_eq!(u.t.get(), AU64(321));
444
445
        // Test methods that depend on alignment (when alignment is not
446
        // satisfied).
447
        let mut u: ForceUnalign<_, AU64> = ForceUnalign::new(Unalign::new(AU64(123)));
448
        assert_eq!(u.t.try_deref(), None);
449
        assert_eq!(u.t.try_deref_mut(), None);
450
451
        // Test methods that depend on `T: Unaligned`.
452
        let mut u = Unalign::new(123u8);
453
        assert_eq!(u.try_deref(), Some(&123));
454
        assert_eq!(u.try_deref_mut(), Some(&mut 123));
455
        assert_eq!(u.deref(), &123);
456
        assert_eq!(u.deref_mut(), &mut 123);
457
        *u = 21;
458
        assert_eq!(u.get(), 21);
459
460
        // Test that some `Unalign` functions and methods are `const`.
461
        const _UNALIGN: Unalign<u64> = Unalign::new(0);
462
        const _UNALIGN_PTR: *const u64 = _UNALIGN.get_ptr();
463
        const _U64: u64 = _UNALIGN.into_inner();
464
        // Make sure all code is considered "used".
465
        //
466
        // TODO(https://github.com/rust-lang/rust/issues/104084): Remove this
467
        // attribute.
468
        #[allow(dead_code)]
469
        const _: () = {
470
            let x: Align<_, AU64> = Align::new(Unalign::new(AU64(123)));
471
            // Make sure that `deref_unchecked` is `const`.
472
            //
473
            // SAFETY: The `Align<_, AU64>` guarantees proper alignment.
474
            let au64 = unsafe { x.t.deref_unchecked() };
475
            match au64 {
476
                AU64(123) => {}
477
                _ => unreachable!(),
478
            }
479
        };
480
    }
481
482
    #[test]
483
    fn test_unalign_update() {
484
        let mut u = Unalign::new(AU64(123));
485
        u.update(|a| a.0 += 1);
486
        assert_eq!(u.get(), AU64(124));
487
488
        // Test that, even if the callback panics, the original is still
489
        // correctly overwritten. Use a `Box` so that Miri is more likely to
490
        // catch any unsoundness (which would likely result in two `Box`es for
491
        // the same heap object, which is the sort of thing that Miri would
492
        // probably catch).
493
        let mut u = Unalign::new(Box::new(AU64(123)));
494
        let res = std::panic::catch_unwind(AssertUnwindSafe(|| {
495
            u.update(|a| {
496
                a.0 += 1;
497
                panic!();
498
            })
499
        }));
500
        assert!(res.is_err());
501
        assert_eq!(u.into_inner(), Box::new(AU64(124)));
502
    }
503
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zeroize-1.8.1/src/lib.rs
Line
Count
Source
1
#![no_std]
2
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3
#![doc(
4
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
5
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
6
)]
7
#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
8
9
//! Securely zero memory with a simple trait ([`Zeroize`]) built on stable Rust
10
//! primitives which guarantee the operation will not be "optimized away".
11
//!
12
//! ## About
13
//!
14
//! [Zeroing memory securely is hard] - compilers optimize for performance, and
15
//! in doing so they love to "optimize away" unnecessary zeroing calls. There are
16
//! many documented "tricks" to attempt to avoid these optimizations and ensure
17
//! that a zeroing routine is performed reliably.
18
//!
19
//! This crate isn't about tricks: it uses [`core::ptr::write_volatile`]
20
//! and [`core::sync::atomic`] memory fences to provide easy-to-use, portable
21
//! zeroing behavior which works on all of Rust's core number types and slices
22
//! thereof, implemented in pure Rust with no usage of FFI or assembly.
23
//!
24
//! - No insecure fallbacks!
25
//! - No dependencies!
26
//! - No FFI or inline assembly! **WASM friendly** (and tested)!
27
//! - `#![no_std]` i.e. **embedded-friendly**!
28
//! - No functionality besides securely zeroing memory!
29
//! - (Optional) Custom derive support for zeroing complex structures
30
//!
31
//! ## Minimum Supported Rust Version
32
//!
33
//! Requires Rust **1.72** or newer.
34
//!
35
//! In the future, we reserve the right to change MSRV (i.e. MSRV is out-of-scope
36
//! for this crate's SemVer guarantees), however when we do it will be accompanied
37
//! by a minor version bump.
38
//!
39
//! ## Usage
40
//!
41
//! ```
42
//! use zeroize::Zeroize;
43
//!
44
//! // Protip: don't embed secrets in your source code.
45
//! // This is just an example.
46
//! let mut secret = b"Air shield password: 1,2,3,4,5".to_vec();
47
//! // [ ... ] open the air shield here
48
//!
49
//! // Now that we're done using the secret, zero it out.
50
//! secret.zeroize();
51
//! ```
52
//!
53
//! The [`Zeroize`] trait is impl'd on all of Rust's core scalar types including
54
//! integers, floats, `bool`, and `char`.
55
//!
56
//! Additionally, it's implemented on slices and `IterMut`s of the above types.
57
//!
58
//! When the `alloc` feature is enabled (which it is by default), it's also
59
//! impl'd for `Vec<T>` for the above types as well as `String`, where it provides
60
//! [`Vec::clear`] / [`String::clear`]-like behavior (truncating to zero-length)
61
//! but ensures the backing memory is securely zeroed with some caveats.
62
//!
63
//! With the `std` feature enabled (which it is **not** by default), [`Zeroize`]
64
//! is also implemented for [`CString`]. After calling `zeroize()` on a `CString`,
65
//! its internal buffer will contain exactly one nul byte. The backing
66
//! memory is zeroed by converting it to a `Vec<u8>` and back into a `CString`.
67
//! (NOTE: see "Stack/Heap Zeroing Notes" for important `Vec`/`String`/`CString` details)
68
//!
69
//! [`CString`]: https://doc.rust-lang.org/std/ffi/struct.CString.html
70
//!
71
//! The [`DefaultIsZeroes`] marker trait can be impl'd on types which also
72
//! impl [`Default`], which implements [`Zeroize`] by overwriting a value with
73
//! the default value.
74
//!
75
//! ## Custom Derive Support
76
//!
77
//! This crate has custom derive support for the `Zeroize` trait,
78
//! gated under the `zeroize` crate's `zeroize_derive` Cargo feature,
79
//! which automatically calls `zeroize()` on all members of a struct
80
//! or tuple struct.
81
//!
82
//! Attributes supported for `Zeroize`:
83
//!
84
//! On the item level:
85
//! - `#[zeroize(drop)]`: *deprecated* use `ZeroizeOnDrop` instead
86
//! - `#[zeroize(bound = "T: MyTrait")]`: this replaces any trait bounds
87
//!   inferred by zeroize
88
//!
89
//! On the field level:
90
//! - `#[zeroize(skip)]`: skips this field or variant when calling `zeroize()`
91
//!
92
//! Attributes supported for `ZeroizeOnDrop`:
93
//!
94
//! On the field level:
95
//! - `#[zeroize(skip)]`: skips this field or variant when calling `zeroize()`
96
//!
97
//! Example which derives `Drop`:
98
//!
99
//! ```
100
//! # #[cfg(feature = "zeroize_derive")]
101
//! # {
102
//! use zeroize::{Zeroize, ZeroizeOnDrop};
103
//!
104
//! // This struct will be zeroized on drop
105
//! #[derive(Zeroize, ZeroizeOnDrop)]
106
//! struct MyStruct([u8; 32]);
107
//! # }
108
//! ```
109
//!
110
//! Example which does not derive `Drop` (useful for e.g. `Copy` types)
111
//!
112
//! ```
113
//! #[cfg(feature = "zeroize_derive")]
114
//! # {
115
//! use zeroize::Zeroize;
116
//!
117
//! // This struct will *NOT* be zeroized on drop
118
//! #[derive(Copy, Clone, Zeroize)]
119
//! struct MyStruct([u8; 32]);
120
//! # }
121
//! ```
122
//!
123
//! Example which only derives `Drop`:
124
//!
125
//! ```
126
//! # #[cfg(feature = "zeroize_derive")]
127
//! # {
128
//! use zeroize::ZeroizeOnDrop;
129
//!
130
//! // This struct will be zeroized on drop
131
//! #[derive(ZeroizeOnDrop)]
132
//! struct MyStruct([u8; 32]);
133
//! # }
134
//! ```
135
//!
136
//! ## `Zeroizing<Z>`: wrapper for zeroizing arbitrary values on drop
137
//!
138
//! `Zeroizing<Z: Zeroize>` is a generic wrapper type that impls `Deref`
139
//! and `DerefMut`, allowing access to an inner value of type `Z`, and also
140
//! impls a `Drop` handler which calls `zeroize()` on its contents:
141
//!
142
//! ```
143
//! use zeroize::Zeroizing;
144
//!
145
//! fn use_secret() {
146
//!     let mut secret = Zeroizing::new([0u8; 5]);
147
//!
148
//!     // Set the air shield password
149
//!     // Protip (again): don't embed secrets in your source code.
150
//!     secret.copy_from_slice(&[1, 2, 3, 4, 5]);
151
//!     assert_eq!(secret.as_ref(), &[1, 2, 3, 4, 5]);
152
//!
153
//!     // The contents of `secret` will be automatically zeroized on drop
154
//! }
155
//!
156
//! # use_secret()
157
//! ```
158
//!
159
//! ## What guarantees does this crate provide?
160
//!
161
//! This crate guarantees the following:
162
//!
163
//! 1. The zeroing operation can't be "optimized away" by the compiler.
164
//! 2. All subsequent reads to memory will see "zeroized" values.
165
//!
166
//! LLVM's volatile semantics ensure #1 is true.
167
//!
168
//! Additionally, thanks to work by the [Unsafe Code Guidelines Working Group],
169
//! we can now fairly confidently say #2 is true as well. Previously there were
170
//! worries that the approach used by this crate (mixing volatile and
171
//! non-volatile accesses) was undefined behavior due to language contained
172
//! in the documentation for `write_volatile`, however after some discussion
173
//! [these remarks have been removed] and the specific usage pattern in this
174
//! crate is considered to be well-defined.
175
//!
176
//! Additionally this crate leverages [`core::sync::atomic::compiler_fence`]
177
//! with the strictest ordering
178
//! ([`Ordering::SeqCst`]) as a
179
//! precaution to help ensure reads are not reordered before memory has been
180
//! zeroed.
181
//!
182
//! All of that said, there is still potential for microarchitectural attacks
183
//! (ala Spectre/Meltdown) to leak "zeroized" secrets through covert channels.
184
//! This crate makes no guarantees that zeroized values cannot be leaked
185
//! through such channels, as they represent flaws in the underlying hardware.
186
//!
187
//! ## Stack/Heap Zeroing Notes
188
//!
189
//! This crate can be used to zero values from either the stack or the heap.
190
//!
191
//! However, be aware several operations in Rust can unintentionally leave
192
//! copies of data in memory. This includes but is not limited to:
193
//!
194
//! - Moves and [`Copy`]
195
//! - Heap reallocation when using [`Vec`] and [`String`]
196
//! - Borrowers of a reference making copies of the data
197
//!
198
//! [`Pin`][`core::pin::Pin`] can be leveraged in conjunction with this crate
199
//! to ensure data kept on the stack isn't moved.
200
//!
201
//! The `Zeroize` impls for `Vec`, `String` and `CString` zeroize the entire
202
//! capacity of their backing buffer, but cannot guarantee copies of the data
203
//! were not previously made by buffer reallocation. It's therefore important
204
//! when attempting to zeroize such buffers to initialize them to the correct
205
//! capacity, and take care to prevent subsequent reallocation.
206
//!
207
//! The `secrecy` crate provides higher-level abstractions for eliminating
208
//! usage patterns which can cause reallocations:
209
//!
210
//! <https://crates.io/crates/secrecy>
211
//!
212
//! ## What about: clearing registers, mlock, mprotect, etc?
213
//!
214
//! This crate is focused on providing simple, unobtrusive support for reliably
215
//! zeroing memory using the best approach possible on stable Rust.
216
//!
217
//! Clearing registers is a difficult problem that can't easily be solved by
218
//! something like a crate, and requires either inline ASM or rustc support.
219
//! See <https://github.com/rust-lang/rust/issues/17046> for background on
220
//! this particular problem.
221
//!
222
//! Other memory protection mechanisms are interesting and useful, but often
223
//! overkill (e.g. defending against RAM scraping or attackers with swap access).
224
//! In as much as there may be merit to these approaches, there are also many
225
//! other crates that already implement more sophisticated memory protections.
226
//! Such protections are explicitly out-of-scope for this crate.
227
//!
228
//! Zeroing memory is [good cryptographic hygiene] and this crate seeks to promote
229
//! it in the most unobtrusive manner possible. This includes omitting complex
230
//! `unsafe` memory protection systems and just trying to make the best memory
231
//! zeroing crate available.
232
//!
233
//! [Zeroing memory securely is hard]: http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
234
//! [Unsafe Code Guidelines Working Group]: https://github.com/rust-lang/unsafe-code-guidelines
235
//! [these remarks have been removed]: https://github.com/rust-lang/rust/pull/60972
236
//! [good cryptographic hygiene]: https://github.com/veorq/cryptocoding#clean-memory-of-secret-data
237
//! [`Ordering::SeqCst`]: core::sync::atomic::Ordering::SeqCst
238
239
#[cfg(feature = "alloc")]
240
extern crate alloc;
241
242
#[cfg(feature = "std")]
243
extern crate std;
244
245
#[cfg(feature = "zeroize_derive")]
246
pub use zeroize_derive::{Zeroize, ZeroizeOnDrop};
247
248
#[cfg(target_arch = "aarch64")]
249
mod aarch64;
250
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
251
mod x86;
252
253
use core::{
254
    marker::{PhantomData, PhantomPinned},
255
    mem::{self, MaybeUninit},
256
    num::{
257
        self, NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize,
258
        NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
259
    },
260
    ops, ptr,
261
    slice::IterMut,
262
    sync::atomic,
263
};
264
265
#[cfg(feature = "alloc")]
266
use alloc::{boxed::Box, string::String, vec::Vec};
267
268
#[cfg(feature = "std")]
269
use std::ffi::CString;
270
271
/// Trait for securely erasing values from memory.
272
pub trait Zeroize {
273
    /// Zero out this object from memory using Rust intrinsics which ensure the
274
    /// zeroization operation is not "optimized away" by the compiler.
275
    fn zeroize(&mut self);
276
}
277
278
/// Marker trait signifying that this type will [`Zeroize::zeroize`] itself on [`Drop`].
279
pub trait ZeroizeOnDrop {}
280
281
/// Marker trait for types whose [`Default`] is the desired zeroization result
282
pub trait DefaultIsZeroes: Copy + Default + Sized {}
283
284
/// Fallible trait for representing cases where zeroization may or may not be
285
/// possible.
286
///
287
/// This is primarily useful for scenarios like reference counted data, where
288
/// zeroization is only possible when the last reference is dropped.
289
pub trait TryZeroize {
290
    /// Try to zero out this object from memory using Rust intrinsics which
291
    /// ensure the zeroization operation is not "optimized away" by the
292
    /// compiler.
293
    #[must_use]
294
    fn try_zeroize(&mut self) -> bool;
295
}
296
297
impl<Z> Zeroize for Z
298
where
299
    Z: DefaultIsZeroes,
300
{
301
0
    fn zeroize(&mut self) {
302
0
        volatile_write(self, Z::default());
303
0
        atomic_fence();
304
0
    }
Unexecuted instantiation: _RNvXCs6qnKa1vNaZb_7zeroizehNtB2_7Zeroize7zeroizeCscC7OSmV1s5f_4blst
Unexecuted instantiation: _RNvXCs6qnKa1vNaZb_7zeroizehNtB2_7Zeroize7zeroizeCscrZQdumITES_3der
Unexecuted instantiation: _RNvXCs6qnKa1vNaZb_7zeroizeINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1ENtB2_7Zeroize7zeroizeB1z_
Unexecuted instantiation: _RNvXCs6qnKa1vNaZb_7zeroizeNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarNtB2_7Zeroize7zeroizeBu_
Unexecuted instantiation: _RNvXCs6qnKa1vNaZb_7zeroizebNtB2_7Zeroize7zeroizeCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXCs6qnKa1vNaZb_7zeroizemNtB2_7Zeroize7zeroizeCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXCs6qnKa1vNaZb_7zeroizeyNtB2_7Zeroize7zeroizeCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXCs6qnKa1vNaZb_7zeroizehNtB2_7Zeroize7zeroizeB2_
305
}
306
307
macro_rules! impl_zeroize_with_default {
308
    ($($type:ty),+) => {
309
        $(impl DefaultIsZeroes for $type {})+
310
    };
311
}
312
313
#[rustfmt::skip]
314
impl_zeroize_with_default! {
315
    PhantomPinned, (), bool, char,
316
    f32, f64,
317
    i8, i16, i32, i64, i128, isize,
318
    u8, u16, u32, u64, u128, usize
319
}
320
321
/// `PhantomPinned` is zero sized so provide a ZeroizeOnDrop implementation.
322
impl ZeroizeOnDrop for PhantomPinned {}
323
324
/// `()` is zero sized so provide a ZeroizeOnDrop implementation.
325
impl ZeroizeOnDrop for () {}
326
327
macro_rules! impl_zeroize_for_non_zero {
328
    ($($type:ty),+) => {
329
        $(
330
            impl Zeroize for $type {
331
0
                fn zeroize(&mut self) {
332
                    const ONE: $type = match <$type>::new(1) {
333
                        Some(one) => one,
334
                        None => unreachable!(),
335
                    };
336
0
                    volatile_write(self, ONE);
337
0
                    atomic_fence();
338
0
                }
Unexecuted instantiation: _RNvXsL_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaENtB5_7Zeroize7zeroize
Unexecuted instantiation: _RNvXsM_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosENtB5_7Zeroize7zeroize
Unexecuted instantiation: _RNvXsN_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolENtB5_7Zeroize7zeroize
Unexecuted instantiation: _RNvXsO_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxENtB5_7Zeroize7zeroize
Unexecuted instantiation: _RNvXsP_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronENtB5_7Zeroize7zeroize
Unexecuted instantiation: _RNvXsQ_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiENtB5_7Zeroize7zeroize
Unexecuted instantiation: _RNvXsR_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohENtB5_7Zeroize7zeroize
Unexecuted instantiation: _RNvXsS_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotENtB5_7Zeroize7zeroize
Unexecuted instantiation: _RNvXsT_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromENtB5_7Zeroize7zeroize
Unexecuted instantiation: _RNvXsU_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyENtB5_7Zeroize7zeroize
Unexecuted instantiation: _RNvXsV_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooENtB5_7Zeroize7zeroize
Unexecuted instantiation: _RNvXsW_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojENtB5_7Zeroize7zeroize
339
            }
340
        )+
341
    };
342
}
343
344
impl_zeroize_for_non_zero!(
345
    NonZeroI8,
346
    NonZeroI16,
347
    NonZeroI32,
348
    NonZeroI64,
349
    NonZeroI128,
350
    NonZeroIsize,
351
    NonZeroU8,
352
    NonZeroU16,
353
    NonZeroU32,
354
    NonZeroU64,
355
    NonZeroU128,
356
    NonZeroUsize
357
);
358
359
impl<Z> Zeroize for num::Wrapping<Z>
360
where
361
    Z: Zeroize,
362
{
363
0
    fn zeroize(&mut self) {
364
0
        self.0.zeroize();
365
0
    }
366
}
367
368
/// Impl [`Zeroize`] on arrays of types that impl [`Zeroize`].
369
impl<Z, const N: usize> Zeroize for [Z; N]
370
where
371
    Z: Zeroize,
372
{
373
0
    fn zeroize(&mut self) {
374
0
        self.iter_mut().zeroize();
375
0
    }
Unexecuted instantiation: _RNvXs2_Cs6qnKa1vNaZb_7zeroizeAhj20_NtB5_7Zeroize7zeroizeCscC7OSmV1s5f_4blst
Unexecuted instantiation: _RNvXs2_Cs6qnKa1vNaZb_7zeroizeAyj5_NtB5_7Zeroize7zeroizeCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXINICs6qnKa1vNaZb_7zeroizes2_0pKpEAppNtB5_7Zeroize7zeroizeB5_
376
}
377
378
/// Impl [`ZeroizeOnDrop`] on arrays of types that impl [`ZeroizeOnDrop`].
379
impl<Z, const N: usize> ZeroizeOnDrop for [Z; N] where Z: ZeroizeOnDrop {}
380
381
impl<Z> Zeroize for IterMut<'_, Z>
382
where
383
    Z: Zeroize,
384
{
385
0
    fn zeroize(&mut self) {
386
0
        for elem in self {
387
0
            elem.zeroize();
388
0
        }
389
0
    }
Unexecuted instantiation: _RNvXs4_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core5slice4iter7IterMuthENtB5_7Zeroize7zeroizeCscC7OSmV1s5f_4blst
Unexecuted instantiation: _RNvXs4_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core5slice4iter7IterMuthENtB5_7Zeroize7zeroizeCscrZQdumITES_3der
Unexecuted instantiation: _RNvXs4_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core5slice4iter7IterMutyENtB5_7Zeroize7zeroizeCsjewTDwKBbyD_4k256
Unexecuted instantiation: _RNvXs4_Cs6qnKa1vNaZb_7zeroizeINtNtNtCsbQ8arDwx5Xq_4core5slice4iter7IterMuthENtB5_7Zeroize7zeroizeB5_
390
}
391
392
impl<Z> Zeroize for Option<Z>
393
where
394
    Z: Zeroize,
395
{
396
0
    fn zeroize(&mut self) {
397
0
        if let Some(value) = self {
398
0
            value.zeroize();
399
0
400
0
            // Ensures self is None and that the value was dropped. Without the take, the drop
401
0
            // of the (zeroized) value isn't called, which might lead to a leak or other
402
0
            // unexpected behavior. For example, if this were Option<Vec<T>>, the above call to
403
0
            // zeroize would not free the allocated memory, but the the `take` call will.
404
0
            self.take();
405
0
        }
406
407
        // Ensure that if the `Option` were previously `Some` but a value was copied/moved out
408
        // that the remaining space in the `Option` is zeroized.
409
        //
410
        // Safety:
411
        //
412
        // The memory pointed to by `self` is valid for `mem::size_of::<Self>()` bytes.
413
        // It is also properly aligned, because `u8` has an alignment of `1`.
414
0
        unsafe {
415
0
            volatile_set((self as *mut Self).cast::<u8>(), 0, mem::size_of::<Self>());
416
0
        }
417
0
418
0
        // Ensures self is overwritten with the `None` bit pattern. volatile_write can't be
419
0
        // used because Option<Z> is not copy.
420
0
        //
421
0
        // Safety:
422
0
        //
423
0
        // self is safe to replace with `None`, which the take() call above should have
424
0
        // already done semantically. Any value which needed to be dropped will have been
425
0
        // done so by take().
426
0
        unsafe { ptr::write_volatile(self, None) }
427
0
428
0
        atomic_fence();
429
0
    }
430
}
431
432
impl<Z> ZeroizeOnDrop for Option<Z> where Z: ZeroizeOnDrop {}
433
434
/// Impl [`Zeroize`] on [`MaybeUninit`] types.
435
///
436
/// This fills the memory with zeroes.
437
/// Note that this ignore invariants that `Z` might have, because
438
/// [`MaybeUninit`] removes all invariants.
439
impl<Z> Zeroize for MaybeUninit<Z> {
440
0
    fn zeroize(&mut self) {
441
0
        // Safety:
442
0
        // `MaybeUninit` is valid for any byte pattern, including zeros.
443
0
        unsafe { ptr::write_volatile(self, MaybeUninit::zeroed()) }
444
0
        atomic_fence();
445
0
    }
446
}
447
448
/// Impl [`Zeroize`] on slices of [`MaybeUninit`] types.
449
///
450
/// This impl can eventually be optimized using an memset intrinsic,
451
/// such as [`core::intrinsics::volatile_set_memory`].
452
///
453
/// This fills the slice with zeroes.
454
///
455
/// Note that this ignore invariants that `Z` might have, because
456
/// [`MaybeUninit`] removes all invariants.
457
impl<Z> Zeroize for [MaybeUninit<Z>] {
458
0
    fn zeroize(&mut self) {
459
0
        let ptr = self.as_mut_ptr().cast::<MaybeUninit<u8>>();
460
0
        let size = self.len().checked_mul(mem::size_of::<Z>()).unwrap();
461
0
        assert!(size <= isize::MAX as usize);
462
463
        // Safety:
464
        //
465
        // This is safe, because every valid pointer is well aligned for u8
466
        // and it is backed by a single allocated object for at least `self.len() * size_pf::<Z>()` bytes.
467
        // and 0 is a valid value for `MaybeUninit<Z>`
468
        // The memory of the slice should not wrap around the address space.
469
0
        unsafe { volatile_set(ptr, MaybeUninit::zeroed(), size) }
470
0
        atomic_fence();
471
0
    }
Unexecuted instantiation: _RNvXs8_Cs6qnKa1vNaZb_7zeroizeSINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninithENtB5_7Zeroize7zeroizeCscrZQdumITES_3der
Unexecuted instantiation: _RNvXs8_Cs6qnKa1vNaZb_7zeroizeSINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninithENtB5_7Zeroize7zeroizeB5_
472
}
473
474
/// Impl [`Zeroize`] on slices of types that can be zeroized with [`Default`].
475
///
476
/// This impl can eventually be optimized using an memset intrinsic,
477
/// such as [`core::intrinsics::volatile_set_memory`]. For that reason the
478
/// blanket impl on slices is bounded by [`DefaultIsZeroes`].
479
///
480
/// To zeroize a mut slice of `Z: Zeroize` which does not impl
481
/// [`DefaultIsZeroes`], call `iter_mut().zeroize()`.
482
impl<Z> Zeroize for [Z]
483
where
484
    Z: DefaultIsZeroes,
485
{
486
0
    fn zeroize(&mut self) {
487
0
        assert!(self.len() <= isize::MAX as usize);
488
489
        // Safety:
490
        //
491
        // This is safe, because the slice is well aligned and is backed by a single allocated
492
        // object for at least `self.len()` elements of type `Z`.
493
        // `self.len()` is also not larger than an `isize`, because of the assertion above.
494
        // The memory of the slice should not wrap around the address space.
495
0
        unsafe { volatile_set(self.as_mut_ptr(), Z::default(), self.len()) };
496
0
        atomic_fence();
497
0
    }
498
}
499
500
impl Zeroize for str {
501
0
    fn zeroize(&mut self) {
502
0
        // Safety:
503
0
        // A zeroized byte slice is a valid UTF-8 string.
504
0
        unsafe { self.as_bytes_mut().zeroize() }
505
0
    }
506
}
507
508
/// [`PhantomData`] is always zero sized so provide a [`Zeroize`] implementation.
509
impl<Z> Zeroize for PhantomData<Z> {
510
0
    fn zeroize(&mut self) {}
511
}
512
513
/// [`PhantomData` is always zero sized so provide a ZeroizeOnDrop implementation.
514
impl<Z> ZeroizeOnDrop for PhantomData<Z> {}
515
516
macro_rules! impl_zeroize_tuple {
517
    ( $( $type_name:ident ),+ ) => {
518
        impl<$($type_name: Zeroize),+> Zeroize for ($($type_name,)+) {
519
0
            fn zeroize(&mut self) {
520
0
                #[allow(non_snake_case)]
521
0
                let ($($type_name,)+) = self;
522
0
                $($type_name.zeroize());+
523
0
            }
Unexecuted instantiation: _RNvXINICs6qnKa1vNaZb_7zeroizesX_0pETpENtB5_7Zeroize7zeroizeB5_
Unexecuted instantiation: _RNvXINICs6qnKa1vNaZb_7zeroizesZ_0ppETppENtB5_7Zeroize7zeroizeB5_
Unexecuted instantiation: _RNvXINICs6qnKa1vNaZb_7zeroizes11_0pppETpppENtB5_7Zeroize7zeroizeB5_
Unexecuted instantiation: _RNvXINICs6qnKa1vNaZb_7zeroizes13_0ppppETppppENtB5_7Zeroize7zeroizeB5_
Unexecuted instantiation: _RNvXINICs6qnKa1vNaZb_7zeroizes15_0pppppETpppppENtB5_7Zeroize7zeroizeB5_
Unexecuted instantiation: _RNvXINICs6qnKa1vNaZb_7zeroizes17_0ppppppETppppppENtB5_7Zeroize7zeroizeB5_
Unexecuted instantiation: _RNvXINICs6qnKa1vNaZb_7zeroizes19_0pppppppETpppppppENtB5_7Zeroize7zeroizeB5_
Unexecuted instantiation: _RNvXINICs6qnKa1vNaZb_7zeroizes1b_0ppppppppETppppppppENtB5_7Zeroize7zeroizeB5_
Unexecuted instantiation: _RNvXINICs6qnKa1vNaZb_7zeroizes1d_0pppppppppETpppppppppENtB5_7Zeroize7zeroizeB5_
Unexecuted instantiation: _RNvXINICs6qnKa1vNaZb_7zeroizes1f_0ppppppppppETppppppppppENtB5_7Zeroize7zeroizeB5_
524
        }
525
526
        impl<$($type_name: ZeroizeOnDrop),+> ZeroizeOnDrop for ($($type_name,)+) { }
527
    }
528
}
529
530
// Generic implementations for tuples up to 10 parameters.
531
impl_zeroize_tuple!(A);
532
impl_zeroize_tuple!(A, B);
533
impl_zeroize_tuple!(A, B, C);
534
impl_zeroize_tuple!(A, B, C, D);
535
impl_zeroize_tuple!(A, B, C, D, E);
536
impl_zeroize_tuple!(A, B, C, D, E, F);
537
impl_zeroize_tuple!(A, B, C, D, E, F, G);
538
impl_zeroize_tuple!(A, B, C, D, E, F, G, H);
539
impl_zeroize_tuple!(A, B, C, D, E, F, G, H, I);
540
impl_zeroize_tuple!(A, B, C, D, E, F, G, H, I, J);
541
542
#[cfg(feature = "alloc")]
543
impl<Z> Zeroize for Vec<Z>
544
where
545
    Z: Zeroize,
546
{
547
    /// "Best effort" zeroization for `Vec`.
548
    ///
549
    /// Ensures the entire capacity of the `Vec` is zeroed. Cannot ensure that
550
    /// previous reallocations did not leave values on the heap.
551
0
    fn zeroize(&mut self) {
552
0
        // Zeroize all the initialized elements.
553
0
        self.iter_mut().zeroize();
554
0
555
0
        // Set the Vec's length to 0 and drop all the elements.
556
0
        self.clear();
557
0
558
0
        // Zero the full capacity of `Vec`.
559
0
        self.spare_capacity_mut().zeroize();
560
0
    }
Unexecuted instantiation: _RNvXsd_Cs6qnKa1vNaZb_7zeroizeINtNtCsiBl6Lc3cFal_5alloc3vec3VechENtB5_7Zeroize7zeroizeCscrZQdumITES_3der
Unexecuted instantiation: _RNvXsd_Cs6qnKa1vNaZb_7zeroizeINtNtCsiBl6Lc3cFal_5alloc3vec3VechENtB5_7Zeroize7zeroizeB5_
561
}
562
563
#[cfg(feature = "alloc")]
564
impl<Z> ZeroizeOnDrop for Vec<Z> where Z: ZeroizeOnDrop {}
565
566
#[cfg(feature = "alloc")]
567
impl<Z> Zeroize for Box<[Z]>
568
where
569
    Z: Zeroize,
570
{
571
    /// Unlike `Vec`, `Box<[Z]>` cannot reallocate, so we can be sure that we are not leaving
572
    /// values on the heap.
573
0
    fn zeroize(&mut self) {
574
0
        self.iter_mut().zeroize();
575
0
    }
576
}
577
578
#[cfg(feature = "alloc")]
579
impl<Z> ZeroizeOnDrop for Box<[Z]> where Z: ZeroizeOnDrop {}
580
581
#[cfg(feature = "alloc")]
582
impl Zeroize for Box<str> {
583
0
    fn zeroize(&mut self) {
584
0
        self.as_mut().zeroize();
585
0
    }
586
}
587
588
#[cfg(feature = "alloc")]
589
impl Zeroize for String {
590
0
    fn zeroize(&mut self) {
591
0
        unsafe { self.as_mut_vec() }.zeroize();
592
0
    }
593
}
594
595
#[cfg(feature = "std")]
596
impl Zeroize for CString {
597
    fn zeroize(&mut self) {
598
        // mem::take uses replace internally to swap the pointer
599
        // Unfortunately this results in an allocation for a Box::new(&[0]) as CString must
600
        // contain a trailing zero byte
601
        let this = mem::take(self);
602
603
        // - CString::into_bytes_with_nul calls ::into_vec which takes ownership of the heap pointer
604
        // as a Vec<u8>
605
        // - Calling .zeroize() on the resulting vector clears out the bytes
606
        // From: https://github.com/RustCrypto/utils/pull/759#issuecomment-1087976570
607
        let mut buf = this.into_bytes_with_nul();
608
        buf.zeroize();
609
610
        // expect() should never fail, because zeroize() truncates the Vec
611
        let zeroed = CString::new(buf).expect("buf not truncated");
612
613
        // Replace self by the zeroed CString to maintain the original ptr of the buffer
614
        let _ = mem::replace(self, zeroed);
615
    }
616
}
617
618
/// `Zeroizing` is a a wrapper for any `Z: Zeroize` type which implements a
619
/// `Drop` handler which zeroizes dropped values.
620
#[derive(Debug, Default, Eq, PartialEq)]
621
pub struct Zeroizing<Z: Zeroize>(Z);
622
623
impl<Z> Zeroizing<Z>
624
where
625
    Z: Zeroize,
626
{
627
    /// Move value inside a `Zeroizing` wrapper which ensures it will be
628
    /// zeroized when it's dropped.
629
    #[inline(always)]
630
0
    pub fn new(value: Z) -> Self {
631
0
        Self(value)
632
0
    }
Unexecuted instantiation: _RNvMsj_Cs6qnKa1vNaZb_7zeroizeINtB5_9ZeroizingNtNtCsiBl6Lc3cFal_5alloc6string6StringE3newCscrZQdumITES_3der
Unexecuted instantiation: _RNvMsj_Cs6qnKa1vNaZb_7zeroizeINtB5_9ZeroizingINtNtCsiBl6Lc3cFal_5alloc3vec3VechEE3newCscrZQdumITES_3der
Unexecuted instantiation: _RNvMsj_Cs6qnKa1vNaZb_7zeroizeINtB5_9ZeroizingpE3newB5_
633
}
634
635
impl<Z: Zeroize + Clone> Clone for Zeroizing<Z> {
636
    #[inline(always)]
637
0
    fn clone(&self) -> Self {
638
0
        Self(self.0.clone())
639
0
    }
640
641
    #[inline(always)]
642
0
    fn clone_from(&mut self, source: &Self) {
643
0
        self.0.zeroize();
644
0
        self.0.clone_from(&source.0);
645
0
    }
646
}
647
648
impl<Z> From<Z> for Zeroizing<Z>
649
where
650
    Z: Zeroize,
651
{
652
    #[inline(always)]
653
0
    fn from(value: Z) -> Zeroizing<Z> {
654
0
        Zeroizing(value)
655
0
    }
656
}
657
658
impl<Z> ops::Deref for Zeroizing<Z>
659
where
660
    Z: Zeroize,
661
{
662
    type Target = Z;
663
664
    #[inline(always)]
665
0
    fn deref(&self) -> &Z {
666
0
        &self.0
667
0
    }
668
}
669
670
impl<Z> ops::DerefMut for Zeroizing<Z>
671
where
672
    Z: Zeroize,
673
{
674
    #[inline(always)]
675
0
    fn deref_mut(&mut self) -> &mut Z {
676
0
        &mut self.0
677
0
    }
678
}
679
680
impl<T, Z> AsRef<T> for Zeroizing<Z>
681
where
682
    T: ?Sized,
683
    Z: AsRef<T> + Zeroize,
684
{
685
    #[inline(always)]
686
0
    fn as_ref(&self) -> &T {
687
0
        self.0.as_ref()
688
0
    }
689
}
690
691
impl<T, Z> AsMut<T> for Zeroizing<Z>
692
where
693
    T: ?Sized,
694
    Z: AsMut<T> + Zeroize,
695
{
696
    #[inline(always)]
697
0
    fn as_mut(&mut self) -> &mut T {
698
0
        self.0.as_mut()
699
0
    }
700
}
701
702
impl<Z> Zeroize for Zeroizing<Z>
703
where
704
    Z: Zeroize,
705
{
706
0
    fn zeroize(&mut self) {
707
0
        self.0.zeroize();
708
0
    }
709
}
710
711
impl<Z> ZeroizeOnDrop for Zeroizing<Z> where Z: Zeroize {}
712
713
impl<Z> Drop for Zeroizing<Z>
714
where
715
    Z: Zeroize,
716
{
717
0
    fn drop(&mut self) {
718
0
        self.0.zeroize()
719
0
    }
720
}
721
722
#[cfg(feature = "serde")]
723
impl<Z> serde::Serialize for Zeroizing<Z>
724
where
725
    Z: Zeroize + serde::Serialize,
726
{
727
    #[inline(always)]
728
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
729
    where
730
        S: serde::Serializer,
731
    {
732
        self.0.serialize(serializer)
733
    }
734
}
735
736
#[cfg(feature = "serde")]
737
impl<'de, Z> serde::Deserialize<'de> for Zeroizing<Z>
738
where
739
    Z: Zeroize + serde::Deserialize<'de>,
740
{
741
    #[inline(always)]
742
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
743
    where
744
        D: serde::Deserializer<'de>,
745
    {
746
        Ok(Self(Z::deserialize(deserializer)?))
747
    }
748
}
749
750
/// Use fences to prevent accesses from being reordered before this
751
/// point, which should hopefully help ensure that all accessors
752
/// see zeroes after this point.
753
#[inline(always)]
754
0
fn atomic_fence() {
755
0
    atomic::compiler_fence(atomic::Ordering::SeqCst);
756
0
}
757
758
/// Perform a volatile write to the destination
759
#[inline(always)]
760
0
fn volatile_write<T: Copy + Sized>(dst: &mut T, src: T) {
761
0
    unsafe { ptr::write_volatile(dst, src) }
762
0
}
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writehECscC7OSmV1s5f_4blst
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writehECscrZQdumITES_3der
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCs8yVsO3EKNkV_14elliptic_curve6scalar9primitive15ScalarPrimitiveNtCsjewTDwKBbyD_4k2569Secp256k1EEB1P_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeNtNtNtCsjewTDwKBbyD_4k25610arithmetic6scalar6ScalarEBK_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writebECsjewTDwKBbyD_4k256
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writemECsjewTDwKBbyD_4k256
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeyECsjewTDwKBbyD_4k256
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writehEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128EB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256EB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeNtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroaEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerosEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerolEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroxEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeronEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroiEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerohEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerotEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeromEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZeroyEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerooEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize14volatile_writeINtNtNtCsbQ8arDwx5Xq_4core3num7nonzero7NonZerojEEB2_
763
764
/// Perform a volatile `memset` operation which fills a slice with a value
765
///
766
/// Safety:
767
/// The memory pointed to by `dst` must be a single allocated object that is valid for `count`
768
/// contiguous elements of `T`.
769
/// `count` must not be larger than an `isize`.
770
/// `dst` being offset by `mem::size_of::<T> * count` bytes must not wrap around the address space.
771
/// Also `dst` must be properly aligned.
772
#[inline(always)]
773
0
unsafe fn volatile_set<T: Copy + Sized>(dst: *mut T, src: T, count: usize) {
774
    // TODO(tarcieri): use `volatile_set_memory` when stabilized
775
0
    for i in 0..count {
776
0
        // Safety:
777
0
        //
778
0
        // This is safe because there is room for at least `count` objects of type `T` in the
779
0
        // allocation pointed to by `dst`, because `count <= isize::MAX` and because
780
0
        // `dst.add(count)` must not wrap around the address space.
781
0
        let ptr = dst.add(i);
782
0
783
0
        // Safety:
784
0
        //
785
0
        // This is safe, because the pointer is valid and because `dst` is well aligned for `T` and
786
0
        // `ptr` is an offset of `dst` by a multiple of `mem::size_of::<T>()` bytes.
787
0
        ptr::write_volatile(ptr, src);
788
0
    }
789
0
}
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize12volatile_setINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninithEECscrZQdumITES_3der
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize12volatile_setINtNtNtCsbQ8arDwx5Xq_4core3mem12maybe_uninit11MaybeUninithEEB2_
Unexecuted instantiation: _RINvCs6qnKa1vNaZb_7zeroize12volatile_sethEB2_
790
791
/// Zeroizes a flat type/struct. Only zeroizes the values that it owns, and it does not work on
792
/// dynamically sized values or trait objects. It would be inefficient to use this function on a
793
/// type that already implements `ZeroizeOnDrop`.
794
///
795
/// # Safety
796
/// - The type must not contain references to outside data or dynamically sized data, such as
797
///   `Vec<T>` or `String`.
798
/// - Values stored in the type must not have `Drop` impls.
799
/// - This function can invalidate the type if it is used after this function is called on it.
800
///   It is advisable to call this function only in `impl Drop`.
801
/// - The bit pattern of all zeroes must be valid for the data being zeroized. This may not be
802
///   true for enums and pointers.
803
///
804
/// # Incompatible data types
805
/// Some data types that cannot be safely zeroized using `zeroize_flat_type` include,
806
/// but are not limited to:
807
/// - References: `&T` and `&mut T`
808
/// - Non-nullable types: `NonNull<T>`, `NonZeroU32`, etc.
809
/// - Enums with explicit non-zero tags.
810
/// - Smart pointers and collections: `Arc<T>`, `Box<T>`, `Vec<T>`, `HashMap<K, V>`, `String`, etc.
811
///
812
/// # Examples
813
/// Safe usage for a struct containing strictly flat data:
814
/// ```
815
/// use zeroize::{ZeroizeOnDrop, zeroize_flat_type};
816
///
817
/// struct DataToZeroize {
818
///     flat_data_1: [u8; 32],
819
///     flat_data_2: SomeMoreFlatData,
820
/// }
821
///
822
/// struct SomeMoreFlatData(u64);
823
///
824
/// impl Drop for DataToZeroize {
825
///     fn drop(&mut self) {
826
///         unsafe { zeroize_flat_type(self as *mut Self) }
827
///     }
828
/// }
829
/// impl ZeroizeOnDrop for DataToZeroize {}
830
///
831
/// let mut data = DataToZeroize {
832
///     flat_data_1: [3u8; 32],
833
///     flat_data_2: SomeMoreFlatData(123u64)
834
/// };
835
///
836
/// // data gets zeroized when dropped
837
/// ```
838
#[inline(always)]
839
0
pub unsafe fn zeroize_flat_type<F: Sized>(data: *mut F) {
840
0
    let size = mem::size_of::<F>();
841
0
    // Safety:
842
0
    //
843
0
    // This is safe because `mem::size_of<T>()` returns the exact size of the object in memory, and
844
0
    // `data_ptr` points directly to the first byte of the data.
845
0
    volatile_set(data as *mut u8, 0, size);
846
0
    atomic_fence()
847
0
}
848
849
/// Internal module used as support for `AssertZeroizeOnDrop`.
850
#[doc(hidden)]
851
pub mod __internal {
852
    use super::*;
853
854
    /// Auto-deref workaround for deriving `ZeroizeOnDrop`.
855
    pub trait AssertZeroizeOnDrop {
856
        fn zeroize_or_on_drop(self);
857
    }
858
859
    impl<T: ZeroizeOnDrop + ?Sized> AssertZeroizeOnDrop for &&mut T {
860
0
        fn zeroize_or_on_drop(self) {}
861
    }
862
863
    /// Auto-deref workaround for deriving `ZeroizeOnDrop`.
864
    pub trait AssertZeroize {
865
        fn zeroize_or_on_drop(&mut self);
866
    }
867
868
    impl<T: Zeroize + ?Sized> AssertZeroize for T {
869
0
        fn zeroize_or_on_drop(&mut self) {
870
0
            self.zeroize()
871
0
        }
872
    }
873
}
/home/oof/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zeroize-1.8.1/src/x86.rs
Line
Count
Source
1
//! [`Zeroize`] impls for x86 SIMD registers
2
3
use crate::{atomic_fence, volatile_write, Zeroize};
4
5
#[cfg(target_arch = "x86")]
6
use core::arch::x86::*;
7
8
#[cfg(target_arch = "x86_64")]
9
use core::arch::x86_64::*;
10
11
macro_rules! impl_zeroize_for_simd_register {
12
    ($($type:ty),* $(,)?) => {
13
        $(
14
            impl Zeroize for $type {
15
                #[inline]
16
0
                fn zeroize(&mut self) {
17
0
                    volatile_write(self, unsafe { core::mem::zeroed() });
18
0
                    atomic_fence();
19
0
                }
Unexecuted instantiation: _RNvXNtCs6qnKa1vNaZb_7zeroize3x86NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m128NtB4_7Zeroize7zeroizeB4_
Unexecuted instantiation: _RNvXs_NtCs6qnKa1vNaZb_7zeroize3x86NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128dNtB6_7Zeroize7zeroizeB6_
Unexecuted instantiation: _RNvXs0_NtCs6qnKa1vNaZb_7zeroize3x86NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m128iNtB7_7Zeroize7zeroizeB7_
Unexecuted instantiation: _RNvXs1_NtCs6qnKa1vNaZb_7zeroize3x86NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x866___m256NtB7_7Zeroize7zeroizeB7_
Unexecuted instantiation: _RNvXs2_NtCs6qnKa1vNaZb_7zeroize3x86NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256dNtB7_7Zeroize7zeroizeB7_
Unexecuted instantiation: _RNvXs3_NtCs6qnKa1vNaZb_7zeroize3x86NtNtNtCsbQ8arDwx5Xq_4core9core_arch3x867___m256iNtB7_7Zeroize7zeroizeB7_
20
            }
21
        )*
22
    };
23
}
24
25
impl_zeroize_for_simd_register!(__m128, __m128d, __m128i, __m256, __m256d, __m256i);
26
27
// NOTE: MSRV 1.72
28
#[cfg(feature = "simd")]
29
impl_zeroize_for_simd_register!(__m512, __m512d, __m512i);
/home/oof/clvm_rs/src/allocator.rs
Line
Count
Source
1
use crate::err_utils::err;
2
use crate::number::{number_from_u8, Number};
3
use crate::reduction::EvalErr;
4
use chia_bls::{G1Element, G2Element};
5
use std::hash::Hash;
6
use std::hash::Hasher;
7
8
const MAX_NUM_ATOMS: usize = 62500000;
9
const MAX_NUM_PAIRS: usize = 62500000;
10
const NODE_PTR_IDX_BITS: u32 = 26;
11
const NODE_PTR_IDX_MASK: u32 = (1 << NODE_PTR_IDX_BITS) - 1;
12
13
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14
pub struct NodePtr(u32);
15
16
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
17
enum ObjectType {
18
    // The low bits form an index into the pair_vec
19
    Pair,
20
    // The low bits form an index into the atom_vec
21
    Bytes,
22
    // The low bits are the atom itself (unsigned integer, 26 bits)
23
    SmallAtom,
24
}
25
26
// The top 6 bits of the NodePtr indicate what type of object it is
27
impl NodePtr {
28
    pub const NIL: Self = Self::new(ObjectType::SmallAtom, 0);
29
30
3.89M
    const fn new(object_type: ObjectType, index: usize) -> Self {
31
3.89M
        debug_assert!(index <= NODE_PTR_IDX_MASK as usize);
32
3.89M
        NodePtr(((object_type as u32) << NODE_PTR_IDX_BITS) | (index as u32))
33
3.89M
    }
34
35
0
    pub fn is_atom(self) -> bool {
36
0
        matches!(
37
0
            self.object_type(),
38
            ObjectType::Bytes | ObjectType::SmallAtom
39
        )
40
0
    }
41
42
72.7k
    pub fn is_pair(self) -> bool {
43
72.7k
        self.object_type() == ObjectType::Pair
44
72.7k
    }
45
46
9.85M
    fn object_type(self) -> ObjectType {
47
9.85M
        match self.0 >> NODE_PTR_IDX_BITS {
48
3.13M
            0 => ObjectType::Pair,
49
893k
            1 => ObjectType::Bytes,
50
5.83M
            2 => ObjectType::SmallAtom,
51
0
            _ => unreachable!(),
52
        }
53
9.85M
    }
54
55
7.41M
    fn index(self) -> u32 {
56
7.41M
        self.0 & NODE_PTR_IDX_MASK
57
7.41M
    }
58
}
59
60
impl Default for NodePtr {
61
0
    fn default() -> Self {
62
0
        Self::NIL
63
0
    }
64
}
65
66
#[derive(PartialEq, Debug)]
67
pub enum SExp {
68
    Atom,
69
    Pair(NodePtr, NodePtr),
70
}
71
72
#[derive(Clone, Copy, Debug)]
73
struct AtomBuf {
74
    start: u32,
75
    end: u32,
76
}
77
78
impl AtomBuf {
79
42.5k
    pub fn len(&self) -> usize {
80
42.5k
        (self.end - self.start) as usize
81
42.5k
    }
82
}
83
84
#[derive(Clone, Copy, Debug)]
85
pub struct IntPair {
86
    first: NodePtr,
87
    rest: NodePtr,
88
}
89
90
// this represents a specific (former) state of an allocator. This can be used
91
// to restore an allocator to a previous state. It cannot be used to re-create
92
// the state from some other allocator.
93
pub struct Checkpoint {
94
    u8s: usize,
95
    pairs: usize,
96
    atoms: usize,
97
    small_atoms: usize,
98
}
99
100
pub enum NodeVisitor<'a> {
101
    Buffer(&'a [u8]),
102
    U32(u32),
103
    Pair(NodePtr, NodePtr),
104
}
105
106
#[derive(Debug, Clone, Copy, Eq)]
107
pub enum Atom<'a> {
108
    Borrowed(&'a [u8]),
109
    U32([u8; 4], usize),
110
}
111
112
impl Hash for Atom<'_> {
113
0
    fn hash<H: Hasher>(&self, state: &mut H) {
114
0
        self.as_ref().hash(state)
115
0
    }
116
}
117
118
impl PartialEq for Atom<'_> {
119
0
    fn eq(&self, other: &Atom) -> bool {
120
0
        self.as_ref().eq(other.as_ref())
121
0
    }
122
}
123
124
impl<'a> AsRef<[u8]> for Atom<'a> {
125
176k
    fn as_ref(&self) -> &[u8] {
126
176k
        match self {
127
97.3k
            Self::Borrowed(bytes) => bytes,
128
79.3k
            Self::U32(bytes, len) => &bytes[4 - len..],
129
        }
130
176k
    }
131
}
132
133
impl<'a> Borrow<[u8]> for Atom<'a> {
134
5.96k
    fn borrow(&self) -> &[u8] {
135
5.96k
        self.as_ref()
136
5.96k
    }
137
}
138
139
#[derive(Debug)]
140
pub struct Allocator {
141
    // this is effectively a grow-only stack where atoms are allocated. Atoms
142
    // are immutable, so once they are created, they will stay around until the
143
    // program completes
144
    u8_vec: Vec<u8>,
145
146
    // storage for all pairs (positive indices)
147
    pair_vec: Vec<IntPair>,
148
149
    // storage for all atoms (negative indices).
150
    // node index -1 refers to index 0 in this vector, -2 refers to 1 and so
151
    // on.
152
    atom_vec: Vec<AtomBuf>,
153
154
    // the atom_vec may not grow past this
155
    heap_limit: usize,
156
157
    // the number of small atoms we've allocated. We keep track of these to ensure the limit on the
158
    // number of atoms is identical to what it was before the small-atom optimization
159
    small_atoms: usize,
160
}
161
162
impl Default for Allocator {
163
0
    fn default() -> Self {
164
0
        Self::new()
165
0
    }
166
}
167
168
640k
pub fn fits_in_small_atom(v: &[u8]) -> Option<u32> {
169
640k
    if !v.is_empty()
170
640k
        && (v.len() > 4
171
359k
        || (v.len() == 1 && v[0] == 0)
172
        // a 1-byte buffer of 0 is not the canonical representation of 0
173
342k
        || (v[0] & 0x80) != 0
174
        // if the top bit is set, it's a negative number (i.e. not positive)
175
297k
        || (v[0] == 0 && (v[1] & 0x80) == 0)
176
        // if the buffer is 4 bytes, the top byte can't use more than 2 bits.
177
        // otherwise the integer won't fit in 26 bits
178
293k
        || (v.len() == 4 && v[0] > 0x03))
179
    {
180
        // if the top byte is a 0 but the top bit of the next byte is not set,
181
        // that's a redundant leading zero. i.e. not canonical representation
182
355k
        None
183
    } else {
184
285k
        let mut ret: u32 = 0;
185
630k
        for b in v {
186
344k
            ret <<= 8;
187
344k
            ret |= *b as u32;
188
344k
        }
189
285k
        Some(ret)
190
    }
191
640k
}
192
193
1.42M
pub fn len_for_value(val: u32) -> usize {
194
1.42M
    if val == 0 {
195
721k
        0
196
702k
    } else if val < 0x80 {
197
594k
        1
198
108k
    } else if val < 0x8000 {
199
101k
        2
200
6.34k
    } else if val < 0x800000 {
201
4.07k
        3
202
2.27k
    } else if val < 0x80000000 {
203
2.27k
        4
204
    } else {
205
0
        5
206
    }
207
1.42M
}
208
209
impl Allocator {
210
27.3k
    pub fn new() -> Self {
211
27.3k
        Self::new_limited(u32::MAX as usize)
212
27.3k
    }
213
214
27.3k
    pub fn new_limited(heap_limit: usize) -> Self {
215
27.3k
        // we have a maximum of 4 GiB heap, because pointers are 32 bit unsigned
216
27.3k
        assert!(heap_limit <= u32::MAX as usize);
217
218
27.3k
        let mut r = Self {
219
27.3k
            u8_vec: Vec::new(),
220
27.3k
            pair_vec: Vec::new(),
221
27.3k
            atom_vec: Vec::new(),
222
27.3k
            // subtract 1 to compensate for the one() we used to allocate unconfitionally
223
27.3k
            heap_limit: heap_limit - 1,
224
27.3k
            // initialize this to 2 to behave as if we had allocated atoms for
225
27.3k
            // nil() and one(), like we used to
226
27.3k
            small_atoms: 2,
227
27.3k
        };
228
27.3k
        r.u8_vec.reserve(1024 * 1024);
229
27.3k
        r.atom_vec.reserve(256);
230
27.3k
        r.pair_vec.reserve(256);
231
27.3k
        r
232
27.3k
    }
233
234
    // create a checkpoint for the current state of the allocator. This can be
235
    // used to go back to an earlier allocator state by passing the Checkpoint
236
    // to restore_checkpoint().
237
27.8k
    pub fn checkpoint(&self) -> Checkpoint {
238
27.8k
        Checkpoint {
239
27.8k
            u8s: self.u8_vec.len(),
240
27.8k
            pairs: self.pair_vec.len(),
241
27.8k
            atoms: self.atom_vec.len(),
242
27.8k
            small_atoms: self.small_atoms,
243
27.8k
        }
244
27.8k
    }
Unexecuted instantiation: _RNvMs6_NtCs4RkbDk9WRL5_5clvmr9allocatorNtB5_9Allocator10checkpointB7_
_RNvMs6_NtCs4RkbDk9WRL5_5clvmr9allocatorNtB5_9Allocator10checkpointCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
237
27.8k
    pub fn checkpoint(&self) -> Checkpoint {
238
27.8k
        Checkpoint {
239
27.8k
            u8s: self.u8_vec.len(),
240
27.8k
            pairs: self.pair_vec.len(),
241
27.8k
            atoms: self.atom_vec.len(),
242
27.8k
            small_atoms: self.small_atoms,
243
27.8k
        }
244
27.8k
    }
245
246
109k
    pub fn restore_checkpoint(&mut self, cp: &Checkpoint) {
247
109k
        // if any of these asserts fire, it means we're trying to restore to
248
109k
        // a state that has already been "long-jumped" passed (via another
249
109k
        // restore to an earlier state). You can only restore backwards in time,
250
109k
        // not forwards.
251
109k
        assert!(self.u8_vec.len() >= cp.u8s);
252
109k
        assert!(self.pair_vec.len() >= cp.pairs);
253
109k
        assert!(self.atom_vec.len() >= cp.atoms);
254
109k
        self.u8_vec.truncate(cp.u8s);
255
109k
        self.pair_vec.truncate(cp.pairs);
256
109k
        self.atom_vec.truncate(cp.atoms);
257
109k
        self.small_atoms = cp.small_atoms;
258
109k
    }
259
260
624k
    pub fn new_atom(&mut self, v: &[u8]) -> Result<NodePtr, EvalErr> {
261
624k
        let start = self.u8_vec.len() as u32;
262
624k
        if (self.heap_limit - start as usize) < v.len() {
263
0
            return err(self.nil(), "out of memory");
264
624k
        }
265
624k
        let idx = self.atom_vec.len();
266
624k
        self.check_atom_limit()?;
267
624k
        if let Some(ret) = fits_in_small_atom(v) {
268
285k
            self.small_atoms += 1;
269
285k
            Ok(NodePtr::new(ObjectType::SmallAtom, ret as usize))
270
        } else {
271
338k
            self.u8_vec.extend_from_slice(v);
272
338k
            let end = self.u8_vec.len() as u32;
273
338k
            self.atom_vec.push(AtomBuf { start, end });
274
338k
            Ok(NodePtr::new(ObjectType::Bytes, idx))
275
        }
276
624k
    }
277
278
223k
    pub fn new_small_number(&mut self, v: u32) -> Result<NodePtr, EvalErr> {
279
223k
        debug_assert!(v <= NODE_PTR_IDX_MASK);
280
223k
        self.check_atom_limit()?;
281
223k
        self.small_atoms += 1;
282
223k
        Ok(NodePtr::new(ObjectType::SmallAtom, v as usize))
283
223k
    }
284
285
353k
    pub fn new_number(&mut self, v: Number) -> Result<NodePtr, EvalErr> {
286
        use num_traits::ToPrimitive;
287
353k
        if let Some(val) = v.to_u32() {
288
224k
            if val <= NODE_PTR_IDX_MASK {
289
223k
                return self.new_small_number(val);
290
434
            }
291
129k
        }
292
129k
        let bytes: Vec<u8> = v.to_signed_bytes_be();
293
129k
        let mut slice = bytes.as_slice();
294
295
        // make number minimal by removing leading zeros
296
129k
        while (!slice.is_empty()) && (slice[0] == 0) {
297
10.4k
            if slice.len() > 1 && (slice[1] & 0x80 == 0x80) {
298
10.4k
                break;
299
0
            }
300
0
            slice = &slice[1..];
301
        }
302
129k
        self.new_atom(slice)
303
353k
    }
304
305
26.3k
    pub fn new_g1(&mut self, g1: G1Element) -> Result<NodePtr, EvalErr> {
306
26.3k
        self.new_atom(&g1.to_bytes())
307
26.3k
    }
308
309
14.4k
    pub fn new_g2(&mut self, g2: G2Element) -> Result<NodePtr, EvalErr> {
310
14.4k
        self.new_atom(&g2.to_bytes())
311
14.4k
    }
312
313
1.90M
    pub fn new_pair(&mut self, first: NodePtr, rest: NodePtr) -> Result<NodePtr, EvalErr> {
314
1.90M
        let idx = self.pair_vec.len();
315
1.90M
        if idx == MAX_NUM_PAIRS {
316
0
            return err(self.nil(), "too many pairs");
317
1.90M
        }
318
1.90M
        self.pair_vec.push(IntPair { first, rest });
319
1.90M
        Ok(NodePtr::new(ObjectType::Pair, idx))
320
1.90M
    }
321
322
951
    pub fn new_substr(&mut self, node: NodePtr, start: u32, end: u32) -> Result<NodePtr, EvalErr> {
323
951
        self.check_atom_limit()?;
324
325
951
        fn bounds_check(node: NodePtr, start: u32, end: u32, len: u32) -> Result<(), EvalErr> {
326
951
            if start > len {
327
0
                return err(node, "substr start out of bounds");
328
951
            }
329
951
            if end > len {
330
0
                return err(node, "substr end out of bounds");
331
951
            }
332
951
            if end < start {
333
0
                return err(node, "substr invalid bounds");
334
951
            }
335
951
            Ok(())
336
951
        }
337
338
951
        match node.object_type() {
339
0
            ObjectType::Pair => err(node, "(internal error) substr expected atom, got pair"),
340
            ObjectType::Bytes => {
341
749
                let atom = self.atom_vec[node.index() as usize];
342
749
                let atom_len = atom.end - atom.start;
343
749
                bounds_check(node, start, end, atom_len)?;
344
749
                let idx = self.atom_vec.len();
345
749
                self.atom_vec.push(AtomBuf {
346
749
                    start: atom.start + start,
347
749
                    end: atom.start + end,
348
749
                });
349
749
                Ok(NodePtr::new(ObjectType::Bytes, idx))
350
            }
351
            ObjectType::SmallAtom => {
352
202
                let val = node.index();
353
202
                let len = len_for_value(val) as u32;
354
202
                bounds_check(node, start, end, len)?;
355
202
                let buf: [u8; 4] = val.to_be_bytes();
356
202
                let buf = &buf[4 - len as usize..];
357
202
                let substr = &buf[start as usize..end as usize];
358
202
                if let Some(new_val) = fits_in_small_atom(substr) {
359
179
                    self.small_atoms += 1;
360
179
                    Ok(NodePtr::new(ObjectType::SmallAtom, new_val as usize))
361
                } else {
362
23
                    let start = self.u8_vec.len();
363
23
                    let end = start + substr.len();
364
23
                    self.u8_vec.extend_from_slice(substr);
365
23
                    let idx = self.atom_vec.len();
366
23
                    self.atom_vec.push(AtomBuf {
367
23
                        start: start as u32,
368
23
                        end: end as u32,
369
23
                    });
370
23
                    Ok(NodePtr::new(ObjectType::Bytes, idx))
371
                }
372
            }
373
        }
374
951
    }
375
376
12.0k
    pub fn new_concat(&mut self, new_size: usize, nodes: &[NodePtr]) -> Result<NodePtr, EvalErr> {
377
12.0k
        self.check_atom_limit()?;
378
12.0k
        let start = self.u8_vec.len();
379
12.0k
        if self.heap_limit - start < new_size {
380
0
            return err(self.nil(), "out of memory");
381
12.0k
        }
382
12.0k
        // TODO: maybe it would make sense to have a special case where
383
12.0k
        // nodes.len() == 1. We can just return the same node
384
12.0k
385
12.0k
        self.u8_vec.reserve(new_size);
386
12.0k
387
12.0k
        let mut counter: usize = 0;
388
45.7k
        for node in nodes {
389
33.6k
            match node.object_type() {
390
                ObjectType::Pair => {
391
0
                    self.u8_vec.truncate(start);
392
0
                    return err(*node, "(internal error) concat expected atom, got pair");
393
                }
394
                ObjectType::Bytes => {
395
21.2k
                    let term = self.atom_vec[node.index() as usize];
396
21.2k
                    if counter + term.len() > new_size {
397
0
                        self.u8_vec.truncate(start);
398
0
                        return err(*node, "(internal error) concat passed invalid new_size");
399
21.2k
                    }
400
21.2k
                    self.u8_vec
401
21.2k
                        .extend_from_within(term.start as usize..term.end as usize);
402
21.2k
                    counter += term.len();
403
                }
404
12.3k
                ObjectType::SmallAtom => {
405
12.3k
                    let val = node.index();
406
12.3k
                    let len = len_for_value(val) as u32;
407
12.3k
                    let buf: [u8; 4] = val.to_be_bytes();
408
12.3k
                    let buf = &buf[4 - len as usize..];
409
12.3k
                    self.u8_vec.extend_from_slice(buf);
410
12.3k
                    counter += len as usize;
411
12.3k
                }
412
            }
413
        }
414
12.0k
        if counter != new_size {
415
0
            self.u8_vec.truncate(start);
416
0
            return err(
417
0
                self.nil(),
418
0
                "(internal error) concat passed invalid new_size",
419
0
            );
420
12.0k
        }
421
12.0k
        let end = self.u8_vec.len() as u32;
422
12.0k
        let idx = self.atom_vec.len();
423
12.0k
        self.atom_vec.push(AtomBuf {
424
12.0k
            start: (start as u32),
425
12.0k
            end,
426
12.0k
        });
427
12.0k
        Ok(NodePtr::new(ObjectType::Bytes, idx))
428
12.0k
    }
429
430
2.28k
    pub fn atom_eq(&self, lhs: NodePtr, rhs: NodePtr) -> bool {
431
2.28k
        let lhs_type = lhs.object_type();
432
2.28k
        let rhs_type = rhs.object_type();
433
2.28k
434
2.28k
        match (lhs_type, rhs_type) {
435
            (ObjectType::Pair, _) | (_, ObjectType::Pair) => {
436
0
                panic!("atom_eq() called on pair");
437
            }
438
            (ObjectType::Bytes, ObjectType::Bytes) => {
439
994
                let lhs = self.atom_vec[lhs.index() as usize];
440
994
                let rhs = self.atom_vec[rhs.index() as usize];
441
994
                self.u8_vec[lhs.start as usize..lhs.end as usize]
442
994
                    == self.u8_vec[rhs.start as usize..rhs.end as usize]
443
            }
444
245
            (ObjectType::SmallAtom, ObjectType::SmallAtom) => lhs.index() == rhs.index(),
445
            (ObjectType::SmallAtom, ObjectType::Bytes) => {
446
534
                self.bytes_eq_int(self.atom_vec[rhs.index() as usize], lhs.index())
447
            }
448
            (ObjectType::Bytes, ObjectType::SmallAtom) => {
449
508
                self.bytes_eq_int(self.atom_vec[lhs.index() as usize], rhs.index())
450
            }
451
        }
452
2.28k
    }
453
454
1.04k
    fn bytes_eq_int(&self, atom: AtomBuf, val: u32) -> bool {
455
1.04k
        let len = len_for_value(val) as u32;
456
1.04k
        if (atom.end - atom.start) != len {
457
988
            return false;
458
54
        }
459
54
        if val == 0 {
460
0
            return true;
461
54
        }
462
54
463
54
        if self.u8_vec[atom.start as usize] & 0x80 != 0 {
464
            // SmallAtom only represents positive values
465
            // if the byte buffer is negative, they can't match
466
10
            return false;
467
44
        }
468
44
469
44
        // since we know the value of atom is small, we can turn it into a u32 and compare
470
44
        // against val
471
44
        let mut atom_val: u32 = 0;
472
62
        for i in atom.start..atom.end {
473
62
            atom_val <<= 8;
474
62
            atom_val |= self.u8_vec[i as usize] as u32;
475
62
        }
476
44
        val == atom_val
477
1.04k
    }
478
479
118k
    pub fn atom(&self, node: NodePtr) -> Atom {
480
118k
        let index = node.index();
481
118k
482
118k
        match node.object_type() {
483
            ObjectType::Bytes => {
484
54.5k
                let atom = self.atom_vec[index as usize];
485
54.5k
                Atom::Borrowed(&self.u8_vec[atom.start as usize..atom.end as usize])
486
            }
487
            ObjectType::SmallAtom => {
488
64.2k
                let len = len_for_value(index);
489
64.2k
                let bytes = index.to_be_bytes();
490
64.2k
                Atom::U32(bytes, len)
491
            }
492
0
            _ => panic!("expected atom, got pair"),
493
        }
494
118k
    }
495
496
1.50M
    pub fn atom_len(&self, node: NodePtr) -> usize {
497
1.50M
        let index = node.index();
498
1.50M
499
1.50M
        match node.object_type() {
500
            ObjectType::Bytes => {
501
290k
                let atom = self.atom_vec[index as usize];
502
290k
                (atom.end - atom.start) as usize
503
            }
504
1.21M
            ObjectType::SmallAtom => len_for_value(index),
505
            _ => {
506
0
                panic!("expected atom, got pair");
507
            }
508
        }
509
1.50M
    }
510
511
2.01M
    pub fn small_number(&self, node: NodePtr) -> Option<u32> {
512
2.01M
        match node.object_type() {
513
1.99M
            ObjectType::SmallAtom => Some(node.index()),
514
            ObjectType::Bytes => {
515
16.2k
                let atom = self.atom_vec[node.index() as usize];
516
16.2k
                let buf = &self.u8_vec[atom.start as usize..atom.end as usize];
517
16.2k
                fits_in_small_atom(buf)
518
            }
519
58
            _ => None,
520
        }
521
2.01M
    }
522
523
245k
    pub fn number(&self, node: NodePtr) -> Number {
524
245k
        let index = node.index();
525
245k
526
245k
        match node.object_type() {
527
            ObjectType::Bytes => {
528
116k
                let atom = self.atom_vec[index as usize];
529
116k
                number_from_u8(&self.u8_vec[atom.start as usize..atom.end as usize])
530
            }
531
129k
            ObjectType::SmallAtom => Number::from(index),
532
            _ => {
533
0
                panic!("number() calld on pair");
534
            }
535
        }
536
245k
    }
537
538
39.0k
    pub fn g1(&self, node: NodePtr) -> Result<G1Element, EvalErr> {
539
39.0k
        let idx = match node.object_type() {
540
37.9k
            ObjectType::Bytes => node.index(),
541
            ObjectType::SmallAtom => {
542
1.09k
                return err(node, "atom is not G1 size, 48 bytes");
543
            }
544
            ObjectType::Pair => {
545
20
                return err(node, "pair found, expected G1 point");
546
            }
547
        };
548
37.9k
        let atom = self.atom_vec[idx as usize];
549
37.9k
        if atom.end - atom.start != 48 {
550
3.08k
            return err(node, "atom is not G1 size, 48 bytes");
551
34.8k
        }
552
34.8k
553
34.8k
        let array: &[u8; 48] = &self.u8_vec[atom.start as usize..atom.end as usize]
554
34.8k
            .try_into()
555
34.8k
            .expect("atom size is not 48 bytes");
556
34.8k
        G1Element::from_bytes(array)
557
34.8k
            .map_err(|_| EvalErr(node, "atom is not a G1 point".to_string()))
558
39.0k
    }
559
560
18.1k
    pub fn g2(&self, node: NodePtr) -> Result<G2Element, EvalErr> {
561
18.1k
        let idx = match node.object_type() {
562
18.0k
            ObjectType::Bytes => node.index(),
563
            ObjectType::SmallAtom => {
564
69
                return err(node, "atom is not G2 size, 96 bytes");
565
            }
566
            ObjectType::Pair => {
567
22
                return err(node, "pair found, expected G2 point");
568
            }
569
        };
570
571
18.0k
        let atom = self.atom_vec[idx as usize];
572
18.0k
        if atom.end - atom.start != 96 {
573
40
            return err(node, "atom is not G2 size, 96 bytes");
574
18.0k
        }
575
18.0k
576
18.0k
        let array: &[u8; 96] = &self.u8_vec[atom.start as usize..atom.end as usize]
577
18.0k
            .try_into()
578
18.0k
            .expect("atom size is not 96 bytes");
579
18.0k
580
18.0k
        G2Element::from_bytes(array)
581
18.0k
            .map_err(|_| EvalErr(node, "atom is not a G2 point".to_string()))
582
18.1k
    }
583
584
298k
    pub fn node(&self, node: NodePtr) -> NodeVisitor {
585
298k
        let index = node.index();
586
298k
587
298k
        match node.object_type() {
588
            ObjectType::Bytes => {
589
119k
                let atom = self.atom_vec[index as usize];
590
119k
                let buf = &self.u8_vec[atom.start as usize..atom.end as usize];
591
119k
                NodeVisitor::Buffer(buf)
592
            }
593
178k
            ObjectType::SmallAtom => NodeVisitor::U32(index),
594
            ObjectType::Pair => {
595
161
                let pair = self.pair_vec[index as usize];
596
161
                NodeVisitor::Pair(pair.first, pair.rest)
597
            }
598
        }
599
298k
    }
600
601
5.50M
    pub fn sexp(&self, node: NodePtr) -> SExp {
602
5.50M
        match node.object_type() {
603
2.37M
            ObjectType::Bytes | ObjectType::SmallAtom => SExp::Atom,
604
            ObjectType::Pair => {
605
3.13M
                let pair = self.pair_vec[node.index() as usize];
606
3.13M
                SExp::Pair(pair.first, pair.rest)
607
            }
608
        }
609
5.50M
    }
610
611
    // this is meant to be used when iterating lists:
612
    // while let Some((i, rest)) = a.next(node) {
613
    //     node = rest;
614
    //     ...
615
    // }
616
1.14M
    pub fn next(&self, n: NodePtr) -> Option<(NodePtr, NodePtr)> {
617
1.14M
        match self.sexp(n) {
618
776k
            SExp::Pair(first, rest) => Some((first, rest)),
619
366k
            SExp::Atom => None,
620
        }
621
1.14M
    }
622
623
829k
    pub fn nil(&self) -> NodePtr {
624
829k
        NodePtr::new(ObjectType::SmallAtom, 0)
625
829k
    }
626
627
293k
    pub fn one(&self) -> NodePtr {
628
293k
        NodePtr::new(ObjectType::SmallAtom, 1)
629
293k
    }
630
631
    #[inline]
632
860k
    fn check_atom_limit(&self) -> Result<(), EvalErr> {
633
860k
        if self.atom_vec.len() + self.small_atoms == MAX_NUM_ATOMS {
634
0
            err(self.nil(), "too many atoms")
635
        } else {
636
860k
            Ok(())
637
        }
638
860k
    }
639
640
    #[cfg(feature = "counters")]
641
    pub fn atom_count(&self) -> usize {
642
        self.atom_vec.len()
643
    }
644
645
    #[cfg(feature = "counters")]
646
    pub fn small_atom_count(&self) -> usize {
647
        self.small_atoms
648
    }
649
650
    #[cfg(feature = "counters")]
651
    pub fn pair_count(&self) -> usize {
652
        self.pair_vec.len()
653
    }
654
655
    #[cfg(feature = "counters")]
656
    pub fn heap_size(&self) -> usize {
657
        self.u8_vec.len()
658
    }
659
}
660
661
#[test]
662
fn test_atom_eq_1() {
663
    // these are a bunch of different representations of 1
664
    // make sure they all compare equal
665
    let mut a = Allocator::new();
666
    let a0 = a.one();
667
    let a1 = a.new_atom(&[1]).unwrap();
668
    let a2 = {
669
        let tmp = a.new_atom(&[0x01, 0xff]).unwrap();
670
        a.new_substr(tmp, 0, 1).unwrap()
671
    };
672
    let a3 = a.new_substr(a2, 0, 1).unwrap();
673
    let a4 = a.new_number(1.into()).unwrap();
674
    let a5 = a.new_small_number(1).unwrap();
675
676
    assert!(a.atom_eq(a0, a0));
677
    assert!(a.atom_eq(a0, a1));
678
    assert!(a.atom_eq(a0, a2));
679
    assert!(a.atom_eq(a0, a3));
680
    assert!(a.atom_eq(a0, a4));
681
    assert!(a.atom_eq(a0, a5));
682
683
    assert!(a.atom_eq(a1, a0));
684
    assert!(a.atom_eq(a1, a1));
685
    assert!(a.atom_eq(a1, a2));
686
    assert!(a.atom_eq(a1, a3));
687
    assert!(a.atom_eq(a1, a4));
688
    assert!(a.atom_eq(a1, a5));
689
690
    assert!(a.atom_eq(a2, a0));
691
    assert!(a.atom_eq(a2, a1));
692
    assert!(a.atom_eq(a2, a2));
693
    assert!(a.atom_eq(a2, a3));
694
    assert!(a.atom_eq(a2, a4));
695
    assert!(a.atom_eq(a2, a5));
696
697
    assert!(a.atom_eq(a3, a0));
698
    assert!(a.atom_eq(a3, a1));
699
    assert!(a.atom_eq(a3, a2));
700
    assert!(a.atom_eq(a3, a3));
701
    assert!(a.atom_eq(a3, a4));
702
    assert!(a.atom_eq(a3, a5));
703
704
    assert!(a.atom_eq(a4, a0));
705
    assert!(a.atom_eq(a4, a1));
706
    assert!(a.atom_eq(a4, a2));
707
    assert!(a.atom_eq(a4, a3));
708
    assert!(a.atom_eq(a4, a4));
709
    assert!(a.atom_eq(a4, a5));
710
711
    assert!(a.atom_eq(a5, a0));
712
    assert!(a.atom_eq(a5, a1));
713
    assert!(a.atom_eq(a5, a2));
714
    assert!(a.atom_eq(a5, a3));
715
    assert!(a.atom_eq(a5, a4));
716
    assert!(a.atom_eq(a5, a5));
717
}
718
719
#[test]
720
fn test_atom_eq_minus_1() {
721
    // these are a bunch of different representations of -1
722
    // make sure they all compare equal
723
    let mut a = Allocator::new();
724
    let a0 = a.new_atom(&[0xff]).unwrap();
725
    let a1 = a.new_number((-1).into()).unwrap();
726
    let a2 = {
727
        let tmp = a.new_atom(&[0x01, 0xff]).unwrap();
728
        a.new_substr(tmp, 1, 2).unwrap()
729
    };
730
    let a3 = a.new_substr(a0, 0, 1).unwrap();
731
732
    assert!(a.atom_eq(a0, a0));
733
    assert!(a.atom_eq(a0, a1));
734
    assert!(a.atom_eq(a0, a2));
735
    assert!(a.atom_eq(a0, a3));
736
737
    assert!(a.atom_eq(a1, a0));
738
    assert!(a.atom_eq(a1, a1));
739
    assert!(a.atom_eq(a1, a2));
740
    assert!(a.atom_eq(a1, a3));
741
742
    assert!(a.atom_eq(a2, a0));
743
    assert!(a.atom_eq(a2, a1));
744
    assert!(a.atom_eq(a2, a2));
745
    assert!(a.atom_eq(a2, a3));
746
747
    assert!(a.atom_eq(a3, a0));
748
    assert!(a.atom_eq(a3, a1));
749
    assert!(a.atom_eq(a3, a2));
750
    assert!(a.atom_eq(a3, a3));
751
}
752
753
#[test]
754
fn test_atom_eq() {
755
    let mut a = Allocator::new();
756
    let a0 = a.nil();
757
    let a1 = a.one();
758
    let a2 = a.new_atom(&[1]).unwrap();
759
    let a3 = a.new_atom(&[0xfa, 0xc7]).unwrap();
760
    let a4 = a.new_small_number(1).unwrap();
761
    let a5 = a.new_number((-1337).into()).unwrap();
762
763
    assert!(a.atom_eq(a0, a0));
764
    assert!(!a.atom_eq(a0, a1));
765
    assert!(!a.atom_eq(a0, a2));
766
    assert!(!a.atom_eq(a0, a3));
767
    assert!(!a.atom_eq(a0, a4));
768
    assert!(!a.atom_eq(a0, a5));
769
770
    assert!(!a.atom_eq(a1, a0));
771
    assert!(a.atom_eq(a1, a1));
772
    assert!(a.atom_eq(a1, a2));
773
    assert!(!a.atom_eq(a1, a3));
774
    assert!(a.atom_eq(a1, a4));
775
    assert!(!a.atom_eq(a1, a5));
776
777
    assert!(!a.atom_eq(a2, a0));
778
    assert!(a.atom_eq(a2, a1));
779
    assert!(a.atom_eq(a2, a2));
780
    assert!(!a.atom_eq(a2, a3));
781
    assert!(a.atom_eq(a2, a4));
782
    assert!(!a.atom_eq(a2, a5));
783
784
    assert!(!a.atom_eq(a3, a0));
785
    assert!(!a.atom_eq(a3, a1));
786
    assert!(!a.atom_eq(a3, a2));
787
    assert!(a.atom_eq(a3, a3));
788
    assert!(!a.atom_eq(a3, a4));
789
    assert!(a.atom_eq(a3, a5));
790
791
    assert!(!a.atom_eq(a4, a0));
792
    assert!(a.atom_eq(a4, a1));
793
    assert!(a.atom_eq(a4, a2));
794
    assert!(!a.atom_eq(a4, a3));
795
    assert!(a.atom_eq(a4, a4));
796
    assert!(!a.atom_eq(a4, a5));
797
}
798
799
#[test]
800
#[should_panic]
801
fn test_atom_eq_pair1() {
802
    let mut a = Allocator::new();
803
    let a0 = a.nil();
804
    let pair = a.new_pair(a0, a0).unwrap();
805
    a.atom_eq(pair, a0);
806
}
807
808
#[test]
809
#[should_panic]
810
fn test_atom_eq_pair2() {
811
    let mut a = Allocator::new();
812
    let a0 = a.nil();
813
    let pair = a.new_pair(a0, a0).unwrap();
814
    a.atom_eq(a0, pair);
815
}
816
817
#[test]
818
#[should_panic]
819
fn test_atom_len_pair() {
820
    let mut a = Allocator::new();
821
    let a0 = a.nil();
822
    let pair = a.new_pair(a0, a0).unwrap();
823
    a.atom_len(pair);
824
}
825
826
#[test]
827
#[should_panic]
828
fn test_number_pair() {
829
    let mut a = Allocator::new();
830
    let a0 = a.nil();
831
    let pair = a.new_pair(a0, a0).unwrap();
832
    a.number(pair);
833
}
834
835
#[test]
836
#[should_panic]
837
fn test_invalid_node_ptr_type() {
838
    let node = NodePtr(3 << NODE_PTR_IDX_BITS);
839
    // unknown NodePtr type
840
    let _ = node.object_type();
841
}
842
843
#[cfg(debug_assertions)]
844
#[test]
845
#[should_panic]
846
fn test_node_ptr_overflow() {
847
    NodePtr::new(ObjectType::Bytes, NODE_PTR_IDX_MASK as usize + 1);
848
}
849
850
#[cfg(debug_assertions)]
851
#[test]
852
#[should_panic]
853
fn test_invalid_small_number() {
854
    let mut a = Allocator::new();
855
    a.new_small_number(NODE_PTR_IDX_MASK + 1).unwrap();
856
}
857
858
#[cfg(test)]
859
#[rstest]
860
#[case(0, 0)]
861
#[case(1, 1)]
862
#[case(0x7f, 1)]
863
#[case(0x80, 2)]
864
#[case(0x7fff, 2)]
865
#[case(0x7fffff, 3)]
866
#[case(0x800000, 4)]
867
#[case(0x7fffffff, 4)]
868
#[case(0x80000000, 5)]
869
#[case(0xffffffff, 5)]
870
fn test_len_for_value(#[case] val: u32, #[case] len: usize) {
871
    assert_eq!(len_for_value(val), len);
872
}
873
874
#[test]
875
fn test_nil() {
876
    let a = Allocator::new();
877
    assert_eq!(a.atom(a.nil()).as_ref(), b"");
878
    assert_eq!(a.sexp(a.nil()), SExp::Atom);
879
    assert_eq!(a.nil(), NodePtr::default());
880
    assert_eq!(a.nil(), NodePtr::NIL);
881
}
882
883
#[test]
884
fn test_one() {
885
    let a = Allocator::new();
886
    assert_eq!(a.atom(a.one()).as_ref(), b"\x01");
887
    assert_eq!(a.sexp(a.one()), SExp::Atom);
888
}
889
890
#[test]
891
fn test_allocate_atom() {
892
    let mut a = Allocator::new();
893
    let atom = a.new_atom(b"foobar").unwrap();
894
    assert_eq!(a.atom(atom).as_ref(), b"foobar");
895
    assert_eq!(a.sexp(atom), SExp::Atom);
896
}
897
898
#[test]
899
fn test_allocate_pair() {
900
    let mut a = Allocator::new();
901
    let atom1 = a.new_atom(b"foo").unwrap();
902
    let atom2 = a.new_atom(b"bar").unwrap();
903
    let pair = a.new_pair(atom1, atom2).unwrap();
904
905
    assert_eq!(a.sexp(pair), SExp::Pair(atom1, atom2));
906
907
    let pair2 = a.new_pair(pair, pair).unwrap();
908
    assert_eq!(a.sexp(pair2), SExp::Pair(pair, pair));
909
}
910
911
#[test]
912
fn test_allocate_heap_limit() {
913
    let mut a = Allocator::new_limited(6);
914
    // we can't allocate 6 bytes
915
    assert_eq!(a.new_atom(b"foobar").unwrap_err().1, "out of memory");
916
    // but 5 is OK
917
    let _atom = a.new_atom(b"fooba").unwrap();
918
}
919
920
#[test]
921
fn test_allocate_atom_limit() {
922
    let mut a = Allocator::new();
923
924
    for _ in 0..MAX_NUM_ATOMS - 2 {
925
        // exhaust the number of atoms allowed to be allocated
926
        let _ = a.new_atom(b"foo").unwrap();
927
    }
928
    assert_eq!(a.new_atom(b"foobar").unwrap_err().1, "too many atoms");
929
    assert_eq!(a.u8_vec.len(), 0);
930
    assert_eq!(a.small_atoms, MAX_NUM_ATOMS);
931
}
932
933
#[test]
934
fn test_allocate_small_number_limit() {
935
    let mut a = Allocator::new();
936
937
    for _ in 0..MAX_NUM_ATOMS - 2 {
938
        // exhaust the number of atoms allowed to be allocated
939
        let _ = a.new_atom(b"foo").unwrap();
940
    }
941
    assert_eq!(a.new_small_number(3).unwrap_err().1, "too many atoms");
942
    assert_eq!(a.u8_vec.len(), 0);
943
    assert_eq!(a.small_atoms, MAX_NUM_ATOMS);
944
}
945
946
#[test]
947
fn test_allocate_substr_limit() {
948
    let mut a = Allocator::new();
949
950
    for _ in 0..MAX_NUM_ATOMS - 3 {
951
        // exhaust the number of atoms allowed to be allocated
952
        let _ = a.new_atom(b"foo").unwrap();
953
    }
954
    let atom = a.new_atom(b"foo").unwrap();
955
    assert_eq!(a.new_substr(atom, 1, 2).unwrap_err().1, "too many atoms");
956
    assert_eq!(a.u8_vec.len(), 0);
957
    assert_eq!(a.small_atoms, MAX_NUM_ATOMS);
958
}
959
960
#[test]
961
fn test_allocate_concat_limit() {
962
    let mut a = Allocator::new();
963
964
    for _ in 0..MAX_NUM_ATOMS - 3 {
965
        // exhaust the number of atoms allowed to be allocated
966
        let _ = a.new_atom(b"foo").unwrap();
967
    }
968
    let atom = a.new_atom(b"foo").unwrap();
969
    assert_eq!(a.new_concat(3, &[atom]).unwrap_err().1, "too many atoms");
970
    assert_eq!(a.u8_vec.len(), 0);
971
    assert_eq!(a.small_atoms, MAX_NUM_ATOMS);
972
}
973
974
#[test]
975
fn test_allocate_pair_limit() {
976
    let mut a = Allocator::new();
977
    let atom = a.new_atom(b"foo").unwrap();
978
    // one pair is OK
979
    let _pair1 = a.new_pair(atom, atom).unwrap();
980
    for _ in 1..MAX_NUM_PAIRS {
981
        // exhaust the number of pairs allowed to be allocated
982
        let _ = a.new_pair(atom, atom).unwrap();
983
    }
984
985
    assert_eq!(a.new_pair(atom, atom).unwrap_err().1, "too many pairs");
986
}
987
988
#[test]
989
fn test_substr() {
990
    let mut a = Allocator::new();
991
    let atom = a.new_atom(b"foobar").unwrap();
992
    let pair = a.new_pair(atom, atom).unwrap();
993
994
    let sub = a.new_substr(atom, 0, 1).unwrap();
995
    assert_eq!(a.atom(sub).as_ref(), b"f");
996
    let sub = a.new_substr(atom, 1, 6).unwrap();
997
    assert_eq!(a.atom(sub).as_ref(), b"oobar");
998
    let sub = a.new_substr(atom, 1, 1).unwrap();
999
    assert_eq!(a.atom(sub).as_ref(), b"");
1000
    let sub = a.new_substr(atom, 0, 0).unwrap();
1001
    assert_eq!(a.atom(sub).as_ref(), b"");
1002
1003
    assert_eq!(
1004
        a.new_substr(atom, 1, 0).unwrap_err().1,
1005
        "substr invalid bounds"
1006
    );
1007
    assert_eq!(
1008
        a.new_substr(atom, 7, 7).unwrap_err().1,
1009
        "substr start out of bounds"
1010
    );
1011
    assert_eq!(
1012
        a.new_substr(atom, 0, 7).unwrap_err().1,
1013
        "substr end out of bounds"
1014
    );
1015
    assert_eq!(
1016
        a.new_substr(atom, u32::MAX, 4).unwrap_err().1,
1017
        "substr start out of bounds"
1018
    );
1019
    assert_eq!(
1020
        a.new_substr(pair, 0, 0).unwrap_err().1,
1021
        "(internal error) substr expected atom, got pair"
1022
    );
1023
}
1024
1025
#[test]
1026
fn test_substr_small_number() {
1027
    let mut a = Allocator::new();
1028
    let atom = a.new_atom(b"a\x80").unwrap();
1029
    assert!(a.small_number(atom).is_some());
1030
1031
    let sub = a.new_substr(atom, 0, 1).unwrap();
1032
    assert_eq!(a.atom(sub).as_ref(), b"a");
1033
    assert!(a.small_number(sub).is_some());
1034
    let sub = a.new_substr(atom, 1, 2).unwrap();
1035
    assert_eq!(a.atom(sub).as_ref(), b"\x80");
1036
    assert!(a.small_number(sub).is_none());
1037
    let sub = a.new_substr(atom, 1, 1).unwrap();
1038
    assert_eq!(a.atom(sub).as_ref(), b"");
1039
    let sub = a.new_substr(atom, 0, 0).unwrap();
1040
    assert_eq!(a.atom(sub).as_ref(), b"");
1041
1042
    assert_eq!(
1043
        a.new_substr(atom, 1, 0).unwrap_err().1,
1044
        "substr invalid bounds"
1045
    );
1046
    assert_eq!(
1047
        a.new_substr(atom, 3, 3).unwrap_err().1,
1048
        "substr start out of bounds"
1049
    );
1050
    assert_eq!(
1051
        a.new_substr(atom, 0, 3).unwrap_err().1,
1052
        "substr end out of bounds"
1053
    );
1054
    assert_eq!(
1055
        a.new_substr(atom, u32::MAX, 2).unwrap_err().1,
1056
        "substr start out of bounds"
1057
    );
1058
}
1059
1060
#[test]
1061
fn test_concat_launder_small_number() {
1062
    let mut a = Allocator::new();
1063
    let atom1 = a.new_small_number(42).expect("new_small_number");
1064
    assert_eq!(a.small_number(atom1), Some(42));
1065
1066
    // this "launders" the small number into actually being allocated on the
1067
    // heap
1068
    let atom2 = a
1069
        .new_concat(1, &[a.nil(), atom1, a.nil()])
1070
        .expect("new_substr");
1071
1072
    // even though this atom is allocated on the heap (and not stored as a small
1073
    // int), we can still retrieve it as one. The CLVM interpreter depends on
1074
    // this when matching operators against quote, apply and softfork.
1075
    assert_eq!(a.small_number(atom2), Some(42));
1076
    assert_eq!(a.atom_len(atom2), 1);
1077
    assert_eq!(a.atom(atom2).as_ref(), &[42]);
1078
}
1079
1080
#[test]
1081
fn test_concat() {
1082
    let mut a = Allocator::new();
1083
    let atom1 = a.new_atom(b"f").unwrap();
1084
    let atom2 = a.new_atom(b"o").unwrap();
1085
    let atom3 = a.new_atom(b"o").unwrap();
1086
    let atom4 = a.new_atom(b"b").unwrap();
1087
    let atom5 = a.new_atom(b"a").unwrap();
1088
    let atom6 = a.new_atom(b"r").unwrap();
1089
    let pair = a.new_pair(atom1, atom2).unwrap();
1090
1091
    let cat = a
1092
        .new_concat(6, &[atom1, atom2, atom3, atom4, atom5, atom6])
1093
        .unwrap();
1094
    assert_eq!(a.atom(cat).as_ref(), b"foobar");
1095
1096
    let cat = a.new_concat(12, &[cat, cat]).unwrap();
1097
    assert_eq!(a.atom(cat).as_ref(), b"foobarfoobar");
1098
1099
    assert_eq!(
1100
        a.new_concat(11, &[cat, cat]).unwrap_err().1,
1101
        "(internal error) concat passed invalid new_size"
1102
    );
1103
    assert_eq!(
1104
        a.new_concat(13, &[cat, cat]).unwrap_err().1,
1105
        "(internal error) concat passed invalid new_size"
1106
    );
1107
    assert_eq!(
1108
        a.new_concat(12, &[atom3, pair]).unwrap_err().1,
1109
        "(internal error) concat expected atom, got pair"
1110
    );
1111
1112
    assert_eq!(
1113
        a.new_concat(4, &[atom1, atom2, atom3]).unwrap_err().1,
1114
        "(internal error) concat passed invalid new_size"
1115
    );
1116
1117
    assert_eq!(
1118
        a.new_concat(2, &[atom1, atom2, atom3]).unwrap_err().1,
1119
        "(internal error) concat passed invalid new_size"
1120
    );
1121
}
1122
1123
#[test]
1124
fn test_concat_large() {
1125
    let mut a = Allocator::new();
1126
    let atom1 = a.new_atom(b"foo").unwrap();
1127
    let atom2 = a.new_atom(b"bar").unwrap();
1128
    let pair = a.new_pair(atom1, atom2).unwrap();
1129
1130
    let cat = a.new_concat(6, &[atom1, atom2]).unwrap();
1131
    assert_eq!(a.atom(cat).as_ref(), b"foobar");
1132
1133
    let cat = a.new_concat(12, &[cat, cat]).unwrap();
1134
    assert_eq!(a.atom(cat).as_ref(), b"foobarfoobar");
1135
1136
    assert_eq!(
1137
        a.new_concat(11, &[cat, cat]).unwrap_err().1,
1138
        "(internal error) concat passed invalid new_size"
1139
    );
1140
    assert_eq!(
1141
        a.new_concat(13, &[cat, cat]).unwrap_err().1,
1142
        "(internal error) concat passed invalid new_size"
1143
    );
1144
    assert_eq!(
1145
        a.new_concat(12, &[atom1, pair]).unwrap_err().1,
1146
        "(internal error) concat expected atom, got pair"
1147
    );
1148
1149
    assert_eq!(
1150
        a.new_concat(4, &[atom1, atom2]).unwrap_err().1,
1151
        "(internal error) concat passed invalid new_size"
1152
    );
1153
1154
    assert_eq!(
1155
        a.new_concat(2, &[atom1, atom2]).unwrap_err().1,
1156
        "(internal error) concat passed invalid new_size"
1157
    );
1158
}
1159
1160
#[test]
1161
fn test_sexp() {
1162
    let mut a = Allocator::new();
1163
    let atom1 = a.new_atom(b"f").unwrap();
1164
    let atom2 = a.new_atom(b"o").unwrap();
1165
    let pair = a.new_pair(atom1, atom2).unwrap();
1166
1167
    assert_eq!(a.sexp(atom1), SExp::Atom);
1168
    assert_eq!(a.sexp(atom2), SExp::Atom);
1169
    assert_eq!(a.sexp(pair), SExp::Pair(atom1, atom2));
1170
}
1171
1172
#[test]
1173
fn test_concat_limit() {
1174
    let mut a = Allocator::new_limited(6);
1175
    let atom1 = a.new_atom(b"f").unwrap();
1176
    let atom2 = a.new_atom(b"o").unwrap();
1177
    let atom3 = a.new_atom(b"o").unwrap();
1178
    let atom4 = a.new_atom(b"b").unwrap();
1179
    let atom5 = a.new_atom(b"a").unwrap();
1180
    let atom6 = a.new_atom(b"r").unwrap();
1181
1182
    // we only have 2 bytes left of allowed heap allocation
1183
    assert_eq!(
1184
        a.new_concat(6, &[atom1, atom2, atom3, atom4, atom5, atom6])
1185
            .unwrap_err()
1186
            .1,
1187
        "out of memory"
1188
    );
1189
    let cat = a.new_concat(2, &[atom1, atom2]).unwrap();
1190
    assert_eq!(a.atom(cat).as_ref(), b"fo");
1191
}
1192
1193
#[cfg(test)]
1194
use rstest::rstest;
1195
1196
#[cfg(test)]
1197
#[rstest]
1198
#[case(0.into(), &[])]
1199
#[case(1.into(), &[1])]
1200
#[case((-1).into(), &[0xff])]
1201
#[case(0x80.into(), &[0, 0x80])]
1202
#[case(0xff.into(), &[0, 0xff])]
1203
#[case(0xffffffff_u64.into(), &[0, 0xff, 0xff, 0xff, 0xff])]
1204
fn test_new_number(#[case] num: Number, #[case] expected: &[u8]) {
1205
    let mut a = Allocator::new();
1206
1207
    // TEST creating the atom from a Number
1208
    let atom = a.new_number(num.clone()).unwrap();
1209
1210
    // make sure we get back the same number
1211
    assert_eq!(a.number(atom), num);
1212
    assert_eq!(a.atom(atom).as_ref(), expected);
1213
    assert_eq!(number_from_u8(expected), num);
1214
1215
    // TEST creating the atom from a buffer
1216
    let atom = a.new_atom(expected).unwrap();
1217
1218
    // make sure we get back the same number
1219
    assert_eq!(a.number(atom), num);
1220
    assert_eq!(a.atom(atom).as_ref(), expected);
1221
    assert_eq!(number_from_u8(expected), num);
1222
}
1223
1224
#[test]
1225
fn test_checkpoints() {
1226
    let mut a = Allocator::new();
1227
1228
    let atom1 = a.new_atom(&[4, 3, 2, 1]).unwrap();
1229
    assert!(a.atom(atom1).as_ref() == [4, 3, 2, 1]);
1230
1231
    let checkpoint = a.checkpoint();
1232
1233
    let atom2 = a.new_atom(&[6, 5, 4, 3]).unwrap();
1234
    assert!(a.atom(atom1).as_ref() == [4, 3, 2, 1]);
1235
    assert!(a.atom(atom2).as_ref() == [6, 5, 4, 3]);
1236
1237
    // at this point we have two atoms and a checkpoint from before the second
1238
    // atom was created
1239
1240
    // now, restoring the checkpoint state will make atom2 disappear
1241
1242
    a.restore_checkpoint(&checkpoint);
1243
1244
    assert!(a.atom(atom1).as_ref() == [4, 3, 2, 1]);
1245
    let atom3 = a.new_atom(&[6, 5, 4, 3]).unwrap();
1246
    assert!(a.atom(atom3).as_ref() == [6, 5, 4, 3]);
1247
1248
    // since atom2 was removed, atom3 should actually be using that slot
1249
    assert_eq!(atom2, atom3);
1250
}
1251
1252
#[cfg(test)]
1253
fn test_g1(a: &Allocator, n: NodePtr) -> EvalErr {
1254
    a.g1(n).unwrap_err()
1255
}
1256
1257
#[cfg(test)]
1258
fn test_g2(a: &Allocator, n: NodePtr) -> EvalErr {
1259
    a.g2(n).unwrap_err()
1260
}
1261
1262
#[cfg(test)]
1263
type TestFun = fn(&Allocator, NodePtr) -> EvalErr;
1264
1265
#[cfg(test)]
1266
#[rstest]
1267
#[case(test_g1, 0, "atom is not G1 size, 48 bytes")]
1268
#[case(test_g1, 3, "atom is not G1 size, 48 bytes")]
1269
#[case(test_g1, 47, "atom is not G1 size, 48 bytes")]
1270
#[case(test_g1, 49, "atom is not G1 size, 48 bytes")]
1271
#[case(test_g1, 48, "atom is not a G1 point")]
1272
#[case(test_g2, 0, "atom is not G2 size, 96 bytes")]
1273
#[case(test_g2, 3, "atom is not G2 size, 96 bytes")]
1274
#[case(test_g2, 95, "atom is not G2 size, 96 bytes")]
1275
#[case(test_g2, 97, "atom is not G2 size, 96 bytes")]
1276
#[case(test_g2, 96, "atom is not a G2 point")]
1277
fn test_point_size_error(#[case] fun: TestFun, #[case] size: usize, #[case] expected: &str) {
1278
    let mut a = Allocator::new();
1279
    let mut buf = Vec::<u8>::new();
1280
    buf.resize(size, 0xcc);
1281
    let n = a.new_atom(&buf).unwrap();
1282
    let r = fun(&a, n);
1283
    assert_eq!(r.0, n);
1284
    assert_eq!(r.1, expected.to_string());
1285
}
1286
1287
#[cfg(test)]
1288
#[rstest]
1289
#[case(test_g1, "pair found, expected G1 point")]
1290
#[case(test_g2, "pair found, expected G2 point")]
1291
fn test_point_atom_pair(#[case] fun: TestFun, #[case] expected: &str) {
1292
    let mut a = Allocator::new();
1293
    let n = a.new_pair(a.nil(), a.one()).unwrap();
1294
    let r = fun(&a, n);
1295
    assert_eq!(r.0, n);
1296
    assert_eq!(r.1, expected.to_string());
1297
}
1298
1299
#[cfg(test)]
1300
#[rstest]
1301
#[case(
1302
    "\
1303
97f1d3a73197d7942695638c4fa9ac0f\
1304
c3688c4f9774b905a14e3a3f171bac58\
1305
6c55e83ff97a1aeffb3af00adb22c6bb"
1306
)]
1307
#[case(
1308
    "\
1309
a572cbea904d67468808c8eb50a9450c\
1310
9721db309128012543902d0ac358a62a\
1311
e28f75bb8f1c7c42c39a8c5529bf0f4e"
1312
)]
1313
fn test_g1_roundtrip(#[case] atom: &str) {
1314
    let mut a = Allocator::new();
1315
    let n = a.new_atom(&hex::decode(atom).unwrap()).unwrap();
1316
    let g1 = a.g1(n).unwrap();
1317
    assert_eq!(hex::encode(g1.to_bytes()), atom);
1318
1319
    let g1_copy = a.new_g1(g1).unwrap();
1320
    let g1_atom = a.atom(g1_copy);
1321
    assert_eq!(hex::encode(g1_atom), atom);
1322
1323
    // try interpreting the point as G1
1324
    assert_eq!(a.g2(n).unwrap_err().1, "atom is not G2 size, 96 bytes");
1325
    assert_eq!(
1326
        a.g2(g1_copy).unwrap_err().1,
1327
        "atom is not G2 size, 96 bytes"
1328
    );
1329
1330
    // try interpreting the point as number
1331
    assert_eq!(a.number(n), number_from_u8(&hex::decode(atom).unwrap()));
1332
    assert_eq!(
1333
        a.number(g1_copy),
1334
        number_from_u8(&hex::decode(atom).unwrap())
1335
    );
1336
}
1337
1338
#[cfg(test)]
1339
#[rstest]
1340
#[case(
1341
    "\
1342
93e02b6052719f607dacd3a088274f65\
1343
596bd0d09920b61ab5da61bbdc7f5049\
1344
334cf11213945d57e5ac7d055d042b7e\
1345
024aa2b2f08f0a91260805272dc51051\
1346
c6e47ad4fa403b02b4510b647ae3d177\
1347
0bac0326a805bbefd48056c8c121bdb8"
1348
)]
1349
#[case(
1350
    "\
1351
aa4edef9c1ed7f729f520e47730a124f\
1352
d70662a904ba1074728114d1031e1572\
1353
c6c886f6b57ec72a6178288c47c33577\
1354
1638533957d540a9d2370f17cc7ed586\
1355
3bc0b995b8825e0ee1ea1e1e4d00dbae\
1356
81f14b0bf3611b78c952aacab827a053"
1357
)]
1358
fn test_g2_roundtrip(#[case] atom: &str) {
1359
    let mut a = Allocator::new();
1360
    let n = a.new_atom(&hex::decode(atom).unwrap()).unwrap();
1361
    let g2 = a.g2(n).unwrap();
1362
    assert_eq!(hex::encode(g2.to_bytes()), atom);
1363
1364
    let g2_copy = a.new_g2(g2).unwrap();
1365
    let g2_atom = a.atom(g2_copy);
1366
    assert_eq!(hex::encode(g2_atom), atom);
1367
1368
    // try interpreting the point as G1
1369
    assert_eq!(a.g1(n).unwrap_err().1, "atom is not G1 size, 48 bytes");
1370
    assert_eq!(
1371
        a.g1(g2_copy).unwrap_err().1,
1372
        "atom is not G1 size, 48 bytes"
1373
    );
1374
1375
    // try interpreting the point as number
1376
    assert_eq!(a.number(n), number_from_u8(&hex::decode(atom).unwrap()));
1377
    assert_eq!(
1378
        a.number(g2_copy),
1379
        number_from_u8(&hex::decode(atom).unwrap())
1380
    );
1381
}
1382
1383
use std::borrow::Borrow;
1384
1385
#[cfg(test)]
1386
type MakeFun = fn(&mut Allocator, &[u8]) -> NodePtr;
1387
1388
#[cfg(test)]
1389
fn make_buf(a: &mut Allocator, bytes: &[u8]) -> NodePtr {
1390
    a.new_atom(bytes).unwrap()
1391
}
1392
1393
#[cfg(test)]
1394
fn make_number(a: &mut Allocator, bytes: &[u8]) -> NodePtr {
1395
    let v = number_from_u8(bytes);
1396
    a.new_number(v).unwrap()
1397
}
1398
1399
#[cfg(test)]
1400
fn make_g1(a: &mut Allocator, bytes: &[u8]) -> NodePtr {
1401
    let v = G1Element::from_bytes(bytes.try_into().unwrap()).unwrap();
1402
    a.new_g1(v).unwrap()
1403
}
1404
1405
#[cfg(test)]
1406
fn make_g2(a: &mut Allocator, bytes: &[u8]) -> NodePtr {
1407
    let v = G2Element::from_bytes(bytes.try_into().unwrap()).unwrap();
1408
    a.new_g2(v).unwrap()
1409
}
1410
1411
#[cfg(test)]
1412
fn make_g1_fail(a: &mut Allocator, bytes: &[u8]) -> NodePtr {
1413
    assert!(<[u8; 48]>::try_from(bytes).is_err());
1414
    a.new_atom(bytes).unwrap()
1415
}
1416
1417
#[cfg(test)]
1418
fn make_g2_fail(a: &mut Allocator, bytes: &[u8]) -> NodePtr {
1419
    assert!(<[u8; 96]>::try_from(bytes).is_err());
1420
    a.new_atom(bytes).unwrap()
1421
}
1422
1423
#[cfg(test)]
1424
type CheckFun = fn(&Allocator, NodePtr, &[u8]);
1425
1426
#[cfg(test)]
1427
fn check_buf(a: &Allocator, n: NodePtr, bytes: &[u8]) {
1428
    let buf = a.atom(n);
1429
    assert_eq!(buf.as_ref(), bytes);
1430
}
1431
1432
#[cfg(test)]
1433
fn check_number(a: &Allocator, n: NodePtr, bytes: &[u8]) {
1434
    let num = a.number(n);
1435
    let v = number_from_u8(bytes);
1436
    assert_eq!(num, v);
1437
}
1438
1439
#[cfg(test)]
1440
fn check_g1(a: &Allocator, n: NodePtr, bytes: &[u8]) {
1441
    let num = a.g1(n).unwrap();
1442
    let v = G1Element::from_bytes(bytes.try_into().unwrap()).unwrap();
1443
    assert_eq!(num, v);
1444
}
1445
1446
#[cfg(test)]
1447
fn check_g2(a: &Allocator, n: NodePtr, bytes: &[u8]) {
1448
    let num = a.g2(n).unwrap();
1449
    let v = G2Element::from_bytes(bytes.try_into().unwrap()).unwrap();
1450
    assert_eq!(num, v);
1451
}
1452
1453
#[cfg(test)]
1454
fn check_g1_fail(a: &Allocator, n: NodePtr, bytes: &[u8]) {
1455
    assert_eq!(a.g1(n).unwrap_err().0, n);
1456
    assert!(<[u8; 48]>::try_from(bytes).is_err());
1457
}
1458
1459
#[cfg(test)]
1460
fn check_g2_fail(a: &Allocator, n: NodePtr, bytes: &[u8]) {
1461
    assert_eq!(a.g2(n).unwrap_err().0, n);
1462
    assert!(<[u8; 96]>::try_from(bytes).is_err());
1463
}
1464
1465
#[cfg(test)]
1466
const EMPTY: &str = "";
1467
1468
#[cfg(test)]
1469
const SMALL_BUF: &str = "133742";
1470
1471
#[cfg(test)]
1472
const VALID_G1: &str = "\
1473
a572cbea904d67468808c8eb50a9450c\
1474
9721db309128012543902d0ac358a62a\
1475
e28f75bb8f1c7c42c39a8c5529bf0f4e";
1476
1477
#[cfg(test)]
1478
const VALID_G2: &str = "\
1479
aa4edef9c1ed7f729f520e47730a124f\
1480
d70662a904ba1074728114d1031e1572\
1481
c6c886f6b57ec72a6178288c47c33577\
1482
1638533957d540a9d2370f17cc7ed586\
1483
3bc0b995b8825e0ee1ea1e1e4d00dbae\
1484
81f14b0bf3611b78c952aacab827a053";
1485
1486
/*
1487
  We want to exercise round-tripping avery kind of value via every other kind
1488
  of value (as far as possible). e.g. Every value can round-trip through a byte buffer
1489
  or a number, but G1 cannot round-trip via G2.
1490
1491
  +-----------+--------+--------+------+------+
1492
  | from / to | buffer | number | G1   | G2   |
1493
  +-----------+--------+--------+------+------+
1494
  | buffer    | o      | o      | -    | -    |
1495
  | number    | o      | o      | -    | -    |
1496
  | G1        | o      | o      | o    | -    |
1497
  | G2        | o      | o      | -    | o    |
1498
  +-----------+--------+--------+------+------+
1499
1500
*/
1501
1502
#[cfg(test)]
1503
#[rstest]
1504
// round trip empty buffer
1505
#[case(EMPTY, make_buf, check_buf)]
1506
#[case(EMPTY, make_buf, check_number)]
1507
#[case(EMPTY, make_buf, check_g1_fail)]
1508
#[case(EMPTY, make_buf, check_g2_fail)]
1509
#[case(EMPTY, make_number, check_buf)]
1510
#[case(EMPTY, make_number, check_number)]
1511
#[case(EMPTY, make_number, check_g1_fail)]
1512
#[case(EMPTY, make_number, check_g2_fail)]
1513
#[case(EMPTY, make_g1_fail, check_buf)]
1514
#[case(EMPTY, make_g1_fail, check_number)]
1515
#[case(EMPTY, make_g1_fail, check_g1_fail)]
1516
#[case(EMPTY, make_g1_fail, check_g2_fail)]
1517
#[case(EMPTY, make_g2_fail, check_buf)]
1518
#[case(EMPTY, make_g2_fail, check_number)]
1519
#[case(EMPTY, make_g2_fail, check_g1_fail)]
1520
#[case(EMPTY, make_g2_fail, check_g2_fail)]
1521
// round trip small buffer
1522
#[case(SMALL_BUF, make_buf, check_buf)]
1523
#[case(SMALL_BUF, make_buf, check_number)]
1524
#[case(SMALL_BUF, make_buf, check_g1_fail)]
1525
#[case(SMALL_BUF, make_buf, check_g2_fail)]
1526
#[case(SMALL_BUF, make_number, check_buf)]
1527
#[case(SMALL_BUF, make_number, check_number)]
1528
#[case(SMALL_BUF, make_number, check_g1_fail)]
1529
#[case(SMALL_BUF, make_number, check_g2_fail)]
1530
#[case(SMALL_BUF, make_g1_fail, check_buf)]
1531
#[case(SMALL_BUF, make_g1_fail, check_number)]
1532
#[case(SMALL_BUF, make_g1_fail, check_g1_fail)]
1533
#[case(SMALL_BUF, make_g1_fail, check_g2_fail)]
1534
#[case(SMALL_BUF, make_g2_fail, check_buf)]
1535
#[case(SMALL_BUF, make_g2_fail, check_number)]
1536
#[case(SMALL_BUF, make_g2_fail, check_g1_fail)]
1537
#[case(SMALL_BUF, make_g2_fail, check_g2_fail)]
1538
// round trip G1 point
1539
#[case(VALID_G1, make_buf, check_buf)]
1540
#[case(VALID_G1, make_buf, check_number)]
1541
#[case(VALID_G1, make_buf, check_g1)]
1542
#[case(VALID_G1, make_buf, check_g2_fail)]
1543
#[case(VALID_G1, make_number, check_buf)]
1544
#[case(VALID_G1, make_number, check_number)]
1545
#[case(VALID_G1, make_number, check_g1)]
1546
#[case(VALID_G1, make_number, check_g2_fail)]
1547
#[case(VALID_G1, make_g1, check_buf)]
1548
#[case(VALID_G1, make_g1, check_number)]
1549
#[case(VALID_G1, make_g1, check_g1)]
1550
#[case(VALID_G1, make_g1, check_g2_fail)]
1551
#[case(VALID_G1, make_g2_fail, check_buf)]
1552
#[case(VALID_G1, make_g2_fail, check_number)]
1553
#[case(VALID_G1, make_g2_fail, check_g1)]
1554
#[case(VALID_G1, make_g2_fail, check_g2_fail)]
1555
// round trip G2 point
1556
#[case(VALID_G2, make_buf, check_buf)]
1557
#[case(VALID_G2, make_buf, check_number)]
1558
#[case(VALID_G2, make_buf, check_g1_fail)]
1559
#[case(VALID_G2, make_buf, check_g2)]
1560
#[case(VALID_G2, make_number, check_buf)]
1561
#[case(VALID_G2, make_number, check_number)]
1562
#[case(VALID_G2, make_number, check_g1_fail)]
1563
#[case(VALID_G2, make_number, check_g2)]
1564
#[case(VALID_G2, make_g1_fail, check_buf)]
1565
#[case(VALID_G2, make_g1_fail, check_number)]
1566
#[case(VALID_G2, make_g1_fail, check_g1_fail)]
1567
#[case(VALID_G2, make_g1_fail, check_g2)]
1568
#[case(VALID_G2, make_g2, check_buf)]
1569
#[case(VALID_G2, make_g2, check_number)]
1570
#[case(VALID_G2, make_g2, check_g1_fail)]
1571
#[case(VALID_G2, make_g2, check_g2)]
1572
fn test_roundtrip(#[case] test_value: &str, #[case] make: MakeFun, #[case] check: CheckFun) {
1573
    let value = hex::decode(test_value).unwrap();
1574
    let mut a = Allocator::new();
1575
    let node = make(&mut a, &value);
1576
    check(&a, node, &value);
1577
}
1578
1579
#[cfg(test)]
1580
#[rstest]
1581
#[case(&[], 0)]
1582
#[case(&[1], 1)]
1583
#[case(&[1,2], 2)]
1584
#[case(&[1,2,3,4,5,6,7,8,9], 9)]
1585
#[case(&[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18], 18)]
1586
fn test_atom_len(#[case] buf: &[u8], #[case] expected: usize) {
1587
    let mut a = Allocator::new();
1588
    let atom = a.new_atom(buf).unwrap();
1589
    assert_eq!(a.atom_len(atom), expected);
1590
}
1591
1592
#[cfg(test)]
1593
#[rstest]
1594
#[case(0.into(), 0)]
1595
#[case(42.into(), 1)]
1596
#[case(127.into(), 1)]
1597
#[case(1337.into(), 2)]
1598
#[case(0x7fffff.into(), 3)]
1599
#[case(0xffffff.into(), 4)]
1600
#[case((-1).into(), 1)]
1601
#[case((-128).into(), 1)]
1602
fn test_atom_len_number(#[case] value: Number, #[case] expected: usize) {
1603
    let mut a = Allocator::new();
1604
    let atom = a.new_number(value).unwrap();
1605
    assert_eq!(a.atom_len(atom), expected);
1606
}
1607
1608
#[cfg(test)]
1609
#[rstest]
1610
#[case(
1611
    "\
1612
97f1d3a73197d7942695638c4fa9ac0f\
1613
c3688c4f9774b905a14e3a3f171bac58\
1614
6c55e83ff97a1aeffb3af00adb22c6bb",
1615
    48
1616
)]
1617
#[case(
1618
    "\
1619
a572cbea904d67468808c8eb50a9450c\
1620
9721db309128012543902d0ac358a62a\
1621
e28f75bb8f1c7c42c39a8c5529bf0f4e",
1622
    48
1623
)]
1624
fn test_atom_len_g1(#[case] buffer_hex: &str, #[case] expected: usize) {
1625
    let mut a = Allocator::new();
1626
    let buffer = &hex::decode(buffer_hex).unwrap();
1627
    let g1 = G1Element::from_bytes(&buffer[..].try_into().unwrap()).expect("invalid G1 point");
1628
    let atom = a.new_g1(g1).unwrap();
1629
    assert_eq!(a.atom_len(atom), expected);
1630
}
1631
1632
#[cfg(test)]
1633
#[rstest]
1634
#[case(
1635
    "\
1636
93e02b6052719f607dacd3a088274f65\
1637
596bd0d09920b61ab5da61bbdc7f5049\
1638
334cf11213945d57e5ac7d055d042b7e\
1639
024aa2b2f08f0a91260805272dc51051\
1640
c6e47ad4fa403b02b4510b647ae3d177\
1641
0bac0326a805bbefd48056c8c121bdb8",
1642
    96
1643
)]
1644
#[case(
1645
    "\
1646
aa4edef9c1ed7f729f520e47730a124f\
1647
d70662a904ba1074728114d1031e1572\
1648
c6c886f6b57ec72a6178288c47c33577\
1649
1638533957d540a9d2370f17cc7ed586\
1650
3bc0b995b8825e0ee1ea1e1e4d00dbae\
1651
81f14b0bf3611b78c952aacab827a053",
1652
    96
1653
)]
1654
fn test_atom_len_g2(#[case] buffer_hex: &str, #[case] expected: usize) {
1655
    let mut a = Allocator::new();
1656
1657
    let buffer = &hex::decode(buffer_hex).unwrap();
1658
    let g2 = G2Element::from_bytes(&buffer[..].try_into().unwrap()).expect("invalid G2 point");
1659
    let atom = a.new_g2(g2).unwrap();
1660
    assert_eq!(a.atom_len(atom), expected);
1661
}
1662
1663
#[cfg(test)]
1664
#[rstest]
1665
#[case(0.into())]
1666
#[case(1.into())]
1667
#[case(0x7f.into())]
1668
#[case(0x80.into())]
1669
#[case(0xff.into())]
1670
#[case(0x100.into())]
1671
#[case(0x7fff.into())]
1672
#[case(0x8000.into())]
1673
#[case(0xffff.into())]
1674
#[case(0x10000.into())]
1675
#[case(0x7ffff.into())]
1676
#[case(0x80000.into())]
1677
#[case(0xfffff.into())]
1678
#[case(0x100000.into())]
1679
#[case(0x7ffffff.into())]
1680
#[case(0x8000000.into())]
1681
#[case(0xfffffff.into())]
1682
#[case(0x10000000.into())]
1683
#[case(0x7ffffffff_u64.into())]
1684
#[case(0x8000000000_u64.into())]
1685
#[case(0xffffffffff_u64.into())]
1686
#[case(0x10000000000_u64.into())]
1687
#[case((-1).into())]
1688
#[case((-0x7f).into())]
1689
#[case((-0x80).into())]
1690
#[case((-0xff).into())]
1691
#[case((-0x100).into())]
1692
#[case((-0x7fff).into())]
1693
#[case((-0x8000).into())]
1694
#[case((-0xffff).into())]
1695
#[case((-0x10000).into())]
1696
#[case((-0x7ffff).into())]
1697
#[case((-0x80000).into())]
1698
#[case((-0xfffff).into())]
1699
#[case((-0x100000).into())]
1700
#[case((-0x7ffffff_i64).into())]
1701
#[case((-0x8000000_i64).into())]
1702
#[case((-0xfffffff_i64).into())]
1703
#[case((-0x10000000_i64).into())]
1704
#[case((-0x7ffffffff_i64).into())]
1705
#[case((-0x8000000000_i64).into())]
1706
#[case((-0xffffffffff_i64).into())]
1707
#[case((-0x10000000000_i64).into())]
1708
fn test_number_roundtrip(#[case] value: Number) {
1709
    let mut a = Allocator::new();
1710
    let atom = a.new_number(value.clone()).expect("new_number()");
1711
    assert_eq!(a.number(atom), value);
1712
}
1713
1714
#[cfg(test)]
1715
#[rstest]
1716
#[case(0)]
1717
#[case(1)]
1718
#[case(0x7f)]
1719
#[case(0x80)]
1720
#[case(0xff)]
1721
#[case(0x100)]
1722
#[case(0x7fff)]
1723
#[case(0x8000)]
1724
#[case(0xffff)]
1725
#[case(0x10000)]
1726
#[case(0x7ffff)]
1727
#[case(0x80000)]
1728
#[case(0xfffff)]
1729
#[case(0x100000)]
1730
#[case(0x7fffff)]
1731
#[case(0x800000)]
1732
#[case(0xffffff)]
1733
#[case(0x1000000)]
1734
#[case(0x3ffffff)]
1735
fn test_small_number_roundtrip(#[case] value: u32) {
1736
    let mut a = Allocator::new();
1737
    let atom = a.new_small_number(value).expect("new_small_number()");
1738
    assert_eq!(a.small_number(atom).expect("small_number()"), value);
1739
}
1740
1741
#[cfg(test)]
1742
#[rstest]
1743
#[case(0.into(), true)]
1744
#[case(1.into(), true)]
1745
#[case(0x3ffffff.into(), true)]
1746
#[case(0x4000000.into(), false)]
1747
#[case(0x7f.into(), true)]
1748
#[case(0x80.into(), true)]
1749
#[case(0xff.into(), true)]
1750
#[case(0x100.into(), true)]
1751
#[case(0x7fff.into(), true)]
1752
#[case(0x8000.into(), true)]
1753
#[case(0xffff.into(), true)]
1754
#[case(0x10000.into(), true)]
1755
#[case(0x7ffff.into(), true)]
1756
#[case(0x80000.into(), true)]
1757
#[case(0xfffff.into(), true)]
1758
#[case(0x100000.into(), true)]
1759
#[case(0x7ffffff.into(), false)]
1760
#[case(0x8000000.into(), false)]
1761
#[case(0xfffffff.into(), false)]
1762
#[case(0x10000000.into(), false)]
1763
#[case(0x7ffffffff_u64.into(), false)]
1764
#[case(0x8000000000_u64.into(), false )]
1765
#[case(0xffffffffff_u64.into(), false)]
1766
#[case(0x10000000000_u64.into(), false)]
1767
#[case((-1).into(), false)]
1768
#[case((-0x7f).into(), false)]
1769
#[case((-0x80).into(), false)]
1770
#[case((-0x10000000000_i64).into(), false)]
1771
fn test_auto_small_number(#[case] value: Number, #[case] expect_small: bool) {
1772
    let mut a = Allocator::new();
1773
    let atom = a.new_number(value.clone()).expect("new_number()");
1774
    assert_eq!(a.small_number(atom).is_some(), expect_small);
1775
    if let Some(v) = a.small_number(atom) {
1776
        use num_traits::ToPrimitive;
1777
        assert_eq!(v, value.to_u32().unwrap());
1778
    }
1779
    assert_eq!(a.number(atom), value);
1780
}
1781
1782
#[cfg(test)]
1783
#[rstest]
1784
// redundant leading zeros are not canoncial
1785
#[case(&[0x00], false)]
1786
#[case(&[0x00, 0x7f], false)]
1787
// negative numbers cannot be small ints
1788
#[case(&[0x80], false)]
1789
#[case(&[0xff], false)]
1790
#[case(&[0xff, 0xff], false)]
1791
#[case(&[0x80, 0xff, 0xff], false)]
1792
// small positive intergers can be small
1793
#[case(&[0x01], true)]
1794
#[case(&[0x00, 0xff], true)]
1795
#[case(&[0x7f, 0xff], true)]
1796
#[case(&[0x7f, 0xff, 0xff], true)]
1797
#[case(&[0x00, 0xff, 0xff, 0xff], true)]
1798
#[case(&[0x02, 0x00, 0x00, 0x00], true)]
1799
#[case(&[0x03, 0xff, 0xff, 0xff], true)]
1800
// too big
1801
#[case(&[0x04, 0x00, 0x00, 0x00], false)]
1802
fn test_auto_small_number_from_buf(#[case] buf: &[u8], #[case] expect_small: bool) {
1803
    let mut a = Allocator::new();
1804
    let atom = a.new_atom(buf).expect("new_atom()");
1805
    assert_eq!(a.small_number(atom).is_some(), expect_small);
1806
    if let Some(v) = a.small_number(atom) {
1807
        use num_traits::ToPrimitive;
1808
        assert_eq!(v, a.number(atom).to_u32().expect("to_u32()"));
1809
    }
1810
    assert_eq!(buf, a.atom(atom).as_ref());
1811
}
1812
1813
#[cfg(test)]
1814
#[rstest]
1815
// redundant leading zeros are not canoncial
1816
#[case(&[0x00], None)]
1817
#[case(&[0x00, 0x7f], None)]
1818
// negative numbers cannot be small ints
1819
#[case(&[0x80], None)]
1820
#[case(&[0xff], None)]
1821
// redundant leading 0xff are still negative
1822
#[case(&[0xff, 0xff], None)]
1823
#[case(&[0x80, 0xff, 0xff], None)]
1824
// to big
1825
#[case(&[0x04, 0x00, 0x00, 0x00], None)]
1826
#[case(&[0x05, 0x00, 0x00, 0x00], None)]
1827
#[case(&[0x04, 0x00, 0x00, 0x00, 0x00], None)]
1828
// small positive intergers can be small
1829
#[case(&[0x01], Some(0x01))]
1830
#[case(&[0x00, 0x80], Some(0x80))]
1831
#[case(&[0x00, 0xff], Some(0xff))]
1832
#[case(&[0x7f, 0xff], Some(0x7fff))]
1833
#[case(&[0x00, 0x80, 0x00], Some(0x8000))]
1834
#[case(&[0x00, 0xff, 0xff], Some(0xffff))]
1835
#[case(&[0x7f, 0xff, 0xff], Some(0x7fffff))]
1836
#[case(&[0x00, 0x80, 0x00, 0x00], Some(0x800000))]
1837
#[case(&[0x00, 0xff, 0xff, 0xff], Some(0xffffff))]
1838
#[case(&[0x02, 0x00, 0x00, 0x00], Some(0x2000000))]
1839
#[case(&[0x03, 0x00, 0x00, 0x00], Some(0x3000000))]
1840
#[case(&[0x03, 0xff, 0xff, 0xff], Some(0x3ffffff))]
1841
fn test_fits_in_small_atom(#[case] buf: &[u8], #[case] expected: Option<u32>) {
1842
    assert_eq!(fits_in_small_atom(buf), expected);
1843
}
1844
1845
#[cfg(test)]
1846
#[rstest]
1847
// 0 is encoded as an empty string
1848
#[case(&[0], "0", &[])]
1849
#[case(&[1], "1", &[1])]
1850
// leading zeroes are redundant
1851
#[case(&[0,0,0,1], "1", &[1])]
1852
#[case(&[0,0,0x80], "128", &[0, 0x80])]
1853
// A leading zero is necessary to encode a positive number with the
1854
// penultimate byte's most significant bit set
1855
#[case(&[0,0xff], "255", &[0, 0xff])]
1856
#[case(&[0x7f,0xff], "32767", &[0x7f, 0xff])]
1857
// the first byte is redundant, it's still -1
1858
#[case(&[0xff,0xff], "-1", &[0xff])]
1859
#[case(&[0xff], "-1", &[0xff])]
1860
#[case(&[0,0,0x80,0], "32768", &[0,0x80,0])]
1861
#[case(&[0,0,0x40,0], "16384", &[0x40,0])]
1862
fn test_number_to_atom(#[case] bytes: &[u8], #[case] text: &str, #[case] buf: &[u8]) {
1863
    let mut a = Allocator::new();
1864
1865
    // 0 is encoded as an empty string
1866
    let num = number_from_u8(bytes);
1867
    assert_eq!(format!("{}", num), text);
1868
    let ptr = a.new_number(num).unwrap();
1869
    assert_eq!(a.atom(ptr).as_ref(), buf);
1870
}
/home/oof/clvm_rs/src/bls_ops.rs
Line
Count
Source
1
use crate::allocator::{Allocator, Atom, NodePtr};
2
use crate::cost::{check_cost, Cost};
3
use crate::err_utils::err;
4
use crate::op_utils::{
5
    atom, first, get_args, get_varargs, int_atom, mod_group_order, new_atom_and_cost, nilp, rest,
6
    MALLOC_COST_PER_BYTE,
7
};
8
use crate::reduction::{EvalErr, Reduction, Response};
9
use chia_bls::{
10
    aggregate_pairing, aggregate_verify, hash_to_g1_with_dst, hash_to_g2_with_dst, G1Element,
11
    G2Element, PublicKey,
12
};
13
14
// the same cost as point_add (aka g1_add)
15
const BLS_G1_SUBTRACT_BASE_COST: Cost = 101094;
16
const BLS_G1_SUBTRACT_COST_PER_ARG: Cost = 1343980;
17
18
const BLS_G1_MULTIPLY_BASE_COST: Cost = 705500;
19
const BLS_G1_MULTIPLY_COST_PER_BYTE: Cost = 10;
20
21
// this is the same cost as XORing the top bit (minus the heap allocation of the
22
// return value, which the operator is adding back)
23
const BLS_G1_NEGATE_BASE_COST: Cost = 1396 - 480;
24
25
// g2_add and g2_subtract have the same cost
26
const BLS_G2_ADD_BASE_COST: Cost = 80000;
27
const BLS_G2_ADD_COST_PER_ARG: Cost = 1950000;
28
const BLS_G2_SUBTRACT_BASE_COST: Cost = 80000;
29
const BLS_G2_SUBTRACT_COST_PER_ARG: Cost = 1950000;
30
31
const BLS_G2_MULTIPLY_BASE_COST: Cost = 2100000;
32
const BLS_G2_MULTIPLY_COST_PER_BYTE: Cost = 5;
33
34
// this is the same cost as XORing the top bit (minus the heap allocation of the
35
// return value, which the operator is adding back)
36
const BLS_G2_NEGATE_BASE_COST: Cost = 2164 - 960;
37
38
const BLS_MAP_TO_G1_BASE_COST: Cost = 195000;
39
const BLS_MAP_TO_G1_COST_PER_BYTE: Cost = 4;
40
const BLS_MAP_TO_G1_COST_PER_DST_BYTE: Cost = 4;
41
42
const BLS_MAP_TO_G2_BASE_COST: Cost = 815000;
43
const BLS_MAP_TO_G2_COST_PER_BYTE: Cost = 4;
44
const BLS_MAP_TO_G2_COST_PER_DST_BYTE: Cost = 4;
45
46
const BLS_PAIRING_BASE_COST: Cost = 3000000;
47
const BLS_PAIRING_COST_PER_ARG: Cost = 1200000;
48
49
const DST_G2: &[u8; 43] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_";
50
51
2.09k
pub fn op_bls_g1_subtract(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
52
2.09k
    let mut cost = BLS_G1_SUBTRACT_BASE_COST;
53
2.09k
    check_cost(a, cost, max_cost)?;
54
2.08k
    let mut total = G1Element::default();
55
2.08k
    let mut is_first = true;
56
6.00k
    while let Some((arg, rest)) = a.next(input) {
57
3.99k
        input = rest;
58
3.99k
        let point = a.g1(arg)?;
59
3.92k
        cost += BLS_G1_SUBTRACT_COST_PER_ARG;
60
3.92k
        check_cost(a, cost, max_cost)?;
61
3.92k
        if is_first {
62
1.97k
            total = point;
63
1.97k
        } else {
64
1.94k
            total -= &point;
65
1.94k
        };
66
3.92k
        is_first = false;
67
    }
68
    Ok(Reduction(
69
2.00k
        cost + 48 * MALLOC_COST_PER_BYTE,
70
2.00k
        a.new_g1(total)?,
71
    ))
72
2.09k
}
73
74
5.51k
pub fn op_bls_g1_multiply(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
75
5.51k
    let [point, scalar] = get_args::<2>(a, input, "g1_multiply")?;
76
77
5.48k
    let mut cost = BLS_G1_MULTIPLY_BASE_COST;
78
5.48k
    check_cost(a, cost, max_cost)?;
79
80
5.47k
    let mut total = a.g1(point)?;
81
5.38k
    let (scalar, scalar_len) = int_atom(a, scalar, "g1_multiply")?;
82
5.37k
    cost += scalar_len as Cost * BLS_G1_MULTIPLY_COST_PER_BYTE;
83
5.37k
    check_cost(a, cost, max_cost)?;
84
85
5.37k
    let scalar = mod_group_order(scalar);
86
5.37k
    total.scalar_multiply(scalar.to_bytes_be().1.as_slice());
87
5.37k
88
5.37k
    Ok(Reduction(
89
5.37k
        cost + 48 * MALLOC_COST_PER_BYTE,
90
5.37k
        a.new_g1(total)?,
91
    ))
92
5.51k
}
93
94
1.80k
pub fn op_bls_g1_negate(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
95
1.80k
    let [point] = get_args::<1>(a, input, "g1_negate")?;
96
97
1.76k
    let blob = atom(a, point, "G1 atom")?;
98
    // this is here to validate the point
99
1.71k
    let _g1 = G1Element::from_bytes(
100
1.75k
        blob.as_ref()
101
1.75k
            .try_into()
102
1.75k
            .map_err(|_| EvalErr(point, "atom is not G1 size, 48 bytes".to_string()))?,
103
    )
104
1.73k
    .map_err(|_| EvalErr(point, "atom is not a valid G1 point".to_string()))?;
105
106
1.71k
    if (blob.as_ref()[0] & 0xe0) == 0xc0 {
107
        // This is compressed infinity. negating it is a no-op
108
        // we can just pass through the same atom as we received. We'll charge
109
        // the allocation cost anyway, for consistency
110
543
        Ok(Reduction(
111
543
            BLS_G1_NEGATE_BASE_COST + 48 * MALLOC_COST_PER_BYTE,
112
543
            point,
113
543
        ))
114
    } else {
115
1.17k
        let mut blob: [u8; 48] = blob.as_ref().try_into().unwrap();
116
1.17k
        blob[0] ^= 0x20;
117
1.17k
        new_atom_and_cost(a, BLS_G1_NEGATE_BASE_COST, &blob)
118
    }
119
1.80k
}
120
121
3.05k
pub fn op_bls_g2_add(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
122
3.05k
    let mut cost = BLS_G2_ADD_BASE_COST;
123
3.05k
    check_cost(a, cost, max_cost)?;
124
3.04k
    let mut total = G2Element::default();
125
6.86k
    while let Some((arg, rest)) = a.next(input) {
126
3.88k
        input = rest;
127
3.88k
        let point = a.g2(arg)?;
128
3.82k
        cost += BLS_G2_ADD_COST_PER_ARG;
129
3.82k
        check_cost(a, cost, max_cost)?;
130
3.82k
        total += &point;
131
    }
132
    Ok(Reduction(
133
2.97k
        cost + 96 * MALLOC_COST_PER_BYTE,
134
2.97k
        a.new_g2(total)?,
135
    ))
136
3.05k
}
137
138
2.02k
pub fn op_bls_g2_subtract(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
139
2.02k
    let mut cost = BLS_G2_SUBTRACT_BASE_COST;
140
2.02k
    check_cost(a, cost, max_cost)?;
141
2.01k
    let mut total = G2Element::default();
142
2.01k
    let mut is_first = true;
143
5.81k
    while let Some((arg, rest)) = a.next(input) {
144
3.88k
        input = rest;
145
3.88k
        let point = a.g2(arg)?;
146
3.79k
        cost += BLS_G2_SUBTRACT_COST_PER_ARG;
147
3.79k
        check_cost(a, cost, max_cost)?;
148
3.79k
        if is_first {
149
1.91k
            total = point;
150
1.91k
        } else {
151
1.88k
            total -= &point;
152
1.88k
        };
153
3.79k
        is_first = false;
154
    }
155
    Ok(Reduction(
156
1.92k
        cost + 96 * MALLOC_COST_PER_BYTE,
157
1.92k
        a.new_g2(total)?,
158
    ))
159
2.02k
}
160
161
5.48k
pub fn op_bls_g2_multiply(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
162
5.48k
    let [point, scalar] = get_args::<2>(a, input, "g2_multiply")?;
163
164
5.45k
    let mut cost = BLS_G2_MULTIPLY_BASE_COST;
165
5.45k
    check_cost(a, cost, max_cost)?;
166
167
5.44k
    let mut total = a.g2(point)?;
168
5.39k
    let (scalar, scalar_len) = int_atom(a, scalar, "g2_multiply")?;
169
5.38k
    cost += scalar_len as Cost * BLS_G2_MULTIPLY_COST_PER_BYTE;
170
5.38k
    check_cost(a, cost, max_cost)?;
171
172
5.38k
    let scalar = mod_group_order(scalar);
173
5.38k
    total.scalar_multiply(scalar.to_bytes_be().1.as_slice());
174
5.38k
175
5.38k
    Ok(Reduction(
176
5.38k
        cost + 96 * MALLOC_COST_PER_BYTE,
177
5.38k
        a.new_g2(total)?,
178
    ))
179
5.48k
}
180
181
1.67k
pub fn op_bls_g2_negate(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
182
1.67k
    let [point] = get_args::<1>(a, input, "g2_negate")?;
183
184
    // we don't validate the point. We may want to soft fork-in validating the
185
    // point once the allocator preserves native representation of points
186
1.65k
    let blob_atom = atom(a, point, "G2 atom")?;
187
1.64k
    let blob = blob_atom.as_ref();
188
189
    // this is here to validate the point
190
1.58k
    let _g2 = G2Element::from_bytes(
191
1.64k
        blob.as_ref()
192
1.64k
            .try_into()
193
1.64k
            .map_err(|_| EvalErr(point, "atom is not G2 size, 96 bytes".to_string()))?,
194
    )
195
1.60k
    .map_err(|_| EvalErr(point, "atom is not a valid G2 point".to_string()))?;
196
197
1.58k
    if (blob[0] & 0xe0) == 0xc0 {
198
        // This is compressed infinity. negating it is a no-op
199
        // we can just pass through the same atom as we received. We'll charge
200
        // the allocation cost anyway, for consistency
201
519
        Ok(Reduction(
202
519
            BLS_G2_NEGATE_BASE_COST + 96 * MALLOC_COST_PER_BYTE,
203
519
            point,
204
519
        ))
205
    } else {
206
1.07k
        let mut blob: [u8; 96] = blob.as_ref().try_into().unwrap();
207
1.07k
        blob[0] ^= 0x20;
208
1.07k
        new_atom_and_cost(a, BLS_G2_NEGATE_BASE_COST, &blob)
209
    }
210
1.67k
}
211
212
4.47k
pub fn op_bls_map_to_g1(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
213
4.47k
    let ([msg, dst], argc) = get_varargs::<2>(a, input, "g1_map")?;
214
4.45k
    if !(1..=2).contains(&argc) {
215
9
        return err(input, "g1_map takes exactly 1 or 2 arguments");
216
4.44k
    }
217
4.44k
    let mut cost: Cost = BLS_MAP_TO_G1_BASE_COST;
218
4.44k
    check_cost(a, cost, max_cost)?;
219
220
4.43k
    let msg = atom(a, msg, "g1_map")?;
221
4.42k
    cost += msg.as_ref().len() as Cost * BLS_MAP_TO_G1_COST_PER_BYTE;
222
4.42k
    check_cost(a, cost, max_cost)?;
223
224
4.42k
    let dst = if argc == 2 {
225
2.55k
        atom(a, dst, "g1_map")?
226
    } else {
227
1.86k
        Atom::Borrowed(b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_".as_slice())
228
    };
229
230
4.41k
    cost += dst.as_ref().len() as Cost * BLS_MAP_TO_G1_COST_PER_DST_BYTE;
231
4.41k
    check_cost(a, cost, max_cost)?;
232
233
4.41k
    let point = hash_to_g1_with_dst(msg.as_ref(), dst.as_ref());
234
4.41k
    Ok(Reduction(
235
4.41k
        cost + 48 * MALLOC_COST_PER_BYTE,
236
4.41k
        a.new_g1(point)?,
237
    ))
238
4.47k
}
239
240
4.16k
pub fn op_bls_map_to_g2(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
241
4.16k
    let ([msg, dst], argc) = get_varargs::<2>(a, input, "g2_map")?;
242
4.15k
    if !(1..=2).contains(&argc) {
243
12
        return err(input, "g2_map takes exactly 1 or 2 arguments");
244
4.14k
    }
245
4.14k
    let mut cost: Cost = BLS_MAP_TO_G2_BASE_COST;
246
4.14k
    check_cost(a, cost, max_cost)?;
247
248
4.13k
    let msg = atom(a, msg, "g2_map")?;
249
4.12k
    cost += msg.as_ref().len() as Cost * BLS_MAP_TO_G2_COST_PER_BYTE;
250
251
4.12k
    let dst = if argc == 2 {
252
2.41k
        atom(a, dst, "g2_map")?
253
    } else {
254
1.71k
        Atom::Borrowed(DST_G2.as_slice())
255
    };
256
257
4.12k
    cost += dst.as_ref().len() as Cost * BLS_MAP_TO_G2_COST_PER_DST_BYTE;
258
4.12k
    check_cost(a, cost, max_cost)?;
259
260
4.12k
    let point = hash_to_g2_with_dst(msg.as_ref(), dst.as_ref());
261
4.12k
    Ok(Reduction(
262
4.12k
        cost + 96 * MALLOC_COST_PER_BYTE,
263
4.12k
        a.new_g2(point)?,
264
    ))
265
4.16k
}
266
267
// This operator takes a variable number of G1 and G2 points. The points must
268
// come in pairs (as a "flat" argument list).
269
// It performs a low-level pairing operation of the (G1, G2)-pairs
270
// and returns if the resulting Gt point is the
271
// identity, otherwise terminates the program with a validation error.
272
3.11k
pub fn op_bls_pairing_identity(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
273
3.11k
    let mut cost = BLS_PAIRING_BASE_COST;
274
3.11k
    check_cost(a, cost, max_cost)?;
275
3.10k
    let mut items = Vec::<(G1Element, G2Element)>::new();
276
3.10k
277
3.10k
    let mut args = input;
278
3.10k
    while !nilp(a, args) {
279
3.08k
        cost += BLS_PAIRING_COST_PER_ARG;
280
3.08k
        check_cost(a, cost, max_cost)?;
281
3.08k
        let g1 = a.g1(first(a, args)?)?;
282
6
        args = rest(a, args)?;
283
6
        let g2 = a.g2(first(a, args)?)?;
284
0
        args = rest(a, args)?;
285
0
        items.push((g1, g2));
286
    }
287
288
20
    if !aggregate_pairing(items) {
289
0
        err(input, "bls_pairing_identity failed")
290
    } else {
291
20
        Ok(Reduction(cost, a.nil()))
292
    }
293
3.11k
}
294
295
// expects: G2 G1 msg G1 msg ...
296
// G2 is the signature
297
// G1 is a public key
298
// the G1 and its corresponding message must be passed in pairs.
299
4.98k
pub fn op_bls_verify(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
300
4.98k
    let mut cost = BLS_PAIRING_BASE_COST;
301
4.98k
    check_cost(a, cost, max_cost)?;
302
303
4.97k
    let mut args = input;
304
305
    // the first argument is the signature
306
4.97k
    let signature = a.g2(first(a, args)?)?;
307
308
    // followed by a variable number of (G1, msg)-pairs (as a flat list)
309
4.88k
    args = rest(a, args)?;
310
311
4.88k
    let mut items = Vec::<(PublicKey, Atom)>::new();
312
12.1k
    while !nilp(a, args) {
313
7.27k
        let pk = a.g1(first(a, args)?)?;
314
7.25k
        args = rest(a, args)?;
315
7.25k
        let msg = atom(a, first(a, args)?, "bls_verify message")?;
316
7.24k
        args = rest(a, args)?;
317
318
7.24k
        cost += BLS_PAIRING_COST_PER_ARG;
319
7.24k
        cost += msg.as_ref().len() as Cost * BLS_MAP_TO_G2_COST_PER_BYTE;
320
7.24k
        cost += DST_G2.len() as Cost * BLS_MAP_TO_G2_COST_PER_DST_BYTE;
321
7.24k
        check_cost(a, cost, max_cost)?;
322
323
7.24k
        items.push((pk, msg));
324
    }
325
326
4.85k
    if !aggregate_verify(&signature, items) {
327
4.54k
        err(input, "bls_verify failed")
328
    } else {
329
305
        Ok(Reduction(cost, a.nil()))
330
    }
331
4.98k
}
/home/oof/clvm_rs/src/chia_dialect.rs
Line
Count
Source
1
use crate::allocator::{Allocator, NodePtr};
2
use crate::bls_ops::{
3
    op_bls_g1_multiply, op_bls_g1_negate, op_bls_g1_subtract, op_bls_g2_add, op_bls_g2_multiply,
4
    op_bls_g2_negate, op_bls_g2_subtract, op_bls_map_to_g1, op_bls_map_to_g2,
5
    op_bls_pairing_identity, op_bls_verify,
6
};
7
use crate::core_ops::{op_cons, op_eq, op_first, op_if, op_listp, op_raise, op_rest};
8
use crate::cost::Cost;
9
use crate::dialect::{Dialect, OperatorSet};
10
use crate::err_utils::err;
11
use crate::more_ops::{
12
    op_add, op_all, op_any, op_ash, op_coinid, op_concat, op_div, op_divmod, op_gr, op_gr_bytes,
13
    op_logand, op_logior, op_lognot, op_logxor, op_lsh, op_mod, op_modpow, op_multiply, op_not,
14
    op_point_add, op_pubkey_for_exp, op_sha256, op_strlen, op_substr, op_subtract, op_unknown,
15
};
16
use crate::reduction::Response;
17
use crate::secp_ops::{op_secp256k1_verify, op_secp256r1_verify};
18
19
// unknown operators are disallowed
20
// (otherwise they are no-ops with well defined cost)
21
pub const NO_UNKNOWN_OPS: u32 = 0x0002;
22
23
// When set, limits the number of atom-bytes allowed to be allocated, as well as
24
// the number of pairs
25
pub const LIMIT_HEAP: u32 = 0x0004;
26
27
// enables the BLS ops extensions *outside* the softfork guard. This is a
28
// hard-fork and should only be enabled when it activates
29
pub const ENABLE_BLS_OPS_OUTSIDE_GUARD: u32 = 0x0020;
30
31
// The default mode when running grnerators in mempool-mode (i.e. the stricter
32
// mode)
33
pub const MEMPOOL_MODE: u32 = NO_UNKNOWN_OPS | LIMIT_HEAP;
34
35
59.3k
fn unknown_operator(
36
59.3k
    allocator: &mut Allocator,
37
59.3k
    o: NodePtr,
38
59.3k
    args: NodePtr,
39
59.3k
    flags: u32,
40
59.3k
    max_cost: Cost,
41
59.3k
) -> Response {
42
59.3k
    if (flags & NO_UNKNOWN_OPS) != 0 {
43
15.8k
        err(o, "unimplemented operator")
44
    } else {
45
43.4k
        op_unknown(allocator, o, args, max_cost)
46
    }
47
59.3k
}
48
49
pub struct ChiaDialect {
50
    flags: u32,
51
}
52
53
impl ChiaDialect {
54
109k
    pub fn new(flags: u32) -> ChiaDialect {
55
109k
        ChiaDialect { flags }
56
109k
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB2_11ChiaDialect3newB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB2_11ChiaDialect3newCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
54
109k
    pub fn new(flags: u32) -> ChiaDialect {
55
109k
        ChiaDialect { flags }
56
109k
    }
57
}
58
59
impl Dialect for ChiaDialect {
60
428k
    fn op(
61
428k
        &self,
62
428k
        allocator: &mut Allocator,
63
428k
        o: NodePtr,
64
428k
        argument_list: NodePtr,
65
428k
        max_cost: Cost,
66
428k
        extension: OperatorSet,
67
428k
    ) -> Response {
68
428k
        let flags = self.flags
69
428k
            | match extension {
70
699
                OperatorSet::BLS => ENABLE_BLS_OPS_OUTSIDE_GUARD,
71
427k
                _ => 0,
72
            };
73
428k
        let op_len = allocator.atom_len(o);
74
428k
        if op_len == 4 {
75
            // these are unknown operators with assigned cost
76
            // the formula is:
77
            // +---+---+---+------------+
78
            // | multiplier|XX | XXXXXX |
79
            // +---+---+---+---+--------+
80
            //  ^           ^    ^
81
            //  |           |    + 6 bits ignored when computing cost
82
            // cost         |
83
            // (3 bytes)    + 2 bits
84
            //                cost_function
85
86
2.81k
            let b = allocator.atom(o);
87
2.81k
            let opcode = u32::from_be_bytes(b.as_ref().try_into().unwrap());
88
89
            // the secp operators have a fixed cost of 1850000 and 1300000,
90
            // which makes the multiplier 0x1c3a8f and 0x0cf84f (there is an
91
            // implied +1) and cost function 0
92
2.81k
            let f = match opcode {
93
1.34k
                0x13d61f00 => op_secp256k1_verify,
94
1.27k
                0x1c3a8f00 => op_secp256r1_verify,
95
                _ => {
96
190
                    return unknown_operator(allocator, o, argument_list, flags, max_cost);
97
                }
98
            };
99
2.62k
            return f(allocator, argument_list, max_cost);
100
425k
        }
101
425k
        if op_len != 1 {
102
687
            return unknown_operator(allocator, o, argument_list, flags, max_cost);
103
424k
        }
104
424k
        let Some(op) = allocator.small_number(o) else {
105
2.43k
            return unknown_operator(allocator, o, argument_list, flags, max_cost);
106
        };
107
366k
        let f = match op {
108
            // 1 = quote
109
            // 2 = apply
110
8.71k
            3 => op_if,
111
3.30k
            4 => op_cons,
112
2.30k
            5 => op_first,
113
3.34k
            6 => op_rest,
114
2.76k
            7 => op_listp,
115
1.14k
            8 => op_raise,
116
2.33k
            9 => op_eq,
117
2.14k
            10 => op_gr_bytes,
118
7.58k
            11 => op_sha256,
119
4.20k
            12 => op_substr,
120
8.70k
            13 => op_strlen,
121
12.1k
            14 => op_concat,
122
            // 15 ---
123
65.3k
            16 => op_add,
124
59.4k
            17 => op_subtract,
125
30.3k
            18 => op_multiply,
126
11.2k
            19 => op_div,
127
2.95k
            20 => op_divmod,
128
2.18k
            21 => op_gr,
129
19.8k
            22 => op_ash,
130
6.66k
            23 => op_lsh,
131
6.36k
            24 => op_logand,
132
6.34k
            25 => op_logior,
133
6.25k
            26 => op_logxor,
134
1.23k
            27 => op_lognot,
135
            // 28 ---
136
12.3k
            29 => op_point_add,
137
3.34k
            30 => op_pubkey_for_exp,
138
            // 31 ---
139
1.47k
            32 => op_not,
140
2.46k
            33 => op_any,
141
2.61k
            34 => op_all,
142
            // 35 ---
143
            // 36 = softfork
144
120k
            48..=61 if (flags & ENABLE_BLS_OPS_OUTSIDE_GUARD) != 0 => match op {
145
3.20k
                48 => op_coinid,
146
2.09k
                49 => op_bls_g1_subtract,
147
5.51k
                50 => op_bls_g1_multiply,
148
1.80k
                51 => op_bls_g1_negate,
149
3.05k
                52 => op_bls_g2_add,
150
2.02k
                53 => op_bls_g2_subtract,
151
5.48k
                54 => op_bls_g2_multiply,
152
1.67k
                55 => op_bls_g2_negate,
153
4.47k
                56 => op_bls_map_to_g1,
154
4.16k
                57 => op_bls_map_to_g2,
155
3.11k
                58 => op_bls_pairing_identity,
156
4.98k
                59 => op_bls_verify,
157
7.63k
                60 => op_modpow,
158
17.7k
                61 => op_mod,
159
                _ => {
160
0
                    unreachable!();
161
                }
162
            },
163
            _ => {
164
55.9k
                return unknown_operator(allocator, o, argument_list, flags, max_cost);
165
            }
166
        };
167
366k
        f(allocator, argument_list, max_cost)
168
428k
    }
169
170
1.15M
    fn quote_kw(&self) -> u32 {
171
1.15M
        1
172
1.15M
    }
Unexecuted instantiation: _RNvXs_NtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB4_11ChiaDialectNtNtB6_7dialect7Dialect8quote_kwB6_
_RNvXs_NtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB4_11ChiaDialectNtNtB6_7dialect7Dialect8quote_kwCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
170
1.15M
    fn quote_kw(&self) -> u32 {
171
1.15M
        1
172
1.15M
    }
173
434k
    fn apply_kw(&self) -> u32 {
174
434k
        2
175
434k
    }
Unexecuted instantiation: _RNvXs_NtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB4_11ChiaDialectNtNtB6_7dialect7Dialect8apply_kwB6_
_RNvXs_NtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB4_11ChiaDialectNtNtB6_7dialect7Dialect8apply_kwCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
173
434k
    fn apply_kw(&self) -> u32 {
174
434k
        2
175
434k
    }
176
431k
    fn softfork_kw(&self) -> u32 {
177
431k
        36
178
431k
    }
Unexecuted instantiation: _RNvXs_NtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB4_11ChiaDialectNtNtB6_7dialect7Dialect11softfork_kwB6_
_RNvXs_NtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB4_11ChiaDialectNtNtB6_7dialect7Dialect11softfork_kwCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
176
431k
    fn softfork_kw(&self) -> u32 {
177
431k
        36
178
431k
    }
179
180
    // interpret the extension argument passed to the softfork operator, and
181
    // return the Operators it enables (or None) if we don't know what it means
182
513
    fn softfork_extension(&self, ext: u32) -> OperatorSet {
183
513
        match ext {
184
487
            0 => OperatorSet::BLS,
185
            // new extensions go here
186
26
            _ => OperatorSet::Default,
187
        }
188
513
    }
Unexecuted instantiation: _RNvXs_NtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB4_11ChiaDialectNtNtB6_7dialect7Dialect18softfork_extensionB6_
_RNvXs_NtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB4_11ChiaDialectNtNtB6_7dialect7Dialect18softfork_extensionCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
182
513
    fn softfork_extension(&self, ext: u32) -> OperatorSet {
183
513
        match ext {
184
487
            0 => OperatorSet::BLS,
185
            // new extensions go here
186
26
            _ => OperatorSet::Default,
187
        }
188
513
    }
189
190
119
    fn allow_unknown_ops(&self) -> bool {
191
119
        (self.flags & NO_UNKNOWN_OPS) == 0
192
119
    }
Unexecuted instantiation: _RNvXs_NtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB4_11ChiaDialectNtNtB6_7dialect7Dialect17allow_unknown_opsB6_
_RNvXs_NtCs4RkbDk9WRL5_5clvmr12chia_dialectNtB4_11ChiaDialectNtNtB6_7dialect7Dialect17allow_unknown_opsCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
190
119
    fn allow_unknown_ops(&self) -> bool {
191
119
        (self.flags & NO_UNKNOWN_OPS) == 0
192
119
    }
193
}
/home/oof/clvm_rs/src/core_ops.rs
Line
Count
Source
1
use crate::allocator::{Allocator, NodePtr, SExp};
2
use crate::cost::Cost;
3
use crate::err_utils::err;
4
use crate::op_utils::{first, get_args, nilp, rest};
5
use crate::reduction::{EvalErr, Reduction, Response};
6
7
const FIRST_COST: Cost = 30;
8
const IF_COST: Cost = 33;
9
// Cons cost lowered from 245. It only allocates a pair, which is small
10
const CONS_COST: Cost = 50;
11
// Rest cost lowered from 77 since it doesn't allocate anything and it should be
12
// the same as first
13
const REST_COST: Cost = 30;
14
const LISTP_COST: Cost = 19;
15
const EQ_BASE_COST: Cost = 117;
16
const EQ_COST_PER_BYTE: Cost = 1;
17
18
8.71k
pub fn op_if(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
19
8.71k
    let [cond, affirmative, negative] = get_args::<3>(a, input, "i")?;
20
8.58k
    let chosen_node = if nilp(a, cond) { negative } else { affirmative };
21
8.58k
    Ok(Reduction(IF_COST, chosen_node))
22
8.71k
}
23
24
3.30k
pub fn op_cons(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
25
3.30k
    let [n1, n2] = get_args::<2>(a, input, "c")?;
26
3.29k
    let r = a.new_pair(n1, n2)?;
27
3.29k
    Ok(Reduction(CONS_COST, r))
28
3.30k
}
29
30
2.30k
pub fn op_first(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
31
2.30k
    let [n] = get_args::<1>(a, input, "f")?;
32
2.27k
    Ok(Reduction(FIRST_COST, first(a, n)?))
33
2.30k
}
34
35
3.34k
pub fn op_rest(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
36
3.34k
    let [n] = get_args::<1>(a, input, "r")?;
37
3.32k
    Ok(Reduction(REST_COST, rest(a, n)?))
38
3.34k
}
39
40
2.76k
pub fn op_listp(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
41
2.76k
    let [n] = get_args::<1>(a, input, "l")?;
42
2.71k
    match a.sexp(n) {
43
2.46k
        SExp::Pair(_, _) => Ok(Reduction(LISTP_COST, a.one())),
44
241
        _ => Ok(Reduction(LISTP_COST, a.nil())),
45
    }
46
2.76k
}
47
48
1.14k
pub fn op_raise(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
49
    // if given a single argument we should raise the single argument rather
50
    // than the full list of arguments. brun also used to behave this way.
51
    // if the single argument here is a pair then don't throw it unwrapped
52
    // as it'd potentially look the same as a throw of multiple arguments.
53
1.14k
    let throw_value = if let Ok([value]) = get_args::<1>(a, input, "") {
54
1.13k
        match a.sexp(value) {
55
1.12k
            SExp::Atom => value,
56
10
            _ => input,
57
        }
58
    } else {
59
13
        input
60
    };
61
62
1.14k
    err(throw_value, "clvm raise")
63
1.14k
}
64
65
4.59k
fn ensure_atom(a: &Allocator, n: NodePtr, op: &str) -> Result<(), EvalErr> {
66
4.59k
    if let SExp::Atom = a.sexp(n) {
67
4.57k
        Ok(())
68
    } else {
69
20
        Err(EvalErr(n, format!("{op} on list")))
70
    }
71
4.59k
}
72
73
2.33k
pub fn op_eq(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
74
2.33k
    let [s0, s1] = get_args::<2>(a, input, "=")?;
75
2.30k
    ensure_atom(a, s0, "=")?;
76
2.29k
    ensure_atom(a, s1, "=")?;
77
2.28k
    let eq = a.atom_eq(s0, s1);
78
2.28k
    let cost = EQ_BASE_COST + (a.atom_len(s0) as Cost + a.atom_len(s1) as Cost) * EQ_COST_PER_BYTE;
79
2.28k
    Ok(Reduction(cost, if eq { a.one() } else { a.nil() }))
80
2.33k
}
/home/oof/clvm_rs/src/cost.rs
Line
Count
Source
1
use crate::allocator::Allocator;
2
use crate::reduction::EvalErr;
3
4
pub type Cost = u64;
5
6
606k
pub fn check_cost(a: &Allocator, cost: Cost, max_cost: Cost) -> Result<(), EvalErr> {
7
606k
    if cost > max_cost {
8
516
        Err(EvalErr(a.nil(), "cost exceeded".into()))
9
    } else {
10
605k
        Ok(())
11
    }
12
606k
}
/home/oof/clvm_rs/src/err_utils.rs
Line
Count
Source
1
use crate::allocator::NodePtr;
2
use crate::reduction::EvalErr;
3
4
44.6k
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
44.6k
    Err(EvalErr(node, msg.into()))
6
44.6k
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errNtNtB4_9allocator7NodePtrEB4_
Line
Count
Source
4
303
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
303
    Err(EvalErr(node, msg.into()))
6
303
}
Unexecuted instantiation: _RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3erruEB4_
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errNtNtCs568wuOlRYFZ_8chia_bls10public_key9PublicKeyEB4_
Line
Count
Source
4
4.20k
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
4.20k
    Err(EvalErr(node, msg.into()))
6
4.20k
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errNtNtCs568wuOlRYFZ_8chia_bls9signature9SignatureEB4_
Line
Count
Source
4
131
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
131
    Err(EvalErr(node, msg.into()))
6
131
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errNtNtB4_9reduction9ReductionEB4_
Line
Count
Source
4
33.3k
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
33.3k
    Err(EvalErr(node, msg.into()))
6
33.3k
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errTANtNtB4_9allocator7NodePtrj2_jEEB4_
Line
Count
Source
4
30
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
30
    Err(EvalErr(node, msg.into()))
6
30
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errTANtNtB4_9allocator7NodePtrj3_jEEB4_
Line
Count
Source
4
24
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
24
    Err(EvalErr(node, msg.into()))
6
24
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errTNtNtCs72ekIXsOXFl_10num_bigint6bigint6BigIntjEEB4_
Line
Count
Source
4
255
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
255
    Err(EvalErr(node, msg.into()))
6
255
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errjEB4_
Line
Count
Source
4
57
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
57
    Err(EvalErr(node, msg.into()))
6
57
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errNtNtB4_9allocator4AtomEB4_
Line
Count
Source
4
166
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
166
    Err(EvalErr(node, msg.into()))
6
166
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errlEB4_
Line
Count
Source
4
1.40k
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
1.40k
    Err(EvalErr(node, msg.into()))
6
1.40k
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errINtNtCs56dDIOPvtI3_5ecdsa9verifying12VerifyingKeyNtCsaHRNXv1Y9Bq_4p2568NistP256EEB4_
Line
Count
Source
4
65
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
65
    Err(EvalErr(node, msg.into()))
6
65
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errINtCs56dDIOPvtI3_5ecdsa9SignatureNtCsaHRNXv1Y9Bq_4p2568NistP256EEB4_
Line
Count
Source
4
47
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
47
    Err(EvalErr(node, msg.into()))
6
47
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errINtNtCs56dDIOPvtI3_5ecdsa9verifying12VerifyingKeyNtCsjewTDwKBbyD_4k2569Secp256k1EEB4_
Line
Count
Source
4
595
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
595
    Err(EvalErr(node, msg.into()))
6
595
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errINtCs56dDIOPvtI3_5ecdsa9SignatureNtCsjewTDwKBbyD_4k2569Secp256k1EEB4_
Line
Count
Source
4
34
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
34
    Err(EvalErr(node, msg.into()))
6
34
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3erryECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
4
3.82k
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
3.82k
    Err(EvalErr(node, msg.into()))
6
3.82k
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errNtNtB4_9reduction9ReductionECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
4
114
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
114
    Err(EvalErr(node, msg.into()))
6
114
}
_RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errTNtNtB4_7dialect11OperatorSetNtNtB4_9allocator7NodePtrB15_EECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
4
26
pub fn err<T>(node: NodePtr, msg: &str) -> Result<T, EvalErr> {
5
26
    Err(EvalErr(node, msg.into()))
6
26
}
Unexecuted instantiation: _RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3errNtNtB4_9allocator7NodePtrECs4LiGCEBy0PZ_16fuzz_run_program
Unexecuted instantiation: _RINvNtCs4RkbDk9WRL5_5clvmr9err_utils3erruECs4LiGCEBy0PZ_16fuzz_run_program
/home/oof/clvm_rs/src/f_table.rs
Line
Count
Source
1
use std::collections::HashMap;
2
3
use crate::allocator::{Allocator, NodePtr};
4
use crate::bls_ops::{
5
    op_bls_g1_multiply, op_bls_g1_negate, op_bls_g1_subtract, op_bls_g2_add, op_bls_g2_multiply,
6
    op_bls_g2_negate, op_bls_g2_subtract, op_bls_map_to_g1, op_bls_map_to_g2,
7
    op_bls_pairing_identity, op_bls_verify,
8
};
9
use crate::core_ops::{op_cons, op_eq, op_first, op_if, op_listp, op_raise, op_rest};
10
use crate::cost::Cost;
11
use crate::more_ops::{
12
    op_add, op_all, op_any, op_ash, op_concat, op_div, op_divmod, op_gr, op_gr_bytes, op_logand,
13
    op_logior, op_lognot, op_logxor, op_lsh, op_mod, op_modpow, op_multiply, op_not, op_point_add,
14
    op_pubkey_for_exp, op_sha256, op_strlen, op_substr, op_subtract,
15
};
16
use crate::reduction::Response;
17
use crate::secp_ops::{op_secp256k1_verify, op_secp256r1_verify};
18
19
type OpFn = fn(&mut Allocator, NodePtr, Cost) -> Response;
20
21
pub type FLookup = [Option<OpFn>; 256];
22
23
0
pub fn opcode_by_name(name: &str) -> Option<OpFn> {
24
0
    let opcode_lookup: [(OpFn, &str); 44] = [
25
0
        (op_if, "op_if"),
26
0
        (op_cons, "op_cons"),
27
0
        (op_first, "op_first"),
28
0
        (op_rest, "op_rest"),
29
0
        (op_listp, "op_listp"),
30
0
        (op_raise, "op_raise"),
31
0
        (op_eq, "op_eq"),
32
0
        (op_sha256, "op_sha256"),
33
0
        (op_add, "op_add"),
34
0
        (op_subtract, "op_subtract"),
35
0
        (op_multiply, "op_multiply"),
36
0
        (op_modpow, "op_modpow"),
37
0
        (op_divmod, "op_divmod"),
38
0
        (op_mod, "op_mod"),
39
0
        (op_substr, "op_substr"),
40
0
        (op_strlen, "op_strlen"),
41
0
        (op_point_add, "op_point_add"),
42
0
        (op_pubkey_for_exp, "op_pubkey_for_exp"),
43
0
        (op_concat, "op_concat"),
44
0
        (op_gr, "op_gr"),
45
0
        (op_gr_bytes, "op_gr_bytes"),
46
0
        (op_logand, "op_logand"),
47
0
        (op_logior, "op_logior"),
48
0
        (op_logxor, "op_logxor"),
49
0
        (op_lognot, "op_lognot"),
50
0
        (op_ash, "op_ash"),
51
0
        (op_lsh, "op_lsh"),
52
0
        (op_not, "op_not"),
53
0
        (op_any, "op_any"),
54
0
        (op_all, "op_all"),
55
0
        (op_div, "op_div"),
56
0
        (op_bls_g1_subtract, "op_g1_subtract"),
57
0
        (op_bls_g1_multiply, "op_g1_multiply"),
58
0
        (op_bls_g1_negate, "op_g1_negate"),
59
0
        (op_bls_g2_add, "op_g2_add"),
60
0
        (op_bls_g2_subtract, "op_g2_subtract"),
61
0
        (op_bls_g2_multiply, "op_g2_multiply"),
62
0
        (op_bls_g2_negate, "op_g2_negate"),
63
0
        (op_bls_map_to_g1, "op_g1_map"),
64
0
        (op_bls_map_to_g2, "op_g2_map"),
65
0
        (op_bls_pairing_identity, "op_bls_pairing_identity"),
66
0
        (op_bls_verify, "op_bls_verify"),
67
0
        (op_secp256k1_verify, "op_secp256k1_verify"),
68
0
        (op_secp256r1_verify, "op_secp256r1_verify"),
69
0
    ];
70
0
    let name: &[u8] = name.as_ref();
71
0
    for (f, op) in opcode_lookup.iter() {
72
0
        let pu8: &[u8] = op.as_ref();
73
0
        if pu8 == name {
74
0
            return Some(*f);
75
0
        }
76
    }
77
0
    None
78
0
}
79
80
0
pub fn f_lookup_for_hashmap(opcode_lookup_by_name: HashMap<String, Vec<u8>>) -> FLookup {
81
0
    let mut f_lookup = [None; 256];
82
0
    for (name, idx) in opcode_lookup_by_name.iter() {
83
0
        if idx.len() == 1 {
84
0
            let index = idx[0];
85
0
            let op = opcode_by_name(name);
86
0
            assert!(op.is_some(), "can't find native operator {name}");
87
0
            f_lookup[index as usize] = op;
88
0
        }
89
    }
90
0
    f_lookup
91
0
}
/home/oof/clvm_rs/src/more_ops.rs
Line
Count
Source
1
use hex_literal::hex;
2
use num_bigint::{BigUint, Sign};
3
use num_integer::Integer;
4
use std::ops::BitAndAssign;
5
use std::ops::BitOrAssign;
6
use std::ops::BitXorAssign;
7
8
use crate::allocator::{len_for_value, Allocator, NodePtr, NodeVisitor, SExp};
9
use crate::cost::{check_cost, Cost};
10
use crate::err_utils::err;
11
use crate::number::Number;
12
use crate::op_utils::{
13
    atom, atom_len, get_args, get_varargs, i32_atom, int_atom, match_args, mod_group_order,
14
    new_atom_and_cost, nilp, u32_from_u8, MALLOC_COST_PER_BYTE,
15
};
16
use crate::reduction::{Reduction, Response};
17
use crate::sha2::Sha256;
18
use chia_bls::G1Element;
19
20
const ARITH_BASE_COST: Cost = 99;
21
const ARITH_COST_PER_ARG: Cost = 320;
22
const ARITH_COST_PER_BYTE: Cost = 3;
23
24
const LOG_BASE_COST: Cost = 100;
25
const LOG_COST_PER_ARG: Cost = 264;
26
const LOG_COST_PER_BYTE: Cost = 3;
27
28
const LOGNOT_BASE_COST: Cost = 331;
29
const LOGNOT_COST_PER_BYTE: Cost = 3;
30
31
const MUL_BASE_COST: Cost = 92;
32
const MUL_COST_PER_OP: Cost = 885;
33
const MUL_LINEAR_COST_PER_BYTE: Cost = 6;
34
const MUL_SQUARE_COST_PER_BYTE_DIVIDER: Cost = 128;
35
36
const GR_BASE_COST: Cost = 498;
37
const GR_COST_PER_BYTE: Cost = 2;
38
39
const GRS_BASE_COST: Cost = 117;
40
const GRS_COST_PER_BYTE: Cost = 1;
41
42
const STRLEN_BASE_COST: Cost = 173;
43
const STRLEN_COST_PER_BYTE: Cost = 1;
44
45
const CONCAT_BASE_COST: Cost = 142;
46
const CONCAT_COST_PER_ARG: Cost = 135;
47
const CONCAT_COST_PER_BYTE: Cost = 3;
48
49
const DIVMOD_BASE_COST: Cost = 1116;
50
const DIVMOD_COST_PER_BYTE: Cost = 6;
51
52
const DIV_BASE_COST: Cost = 988;
53
const DIV_COST_PER_BYTE: Cost = 4;
54
55
const SHA256_BASE_COST: Cost = 87;
56
const SHA256_COST_PER_ARG: Cost = 134;
57
const SHA256_COST_PER_BYTE: Cost = 2;
58
59
const ASHIFT_BASE_COST: Cost = 596;
60
const ASHIFT_COST_PER_BYTE: Cost = 3;
61
62
const LSHIFT_BASE_COST: Cost = 277;
63
const LSHIFT_COST_PER_BYTE: Cost = 3;
64
65
const BOOL_BASE_COST: Cost = 200;
66
const BOOL_COST_PER_ARG: Cost = 300;
67
68
// Raspberry PI 4 is about 7.679960 / 1.201742 = 6.39 times slower
69
// in the point_add benchmark
70
71
// increased from 31592 to better model Raspberry PI
72
const POINT_ADD_BASE_COST: Cost = 101094;
73
// increased from 419994 to better model Raspberry PI
74
const POINT_ADD_COST_PER_ARG: Cost = 1343980;
75
76
// Raspberry PI 4 is about 2.833543 / 0.447859 = 6.32686 times slower
77
// in the pubkey benchmark
78
79
// increased from 419535 to better model Raspberry PI
80
const PUBKEY_BASE_COST: Cost = 1325730;
81
// increased from 12 to closer model Raspberry PI
82
const PUBKEY_COST_PER_BYTE: Cost = 38;
83
84
// the new coinid operator
85
// we subtract 153 cost as a discount, to incentivize using this operator rather
86
// than "naked" sha256
87
const COINID_COST: Cost =
88
    SHA256_BASE_COST + SHA256_COST_PER_ARG * 3 + SHA256_COST_PER_BYTE * (32 + 32 + 8) - 153;
89
90
const MODPOW_BASE_COST: Cost = 17000;
91
const MODPOW_COST_PER_BYTE_BASE_VALUE: Cost = 38;
92
// the cost for exponent and modular scale by the square of the size of the
93
// respective operands
94
const MODPOW_COST_PER_BYTE_EXPONENT: Cost = 3;
95
const MODPOW_COST_PER_BYTE_MOD: Cost = 21;
96
97
62.0k
fn limbs_for_int(v: &Number) -> usize {
98
62.0k
    ((v.bits() + 7) / 8) as usize
99
62.0k
}
100
101
#[cfg(test)]
102
fn limb_test_helper(bytes: &[u8]) {
103
    let bigint = Number::from_signed_bytes_be(bytes);
104
    println!("{} bits: {}", &bigint, &bigint.bits());
105
106
    // redundant leading zeros don't count, since they aren't stored internally
107
    let expected = if !bytes.is_empty() && bytes[0] == 0 {
108
        bytes.len() - 1
109
    } else {
110
        bytes.len()
111
    };
112
    assert_eq!(limbs_for_int(&bigint), expected);
113
}
114
115
#[test]
116
fn test_limbs_for_int() {
117
    limb_test_helper(&[]);
118
    limb_test_helper(&[0x1]);
119
    limb_test_helper(&[0x80]);
120
    limb_test_helper(&[0x81]);
121
    limb_test_helper(&[0x7f]);
122
    limb_test_helper(&[0xff]);
123
    limb_test_helper(&[0, 0xff]);
124
    limb_test_helper(&[0x7f, 0xff]);
125
    limb_test_helper(&[0x7f, 0]);
126
    limb_test_helper(&[0x7f, 0x77]);
127
128
    limb_test_helper(&[0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
129
    limb_test_helper(&[0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
130
    limb_test_helper(&[0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
131
    limb_test_helper(&[0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
132
    limb_test_helper(&[0x40, 0, 0, 0, 0, 0, 0, 0, 0]);
133
    limb_test_helper(&[0x40, 0, 0, 0, 0, 0, 0, 0]);
134
135
    limb_test_helper(&[0x80, 0, 0, 0, 0, 0, 0]);
136
    limb_test_helper(&[0x40, 0, 0, 0, 0, 0, 0]);
137
    limb_test_helper(&[0x20, 0, 0, 0, 0, 0, 0]);
138
    limb_test_helper(&[0x10, 0, 0, 0, 0, 0, 0]);
139
    limb_test_helper(&[0x08, 0, 0, 0, 0, 0, 0]);
140
    limb_test_helper(&[0x04, 0, 0, 0, 0, 0, 0]);
141
    limb_test_helper(&[0x02, 0, 0, 0, 0, 0, 0]);
142
    limb_test_helper(&[0x01, 0, 0, 0, 0, 0, 0]);
143
144
    limb_test_helper(&[0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
145
    limb_test_helper(&[0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
146
    limb_test_helper(&[0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
147
    limb_test_helper(&[0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
148
    limb_test_helper(&[0x80, 0, 0, 0, 0, 0, 0, 0, 0]);
149
    limb_test_helper(&[0x80, 0, 0, 0, 0, 0, 0, 0]);
150
}
151
152
222k
fn malloc_cost(a: &Allocator, cost: Cost, ptr: NodePtr) -> Reduction {
153
222k
    let c = a.atom_len(ptr) as Cost * MALLOC_COST_PER_BYTE;
154
222k
    Reduction(cost + c, ptr)
155
222k
}
156
157
43.4k
pub fn op_unknown(
158
43.4k
    allocator: &mut Allocator,
159
43.4k
    o: NodePtr,
160
43.4k
    mut args: NodePtr,
161
43.4k
    max_cost: Cost,
162
43.4k
) -> Response {
163
43.4k
    // unknown opcode in lenient mode
164
43.4k
    // unknown ops are reserved if they start with 0xffff
165
43.4k
    // otherwise, unknown ops are no-ops, but they have costs. The cost is computed
166
43.4k
    // like this:
167
43.4k
168
43.4k
    // byte index (reverse):
169
43.4k
    // | 4 | 3 | 2 | 1 | 0          |
170
43.4k
    // +---+---+---+---+------------+
171
43.4k
    // | multiplier    |XX | XXXXXX |
172
43.4k
    // +---+---+---+---+---+--------+
173
43.4k
    //  ^               ^    ^
174
43.4k
    //  |               |    + 6 bits ignored when computing cost
175
43.4k
    // cost_multiplier  |
176
43.4k
    // (up to 4 bytes)  + 2 bits
177
43.4k
    //                    cost_function
178
43.4k
179
43.4k
    // 1 is always added to the multiplier before using it to multiply the cost, this
180
43.4k
    // is since cost may not be 0.
181
43.4k
182
43.4k
    // cost_function is 2 bits and defines how cost is computed based on arguments:
183
43.4k
    // 0: constant, cost is 1 * (multiplier + 1)
184
43.4k
    // 1: computed like operator add, multiplied by (multiplier + 1)
185
43.4k
    // 2: computed like operator mul, multiplied by (multiplier + 1)
186
43.4k
    // 3: computed like operator concat, multiplied by (multiplier + 1)
187
43.4k
188
43.4k
    // this means that unknown ops where cost_function is 1, 2, or 3, may still be
189
43.4k
    // fatal errors if the arguments passed are not atoms.
190
43.4k
191
43.4k
    let op_atom = allocator.atom(o);
192
43.4k
    let op = op_atom.as_ref();
193
43.4k
194
43.4k
    if op.is_empty() || (op.len() >= 2 && op[0] == 0xff && op[1] == 0xff) {
195
74
        return err(o, "reserved operator");
196
43.3k
    }
197
43.3k
198
43.3k
    let cost_function = (op[op.len() - 1] & 0b11000000) >> 6;
199
43.3k
    let cost_multiplier: u64 = match u32_from_u8(&op[0..op.len() - 1]) {
200
43.3k
        Some(v) => v as u64,
201
        None => {
202
30
            return err(o, "invalid operator");
203
        }
204
    };
205
206
43.3k
    let mut cost = match cost_function {
207
42.2k
        0 => 1,
208
        1 => {
209
658
            let mut cost = ARITH_BASE_COST;
210
658
            let mut byte_count: u64 = 0;
211
1.49k
            while let Some((arg, rest)) = allocator.next(args) {
212
851
                args = rest;
213
851
                cost += ARITH_COST_PER_ARG;
214
851
                let len = atom_len(allocator, arg, "unknown op")?;
215
840
                byte_count += len as u64;
216
840
                check_cost(
217
840
                    allocator,
218
840
                    cost + (byte_count as Cost * ARITH_COST_PER_BYTE),
219
840
                    max_cost,
220
840
                )?;
221
            }
222
644
            cost + (byte_count * ARITH_COST_PER_BYTE)
223
        }
224
        2 => {
225
174
            let mut cost = MUL_BASE_COST;
226
174
            let mut first_iter: bool = true;
227
174
            let mut l0: u64 = 0;
228
716
            while let Some((arg, rest)) = allocator.next(args) {
229
561
                args = rest;
230
561
                let len = atom_len(allocator, arg, "unknown op")?;
231
542
                if first_iter {
232
137
                    l0 = len as u64;
233
137
                    first_iter = false;
234
137
                    continue;
235
405
                }
236
405
                let l1 = len as u64;
237
405
                cost += MUL_COST_PER_OP;
238
405
                cost += (l0 + l1) * MUL_LINEAR_COST_PER_BYTE;
239
405
                cost += (l0 * l1) / MUL_SQUARE_COST_PER_BYTE_DIVIDER;
240
405
                l0 += l1;
241
405
                check_cost(allocator, cost, max_cost)?;
242
            }
243
155
            cost
244
        }
245
        3 => {
246
240
            let mut cost = CONCAT_BASE_COST;
247
240
            let mut total_size: u64 = 0;
248
544
            while let Some((arg, rest)) = allocator.next(args) {
249
309
                args = rest;
250
309
                cost += CONCAT_COST_PER_ARG;
251
309
                let len = atom_len(allocator, arg, "unknown op")?;
252
306
                total_size += len as u64;
253
306
                check_cost(
254
306
                    allocator,
255
306
                    cost + total_size as Cost * CONCAT_COST_PER_BYTE,
256
306
                    max_cost,
257
306
                )?;
258
            }
259
235
            cost + total_size * CONCAT_COST_PER_BYTE
260
        }
261
0
        _ => 1,
262
    };
263
264
43.2k
    assert!(cost > 0);
265
266
43.2k
    check_cost(allocator, cost, max_cost)?;
267
43.2k
    cost *= cost_multiplier + 1;
268
43.2k
    if cost > u32::MAX as u64 {
269
5
        err(o, "invalid operator")
270
    } else {
271
43.2k
        Ok(Reduction(cost as Cost, allocator.nil()))
272
    }
273
43.4k
}
274
275
#[cfg(test)]
276
fn test_op_unknown(buf: &[u8], a: &mut Allocator, n: NodePtr) -> Response {
277
    let buf = a.new_atom(buf)?;
278
    op_unknown(a, buf, n, 1000000)
279
}
280
281
#[test]
282
fn test_unknown_op_reserved() {
283
    let mut a = Allocator::new();
284
285
    // any op starting with ffff is reserved and a hard failure
286
    let buf = vec![0xff, 0xff];
287
    let nil = a.nil();
288
    assert!(test_op_unknown(&buf, &mut a, nil).is_err());
289
290
    let buf = vec![0xff, 0xff, 0xff];
291
    assert!(test_op_unknown(&buf, &mut a, nil).is_err());
292
293
    let buf = vec![0xff, 0xff, b'0'];
294
    assert!(test_op_unknown(&buf, &mut a, nil).is_err());
295
296
    let buf = vec![0xff, 0xff, 0];
297
    assert!(test_op_unknown(&buf, &mut a, nil).is_err());
298
299
    let buf = vec![0xff, 0xff, 0xcc, 0xcc, 0xfe, 0xed, 0xce];
300
    assert!(test_op_unknown(&buf, &mut a, nil).is_err());
301
302
    // an empty atom is not a valid opcode
303
    let buf = Vec::<u8>::new();
304
    assert!(test_op_unknown(&buf, &mut a, nil).is_err());
305
306
    // a single ff is not sufficient to be treated as a reserved opcode
307
    let buf = vec![0xff];
308
    assert_eq!(test_op_unknown(&buf, &mut a, nil), Ok(Reduction(142, nil)));
309
310
    // leading zeros count, so this is not considered an ffff-prefix
311
    let buf = vec![0x00, 0xff, 0xff, 0x00, 0x00];
312
    // the cost is 0xffff00 = 16776960 plus the implied 1
313
    assert_eq!(
314
        test_op_unknown(&buf, &mut a, nil),
315
        Ok(Reduction(16776961, nil))
316
    );
317
}
318
319
#[test]
320
fn test_lenient_mode_last_bits() {
321
    let mut a = crate::allocator::Allocator::new();
322
323
    // the last 6 bits are ignored for computing cost
324
    let buf = vec![0x3c, 0x3f];
325
    let nil = a.nil();
326
    assert_eq!(test_op_unknown(&buf, &mut a, nil), Ok(Reduction(61, nil)));
327
328
    let buf = vec![0x3c, 0x0f];
329
    assert_eq!(test_op_unknown(&buf, &mut a, nil), Ok(Reduction(61, nil)));
330
331
    let buf = vec![0x3c, 0x00];
332
    assert_eq!(test_op_unknown(&buf, &mut a, nil), Ok(Reduction(61, nil)));
333
334
    let buf = vec![0x3c, 0x2c];
335
    assert_eq!(test_op_unknown(&buf, &mut a, nil), Ok(Reduction(61, nil)));
336
}
337
338
// contains SHA256(1 .. x), where x is the index into the array and .. is
339
// concatenation. This was computed by:
340
// print(f"    hex!(\"{sha256(bytes([1])).hexdigest()}\"),")
341
// for i in range(1, 37):
342
//     print(f"    hex!(\"{sha256(bytes([1, i])).hexdigest()}\"),")
343
pub const PRECOMPUTED_HASHES: [[u8; 32]; 37] = [
344
    hex!("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a"),
345
    hex!("9dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2"),
346
    hex!("a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222"),
347
    hex!("c79b932e1e1da3c0e098e5ad2c422937eb904a76cf61d83975a74a68fbb04b99"),
348
    hex!("a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5"),
349
    hex!("bc5959f43bc6e47175374b6716e53c9a7d72c59424c821336995bad760d9aeb3"),
350
    hex!("44602a999abbebedf7de0ae1318e4f57e3cb1d67e482a65f9657f7541f3fe4bb"),
351
    hex!("ca6c6588fa01171b200740344d354e8548b7470061fb32a34f4feee470ec281f"),
352
    hex!("9e6282e4f25e370ce617e21d6fe265e88b9e7b8682cf00059b9d128d9381f09d"),
353
    hex!("ac9e61d54eb6967e212c06aab15408292f8558c48f06f9d705150063c68753b0"),
354
    hex!("c04b5bb1a5b2eb3e9cd4805420dba5a9d133da5b7adeeafb5474c4adae9faa80"),
355
    hex!("57bfd1cb0adda3d94315053fda723f2028320faa8338225d99f629e3d46d43a9"),
356
    hex!("6b6daa8334bbcc8f6b5906b6c04be041d92700b74024f73f50e0a9f0dae5f06f"),
357
    hex!("c7b89cfb9abf2c4cb212a4840b37d762f4c880b8517b0dadb0c310ded24dd86d"),
358
    hex!("653b3bb3e18ef84d5b1e8ff9884aecf1950c7a1c98715411c22b987663b86dda"),
359
    hex!("24255ef5d941493b9978f3aabb0ed07d084ade196d23f463ff058954cbf6e9b6"),
360
    hex!("af340aa58ea7d72c2f9a7405f3734167bb27dd2a520d216addef65f8362102b6"),
361
    hex!("26e7f98cfafee5b213726e22632923bf31bf3e988233235f8f5ca5466b3ac0ed"),
362
    hex!("115b498ce94335826baa16386cd1e2fde8ca408f6f50f3785964f263cdf37ebe"),
363
    hex!("d8c50d6282a1ba47f0a23430d177bbfbb72e2b84713745e894f575570f1f3d6e"),
364
    hex!("dbe726e81a7221a385e007ef9e834a975a4b528c6f55a5d2ece288bee831a3d1"),
365
    hex!("764c8a3561c7cf261771b4e1969b84c210836f3c034baebac5e49a394a6ee0a9"),
366
    hex!("dce37f3512b6337d27290436ba9289e2fd6c775494c33668dd177cf811fbd47a"),
367
    hex!("5809addc9f6926fc5c4e20cf87958858c4454c21cdfc6b02f377f12c06b35cca"),
368
    hex!("b519be874447e0f0a38ee8ec84ecd2198a9fac778fccce19cc8d87be5d8ed6b1"),
369
    hex!("ae58b7e08e266680e93e46639a2a7e89fde78a6f3c8e4219d1087c406c25c24c"),
370
    hex!("2986113d3bc27183978188edd7e72c3352c5cd6c8f2de6b65a466fc15bc2b49e"),
371
    hex!("145bfb83f7b3ef33ac1eada788c187e4d1feb7326bcf340bb060a62e75434854"),
372
    hex!("387da93c57e24aca43495b2e241399d532048e038ee0ed9ca740c22a06cbce91"),
373
    hex!("af2c6f1512d1cabedeaf129e0643863c5741973283e065564f2c00bde7c92fe1"),
374
    hex!("5df7504bc193ee4c3deadede1459eccca172e87cca35e81f11ce14be5e94acaf"),
375
    hex!("5d9ae980408df9325fbc46da2612c599ef76949450516ae38bf3b4c64721613d"),
376
    hex!("3145e7a95720a1db303f2198e796ea848f52b6079b5bf4f47d32fad69c2bce77"),
377
    hex!("c846f87c9d6bdfaa33038ac78269cfd5a08aa89a0918e99c4c4ae2e804a4f9a3"),
378
    hex!("b70654fead634e1ede4518ef34872c9d4f083a53773bdbfb75ae926bd3a4ce47"),
379
    hex!("b71de80778f2783383f5d5a3028af84eab2f18a4eb38968172ca41724dd4b3f4"),
380
    hex!("3f2d2a889d22530bd1abdc40ff1cbb23ca53ae3f1983e58c70d46a15c120e780"),
381
];
382
383
7.58k
pub fn op_sha256(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
384
7.58k
    let mut cost = SHA256_BASE_COST;
385
386
7.58k
    if let Some([v0, v1]) = match_args::<2>(a, input) {
387
457
        if a.small_number(v0) == Some(1) {
388
20
            if let Some(val) = a.small_number(v1) {
389
                // in this case, we're hashing 1 concatenated with a small
390
                // integer, we may have a pre-computed hash for this
391
10
                if (val as usize) < PRECOMPUTED_HASHES.len() {
392
10
                    let num_bytes = if val > 0 { 2 } else { 1 };
393
10
                    cost += num_bytes * SHA256_COST_PER_BYTE + 2 as Cost * SHA256_COST_PER_ARG;
394
10
                    return new_atom_and_cost(a, cost, &PRECOMPUTED_HASHES[val as usize]);
395
0
                }
396
10
            }
397
437
        }
398
7.13k
    }
399
400
7.57k
    let mut byte_count: usize = 0;
401
7.57k
    let mut hasher = Sha256::new();
402
30.4k
    while let Some((arg, rest)) = a.next(input) {
403
22.9k
        input = rest;
404
22.9k
        cost += SHA256_COST_PER_ARG;
405
22.9k
        check_cost(
406
22.9k
            a,
407
22.9k
            cost + byte_count as Cost * SHA256_COST_PER_BYTE,
408
22.9k
            max_cost,
409
22.9k
        )?;
410
22.9k
        let blob = atom(a, arg, "sha256")?;
411
22.8k
        byte_count += blob.as_ref().len();
412
22.8k
        hasher.update(blob);
413
    }
414
7.55k
    cost += byte_count as Cost * SHA256_COST_PER_BYTE;
415
7.55k
    new_atom_and_cost(a, cost, &hasher.finalize())
416
7.58k
}
417
418
65.3k
pub fn op_add(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
419
65.3k
    let mut cost = ARITH_BASE_COST;
420
65.3k
    let mut byte_count: usize = 0;
421
65.3k
    let mut total: Number = 0.into();
422
217k
    while let Some((arg, rest)) = a.next(input) {
423
152k
        input = rest;
424
152k
        cost += ARITH_COST_PER_ARG;
425
152k
        check_cost(
426
152k
            a,
427
152k
            cost + (byte_count as Cost * ARITH_COST_PER_BYTE),
428
152k
            max_cost,
429
152k
        )?;
430
431
152k
        match a.node(arg) {
432
78.7k
            NodeVisitor::Buffer(buf) => {
433
78.7k
                use crate::number::number_from_u8;
434
78.7k
                total += number_from_u8(buf);
435
78.7k
                byte_count += buf.len();
436
78.7k
            }
437
73.3k
            NodeVisitor::U32(val) => {
438
73.3k
                total += val;
439
73.3k
                byte_count += len_for_value(val);
440
73.3k
            }
441
            NodeVisitor::Pair(_, _) => {
442
25
                return err(arg, "+ requires int args");
443
            }
444
        }
445
    }
446
65.2k
    let total = a.new_number(total)?;
447
65.2k
    cost += byte_count as Cost * ARITH_COST_PER_BYTE;
448
65.2k
    Ok(malloc_cost(a, cost, total))
449
65.3k
}
450
451
59.4k
pub fn op_subtract(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
452
59.4k
    let mut cost = ARITH_BASE_COST;
453
59.4k
    let mut byte_count: usize = 0;
454
59.4k
    let mut total: Number = 0.into();
455
59.4k
    let mut is_first = true;
456
164k
    while let Some((arg, rest)) = a.next(input) {
457
105k
        input = rest;
458
105k
        cost += ARITH_COST_PER_ARG;
459
105k
        check_cost(a, cost + byte_count as Cost * ARITH_COST_PER_BYTE, max_cost)?;
460
105k
        if is_first {
461
53.1k
            let (v, len) = int_atom(a, arg, "-")?;
462
53.0k
            byte_count = len;
463
53.0k
            total = v;
464
        } else {
465
51.9k
            match a.node(arg) {
466
14.7k
                NodeVisitor::Buffer(buf) => {
467
14.7k
                    use crate::number::number_from_u8;
468
14.7k
                    total -= number_from_u8(buf);
469
14.7k
                    byte_count += buf.len();
470
14.7k
                }
471
37.1k
                NodeVisitor::U32(val) => {
472
37.1k
                    total -= val;
473
37.1k
                    byte_count += len_for_value(val);
474
37.1k
                }
475
                NodeVisitor::Pair(_, _) => {
476
49
                    return err(arg, "- requires int args");
477
                }
478
            }
479
        };
480
104k
        is_first = false;
481
    }
482
59.4k
    let total = a.new_number(total)?;
483
59.4k
    cost += byte_count as Cost * ARITH_COST_PER_BYTE;
484
59.4k
    Ok(malloc_cost(a, cost, total))
485
59.4k
}
486
487
30.3k
pub fn op_multiply(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
488
30.3k
    let mut cost: Cost = MUL_BASE_COST;
489
30.3k
    let mut first_iter: bool = true;
490
30.3k
    let mut total: Number = 1.into();
491
30.3k
    let mut l0: usize = 0;
492
98.8k
    while let Some((arg, rest)) = a.next(input) {
493
68.5k
        input = rest;
494
68.5k
        check_cost(a, cost, max_cost)?;
495
68.5k
        if first_iter {
496
30.2k
            (total, l0) = int_atom(a, arg, "*")?;
497
30.2k
            first_iter = false;
498
30.2k
            continue;
499
38.2k
        }
500
501
38.2k
        let l1 = match a.node(arg) {
502
18.6k
            NodeVisitor::Buffer(buf) => {
503
                use crate::number::number_from_u8;
504
18.6k
                total *= number_from_u8(buf);
505
18.6k
                buf.len()
506
            }
507
19.5k
            NodeVisitor::U32(val) => {
508
19.5k
                total *= val;
509
19.5k
                len_for_value(val)
510
            }
511
            NodeVisitor::Pair(_, _) => {
512
40
                return err(arg, "* requires int args");
513
            }
514
        };
515
516
38.2k
        cost += MUL_COST_PER_OP;
517
38.2k
        cost += (l0 + l1) as Cost * MUL_LINEAR_COST_PER_BYTE;
518
38.2k
        cost += (l0 * l1) as Cost / MUL_SQUARE_COST_PER_BYTE_DIVIDER;
519
38.2k
        l0 = limbs_for_int(&total);
520
    }
521
30.2k
    let total = a.new_number(total)?;
522
30.2k
    Ok(malloc_cost(a, cost, total))
523
30.3k
}
524
525
11.2k
pub fn op_div(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
526
11.2k
    let [v0, v1] = get_args::<2>(a, input, "/")?;
527
11.1k
    let (a0, a0_len) = int_atom(a, v0, "/")?;
528
11.1k
    let (a1, a1_len) = int_atom(a, v1, "/")?;
529
11.1k
    let cost = DIV_BASE_COST + ((a0_len + a1_len) as Cost) * DIV_COST_PER_BYTE;
530
11.1k
    if a1.sign() == Sign::NoSign {
531
1.05k
        err(input, "div with 0")
532
    } else {
533
10.0k
        let q = a0.div_floor(&a1);
534
10.0k
        let q = a.new_number(q)?;
535
10.0k
        Ok(malloc_cost(a, cost, q))
536
    }
537
11.2k
}
538
539
2.95k
pub fn op_divmod(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
540
2.95k
    let [v0, v1] = get_args::<2>(a, input, "divmod")?;
541
2.92k
    let (a0, a0_len) = int_atom(a, v0, "divmod")?;
542
2.91k
    let (a1, a1_len) = int_atom(a, v1, "divmod")?;
543
2.89k
    let cost = DIVMOD_BASE_COST + ((a0_len + a1_len) as Cost) * DIVMOD_COST_PER_BYTE;
544
2.89k
    if a1.sign() == Sign::NoSign {
545
530
        err(input, "divmod with 0")
546
    } else {
547
2.36k
        let (q, r) = a0.div_mod_floor(&a1);
548
2.36k
        let q1 = a.new_number(q)?;
549
2.36k
        let r1 = a.new_number(r)?;
550
551
2.36k
        let c = (a.atom_len(q1) + a.atom_len(r1)) as Cost * MALLOC_COST_PER_BYTE;
552
2.36k
        let r: NodePtr = a.new_pair(q1, r1)?;
553
2.36k
        Ok(Reduction(cost + c, r))
554
    }
555
2.95k
}
556
557
17.7k
pub fn op_mod(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
558
17.7k
    let [v0, v1] = get_args::<2>(a, input, "mod")?;
559
17.6k
    let (a0, a0_len) = int_atom(a, v0, "mod")?;
560
17.6k
    let (a1, a1_len) = int_atom(a, v1, "mod")?;
561
17.6k
    let cost = DIV_BASE_COST + ((a0_len + a1_len) as Cost) * DIV_COST_PER_BYTE;
562
17.6k
    if a1.sign() == Sign::NoSign {
563
744
        err(input, "mod with 0")
564
    } else {
565
16.8k
        let q = a.new_number(a0.mod_floor(&a1))?;
566
16.8k
        let c = a.atom_len(q) as Cost * MALLOC_COST_PER_BYTE;
567
16.8k
        Ok(Reduction(cost + c, q))
568
    }
569
17.7k
}
570
571
2.18k
pub fn op_gr(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
572
2.18k
    let [v0, v1] = get_args::<2>(a, input, ">")?;
573
574
2.15k
    match (a.small_number(v0), a.small_number(v1)) {
575
788
        (Some(lhs), Some(rhs)) => {
576
788
            let cost =
577
788
                GR_BASE_COST + (len_for_value(lhs) + len_for_value(rhs)) as Cost * GR_COST_PER_BYTE;
578
788
            Ok(Reduction(cost, if lhs > rhs { a.one() } else { a.nil() }))
579
        }
580
        _ => {
581
1.36k
            let (v0, v0_len) = int_atom(a, v0, ">")?;
582
1.33k
            let (v1, v1_len) = int_atom(a, v1, ">")?;
583
1.31k
            let cost = GR_BASE_COST + (v0_len + v1_len) as Cost * GR_COST_PER_BYTE;
584
1.31k
            Ok(Reduction(cost, if v0 > v1 { a.one() } else { a.nil() }))
585
        }
586
    }
587
2.18k
}
588
589
2.14k
pub fn op_gr_bytes(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
590
2.14k
    let [n0, n1] = get_args::<2>(a, input, ">s")?;
591
2.12k
    let v0_atom = atom(a, n0, ">s")?;
592
2.11k
    let v1_atom = atom(a, n1, ">s")?;
593
2.10k
    let v0 = v0_atom.as_ref();
594
2.10k
    let v1 = v1_atom.as_ref();
595
2.10k
    let cost = GRS_BASE_COST + (v0.len() + v1.len()) as Cost * GRS_COST_PER_BYTE;
596
2.10k
    Ok(Reduction(cost, if v0 > v1 { a.one() } else { a.nil() }))
597
2.14k
}
598
599
8.70k
pub fn op_strlen(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
600
8.70k
    let [n] = get_args::<1>(a, input, "strlen")?;
601
8.67k
    let size = atom_len(a, n, "strlen")?;
602
8.66k
    let size_node = a.new_number(size.into())?;
603
8.66k
    let cost = STRLEN_BASE_COST + size as Cost * STRLEN_COST_PER_BYTE;
604
8.66k
    Ok(malloc_cost(a, cost, size_node))
605
8.70k
}
606
607
4.20k
pub fn op_substr(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
608
4.20k
    let ([a0, start, end], argc) = get_varargs::<3>(a, input, "substr")?;
609
4.18k
    if !(2..=3).contains(&argc) {
610
51
        return err(input, "substr takes exactly 2 or 3 arguments");
611
4.13k
    }
612
4.13k
    let size = atom_len(a, a0, "substr")?;
613
4.12k
    let start = i32_atom(a, start, "substr")?;
614
615
3.81k
    let end = if argc == 3 {
616
2.02k
        i32_atom(a, end, "substr")?
617
    } else {
618
1.79k
        size as i32
619
    };
620
3.64k
    if end < 0 || start < 0 || end as usize > size || end < start {
621
2.68k
        err(input, "invalid indices for substr")
622
    } else {
623
951
        let r = a.new_substr(a0, start as u32, end as u32)?;
624
951
        let cost: Cost = 1;
625
951
        Ok(Reduction(cost, r))
626
    }
627
4.20k
}
628
629
12.1k
pub fn op_concat(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
630
12.1k
    let mut cost = CONCAT_BASE_COST;
631
12.1k
    let mut total_size: usize = 0;
632
12.1k
    let mut terms = Vec::<NodePtr>::new();
633
45.8k
    while let Some((arg, rest)) = a.next(input) {
634
33.7k
        input = rest;
635
33.7k
        cost += CONCAT_COST_PER_ARG;
636
33.7k
        check_cost(
637
33.7k
            a,
638
33.7k
            cost + total_size as Cost * CONCAT_COST_PER_BYTE,
639
33.7k
            max_cost,
640
33.7k
        )?;
641
33.7k
        match a.sexp(arg) {
642
26
            SExp::Pair(_, _) => return err(arg, "concat on list"),
643
33.7k
            SExp::Atom => total_size += a.atom_len(arg),
644
33.7k
        };
645
33.7k
        terms.push(arg);
646
    }
647
648
12.1k
    cost += total_size as Cost * CONCAT_COST_PER_BYTE;
649
12.1k
    cost += total_size as Cost * MALLOC_COST_PER_BYTE;
650
12.1k
    check_cost(a, cost, max_cost)?;
651
12.0k
    let new_atom = a.new_concat(total_size, &terms)?;
652
12.0k
    Ok(Reduction(cost, new_atom))
653
12.1k
}
654
655
19.8k
pub fn op_ash(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
656
19.8k
    let [n0, n1] = get_args::<2>(a, input, "ash")?;
657
19.8k
    let (i0, l0) = int_atom(a, n0, "ash")?;
658
19.7k
    let a1 = i32_atom(a, n1, "ash")?;
659
19.2k
    if !(-65535..=65535).contains(&a1) {
660
843
        return err(n1, "shift too large");
661
18.4k
    }
662
663
18.4k
    let v: Number = if a1 > 0 { i0 << a1 } else { i0 >> -a1 };
664
18.4k
    let l1 = limbs_for_int(&v);
665
18.4k
    let r = a.new_number(v)?;
666
18.4k
    let cost = ASHIFT_BASE_COST + ((l0 + l1) as Cost) * ASHIFT_COST_PER_BYTE;
667
18.4k
    Ok(malloc_cost(a, cost, r))
668
19.8k
}
669
670
#[cfg(test)]
671
fn test_shift(
672
    op: fn(&mut Allocator, NodePtr, Cost) -> Response,
673
    a: &mut Allocator,
674
    a1: &[u8],
675
    a2: &[u8],
676
) -> Response {
677
    let args = a.nil();
678
    let a2 = a.new_atom(a2).unwrap();
679
    let args = a.new_pair(a2, args).unwrap();
680
    let a1 = a.new_atom(a1).unwrap();
681
    let args = a.new_pair(a1, args).unwrap();
682
    op(a, args, 10000000 as Cost)
683
}
684
685
#[test]
686
fn test_op_ash() {
687
    let mut a = Allocator::new();
688
689
    assert_eq!(
690
        test_shift(op_ash, &mut a, &[1], &[0x80, 0, 0, 0])
691
            .unwrap_err()
692
            .1,
693
        "shift too large"
694
    );
695
696
    assert_eq!(
697
        test_shift(op_ash, &mut a, &[1], &[0x80, 0, 0])
698
            .unwrap_err()
699
            .1,
700
        "shift too large"
701
    );
702
703
    let node = test_shift(op_ash, &mut a, &[1], &[0x80, 0]).unwrap().1;
704
    assert_eq!(a.atom(node).as_ref(), &[]);
705
706
    assert_eq!(
707
        test_shift(op_ash, &mut a, &[1], &[0x7f, 0, 0, 0])
708
            .unwrap_err()
709
            .1,
710
        "shift too large"
711
    );
712
713
    assert_eq!(
714
        test_shift(op_ash, &mut a, &[1], &[0x7f, 0, 0])
715
            .unwrap_err()
716
            .1,
717
        "shift too large"
718
    );
719
720
    let node = test_shift(op_ash, &mut a, &[1], &[0x7f, 0]).unwrap().1;
721
    // the result is 1 followed by 4064 zeroes
722
    let node_atom = a.atom(node);
723
    let node_bytes = node_atom.as_ref();
724
    assert_eq!(node_bytes[0], 1);
725
    assert_eq!(node_bytes.len(), 4065);
726
}
727
728
6.66k
pub fn op_lsh(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
729
6.66k
    let [n0, n1] = get_args::<2>(a, input, "lsh")?;
730
6.63k
    let b0_atom = atom(a, n0, "lsh")?;
731
6.62k
    let b0 = b0_atom.as_ref();
732
6.62k
    let a1 = i32_atom(a, n1, "lsh")?;
733
6.21k
    if !(-65535..=65535).contains(&a1) {
734
857
        return err(n1, "shift too large");
735
5.35k
    }
736
5.35k
    let i0 = BigUint::from_bytes_be(b0);
737
5.35k
    let l0 = b0.len();
738
5.35k
    let i0: Number = i0.into();
739
740
5.35k
    let v: Number = if a1 > 0 { i0 << a1 } else { i0 >> -a1 };
741
742
5.35k
    let l1 = limbs_for_int(&v);
743
5.35k
    let r = a.new_number(v)?;
744
5.35k
    let cost = LSHIFT_BASE_COST + ((l0 + l1) as Cost) * LSHIFT_COST_PER_BYTE;
745
5.35k
    Ok(malloc_cost(a, cost, r))
746
6.66k
}
747
748
#[test]
749
fn test_op_lsh() {
750
    let mut a = Allocator::new();
751
752
    assert_eq!(
753
        test_shift(op_lsh, &mut a, &[1], &[0x80, 0, 0, 0])
754
            .unwrap_err()
755
            .1,
756
        "shift too large"
757
    );
758
759
    assert_eq!(
760
        test_shift(op_lsh, &mut a, &[1], &[0x80, 0, 0])
761
            .unwrap_err()
762
            .1,
763
        "shift too large"
764
    );
765
766
    let node = test_shift(op_lsh, &mut a, &[1], &[0x80, 0]).unwrap().1;
767
    assert_eq!(a.atom(node).as_ref(), &[]);
768
769
    assert_eq!(
770
        test_shift(op_lsh, &mut a, &[1], &[0x7f, 0, 0, 0])
771
            .unwrap_err()
772
            .1,
773
        "shift too large"
774
    );
775
776
    assert_eq!(
777
        test_shift(op_lsh, &mut a, &[1], &[0x7f, 0, 0])
778
            .unwrap_err()
779
            .1,
780
        "shift too large"
781
    );
782
783
    let node = test_shift(op_lsh, &mut a, &[1], &[0x7f, 0]).unwrap().1;
784
    // the result is 1 followed by 4064 zeroes
785
    let node_atom = a.atom(node);
786
    let node_bytes = node_atom.as_ref();
787
    assert_eq!(node_bytes[0], 1);
788
    assert_eq!(node_bytes.len(), 4065);
789
}
790
791
18.9k
fn binop_reduction(
792
18.9k
    op_name: &str,
793
18.9k
    a: &mut Allocator,
794
18.9k
    initial_value: Number,
795
18.9k
    mut input: NodePtr,
796
18.9k
    max_cost: Cost,
797
18.9k
    op_f: fn(&mut Number, &Number) -> (),
798
18.9k
) -> Response {
799
18.9k
    let mut total = initial_value;
800
18.9k
    let mut arg_size: usize = 0;
801
18.9k
    let mut cost = LOG_BASE_COST;
802
58.0k
    while let Some((arg, rest)) = a.next(input) {
803
39.0k
        input = rest;
804
39.0k
        let (n0, len) = int_atom(a, arg, op_name)?;
805
39.0k
        op_f(&mut total, &n0);
806
39.0k
        arg_size += len;
807
39.0k
        cost += LOG_COST_PER_ARG;
808
39.0k
        check_cost(a, cost + (arg_size as Cost * LOG_COST_PER_BYTE), max_cost)?;
809
    }
810
18.9k
    cost += arg_size as Cost * LOG_COST_PER_BYTE;
811
18.9k
    let total = a.new_number(total)?;
812
18.9k
    Ok(malloc_cost(a, cost, total))
813
18.9k
}
814
815
13.5k
fn logand_op(a: &mut Number, b: &Number) {
816
13.5k
    a.bitand_assign(b);
817
13.5k
}
818
819
6.36k
pub fn op_logand(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
820
6.36k
    let v: Number = (-1).into();
821
6.36k
    binop_reduction("logand", a, v, input, max_cost, logand_op)
822
6.36k
}
823
824
12.7k
fn logior_op(a: &mut Number, b: &Number) {
825
12.7k
    a.bitor_assign(b);
826
12.7k
}
827
828
6.34k
pub fn op_logior(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
829
6.34k
    let v: Number = (0).into();
830
6.34k
    binop_reduction("logior", a, v, input, max_cost, logior_op)
831
6.34k
}
832
833
12.7k
fn logxor_op(a: &mut Number, b: &Number) {
834
12.7k
    a.bitxor_assign(b);
835
12.7k
}
836
837
6.25k
pub fn op_logxor(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
838
6.25k
    let v: Number = (0).into();
839
6.25k
    binop_reduction("logxor", a, v, input, max_cost, logxor_op)
840
6.25k
}
841
842
1.23k
pub fn op_lognot(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
843
1.23k
    let [n] = get_args::<1>(a, input, "lognot")?;
844
1.22k
    let (mut n, len) = int_atom(a, n, "lognot")?;
845
1.21k
    n = !n;
846
1.21k
    let cost = LOGNOT_BASE_COST + ((len as Cost) * LOGNOT_COST_PER_BYTE);
847
1.21k
    let r = a.new_number(n)?;
848
1.21k
    Ok(malloc_cost(a, cost, r))
849
1.23k
}
850
851
1.47k
pub fn op_not(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
852
1.47k
    let [n] = get_args::<1>(a, input, "not")?;
853
1.46k
    let r = if nilp(a, n) { a.one() } else { a.nil() };
854
1.46k
    let cost = BOOL_BASE_COST;
855
1.46k
    Ok(Reduction(cost, r))
856
1.47k
}
857
858
2.46k
pub fn op_any(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
859
2.46k
    let mut cost = BOOL_BASE_COST;
860
2.46k
    let mut is_any = false;
861
8.02k
    while let Some((arg, rest)) = a.next(input) {
862
5.55k
        input = rest;
863
5.55k
        cost += BOOL_COST_PER_ARG;
864
5.55k
        check_cost(a, cost, max_cost)?;
865
5.55k
        is_any = is_any || !nilp(a, arg);
866
    }
867
2.46k
    Ok(Reduction(cost, if is_any { a.one() } else { a.nil() }))
868
2.46k
}
869
870
2.61k
pub fn op_all(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
871
2.61k
    let mut cost = BOOL_BASE_COST;
872
2.61k
    let mut is_all = true;
873
8.88k
    while let Some((arg, rest)) = a.next(input) {
874
6.27k
        input = rest;
875
6.27k
        cost += BOOL_COST_PER_ARG;
876
6.27k
        check_cost(a, cost, max_cost)?;
877
6.27k
        is_all = is_all && !nilp(a, arg);
878
    }
879
2.61k
    Ok(Reduction(cost, if is_all { a.one() } else { a.nil() }))
880
2.61k
}
881
882
3.34k
pub fn op_pubkey_for_exp(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
883
3.34k
    let [n] = get_args::<1>(a, input, "pubkey_for_exp")?;
884
3.33k
    let (v0, v0_len) = int_atom(a, n, "pubkey_for_exp")?;
885
3.32k
    let bytes = mod_group_order(v0).to_bytes_be().1;
886
3.32k
887
3.32k
    let point = G1Element::from_integer(&bytes);
888
3.32k
889
3.32k
    let cost = PUBKEY_BASE_COST + (v0_len as Cost) * PUBKEY_COST_PER_BYTE;
890
3.32k
    Ok(Reduction(
891
3.32k
        cost + 48 * MALLOC_COST_PER_BYTE,
892
3.32k
        a.new_g1(point)?,
893
    ))
894
3.34k
}
895
896
12.3k
pub fn op_point_add(a: &mut Allocator, mut input: NodePtr, max_cost: Cost) -> Response {
897
12.3k
    let mut cost = POINT_ADD_BASE_COST;
898
12.3k
    let mut total = G1Element::default();
899
30.4k
    while let Some((arg, rest)) = a.next(input) {
900
19.2k
        input = rest;
901
19.2k
        let point = a.g1(arg)?;
902
18.0k
        cost += POINT_ADD_COST_PER_ARG;
903
18.0k
        check_cost(a, cost, max_cost)?;
904
18.0k
        total += &point;
905
    }
906
    Ok(Reduction(
907
11.2k
        cost + 48 * MALLOC_COST_PER_BYTE,
908
11.2k
        a.new_g1(total)?,
909
    ))
910
12.3k
}
911
912
3.20k
pub fn op_coinid(a: &mut Allocator, input: NodePtr, _max_cost: Cost) -> Response {
913
3.20k
    let [parent_coin, puzzle_hash, amount] = get_args::<3>(a, input, "coinid")?;
914
915
3.14k
    let parent_coin = atom(a, parent_coin, "coinid")?;
916
3.14k
    if parent_coin.as_ref().len() != 32 {
917
190
        return err(input, "coinid: invalid parent coin id (must be 32 bytes)");
918
2.95k
    }
919
2.95k
    let puzzle_hash = atom(a, puzzle_hash, "coinid")?;
920
2.94k
    if puzzle_hash.as_ref().len() != 32 {
921
156
        return err(input, "coinid: invalid puzzle hash (must be 32 bytes)");
922
2.79k
    }
923
2.79k
    let amount_atom = atom(a, amount, "coinid")?;
924
2.78k
    let amount = amount_atom.as_ref();
925
2.78k
    if !amount.is_empty() {
926
2.29k
        if (amount[0] & 0x80) != 0 {
927
663
            return err(input, "coinid: invalid amount (may not be negative");
928
1.63k
        }
929
1.63k
        if amount == [0_u8] || (amount.len() > 1 && amount[0] == 0 && (amount[1] & 0x80) == 0) {
930
6
            return err(
931
6
                input,
932
6
                "coinid: invalid amount (may not have redundant leading zero)",
933
6
            );
934
1.62k
        }
935
1.62k
        // the only valid coin value that's 9 bytes is when a leading zero is
936
1.62k
        // required to not have the value interpreted as negative
937
1.62k
        if amount.len() > 9 || (amount.len() == 9 && amount[0] != 0) {
938
65
            return err(
939
65
                input,
940
65
                "coinid: invalid amount (may not exceed max coin amount)",
941
65
            );
942
1.56k
        }
943
493
    }
944
945
2.05k
    let mut hasher = Sha256::new();
946
2.05k
    hasher.update(parent_coin);
947
2.05k
    hasher.update(puzzle_hash);
948
2.05k
    hasher.update(amount);
949
2.05k
    let ret: [u8; 32] = hasher
950
2.05k
        .finalize()
951
2.05k
        .as_slice()
952
2.05k
        .try_into()
953
2.05k
        .expect("sha256 hash is not 32 bytes");
954
2.05k
955
2.05k
    new_atom_and_cost(a, COINID_COST, &ret)
956
3.20k
}
957
958
7.63k
pub fn op_modpow(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
959
7.63k
    let [base, exponent, modulus] = get_args::<3>(a, input, "modpow")?;
960
961
7.41k
    let mut cost = MODPOW_BASE_COST;
962
7.41k
    let (base, bsize) = int_atom(a, base, "modpow")?;
963
7.40k
    cost += bsize as Cost * MODPOW_COST_PER_BYTE_BASE_VALUE;
964
7.40k
    let (exponent, esize) = int_atom(a, exponent, "modpow")?;
965
7.40k
    cost += (esize * esize) as Cost * MODPOW_COST_PER_BYTE_EXPONENT;
966
7.40k
    check_cost(a, cost, max_cost)?;
967
7.37k
    let (modulus, msize) = int_atom(a, modulus, "modpow")?;
968
7.36k
    cost += (msize * msize) as Cost * MODPOW_COST_PER_BYTE_MOD;
969
7.36k
    check_cost(a, cost, max_cost)?;
970
971
7.08k
    if exponent.sign() == Sign::Minus {
972
1.53k
        return err(input, "modpow with negative exponent");
973
5.54k
    }
974
5.54k
975
5.54k
    if modulus.sign() == Sign::NoSign {
976
519
        return err(input, "modpow with 0 modulus");
977
5.03k
    }
978
5.03k
979
5.03k
    let ret = base.modpow(&exponent, &modulus);
980
5.03k
    let ret = a.new_number(ret)?;
981
5.03k
    Ok(malloc_cost(a, cost, ret))
982
7.63k
}
983
984
#[cfg(test)]
985
fn test_sha256_atom(buf: &[u8]) {
986
    let mut a = Allocator::new();
987
    let mut args = a.nil();
988
    let v = a.new_atom(buf).unwrap();
989
    args = a.new_pair(v, args).unwrap();
990
    let v = a.new_small_number(1).unwrap();
991
    args = a.new_pair(v, args).unwrap();
992
993
    let cost = SHA256_BASE_COST
994
        + (2 * SHA256_COST_PER_ARG)
995
        + ((1 + buf.len()) as Cost * SHA256_COST_PER_BYTE)
996
        + 32 * MALLOC_COST_PER_BYTE;
997
    let Reduction(actual_cost, result) = op_sha256(&mut a, args, cost).unwrap();
998
999
    let mut hasher = Sha256::new();
1000
    hasher.update([1_u8]);
1001
    if !buf.is_empty() {
1002
        hasher.update(buf);
1003
    }
1004
1005
    println!("buf: {buf:?}");
1006
    assert_eq!(a.atom(result).as_ref(), hasher.finalize().as_slice());
1007
    assert_eq!(actual_cost, cost);
1008
}
1009
1010
#[test]
1011
fn sha256_small_values() {
1012
    test_sha256_atom(&[]);
1013
    for val in 0..255 {
1014
        test_sha256_atom(&[val]);
1015
    }
1016
1017
    for val in 0..255 {
1018
        test_sha256_atom(&[0, val]);
1019
    }
1020
1021
    for val in 0..255 {
1022
        test_sha256_atom(&[0xff, val]);
1023
    }
1024
}
/home/oof/clvm_rs/src/number.rs
Line
Count
Source
1
use num_bigint::BigInt;
2
pub type Number = BigInt;
3
4
// This low-level conversion function is meant to be used by the Allocator, for
5
// logic interacting with the CLVM heap/allocator, use new_number() and number()
6
// instead.
7
228k
pub fn number_from_u8(v: &[u8]) -> Number {
8
228k
    let len = v.len();
9
228k
    if len == 0 {
10
261
        0.into()
11
    } else {
12
228k
        Number::from_signed_bytes_be(v)
13
    }
14
228k
}
15
16
#[cfg(test)]
17
use num_bigint::{BigUint, Sign};
18
19
#[cfg(test)]
20
fn roundtrip_bytes(b: &[u8]) {
21
    let negative = !b.is_empty() && (b[0] & 0x80) != 0;
22
    let zero = b.is_empty() || (b.len() == 1 && b[0] == 0);
23
24
    {
25
        let num = Number::from_signed_bytes_be(b);
26
27
        if negative {
28
            assert!(num.sign() == Sign::Minus);
29
        } else if zero {
30
            assert!(num.sign() == Sign::NoSign);
31
        } else {
32
            assert!(num.sign() == Sign::Plus);
33
        }
34
35
        let round_trip = num.to_signed_bytes_be();
36
        // num-bigin produces a single 0 byte for the value 0. We expect an
37
        // empty array
38
        let round_trip = if round_trip == [0] {
39
            &round_trip[1..]
40
        } else {
41
            &round_trip
42
        };
43
44
        assert_eq!(round_trip, b);
45
46
        // test to_bytes_le()
47
        let (sign, mut buf_le) = num.to_bytes_le();
48
49
        // there's a special case for empty input buffers, which will result in
50
        // a single 0 byte here
51
        if b.is_empty() {
52
            assert_eq!(buf_le, &[0]);
53
            buf_le.remove(0);
54
        }
55
        assert!(sign == num.sign());
56
57
        // the buffer we get from to_bytes_le() is unsigned (since the sign is
58
        // returned separately). This means it doesn't ever need to prepend a 0
59
        // byte when the MSB is set. When we're comparing this against the input
60
        // buffer, we need to add such 0 byte to buf_le to make them compare
61
        // equal.
62
        // the 0 prefix has to be added to the end though, since it's little
63
        // endian
64
        if !buf_le.is_empty() && (buf_le.last().unwrap() & 0x80) != 0 {
65
            buf_le.push(0);
66
        }
67
68
        if sign != Sign::Minus {
69
            assert!(buf_le.iter().eq(b.iter().rev()));
70
        } else {
71
            let negated = -num;
72
            let magnitude = negated.to_signed_bytes_be();
73
            assert!(buf_le.iter().eq(magnitude.iter().rev()));
74
        }
75
    }
76
77
    // test parsing unsigned bytes
78
    {
79
        let unsigned_num: Number = BigUint::from_bytes_be(b).into();
80
        assert!(unsigned_num.sign() != Sign::Minus);
81
        let unsigned_round_trip = unsigned_num.to_signed_bytes_be();
82
        let unsigned_round_trip = if unsigned_round_trip == [0] {
83
            &unsigned_round_trip[1..]
84
        } else {
85
            &unsigned_round_trip
86
        };
87
        if !b.is_empty() && (b[0] & 0x80) != 0 {
88
            // we expect a new leading zero here, to keep the value positive
89
            assert!(unsigned_round_trip[0] == 0);
90
            assert_eq!(&unsigned_round_trip[1..], b);
91
        } else {
92
            assert_eq!(unsigned_round_trip, b);
93
        }
94
    }
95
}
96
97
#[test]
98
fn test_number_round_trip_bytes() {
99
    roundtrip_bytes(&[]);
100
101
    for i in 1..=255 {
102
        roundtrip_bytes(&[i]);
103
    }
104
105
    for i in 0..=127 {
106
        roundtrip_bytes(&[0xff, i]);
107
    }
108
109
    for i in 128..=255 {
110
        roundtrip_bytes(&[0, i]);
111
    }
112
113
    for i in 0..=127 {
114
        roundtrip_bytes(&[
115
            0xff, i, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
116
        ]);
117
    }
118
119
    for i in 128..=255 {
120
        roundtrip_bytes(&[
121
            0, i, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
122
        ]);
123
    }
124
125
    for i in 0..=127 {
126
        roundtrip_bytes(&[0xff, i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
127
    }
128
129
    for i in 128..=255 {
130
        roundtrip_bytes(&[0, i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
131
    }
132
}
133
134
#[cfg(test)]
135
fn roundtrip_u64(v: u64) {
136
    let num: Number = v.into();
137
    assert!(num.sign() != Sign::Minus);
138
139
    assert!(num.bits() <= 64);
140
141
    let round_trip: u64 = TryFrom::try_from(num).unwrap();
142
    assert_eq!(round_trip, v);
143
}
144
145
#[test]
146
fn test_round_trip_u64() {
147
    for v in 0..=0x100 {
148
        roundtrip_u64(v);
149
    }
150
151
    for v in 0x7ffe..=0x8001 {
152
        roundtrip_u64(v);
153
    }
154
155
    for v in 0xfffe..=0x10000 {
156
        roundtrip_u64(v);
157
    }
158
159
    for v in 0x7ffffffe..=0x80000001 {
160
        roundtrip_u64(v);
161
    }
162
    for v in 0xfffffffe..=0x100000000 {
163
        roundtrip_u64(v);
164
    }
165
166
    for v in 0x7ffffffffffffffe..=0x8000000000000001 {
167
        roundtrip_u64(v);
168
    }
169
170
    for v in 0xfffffffffffffffe..=0xffffffffffffffff {
171
        roundtrip_u64(v);
172
    }
173
}
174
175
#[cfg(test)]
176
fn roundtrip_i64(v: i64) {
177
    use std::cmp::Ordering;
178
179
    let num: Number = v.into();
180
181
    match v.cmp(&0) {
182
        Ordering::Equal => assert!(num.sign() == Sign::NoSign),
183
        Ordering::Less => assert!(num.sign() == Sign::Minus),
184
        Ordering::Greater => assert!(num.sign() == Sign::Plus),
185
    }
186
187
    assert!(num.bits() <= 64);
188
189
    let round_trip: i64 = TryFrom::try_from(num).unwrap();
190
    assert_eq!(round_trip, v);
191
}
192
193
#[test]
194
fn test_round_trip_i64() {
195
    for v in -0x100..=0x100 {
196
        roundtrip_i64(v);
197
    }
198
199
    for v in 0x7ffe..=0x8001 {
200
        roundtrip_i64(v);
201
    }
202
203
    for v in -0x8001..-0x7ffe {
204
        roundtrip_i64(v);
205
    }
206
207
    for v in 0xfffe..=0x10000 {
208
        roundtrip_i64(v);
209
    }
210
211
    for v in -0x10000..-0xfffe {
212
        roundtrip_i64(v);
213
    }
214
215
    for v in 0x7ffffffe..=0x80000001 {
216
        roundtrip_i64(v);
217
    }
218
219
    for v in -0x80000001..-0x7ffffffe {
220
        roundtrip_i64(v);
221
    }
222
223
    for v in 0xfffffffe..=0x100000000 {
224
        roundtrip_i64(v);
225
    }
226
227
    for v in -0x100000000..-0xfffffffe {
228
        roundtrip_i64(v);
229
    }
230
231
    for v in 0x7ffffffffffffffe..=0x7fffffffffffffff {
232
        roundtrip_i64(v);
233
    }
234
235
    for v in -0x8000000000000000..-0x7ffffffffffffffe {
236
        roundtrip_i64(v);
237
    }
238
}
239
240
#[cfg(test)]
241
fn bits(b: &[u8]) -> u64 {
242
    Number::from_signed_bytes_be(b).bits()
243
}
244
245
#[test]
246
fn test_bits() {
247
    assert_eq!(bits(&[]), 0);
248
    assert_eq!(bits(&[0]), 0);
249
    assert_eq!(bits(&[0b01111111]), 7);
250
    assert_eq!(bits(&[0b00111111]), 6);
251
    assert_eq!(bits(&[0b00011111]), 5);
252
    assert_eq!(bits(&[0b00001111]), 4);
253
    assert_eq!(bits(&[0b00000111]), 3);
254
    assert_eq!(bits(&[0b00000011]), 2);
255
    assert_eq!(bits(&[0b00000001]), 1);
256
    assert_eq!(bits(&[0b00000000]), 0);
257
258
    assert_eq!(bits(&[0b01111111, 0xff]), 15);
259
    assert_eq!(bits(&[0b00111111, 0xff]), 14);
260
    assert_eq!(bits(&[0b00011111, 0xff]), 13);
261
    assert_eq!(bits(&[0b00001111, 0xff]), 12);
262
    assert_eq!(bits(&[0b00000111, 0xff]), 11);
263
    assert_eq!(bits(&[0b00000011, 0xff]), 10);
264
    assert_eq!(bits(&[0b00000001, 0xff]), 9);
265
    assert_eq!(bits(&[0b00000000, 0xff]), 8);
266
267
    assert_eq!(bits(&[0b11111111]), 1);
268
    assert_eq!(bits(&[0b11111110]), 2);
269
    assert_eq!(bits(&[0b11111100]), 3);
270
    assert_eq!(bits(&[0b11111000]), 4);
271
    assert_eq!(bits(&[0b11110000]), 5);
272
    assert_eq!(bits(&[0b11100000]), 6);
273
    assert_eq!(bits(&[0b11000000]), 7);
274
    assert_eq!(bits(&[0b10000000]), 8);
275
276
    assert_eq!(bits(&[0b11111111, 0]), 9);
277
    assert_eq!(bits(&[0b11111110, 0]), 10);
278
    assert_eq!(bits(&[0b11111100, 0]), 11);
279
    assert_eq!(bits(&[0b11111000, 0]), 12);
280
    assert_eq!(bits(&[0b11110000, 0]), 13);
281
    assert_eq!(bits(&[0b11100000, 0]), 14);
282
    assert_eq!(bits(&[0b11000000, 0]), 15);
283
    assert_eq!(bits(&[0b10000000, 0]), 16);
284
}
/home/oof/clvm_rs/src/op_utils.rs
Line
Count
Source
1
use crate::allocator::{Allocator, Atom, NodePtr, NodeVisitor, SExp};
2
use crate::cost::Cost;
3
use crate::err_utils::err;
4
use crate::number::Number;
5
use crate::reduction::EvalErr;
6
use crate::reduction::{Reduction, Response};
7
use lazy_static::lazy_static;
8
use num_bigint::{BigUint, Sign};
9
use num_integer::Integer;
10
11
// We ascribe some additional cost per byte for operations that allocate new atoms
12
pub const MALLOC_COST_PER_BYTE: Cost = 10;
13
14
136k
pub fn get_args<const N: usize>(
15
136k
    a: &Allocator,
16
136k
    args: NodePtr,
17
136k
    name: &str,
18
136k
) -> Result<[NodePtr; N], EvalErr> {
19
136k
    match_args::<N>(a, args).ok_or_else(|| {
20
1.49k
        EvalErr(
21
1.49k
            args,
22
1.49k
            format!(
23
1.49k
                "{name} takes exactly {N} argument{}",
24
1.49k
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
136k
    })
_RNCINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj1_E0B6_
Line
Count
Source
19
236
    match_args::<N>(a, args).ok_or_else(|| {
20
236
        EvalErr(
21
236
            args,
22
236
            format!(
23
236
                "{name} takes exactly {N} argument{}",
24
236
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
236
    })
_RNCINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj2_E0B6_
Line
Count
Source
19
494
    match_args::<N>(a, args).ok_or_else(|| {
20
494
        EvalErr(
21
494
            args,
22
494
            format!(
23
494
                "{name} takes exactly {N} argument{}",
24
494
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
494
    })
_RNCINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj3_E0B6_
Line
Count
Source
19
489
    match_args::<N>(a, args).ok_or_else(|| {
20
489
        EvalErr(
21
489
            args,
22
489
            format!(
23
489
                "{name} takes exactly {N} argument{}",
24
489
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
489
    })
_RNCINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj1_E0Cs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
19
143
    match_args::<N>(a, args).ok_or_else(|| {
20
143
        EvalErr(
21
143
            args,
22
143
            format!(
23
143
                "{name} takes exactly {N} argument{}",
24
143
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
143
    })
_RNCINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj2_E0Cs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
19
64
    match_args::<N>(a, args).ok_or_else(|| {
20
64
        EvalErr(
21
64
            args,
22
64
            format!(
23
64
                "{name} takes exactly {N} argument{}",
24
64
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
64
    })
_RNCINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj4_E0Cs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
19
66
    match_args::<N>(a, args).ok_or_else(|| {
20
66
        EvalErr(
21
66
            args,
22
66
            format!(
23
66
                "{name} takes exactly {N} argument{}",
24
66
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
66
    })
28
136k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj1_EB4_
Line
Count
Source
14
27.8k
pub fn get_args<const N: usize>(
15
27.8k
    a: &Allocator,
16
27.8k
    args: NodePtr,
17
27.8k
    name: &str,
18
27.8k
) -> Result<[NodePtr; N], EvalErr> {
19
27.8k
    match_args::<N>(a, args).ok_or_else(|| {
20
        EvalErr(
21
            args,
22
            format!(
23
                "{name} takes exactly {N} argument{}",
24
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
27.8k
    })
28
27.8k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj2_EB4_
Line
Count
Source
14
79.4k
pub fn get_args<const N: usize>(
15
79.4k
    a: &Allocator,
16
79.4k
    args: NodePtr,
17
79.4k
    name: &str,
18
79.4k
) -> Result<[NodePtr; N], EvalErr> {
19
79.4k
    match_args::<N>(a, args).ok_or_else(|| {
20
        EvalErr(
21
            args,
22
            format!(
23
                "{name} takes exactly {N} argument{}",
24
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
79.4k
    })
28
79.4k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj3_EB4_
Line
Count
Source
14
22.1k
pub fn get_args<const N: usize>(
15
22.1k
    a: &Allocator,
16
22.1k
    args: NodePtr,
17
22.1k
    name: &str,
18
22.1k
) -> Result<[NodePtr; N], EvalErr> {
19
22.1k
    match_args::<N>(a, args).ok_or_else(|| {
20
        EvalErr(
21
            args,
22
            format!(
23
                "{name} takes exactly {N} argument{}",
24
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
22.1k
    })
28
22.1k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj1_ECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
14
3.32k
pub fn get_args<const N: usize>(
15
3.32k
    a: &Allocator,
16
3.32k
    args: NodePtr,
17
3.32k
    name: &str,
18
3.32k
) -> Result<[NodePtr; N], EvalErr> {
19
3.32k
    match_args::<N>(a, args).ok_or_else(|| {
20
        EvalErr(
21
            args,
22
            format!(
23
                "{name} takes exactly {N} argument{}",
24
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
3.32k
    })
28
3.32k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj2_ECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
14
2.68k
pub fn get_args<const N: usize>(
15
2.68k
    a: &Allocator,
16
2.68k
    args: NodePtr,
17
2.68k
    name: &str,
18
2.68k
) -> Result<[NodePtr; N], EvalErr> {
19
2.68k
    match_args::<N>(a, args).ok_or_else(|| {
20
        EvalErr(
21
            args,
22
            format!(
23
                "{name} takes exactly {N} argument{}",
24
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
2.68k
    })
28
2.68k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils8get_argsKj4_ECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
14
606
pub fn get_args<const N: usize>(
15
606
    a: &Allocator,
16
606
    args: NodePtr,
17
606
    name: &str,
18
606
) -> Result<[NodePtr; N], EvalErr> {
19
606
    match_args::<N>(a, args).ok_or_else(|| {
20
        EvalErr(
21
            args,
22
            format!(
23
                "{name} takes exactly {N} argument{}",
24
                if N == 1 { "" } else { "s" }
25
            ),
26
        )
27
606
    })
28
606
}
29
30
143k
pub fn match_args<const N: usize>(a: &Allocator, args: NodePtr) -> Option<[NodePtr; N]> {
31
143k
    let mut next = args;
32
143k
    let mut counter = 0;
33
143k
    let mut ret = [NodePtr::NIL; N];
34
35
422k
    while let Some((first, rest)) = a.next(next) {
36
286k
        next = rest;
37
286k
        if counter == N {
38
7.73k
            return None;
39
278k
        }
40
278k
        ret[counter] = first;
41
278k
        counter += 1;
42
    }
43
44
135k
    if counter != N {
45
885
        None
46
    } else {
47
135k
        Some(ret)
48
    }
49
143k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils10match_argsKj1_EB4_
Line
Count
Source
30
27.8k
pub fn match_args<const N: usize>(a: &Allocator, args: NodePtr) -> Option<[NodePtr; N]> {
31
27.8k
    let mut next = args;
32
27.8k
    let mut counter = 0;
33
27.8k
    let mut ret = [NodePtr::NIL; N];
34
35
55.5k
    while let Some((first, rest)) = a.next(next) {
36
27.9k
        next = rest;
37
27.9k
        if counter == N {
38
173
            return None;
39
27.7k
        }
40
27.7k
        ret[counter] = first;
41
27.7k
        counter += 1;
42
    }
43
44
27.6k
    if counter != N {
45
63
        None
46
    } else {
47
27.5k
        Some(ret)
48
    }
49
27.8k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils10match_argsKj2_EB4_
Line
Count
Source
30
87.0k
pub fn match_args<const N: usize>(a: &Allocator, args: NodePtr) -> Option<[NodePtr; N]> {
31
87.0k
    let mut next = args;
32
87.0k
    let mut counter = 0;
33
87.0k
    let mut ret = [NodePtr::NIL; N];
34
35
260k
    while let Some((first, rest)) = a.next(next) {
36
180k
        next = rest;
37
180k
        if counter == N {
38
7.21k
            return None;
39
173k
        }
40
173k
        ret[counter] = first;
41
173k
        counter += 1;
42
    }
43
44
79.8k
    if counter != N {
45
407
        None
46
    } else {
47
79.4k
        Some(ret)
48
    }
49
87.0k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils10match_argsKj3_EB4_
Line
Count
Source
30
22.1k
pub fn match_args<const N: usize>(a: &Allocator, args: NodePtr) -> Option<[NodePtr; N]> {
31
22.1k
    let mut next = args;
32
22.1k
    let mut counter = 0;
33
22.1k
    let mut ret = [NodePtr::NIL; N];
34
35
88.1k
    while let Some((first, rest)) = a.next(next) {
36
66.1k
        next = rest;
37
66.1k
        if counter == N {
38
165
            return None;
39
65.9k
        }
40
65.9k
        ret[counter] = first;
41
65.9k
        counter += 1;
42
    }
43
44
22.0k
    if counter != N {
45
324
        None
46
    } else {
47
21.6k
        Some(ret)
48
    }
49
22.1k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils10match_argsKj1_ECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
30
3.32k
pub fn match_args<const N: usize>(a: &Allocator, args: NodePtr) -> Option<[NodePtr; N]> {
31
3.32k
    let mut next = args;
32
3.32k
    let mut counter = 0;
33
3.32k
    let mut ret = [NodePtr::NIL; N];
34
35
6.65k
    while let Some((first, rest)) = a.next(next) {
36
3.46k
        next = rest;
37
3.46k
        if counter == N {
38
143
            return None;
39
3.32k
        }
40
3.32k
        ret[counter] = first;
41
3.32k
        counter += 1;
42
    }
43
44
3.18k
    if counter != N {
45
0
        None
46
    } else {
47
3.18k
        Some(ret)
48
    }
49
3.32k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils10match_argsKj2_ECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
30
2.68k
pub fn match_args<const N: usize>(a: &Allocator, args: NodePtr) -> Option<[NodePtr; N]> {
31
2.68k
    let mut next = args;
32
2.68k
    let mut counter = 0;
33
2.68k
    let mut ret = [NodePtr::NIL; N];
34
35
8.00k
    while let Some((first, rest)) = a.next(next) {
36
5.34k
        next = rest;
37
5.34k
        if counter == N {
38
28
            return None;
39
5.32k
        }
40
5.32k
        ret[counter] = first;
41
5.32k
        counter += 1;
42
    }
43
44
2.65k
    if counter != N {
45
36
        None
46
    } else {
47
2.62k
        Some(ret)
48
    }
49
2.68k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils10match_argsKj4_ECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
30
606
pub fn match_args<const N: usize>(a: &Allocator, args: NodePtr) -> Option<[NodePtr; N]> {
31
606
    let mut next = args;
32
606
    let mut counter = 0;
33
606
    let mut ret = [NodePtr::NIL; N];
34
35
2.92k
    while let Some((first, rest)) = a.next(next) {
36
2.33k
        next = rest;
37
2.33k
        if counter == N {
38
11
            return None;
39
2.32k
        }
40
2.32k
        ret[counter] = first;
41
2.32k
        counter += 1;
42
    }
43
44
595
    if counter != N {
45
55
        None
46
    } else {
47
540
        Some(ret)
48
    }
49
606
}
50
51
#[test]
52
fn test_get_args() {
53
    let mut a = Allocator::new();
54
    let a0 = a.new_number(42.into()).unwrap();
55
    let a1 = a.new_number(1337.into()).unwrap();
56
    let a2 = a.new_number(0.into()).unwrap();
57
    let a3 = a.new_atom(&[]).unwrap();
58
    let args0 = a.nil();
59
    let args1 = a.new_pair(a3, args0).unwrap();
60
    let args2 = a.new_pair(a2, args1).unwrap();
61
    let args3 = a.new_pair(a1, args2).unwrap();
62
    let args4 = a.new_pair(a0, args3).unwrap();
63
64
    assert_eq!(get_args::<4>(&a, args4, "test").unwrap(), [a0, a1, a2, a3]);
65
66
    let r = get_args::<3>(&a, args4, "test").unwrap_err();
67
    assert_eq!(r.0, args4);
68
    assert_eq!(r.1, "test takes exactly 3 arguments");
69
70
    let r = get_args::<5>(&a, args4, "test").unwrap_err();
71
    assert_eq!(r.0, args4);
72
    assert_eq!(r.1, "test takes exactly 5 arguments");
73
74
    let r = get_args::<4>(&a, args3, "test").unwrap_err();
75
    assert_eq!(r.0, args3);
76
    assert_eq!(r.1, "test takes exactly 4 arguments");
77
78
    let r = get_args::<4>(&a, args2, "test").unwrap_err();
79
    assert_eq!(r.0, args2);
80
    assert_eq!(r.1, "test takes exactly 4 arguments");
81
82
    let r = get_args::<1>(&a, args2, "test").unwrap_err();
83
    assert_eq!(r.0, args2);
84
    assert_eq!(r.1, "test takes exactly 1 argument");
85
}
86
87
12.8k
pub fn get_varargs<const N: usize>(
88
12.8k
    a: &Allocator,
89
12.8k
    args: NodePtr,
90
12.8k
    name: &str,
91
12.8k
) -> Result<([NodePtr; N], usize), EvalErr> {
92
12.8k
    let mut next = args;
93
12.8k
    let mut counter = 0;
94
12.8k
    let mut ret = [NodePtr::NIL; N];
95
96
37.0k
    while let Some((first, rest)) = a.next(next) {
97
24.2k
        next = rest;
98
24.2k
        if counter == N {
99
            return err(
100
54
                args,
101
54
                &format!(
102
54
                    "{name} takes no more than {N} argument{}",
103
54
                    if N == 1 { "" } else { "s" }
104
                ),
105
            );
106
24.2k
        }
107
24.2k
        ret[counter] = first;
108
24.2k
        counter += 1;
109
    }
110
111
12.7k
    Ok((ret, counter))
112
12.8k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils11get_varargsKj2_EB4_
Line
Count
Source
87
8.63k
pub fn get_varargs<const N: usize>(
88
8.63k
    a: &Allocator,
89
8.63k
    args: NodePtr,
90
8.63k
    name: &str,
91
8.63k
) -> Result<([NodePtr; N], usize), EvalErr> {
92
8.63k
    let mut next = args;
93
8.63k
    let mut counter = 0;
94
8.63k
    let mut ret = [NodePtr::NIL; N];
95
96
22.2k
    while let Some((first, rest)) = a.next(next) {
97
13.6k
        next = rest;
98
13.6k
        if counter == N {
99
            return err(
100
30
                args,
101
30
                &format!(
102
30
                    "{name} takes no more than {N} argument{}",
103
30
                    if N == 1 { "" } else { "s" }
104
                ),
105
            );
106
13.6k
        }
107
13.6k
        ret[counter] = first;
108
13.6k
        counter += 1;
109
    }
110
111
8.60k
    Ok((ret, counter))
112
8.63k
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils11get_varargsKj3_EB4_
Line
Count
Source
87
4.20k
pub fn get_varargs<const N: usize>(
88
4.20k
    a: &Allocator,
89
4.20k
    args: NodePtr,
90
4.20k
    name: &str,
91
4.20k
) -> Result<([NodePtr; N], usize), EvalErr> {
92
4.20k
    let mut next = args;
93
4.20k
    let mut counter = 0;
94
4.20k
    let mut ret = [NodePtr::NIL; N];
95
96
14.7k
    while let Some((first, rest)) = a.next(next) {
97
10.5k
        next = rest;
98
10.5k
        if counter == N {
99
            return err(
100
24
                args,
101
24
                &format!(
102
24
                    "{name} takes no more than {N} argument{}",
103
24
                    if N == 1 { "" } else { "s" }
104
                ),
105
            );
106
10.5k
        }
107
10.5k
        ret[counter] = first;
108
10.5k
        counter += 1;
109
    }
110
111
4.18k
    Ok((ret, counter))
112
4.20k
}
113
114
#[test]
115
fn test_get_varargs() {
116
    let mut a = Allocator::new();
117
    let a0 = a.new_number(42.into()).unwrap();
118
    let a1 = a.new_number(1337.into()).unwrap();
119
    let a2 = a.new_number(0.into()).unwrap();
120
    let a3 = a.new_atom(&[]).unwrap();
121
    let args0 = a.nil();
122
    let args1 = a.new_pair(a3, args0).unwrap();
123
    let args2 = a.new_pair(a2, args1).unwrap();
124
    let args3 = a.new_pair(a1, args2).unwrap();
125
    let args4 = a.new_pair(a0, args3).unwrap();
126
127
    // happy path
128
    assert_eq!(
129
        get_varargs::<4>(&a, args4, "test").unwrap(),
130
        ([a0, a1, a2, a3], 4)
131
    );
132
    assert_eq!(
133
        get_varargs::<4>(&a, args3, "test").unwrap(),
134
        ([a1, a2, a3, NodePtr::NIL], 3)
135
    );
136
    assert_eq!(
137
        get_varargs::<4>(&a, args2, "test").unwrap(),
138
        ([a2, a3, NodePtr::NIL, NodePtr::NIL], 2)
139
    );
140
    assert_eq!(
141
        get_varargs::<4>(&a, args1, "test").unwrap(),
142
        ([a3, NodePtr::NIL, NodePtr::NIL, NodePtr::NIL], 1)
143
    );
144
    assert_eq!(
145
        get_varargs::<4>(&a, args0, "test").unwrap(),
146
        ([NodePtr::NIL; 4], 0)
147
    );
148
149
    let r = get_varargs::<3>(&a, args4, "test").unwrap_err();
150
    assert_eq!(r.0, args4);
151
    assert_eq!(r.1, "test takes no more than 3 arguments");
152
153
    let r = get_varargs::<1>(&a, args4, "test").unwrap_err();
154
    assert_eq!(r.0, args4);
155
    assert_eq!(r.1, "test takes no more than 1 argument");
156
}
157
158
33.0k
pub fn nilp(a: &Allocator, n: NodePtr) -> bool {
159
33.0k
    match a.sexp(n) {
160
22.5k
        SExp::Atom => a.atom_len(n) == 0,
161
10.5k
        _ => false,
162
    }
163
33.0k
}
164
165
#[test]
166
fn test_nilp() {
167
    let mut a = Allocator::new();
168
    let a0 = a.new_number(42.into()).unwrap();
169
    let a1 = a.new_number(1337.into()).unwrap();
170
    let a3 = a.new_number(0.into()).unwrap();
171
    let a4 = a.new_atom(&[]).unwrap();
172
    let a5 = a.nil();
173
    let pair = a.new_pair(a0, a1).unwrap();
174
    assert!(!nilp(&a, pair));
175
    assert!(!nilp(&a, a0));
176
    assert!(!nilp(&a, a1));
177
    assert!(nilp(&a, a3));
178
    assert!(nilp(&a, a4));
179
    assert!(nilp(&a, a5));
180
}
181
182
28.2k
pub fn first(a: &Allocator, n: NodePtr) -> Result<NodePtr, EvalErr> {
183
28.2k
    match a.sexp(n) {
184
28.1k
        SExp::Pair(first, _) => Ok(first),
185
140
        _ => err(n, "first of non-cons"),
186
    }
187
28.2k
}
188
189
#[test]
190
fn test_first() {
191
    let mut a = Allocator::new();
192
    let a0 = a.new_number(42.into()).unwrap();
193
    let a1 = a.new_number(1337.into()).unwrap();
194
    let pair = a.new_pair(a0, a1).unwrap();
195
    assert_eq!(first(&a, pair).unwrap(), a0);
196
197
    let r = first(&a, a0).unwrap_err();
198
    assert_eq!(r.0, a0);
199
    assert_eq!(r.1, "first of non-cons");
200
}
201
202
22.7k
pub fn rest(a: &Allocator, n: NodePtr) -> Result<NodePtr, EvalErr> {
203
22.7k
    match a.sexp(n) {
204
22.5k
        SExp::Pair(_, rest) => Ok(rest),
205
163
        _ => err(n, "rest of non-cons"),
206
    }
207
22.7k
}
208
209
#[test]
210
fn test_rest() {
211
    let mut a = Allocator::new();
212
    let a0 = a.new_number(42.into()).unwrap();
213
    let a1 = a.new_number(1337.into()).unwrap();
214
    let pair = a.new_pair(a0, a1).unwrap();
215
    assert_eq!(rest(&a, pair).unwrap(), a1);
216
217
    let r = rest(&a, a0).unwrap_err();
218
    assert_eq!(r.0, a0);
219
    assert_eq!(r.1, "rest of non-cons");
220
}
221
222
245k
pub fn int_atom(a: &Allocator, args: NodePtr, op_name: &str) -> Result<(Number, usize), EvalErr> {
223
245k
    match a.sexp(args) {
224
245k
        SExp::Atom => Ok((a.number(args), a.atom_len(args))),
225
255
        _ => err(args, &format!("{op_name} requires int args")),
226
    }
227
245k
}
228
229
#[cfg(test)]
230
#[rstest]
231
#[case(0.into(), (0.into(), 0))]
232
#[case(1.into(), (1.into(), 1))]
233
#[case(42.into(), (42.into(), 1))]
234
#[case(1337.into(), (1337.into(), 2))]
235
#[case(0x5fffff.into(), (0x5fffff.into(), 3))]
236
#[case(0xffffff.into(), (0xffffff.into(), 4))]
237
fn test_int_atom(#[case] value: Number, #[case] expected: (Number, usize)) {
238
    let mut a = Allocator::new();
239
    let a0 = a.new_number(value).unwrap();
240
    assert_eq!(int_atom(&a, a0, "test").unwrap(), expected);
241
}
242
243
#[test]
244
fn test_int_atom_failure() {
245
    let mut a = Allocator::new();
246
    let a0 = a.new_number(42.into()).unwrap();
247
    let a1 = a.new_number(1337.into()).unwrap();
248
    let pair = a.new_pair(a0, a1).unwrap();
249
    let r = int_atom(&a, pair, "test").unwrap_err();
250
    assert_eq!(r.0, pair);
251
    assert_eq!(r.1, "test requires int args");
252
}
253
254
14.5k
pub fn atom_len(a: &Allocator, args: NodePtr, op_name: &str) -> Result<usize, EvalErr> {
255
14.5k
    match a.sexp(args) {
256
14.4k
        SExp::Atom => Ok(a.atom_len(args)),
257
57
        _ => err(args, &format!("{op_name} requires an atom")),
258
    }
259
14.5k
}
260
261
#[test]
262
fn test_atom_len() {
263
    let mut a = Allocator::new();
264
265
    let a0 = a.new_number(42.into()).unwrap();
266
    let a1 = a.new_number(1337.into()).unwrap();
267
    let pair = a.new_pair(a0, a1).unwrap();
268
269
    let r = atom_len(&a, pair, "test").unwrap_err();
270
    assert_eq!(r.0, pair);
271
    assert_eq!(r.1, "test requires an atom");
272
273
    assert_eq!(atom_len(&a, a0, "test").unwrap(), 1);
274
    assert_eq!(atom_len(&a, a1, "test").unwrap(), 2);
275
}
276
277
3.94k
pub fn uint_atom<const SIZE: usize>(
278
3.94k
    a: &Allocator,
279
3.94k
    args: NodePtr,
280
3.94k
    op_name: &str,
281
3.94k
) -> Result<u64, EvalErr> {
282
3.94k
    match a.node(args) {
283
2.75k
        NodeVisitor::Buffer(bytes) => {
284
2.75k
            if bytes.is_empty() {
285
13
                return Ok(0);
286
2.74k
            }
287
2.74k
288
2.74k
            if (bytes[0] & 0x80) != 0 {
289
139
                return err(args, &format!("{op_name} requires positive int arg"));
290
2.60k
            }
291
2.60k
292
2.60k
            // strip leading zeros
293
2.60k
            let mut buf: &[u8] = bytes;
294
10.7k
            while !buf.is_empty() && buf[0] == 0 {
295
8.15k
                buf = &buf[1..];
296
8.15k
            }
297
298
2.60k
            if buf.len() > SIZE {
299
43
                return err(args, &format!("{op_name} requires u{} arg", SIZE * 8));
300
2.55k
            }
301
2.55k
302
2.55k
            let mut ret = 0;
303
15.2k
            for b in buf {
304
12.6k
                ret <<= 8;
305
12.6k
                ret |= *b as u64;
306
12.6k
            }
307
2.55k
            Ok(ret)
308
        }
309
1.16k
        NodeVisitor::U32(val) => Ok(val as u64),
310
20
        NodeVisitor::Pair(_, _) => err(args, &format!("{op_name} requires int arg")),
311
    }
312
3.94k
}
Unexecuted instantiation: _RINvNtCs4RkbDk9WRL5_5clvmr8op_utils9uint_atomKpEB4_
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils9uint_atomKj4_ECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
277
540
pub fn uint_atom<const SIZE: usize>(
278
540
    a: &Allocator,
279
540
    args: NodePtr,
280
540
    op_name: &str,
281
540
) -> Result<u64, EvalErr> {
282
540
    match a.node(args) {
283
45
        NodeVisitor::Buffer(bytes) => {
284
45
            if bytes.is_empty() {
285
3
                return Ok(0);
286
42
            }
287
42
288
42
            if (bytes[0] & 0x80) != 0 {
289
10
                return err(args, &format!("{op_name} requires positive int arg"));
290
32
            }
291
32
292
32
            // strip leading zeros
293
32
            let mut buf: &[u8] = bytes;
294
82
            while !buf.is_empty() && buf[0] == 0 {
295
50
                buf = &buf[1..];
296
50
            }
297
298
32
            if buf.len() > SIZE {
299
7
                return err(args, &format!("{op_name} requires u{} arg", SIZE * 8));
300
25
            }
301
25
302
25
            let mut ret = 0;
303
63
            for b in buf {
304
38
                ret <<= 8;
305
38
                ret |= *b as u64;
306
38
            }
307
25
            Ok(ret)
308
        }
309
485
        NodeVisitor::U32(val) => Ok(val as u64),
310
10
        NodeVisitor::Pair(_, _) => err(args, &format!("{op_name} requires int arg")),
311
    }
312
540
}
_RINvNtCs4RkbDk9WRL5_5clvmr8op_utils9uint_atomKj8_ECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
277
3.40k
pub fn uint_atom<const SIZE: usize>(
278
3.40k
    a: &Allocator,
279
3.40k
    args: NodePtr,
280
3.40k
    op_name: &str,
281
3.40k
) -> Result<u64, EvalErr> {
282
3.40k
    match a.node(args) {
283
2.70k
        NodeVisitor::Buffer(bytes) => {
284
2.70k
            if bytes.is_empty() {
285
10
                return Ok(0);
286
2.69k
            }
287
2.69k
288
2.69k
            if (bytes[0] & 0x80) != 0 {
289
129
                return err(args, &format!("{op_name} requires positive int arg"));
290
2.56k
            }
291
2.56k
292
2.56k
            // strip leading zeros
293
2.56k
            let mut buf: &[u8] = bytes;
294
10.6k
            while !buf.is_empty() && buf[0] == 0 {
295
8.10k
                buf = &buf[1..];
296
8.10k
            }
297
298
2.56k
            if buf.len() > SIZE {
299
36
                return err(args, &format!("{op_name} requires u{} arg", SIZE * 8));
300
2.53k
            }
301
2.53k
302
2.53k
            let mut ret = 0;
303
15.1k
            for b in buf {
304
12.6k
                ret <<= 8;
305
12.6k
                ret |= *b as u64;
306
12.6k
            }
307
2.53k
            Ok(ret)
308
        }
309
682
        NodeVisitor::U32(val) => Ok(val as u64),
310
10
        NodeVisitor::Pair(_, _) => err(args, &format!("{op_name} requires int arg")),
311
    }
312
3.40k
}
313
314
#[cfg(test)]
315
use rstest::rstest;
316
317
// u32, 4 bytes
318
#[cfg(test)]
319
#[rstest]
320
#[case(&[0], 0)]
321
#[case(&[0,0,0,1], 1)]
322
#[case(&[0,0xff,0xff,0xff,0xff], 0xffffffff)]
323
#[case(&[0,0,0,0,0,0xff,0xff,0xff,0xff], 0xffffffff)]
324
#[case(&[0x7f,0xff], 0x7fff)]
325
#[case(&[0x7f,0xff, 0xff], 0x7fffff)]
326
#[case(&[0x7f,0xff,0xff, 0xff], 0x7fffffff)]
327
#[case(&[0x01,0x02,0x03, 0x04], 0x1020304)]
328
#[case(&[] as &[u8], 0)]
329
fn test_uint_atom_4_success(#[case] buf: &[u8], #[case] expected: u64) {
330
    use crate::allocator::Allocator;
331
    let mut a = Allocator::new();
332
    let n = a.new_atom(buf).unwrap();
333
    assert!(uint_atom::<4>(&a, n, "test") == Ok(expected));
334
}
335
336
// u32, 4 bytes
337
#[cfg(test)]
338
#[rstest]
339
#[case(&[0xff,0xff,0xff,0xff], "test requires positive int arg")]
340
#[case(&[0xff], "test requires positive int arg")]
341
#[case(&[0x80], "test requires positive int arg")]
342
#[case(&[0x80,0,0,0], "test requires positive int arg")]
343
#[case(&[1, 0xff,0xff,0xff,0xff], "test requires u32 arg")]
344
fn test_uint_atom_4_failure(#[case] buf: &[u8], #[case] expected: &str) {
345
    use crate::allocator::Allocator;
346
    let mut a = Allocator::new();
347
    let n = a.new_atom(buf).unwrap();
348
    assert!(uint_atom::<4>(&a, n, "test") == err(n, expected));
349
}
350
351
#[test]
352
fn test_uint_atom_4_pair() {
353
    use crate::allocator::Allocator;
354
    let mut a = Allocator::new();
355
    let n = a.new_atom(&[0, 0]).unwrap();
356
    let p = a.new_pair(n, n).unwrap();
357
    assert!(uint_atom::<4>(&a, p, "test") == err(p, "test requires int arg"));
358
}
359
360
// u64, 8 bytes
361
#[cfg(test)]
362
#[rstest]
363
#[case(&[0], 0)]
364
#[case(&[0,0,0,1], 1)]
365
#[case(&[0,0xff,0xff,0xff,0xff], 0xffffffff)]
366
#[case(&[0,0,0,0,0xff,0xff,0xff,0xff], 0xffffffff)]
367
#[case(&[0x7f, 0xff], 0x7fff)]
368
#[case(&[0x7f, 0xff, 0xff], 0x7fffff)]
369
#[case(&[0x7f, 0xff,0xff, 0xff], 0x7fffffff)]
370
#[case(&[0x7f, 0xff,0xff, 0xff, 0xff], 0x7fffffffff)]
371
#[case(&[0x7f, 0xff,0xff, 0xff, 0xff, 0xff], 0x7fffffffffff)]
372
#[case(&[0x7f, 0xff,0xff, 0xff, 0xff, 0xff, 0xff], 0x7fffffffffffff)]
373
#[case(&[0x7f, 0xff,0xff, 0xff, 0xff, 0xff, 0xff, 0xff], 0x7fffffffffffffff)]
374
#[case(&[0x01, 0x02,0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ], 0x102030405060708)]
375
#[case(&[] as &[u8], 0)]
376
fn test_uint_atom_8_success(#[case] buf: &[u8], #[case] expected: u64) {
377
    use crate::allocator::Allocator;
378
    let mut a = Allocator::new();
379
    let n = a.new_atom(buf).unwrap();
380
    assert!(uint_atom::<8>(&a, n, "test") == Ok(expected));
381
}
382
383
// u64, 8 bytes
384
#[cfg(test)]
385
#[rstest]
386
#[case(&[0xff,0xff,0xff,0xff], "test requires positive int arg")]
387
#[case(&[0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff], "test requires positive int arg")]
388
#[case(&[0xff], "test requires positive int arg")]
389
#[case(&[0x80], "test requires positive int arg")]
390
#[case(&[0x80,0,0,0], "test requires positive int arg")]
391
#[case(&[1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff], "test requires u64 arg")]
392
fn test_uint_atom_8_failure(#[case] buf: &[u8], #[case] expected: &str) {
393
    use crate::allocator::Allocator;
394
    let mut a = Allocator::new();
395
    let n = a.new_atom(buf).unwrap();
396
    assert!(uint_atom::<8>(&a, n, "test") == err(n, expected));
397
}
398
399
#[test]
400
fn test_uint_atom_8_pair() {
401
    use crate::allocator::Allocator;
402
    let mut a = Allocator::new();
403
    let n = a.new_atom(&[0, 0]).unwrap();
404
    let p = a.new_pair(n, n).unwrap();
405
    assert!(uint_atom::<8>(&a, p, "test") == err(p, "test requires int arg"));
406
}
407
408
72.7k
pub fn atom<'a>(a: &'a Allocator, n: NodePtr, op_name: &str) -> Result<Atom<'a>, EvalErr> {
409
72.7k
    if n.is_pair() {
410
166
        return err(n, &format!("{op_name} on list"));
411
72.5k
    }
412
72.5k
    Ok(a.atom(n))
413
72.7k
}
414
415
46.5k
fn u32_from_u8_impl(buf: &[u8], signed: bool) -> Option<u32> {
416
46.5k
    if buf.is_empty() {
417
42.7k
        return Some(0);
418
3.80k
    }
419
3.80k
420
3.80k
    // too many bytes for u32
421
3.80k
    if buf.len() > 4 {
422
1.41k
        return None;
423
2.39k
    }
424
2.39k
425
2.39k
    let sign_extend = (buf[0] & 0x80) != 0;
426
2.39k
    let mut ret: u32 = if signed && sign_extend { 0xffffffff } else { 0 };
427
10.0k
    for b in buf {
428
7.70k
        ret <<= 8;
429
7.70k
        ret |= *b as u32;
430
7.70k
    }
431
2.39k
    Some(ret)
432
46.5k
}
433
434
43.3k
pub fn u32_from_u8(buf: &[u8]) -> Option<u32> {
435
43.3k
    u32_from_u8_impl(buf, false)
436
43.3k
}
437
438
#[test]
439
fn test_u32_from_u8() {
440
    assert_eq!(u32_from_u8(&[]), Some(0));
441
    assert_eq!(u32_from_u8(&[0xcc]), Some(0xcc));
442
    assert_eq!(u32_from_u8(&[0xcc, 0x55]), Some(0xcc55));
443
    assert_eq!(u32_from_u8(&[0xcc, 0x55, 0x88]), Some(0xcc5588));
444
    assert_eq!(u32_from_u8(&[0xcc, 0x55, 0x88, 0xf3]), Some(0xcc5588f3));
445
446
    assert_eq!(u32_from_u8(&[0xff]), Some(0xff));
447
    assert_eq!(u32_from_u8(&[0xff, 0xff]), Some(0xffff));
448
    assert_eq!(u32_from_u8(&[0xff, 0xff, 0xff]), Some(0xffffff));
449
    assert_eq!(u32_from_u8(&[0xff, 0xff, 0xff, 0xff]), Some(0xffffffff));
450
451
    // leading zeros are not stripped, and not allowed beyond 4 bytes
452
    assert_eq!(u32_from_u8(&[0x00]), Some(0));
453
    assert_eq!(u32_from_u8(&[0x00, 0x00]), Some(0));
454
    assert_eq!(u32_from_u8(&[0x00, 0xcc, 0x55, 0x88]), Some(0xcc5588));
455
    assert_eq!(u32_from_u8(&[0x00, 0x00, 0xcc, 0x55, 0x88]), None);
456
    assert_eq!(u32_from_u8(&[0x00, 0xcc, 0x55, 0x88, 0xf3]), None);
457
458
    // overflow, too many bytes
459
    assert_eq!(u32_from_u8(&[0x01, 0xcc, 0x55, 0x88, 0xf3]), None);
460
    assert_eq!(u32_from_u8(&[0x01, 0x00, 0x00, 0x00, 0x00]), None);
461
    assert_eq!(u32_from_u8(&[0x7d, 0xcc, 0x55, 0x88, 0xf3]), None);
462
}
463
464
3.23k
pub fn i32_from_u8(buf: &[u8]) -> Option<i32> {
465
3.23k
    u32_from_u8_impl(buf, true).map(|v| v as i32)
466
3.23k
}
467
468
#[test]
469
fn test_i32_from_u8() {
470
    assert_eq!(i32_from_u8(&[]), Some(0));
471
    assert_eq!(i32_from_u8(&[0xcc]), Some(-52));
472
    assert_eq!(i32_from_u8(&[0xcc, 0x55]), Some(-13227));
473
    assert_eq!(i32_from_u8(&[0xcc, 0x55, 0x88]), Some(-3385976));
474
    assert_eq!(i32_from_u8(&[0xcc, 0x55, 0x88, 0xf3]), Some(-866809613));
475
476
    assert_eq!(i32_from_u8(&[0xff]), Some(-1));
477
    assert_eq!(i32_from_u8(&[0xff, 0xff]), Some(-1));
478
    assert_eq!(i32_from_u8(&[0xff, 0xff, 0xff]), Some(-1));
479
    assert_eq!(i32_from_u8(&[0xff, 0xff, 0xff, 0xff]), Some(-1));
480
481
    // leading zeros are not stripped, and not allowed beyond 4 bytes
482
    assert_eq!(i32_from_u8(&[0x00]), Some(0));
483
    assert_eq!(i32_from_u8(&[0x00, 0x00]), Some(0));
484
    assert_eq!(i32_from_u8(&[0x00, 0xcc, 0x55, 0x88]), Some(0xcc5588));
485
    assert_eq!(i32_from_u8(&[0x00, 0x00, 0xcc, 0x55, 0x88]), None);
486
    assert_eq!(i32_from_u8(&[0x00, 0xcc, 0x55, 0x88, 0xf3]), None);
487
488
    // overflow, it doesn't really matter whether the bytes are 0 or not, any
489
    // atom larger than 4 bytes is rejected
490
    assert_eq!(i32_from_u8(&[0x01, 0xcc, 0x55, 0x88, 0xf3]), None);
491
    assert_eq!(i32_from_u8(&[0x01, 0x00, 0x00, 0x00, 0x00]), None);
492
    assert_eq!(i32_from_u8(&[0x7d, 0xcc, 0x55, 0x88, 0xf3]), None);
493
}
494
495
0
pub fn u64_from_bytes(buf: &[u8]) -> u64 {
496
0
    if buf.is_empty() {
497
0
        return 0;
498
0
    }
499
0
500
0
    let mut ret: u64 = 0;
501
0
    for b in buf {
502
0
        ret <<= 8;
503
0
        ret |= *b as u64;
504
0
    }
505
0
    ret
506
0
}
507
508
#[test]
509
fn test_u64_from_bytes() {
510
    assert_eq!(u64_from_bytes(&[]), 0);
511
    assert_eq!(u64_from_bytes(&[0xcc]), 0xcc);
512
    assert_eq!(u64_from_bytes(&[0xcc, 0x55]), 0xcc55);
513
    assert_eq!(u64_from_bytes(&[0xcc, 0x55, 0x88]), 0xcc5588);
514
    assert_eq!(u64_from_bytes(&[0xcc, 0x55, 0x88, 0xf3]), 0xcc5588f3);
515
516
    assert_eq!(u64_from_bytes(&[0xff]), 0xff);
517
    assert_eq!(u64_from_bytes(&[0xff, 0xff]), 0xffff);
518
    assert_eq!(u64_from_bytes(&[0xff, 0xff, 0xff]), 0xffffff);
519
    assert_eq!(u64_from_bytes(&[0xff, 0xff, 0xff, 0xff]), 0xffffffff);
520
521
    assert_eq!(u64_from_bytes(&[0x00]), 0);
522
    assert_eq!(u64_from_bytes(&[0x00, 0x00]), 0);
523
    assert_eq!(u64_from_bytes(&[0x00, 0xcc, 0x55, 0x88]), 0xcc5588);
524
    assert_eq!(u64_from_bytes(&[0x00, 0x00, 0xcc, 0x55, 0x88]), 0xcc5588);
525
    assert_eq!(u64_from_bytes(&[0x00, 0xcc, 0x55, 0x88, 0xf3]), 0xcc5588f3);
526
527
    assert_eq!(
528
        u64_from_bytes(&[0xcc, 0x55, 0x88, 0xf3, 0xcc, 0x55, 0x88, 0xf3]),
529
        0xcc5588f3cc5588f3
530
    );
531
}
532
533
32.5k
pub fn i32_atom(a: &Allocator, args: NodePtr, op_name: &str) -> Result<i32, EvalErr> {
534
32.5k
    match a.node(args) {
535
3.23k
        NodeVisitor::Buffer(buf) => match i32_from_u8(buf) {
536
1.85k
            Some(v) => Ok(v),
537
1.38k
            _ => err(
538
1.38k
                args,
539
1.38k
                &format!("{op_name} requires int32 args (with no leading zeros)"),
540
1.38k
            ),
541
        },
542
29.3k
        NodeVisitor::U32(val) => Ok(val as i32),
543
27
        NodeVisitor::Pair(_, _) => err(args, &format!("{op_name} requires int32 args")),
544
    }
545
32.5k
}
546
547
#[test]
548
fn test_i32_atom() {
549
    let mut a = Allocator::new();
550
551
    let a0 = a.new_number(42.into()).unwrap();
552
    let a1 = a.new_number(1337.into()).unwrap();
553
554
    let pair = a.new_pair(a0, a1).unwrap();
555
556
    let r = i32_atom(&a, pair, "test").unwrap_err();
557
    assert_eq!(r.0, pair);
558
    assert_eq!(r.1, "test requires int32 args");
559
560
    assert_eq!(i32_atom(&a, a0, "test").unwrap(), 42);
561
    assert_eq!(i32_atom(&a, a1, "test").unwrap(), 1337);
562
563
    let a2 = a.new_number(0x100000000_i64.into()).unwrap();
564
    let r = i32_atom(&a, a2, "test").unwrap_err();
565
    assert_eq!(r.0, a2);
566
    assert_eq!(r.1, "test requires int32 args (with no leading zeros)");
567
568
    let a3 = a.new_number((-0xffffffff_i64).into()).unwrap();
569
    let r = i32_atom(&a, a3, "test").unwrap_err();
570
    assert_eq!(r.0, a3);
571
    assert_eq!(r.1, "test requires int32 args (with no leading zeros)");
572
}
573
574
11.8k
pub fn new_atom_and_cost(a: &mut Allocator, cost: Cost, buf: &[u8]) -> Response {
575
11.8k
    let c = buf.len() as Cost * MALLOC_COST_PER_BYTE;
576
11.8k
    Ok(Reduction(cost + c, a.new_atom(buf)?))
577
11.8k
}
578
579
14.0k
pub fn mod_group_order(n: Number) -> Number {
580
14.0k
    let order = GROUP_ORDER.clone();
581
14.0k
    let mut remainder = n.mod_floor(&order);
582
14.0k
    if remainder.sign() == Sign::Minus {
583
0
        remainder += order;
584
14.0k
    }
585
14.0k
    remainder
586
14.0k
}
587
588
lazy_static! {
589
    static ref GROUP_ORDER: Number = {
590
        let order_as_bytes = &[
591
            0x73, 0xed, 0xa7, 0x53, 0x29, 0x9d, 0x7d, 0x48, 0x33, 0x39, 0xd8, 0x08, 0x09, 0xa1,
592
            0xd8, 0x05, 0x53, 0xbd, 0xa4, 0x02, 0xff, 0xfe, 0x5b, 0xfe, 0xff, 0xff, 0xff, 0xff,
593
            0x00, 0x00, 0x00, 0x01,
594
        ];
595
        let n = BigUint::from_bytes_be(order_as_bytes);
596
        n.into()
597
    };
598
}
/home/oof/clvm_rs/src/reduction.rs
Line
Count
Source
1
use std::{fmt, io};
2
3
use crate::allocator::NodePtr;
4
use crate::cost::Cost;
5
6
#[derive(Debug, Clone, PartialEq, Eq)]
7
pub struct EvalErr(pub NodePtr, pub String);
8
9
#[derive(Debug, PartialEq, Eq)]
10
pub struct Reduction(pub Cost, pub NodePtr);
11
12
pub type Response = Result<Reduction, EvalErr>;
13
14
impl fmt::Display for EvalErr {
15
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16
0
        write!(f, "Error at {:?}: {}", self.0, self.1)
17
0
    }
18
}
19
20
impl std::error::Error for EvalErr {}
21
22
impl From<EvalErr> for io::Error {
23
0
    fn from(v: EvalErr) -> Self {
24
0
        Self::new(io::ErrorKind::Other, v.1)
25
0
    }
26
}
/home/oof/clvm_rs/src/run_program.rs
Line
Count
Source
1
use super::traverse_path::{traverse_path, traverse_path_fast};
2
use crate::allocator::{Allocator, Checkpoint, NodePtr, NodeVisitor, SExp};
3
use crate::cost::Cost;
4
use crate::dialect::{Dialect, OperatorSet};
5
use crate::err_utils::err;
6
use crate::op_utils::{first, get_args, uint_atom};
7
use crate::reduction::{EvalErr, Reduction, Response};
8
9
// lowered from 46
10
const QUOTE_COST: Cost = 20;
11
// lowered from 138
12
const APPLY_COST: Cost = 90;
13
// the cost of entering a softfork guard
14
const GUARD_COST: Cost = 140;
15
// mandatory base cost for every operator we execute
16
const OP_COST: Cost = 1;
17
18
// The max number of elements allowed on the stack. The program fails if this is
19
// exceeded
20
const STACK_SIZE_LIMIT: usize = 20000000;
21
22
#[cfg(feature = "pre-eval")]
23
pub type PreEval =
24
    Box<dyn Fn(&mut Allocator, NodePtr, NodePtr) -> Result<Option<Box<PostEval>>, EvalErr>>;
25
26
#[cfg(feature = "pre-eval")]
27
pub type PostEval = dyn Fn(&mut Allocator, Option<NodePtr>);
28
29
#[repr(u8)]
30
enum Operation {
31
    Apply,
32
    Cons,
33
    ExitGuard,
34
    SwapEval,
35
36
    #[cfg(feature = "pre-eval")]
37
    PostEval,
38
}
39
40
#[cfg(feature = "counters")]
41
#[derive(Debug)]
42
pub struct Counters {
43
    pub val_stack_usage: usize,
44
    pub env_stack_usage: usize,
45
    pub op_stack_usage: usize,
46
    pub atom_count: u32,
47
    pub small_atom_count: u32,
48
    pub pair_count: u32,
49
    pub heap_size: u32,
50
}
51
52
#[cfg(feature = "counters")]
53
impl Counters {
54
    fn new() -> Self {
55
        Counters {
56
            val_stack_usage: 0,
57
            env_stack_usage: 0,
58
            op_stack_usage: 0,
59
            atom_count: 0,
60
            small_atom_count: 0,
61
            pair_count: 0,
62
            heap_size: 0,
63
        }
64
    }
65
}
66
67
// this represents the state we were in before entering a soft-fork guard. We
68
// may need this to long-jump out of the guard, and also to validate the cost
69
// when exiting the guard
70
struct SoftforkGuard {
71
    // This is the expected cost of the program when exiting the guard. i.e. the
72
    // current_cost + the first argument to the operator
73
    expected_cost: Cost,
74
75
    // When exiting a softfork guard, all values used inside it are zapped. This
76
    // was the state of the allocator before entering. We restore to this state
77
    // on exit.
78
    allocator_state: Checkpoint,
79
80
    // this specifies which new operators are available
81
    operator_set: OperatorSet,
82
83
    #[cfg(test)]
84
    start_cost: Cost,
85
}
86
87
// `run_program` has three stacks:
88
// 1. the operand stack of `NodePtr` objects. val_stack
89
// 2. the operator stack of Operation. op_stack
90
// 3. the environment stack (points to the environment for the current
91
//    operation). env_stack
92
93
struct RunProgramContext<'a, D> {
94
    allocator: &'a mut Allocator,
95
    dialect: &'a D,
96
    val_stack: Vec<NodePtr>,
97
    env_stack: Vec<NodePtr>,
98
    op_stack: Vec<Operation>,
99
    softfork_stack: Vec<SoftforkGuard>,
100
    #[cfg(feature = "counters")]
101
    pub counters: Counters,
102
103
    #[cfg(feature = "pre-eval")]
104
    pre_eval: Option<PreEval>,
105
    #[cfg(feature = "pre-eval")]
106
    posteval_stack: Vec<Box<PostEval>>,
107
}
108
109
1.49M
fn augment_cost_errors(r: Result<Cost, EvalErr>, max_cost: NodePtr) -> Result<Cost, EvalErr> {
110
1.49M
    r.map_err(|e| {
111
47.2k
        if &e.1 != "cost exceeded" {
112
44.4k
            e
113
        } else {
114
2.88k
            EvalErr(max_cost, e.1)
115
        }
116
1.49M
    })
117
1.49M
}
118
119
impl<'a, D: Dialect> RunProgramContext<'a, D> {
120
    #[cfg(feature = "counters")]
121
    #[inline(always)]
122
    fn account_val_push(&mut self) {
123
        self.counters.val_stack_usage =
124
            std::cmp::max(self.counters.val_stack_usage, self.val_stack.len());
125
    }
126
127
    #[cfg(feature = "counters")]
128
    #[inline(always)]
129
    fn account_env_push(&mut self) {
130
        self.counters.env_stack_usage =
131
            std::cmp::max(self.counters.env_stack_usage, self.env_stack.len());
132
    }
133
134
    #[cfg(feature = "counters")]
135
    #[inline(always)]
136
    fn account_op_push(&mut self) {
137
        self.counters.op_stack_usage =
138
            std::cmp::max(self.counters.op_stack_usage, self.op_stack.len());
139
    }
140
141
    #[cfg(not(feature = "counters"))]
142
    #[inline(always)]
143
5.24M
    fn account_val_push(&mut self) {}
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE16account_val_pushB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE16account_val_pushCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
143
5.24M
    fn account_val_push(&mut self) {}
144
145
    #[cfg(not(feature = "counters"))]
146
    #[inline(always)]
147
515k
    fn account_env_push(&mut self) {}
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE16account_env_pushB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE16account_env_pushCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
147
515k
    fn account_env_push(&mut self) {}
148
149
    #[cfg(not(feature = "counters"))]
150
    #[inline(always)]
151
2.71M
    fn account_op_push(&mut self) {}
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE15account_op_pushB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE15account_op_pushCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
151
2.71M
    fn account_op_push(&mut self) {}
152
153
5.01M
    pub fn pop(&mut self) -> Result<NodePtr, EvalErr> {
154
5.01M
        let v: Option<NodePtr> = self.val_stack.pop();
155
5.01M
        match v {
156
            None => {
157
0
                let node: NodePtr = self.allocator.nil();
158
0
                err(node, "runtime error: value stack empty")
159
            }
160
5.01M
            Some(k) => Ok(k),
161
        }
162
5.01M
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE3popB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE3popCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
153
5.01M
    pub fn pop(&mut self) -> Result<NodePtr, EvalErr> {
154
5.01M
        let v: Option<NodePtr> = self.val_stack.pop();
155
5.01M
        match v {
156
            None => {
157
0
                let node: NodePtr = self.allocator.nil();
158
0
                err(node, "runtime error: value stack empty")
159
            }
160
5.01M
            Some(k) => Ok(k),
161
        }
162
5.01M
    }
163
5.24M
    pub fn push(&mut self, node: NodePtr) -> Result<(), EvalErr> {
164
5.24M
        if self.val_stack.len() == STACK_SIZE_LIMIT {
165
0
            return err(node, "value stack limit reached");
166
5.24M
        }
167
5.24M
        self.val_stack.push(node);
168
5.24M
        self.account_val_push();
169
5.24M
        Ok(())
170
5.24M
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE4pushB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE4pushCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
163
5.24M
    pub fn push(&mut self, node: NodePtr) -> Result<(), EvalErr> {
164
5.24M
        if self.val_stack.len() == STACK_SIZE_LIMIT {
165
0
            return err(node, "value stack limit reached");
166
5.24M
        }
167
5.24M
        self.val_stack.push(node);
168
5.24M
        self.account_val_push();
169
5.24M
        Ok(())
170
5.24M
    }
171
172
515k
    pub fn push_env(&mut self, env: NodePtr) -> Result<(), EvalErr> {
173
515k
        if self.env_stack.len() == STACK_SIZE_LIMIT {
174
0
            return err(env, "environment stack limit reached");
175
515k
        }
176
515k
        self.env_stack.push(env);
177
515k
        self.account_env_push();
178
515k
        Ok(())
179
515k
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE8push_envB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE8push_envCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
172
515k
    pub fn push_env(&mut self, env: NodePtr) -> Result<(), EvalErr> {
173
515k
        if self.env_stack.len() == STACK_SIZE_LIMIT {
174
0
            return err(env, "environment stack limit reached");
175
515k
        }
176
515k
        self.env_stack.push(env);
177
515k
        self.account_env_push();
178
515k
        Ok(())
179
515k
    }
180
181
    #[cfg(feature = "pre-eval")]
182
    fn new_with_pre_eval(
183
        allocator: &'a mut Allocator,
184
        dialect: &'a D,
185
        pre_eval: Option<PreEval>,
186
    ) -> Self {
187
        RunProgramContext {
188
            allocator,
189
            dialect,
190
            val_stack: Vec::new(),
191
            env_stack: Vec::new(),
192
            op_stack: Vec::new(),
193
            softfork_stack: Vec::new(),
194
            #[cfg(feature = "counters")]
195
            counters: Counters::new(),
196
            pre_eval,
197
            posteval_stack: Vec::new(),
198
        }
199
    }
200
201
109k
    fn new(allocator: &'a mut Allocator, dialect: &'a D) -> Self {
202
109k
        RunProgramContext {
203
109k
            allocator,
204
109k
            dialect,
205
109k
            val_stack: Vec::new(),
206
109k
            env_stack: Vec::new(),
207
109k
            op_stack: Vec::new(),
208
109k
            softfork_stack: Vec::new(),
209
109k
            #[cfg(feature = "counters")]
210
109k
            counters: Counters::new(),
211
109k
            #[cfg(feature = "pre-eval")]
212
109k
            pre_eval: None,
213
109k
            #[cfg(feature = "pre-eval")]
214
109k
            posteval_stack: Vec::new(),
215
109k
        }
216
109k
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE3newB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE3newCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
201
109k
    fn new(allocator: &'a mut Allocator, dialect: &'a D) -> Self {
202
109k
        RunProgramContext {
203
109k
            allocator,
204
109k
            dialect,
205
109k
            val_stack: Vec::new(),
206
109k
            env_stack: Vec::new(),
207
109k
            op_stack: Vec::new(),
208
109k
            softfork_stack: Vec::new(),
209
109k
            #[cfg(feature = "counters")]
210
109k
            counters: Counters::new(),
211
109k
            #[cfg(feature = "pre-eval")]
212
109k
            pre_eval: None,
213
109k
            #[cfg(feature = "pre-eval")]
214
109k
            posteval_stack: Vec::new(),
215
109k
        }
216
109k
    }
217
218
980k
    fn cons_op(&mut self) -> Result<Cost, EvalErr> {
219
        /* Join the top two operands. */
220
980k
        let v1 = self.pop()?;
221
980k
        let v2 = self.pop()?;
222
980k
        let p = self.allocator.new_pair(v1, v2)?;
223
980k
        self.push(p)?;
224
980k
        Ok(0)
225
980k
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE7cons_opB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE7cons_opCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
218
980k
    fn cons_op(&mut self) -> Result<Cost, EvalErr> {
219
        /* Join the top two operands. */
220
980k
        let v1 = self.pop()?;
221
980k
        let v2 = self.pop()?;
222
980k
        let p = self.allocator.new_pair(v1, v2)?;
223
980k
        self.push(p)?;
224
980k
        Ok(0)
225
980k
    }
226
227
1.15M
    fn eval_op_atom(
228
1.15M
        &mut self,
229
1.15M
        operator_node: NodePtr,
230
1.15M
        operand_list: NodePtr,
231
1.15M
        env: NodePtr,
232
1.15M
    ) -> Result<Cost, EvalErr> {
233
1.15M
        // special case check for quote
234
1.15M
        if self.allocator.small_number(operator_node) == Some(self.dialect.quote_kw()) {
235
637k
            self.push(operand_list)?;
236
637k
            Ok(QUOTE_COST)
237
        } else {
238
512k
            self.push_env(env)?;
239
512k
            self.op_stack.push(Operation::Apply);
240
512k
            self.account_op_push();
241
512k
            self.push(operator_node)?;
242
512k
            let mut operands: NodePtr = operand_list;
243
1.64M
            while let SExp::Pair(first, rest) = self.allocator.sexp(operands) {
244
                // We evaluate every entry in the argument list (using the
245
                // environment at the top of the env_stack) The resulting return
246
                // values are arranged in a list. the top item on the stack is
247
                // the resulting list, and below it is the next pair to
248
                // evaluated.
249
                //
250
                // each evaluation pops both, pushes the result list
251
                // back, evaluates and the executes the Cons operation
252
                // to add the most recent result to the list. Leaving
253
                // the new list at the top of the stack for the next
254
                // pair to be evaluated.
255
1.13M
                self.op_stack.push(Operation::SwapEval);
256
1.13M
                self.account_op_push();
257
1.13M
                self.push(first)?;
258
1.13M
                operands = rest;
259
            }
260
            // ensure a correct nil terminator
261
512k
            if self.allocator.atom_len(operands) != 0 {
262
904
                err(operand_list, "bad operand list")
263
            } else {
264
511k
                self.push(self.allocator.nil())?;
265
511k
                Ok(OP_COST)
266
            }
267
        }
268
1.15M
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE12eval_op_atomB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE12eval_op_atomCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
227
1.15M
    fn eval_op_atom(
228
1.15M
        &mut self,
229
1.15M
        operator_node: NodePtr,
230
1.15M
        operand_list: NodePtr,
231
1.15M
        env: NodePtr,
232
1.15M
    ) -> Result<Cost, EvalErr> {
233
1.15M
        // special case check for quote
234
1.15M
        if self.allocator.small_number(operator_node) == Some(self.dialect.quote_kw()) {
235
637k
            self.push(operand_list)?;
236
637k
            Ok(QUOTE_COST)
237
        } else {
238
512k
            self.push_env(env)?;
239
512k
            self.op_stack.push(Operation::Apply);
240
512k
            self.account_op_push();
241
512k
            self.push(operator_node)?;
242
512k
            let mut operands: NodePtr = operand_list;
243
1.64M
            while let SExp::Pair(first, rest) = self.allocator.sexp(operands) {
244
                // We evaluate every entry in the argument list (using the
245
                // environment at the top of the env_stack) The resulting return
246
                // values are arranged in a list. the top item on the stack is
247
                // the resulting list, and below it is the next pair to
248
                // evaluated.
249
                //
250
                // each evaluation pops both, pushes the result list
251
                // back, evaluates and the executes the Cons operation
252
                // to add the most recent result to the list. Leaving
253
                // the new list at the top of the stack for the next
254
                // pair to be evaluated.
255
1.13M
                self.op_stack.push(Operation::SwapEval);
256
1.13M
                self.account_op_push();
257
1.13M
                self.push(first)?;
258
1.13M
                operands = rest;
259
            }
260
            // ensure a correct nil terminator
261
512k
            if self.allocator.atom_len(operands) != 0 {
262
904
                err(operand_list, "bad operand list")
263
            } else {
264
511k
                self.push(self.allocator.nil())?;
265
511k
                Ok(OP_COST)
266
            }
267
        }
268
1.15M
    }
269
270
1.17M
    fn eval_pair(&mut self, program: NodePtr, env: NodePtr) -> Result<Cost, EvalErr> {
271
        #[cfg(feature = "pre-eval")]
272
        if let Some(pre_eval) = &self.pre_eval {
273
            if let Some(post_eval) = pre_eval(self.allocator, program, env)? {
274
                self.posteval_stack.push(post_eval);
275
                self.op_stack.push(Operation::PostEval);
276
            }
277
        };
278
279
        // put a bunch of ops on op_stack
280
1.17M
        let SExp::Pair(op_node, op_list) = self.allocator.sexp(program) else {
281
            // the program is just a bitfield path through the env tree
282
19.5k
            let r = match self.allocator.node(program) {
283
1.18k
                NodeVisitor::Buffer(buf) => traverse_path(self.allocator, buf, env)?,
284
18.3k
                NodeVisitor::U32(val) => traverse_path_fast(self.allocator, val, env)?,
285
                NodeVisitor::Pair(_, _) => {
286
0
                    panic!("expected atom, got pair");
287
                }
288
            };
289
19.0k
            self.push(r.1)?;
290
19.0k
            return Ok(r.0);
291
        };
292
293
1.15M
        match self.allocator.sexp(op_node) {
294
3.32k
            SExp::Pair(new_operator, _) => {
295
3.32k
                let [inner] = get_args::<1>(
296
3.32k
                    self.allocator,
297
3.32k
                    op_node,
298
3.32k
                    "in the ((X)...) syntax, the inner list",
299
3.32k
                )?;
300
3.18k
                if let SExp::Pair(_, _) = self.allocator.sexp(inner) {
301
84
                    return err(program, "in ((X)...) syntax X must be lone atom");
302
3.09k
                }
303
3.09k
                self.push_env(env)?;
304
3.09k
                self.push(new_operator)?;
305
3.09k
                self.push(op_list)?;
306
3.09k
                self.op_stack.push(Operation::Apply);
307
3.09k
                self.account_op_push();
308
3.09k
                Ok(APPLY_COST)
309
            }
310
1.15M
            SExp::Atom => self.eval_op_atom(op_node, op_list, env),
311
        }
312
1.17M
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE9eval_pairB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE9eval_pairCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
270
1.17M
    fn eval_pair(&mut self, program: NodePtr, env: NodePtr) -> Result<Cost, EvalErr> {
271
        #[cfg(feature = "pre-eval")]
272
        if let Some(pre_eval) = &self.pre_eval {
273
            if let Some(post_eval) = pre_eval(self.allocator, program, env)? {
274
                self.posteval_stack.push(post_eval);
275
                self.op_stack.push(Operation::PostEval);
276
            }
277
        };
278
279
        // put a bunch of ops on op_stack
280
1.17M
        let SExp::Pair(op_node, op_list) = self.allocator.sexp(program) else {
281
            // the program is just a bitfield path through the env tree
282
19.5k
            let r = match self.allocator.node(program) {
283
1.18k
                NodeVisitor::Buffer(buf) => traverse_path(self.allocator, buf, env)?,
284
18.3k
                NodeVisitor::U32(val) => traverse_path_fast(self.allocator, val, env)?,
285
                NodeVisitor::Pair(_, _) => {
286
0
                    panic!("expected atom, got pair");
287
                }
288
            };
289
19.0k
            self.push(r.1)?;
290
19.0k
            return Ok(r.0);
291
        };
292
293
1.15M
        match self.allocator.sexp(op_node) {
294
3.32k
            SExp::Pair(new_operator, _) => {
295
3.32k
                let [inner] = get_args::<1>(
296
3.32k
                    self.allocator,
297
3.32k
                    op_node,
298
3.32k
                    "in the ((X)...) syntax, the inner list",
299
3.32k
                )?;
300
3.18k
                if let SExp::Pair(_, _) = self.allocator.sexp(inner) {
301
84
                    return err(program, "in ((X)...) syntax X must be lone atom");
302
3.09k
                }
303
3.09k
                self.push_env(env)?;
304
3.09k
                self.push(new_operator)?;
305
3.09k
                self.push(op_list)?;
306
3.09k
                self.op_stack.push(Operation::Apply);
307
3.09k
                self.account_op_push();
308
3.09k
                Ok(APPLY_COST)
309
            }
310
1.15M
            SExp::Atom => self.eval_op_atom(op_node, op_list, env),
311
        }
312
1.17M
    }
313
314
1.06M
    fn swap_eval_op(&mut self) -> Result<Cost, EvalErr> {
315
1.06M
        let v2 = self.pop()?;
316
1.06M
        let program: NodePtr = self.pop()?;
317
1.06M
        let env: NodePtr = *self
318
1.06M
            .env_stack
319
1.06M
            .last()
320
1.06M
            .ok_or_else(|| EvalErr(program, "runtime error: env stack empty".into()))?;
Unexecuted instantiation: _RNCNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB4_17RunProgramContextpE12swap_eval_op0B6_
Unexecuted instantiation: _RNCNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB4_17RunProgramContextNtNtB6_12chia_dialect11ChiaDialectE12swap_eval_op0Cs4LiGCEBy0PZ_16fuzz_run_program
321
1.06M
        self.push(v2)?;
322
323
        // on the way back, build a list from the values
324
1.06M
        self.op_stack.push(Operation::Cons);
325
1.06M
        self.account_op_push();
326
1.06M
327
1.06M
        self.eval_pair(program, env)
328
1.06M
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE12swap_eval_opB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE12swap_eval_opCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
314
1.06M
    fn swap_eval_op(&mut self) -> Result<Cost, EvalErr> {
315
1.06M
        let v2 = self.pop()?;
316
1.06M
        let program: NodePtr = self.pop()?;
317
1.06M
        let env: NodePtr = *self
318
1.06M
            .env_stack
319
1.06M
            .last()
320
1.06M
            .ok_or_else(|| EvalErr(program, "runtime error: env stack empty".into()))?;
321
1.06M
        self.push(v2)?;
322
323
        // on the way back, build a list from the values
324
1.06M
        self.op_stack.push(Operation::Cons);
325
1.06M
        self.account_op_push();
326
1.06M
327
1.06M
        self.eval_pair(program, env)
328
1.06M
    }
329
330
606
    fn parse_softfork_arguments(
331
606
        &self,
332
606
        args: NodePtr,
333
606
    ) -> Result<(OperatorSet, NodePtr, NodePtr), EvalErr> {
334
606
        let [_cost, extension, program, env] = get_args::<4>(self.allocator, args, "softfork")?;
335
336
513
        let extension =
337
540
            self.dialect
338
540
                .softfork_extension(uint_atom::<4>(self.allocator, extension, "softfork")? as u32);
339
513
        if extension == OperatorSet::Default {
340
26
            err(args, "unknown softfork extension")
341
        } else {
342
487
            Ok((extension, program, env))
343
        }
344
606
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE24parse_softfork_argumentsB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE24parse_softfork_argumentsCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
330
606
    fn parse_softfork_arguments(
331
606
        &self,
332
606
        args: NodePtr,
333
606
    ) -> Result<(OperatorSet, NodePtr, NodePtr), EvalErr> {
334
606
        let [_cost, extension, program, env] = get_args::<4>(self.allocator, args, "softfork")?;
335
336
513
        let extension =
337
540
            self.dialect
338
540
                .softfork_extension(uint_atom::<4>(self.allocator, extension, "softfork")? as u32);
339
513
        if extension == OperatorSet::Default {
340
26
            err(args, "unknown softfork extension")
341
        } else {
342
487
            Ok((extension, program, env))
343
        }
344
606
    }
345
346
434k
    fn apply_op(&mut self, current_cost: Cost, max_cost: Cost) -> Result<Cost, EvalErr> {
347
434k
        let operand_list = self.pop()?;
348
434k
        let operator = self.pop()?;
349
434k
        if self.env_stack.pop().is_none() {
350
0
            return err(operator, "runtime error: env stack empty");
351
434k
        }
352
434k
        let op_atom = self.allocator.small_number(operator);
353
434k
354
434k
        if op_atom == Some(self.dialect.apply_kw()) {
355
2.68k
            let [new_operator, env] = get_args::<2>(self.allocator, operand_list, "apply")?;
356
2.62k
            self.eval_pair(new_operator, env).map(|c| c + APPLY_COST)
Unexecuted instantiation: _RNCNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB4_17RunProgramContextpE8apply_op0B6_
_RNCNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB4_17RunProgramContextNtNtB6_12chia_dialect11ChiaDialectE8apply_op0Cs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
356
2.59k
            self.eval_pair(new_operator, env).map(|c| c + APPLY_COST)
357
431k
        } else if op_atom == Some(self.dialect.softfork_kw()) {
358
3.22k
            let expected_cost = uint_atom::<8>(
359
3.41k
                self.allocator,
360
3.41k
                first(self.allocator, operand_list)?,
361
3.40k
                "softfork",
362
175
            )?;
363
3.22k
            if expected_cost > max_cost {
364
2.37k
                return err(operand_list, "cost exceeded");
365
854
            }
366
854
            if expected_cost == 0 {
367
248
                return err(operand_list, "cost must be > 0");
368
606
            }
369
370
            // we can't blindly propagate errors here, since we handle errors
371
            // differently depending on whether we allow unknown ops or not
372
606
            let (ext, prg, env) = match self.parse_softfork_arguments(operand_list) {
373
487
                Ok(ret_values) => ret_values,
374
119
                Err(err) => {
375
119
                    if self.dialect.allow_unknown_ops() {
376
                        // In this case, we encountered a softfork invocation
377
                        // that doesn't pass the correct arguments.
378
                        // if we're in consensus mode, we have to accept this as
379
                        // something we don't understand
380
82
                        self.push(self.allocator.nil())?;
381
82
                        return Ok(expected_cost);
382
37
                    }
383
37
                    return Err(err);
384
                }
385
            };
386
387
487
            self.softfork_stack.push(SoftforkGuard {
388
487
                expected_cost: current_cost + expected_cost,
389
487
                allocator_state: self.allocator.checkpoint(),
390
487
                operator_set: ext,
391
487
                #[cfg(test)]
392
487
                start_cost: current_cost,
393
487
            });
394
487
395
487
            // once the softfork guard exits, we need to ensure the cost that was
396
487
            // specified match the true cost. We also free heap allocations
397
487
            self.op_stack.push(Operation::ExitGuard);
398
487
399
487
            self.eval_pair(prg, env).map(|c| c + GUARD_COST)
Unexecuted instantiation: _RNCNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB4_17RunProgramContextpE8apply_ops_0B6_
_RNCNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB4_17RunProgramContextNtNtB6_12chia_dialect11ChiaDialectE8apply_ops_0Cs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
399
464
            self.eval_pair(prg, env).map(|c| c + GUARD_COST)
400
        } else {
401
428k
            let current_extensions = if let Some(sf) = self.softfork_stack.last() {
402
699
                sf.operator_set
403
            } else {
404
427k
                OperatorSet::Default
405
            };
406
407
428k
            let r = self.dialect.op(
408
428k
                self.allocator,
409
428k
                operator,
410
428k
                operand_list,
411
428k
                max_cost,
412
428k
                current_extensions,
413
428k
            )?;
414
385k
            self.push(r.1)?;
415
385k
            Ok(r.0)
416
        }
417
434k
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE8apply_opB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE8apply_opCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
346
434k
    fn apply_op(&mut self, current_cost: Cost, max_cost: Cost) -> Result<Cost, EvalErr> {
347
434k
        let operand_list = self.pop()?;
348
434k
        let operator = self.pop()?;
349
434k
        if self.env_stack.pop().is_none() {
350
0
            return err(operator, "runtime error: env stack empty");
351
434k
        }
352
434k
        let op_atom = self.allocator.small_number(operator);
353
434k
354
434k
        if op_atom == Some(self.dialect.apply_kw()) {
355
2.68k
            let [new_operator, env] = get_args::<2>(self.allocator, operand_list, "apply")?;
356
2.62k
            self.eval_pair(new_operator, env).map(|c| c + APPLY_COST)
357
431k
        } else if op_atom == Some(self.dialect.softfork_kw()) {
358
3.22k
            let expected_cost = uint_atom::<8>(
359
3.41k
                self.allocator,
360
3.41k
                first(self.allocator, operand_list)?,
361
3.40k
                "softfork",
362
175
            )?;
363
3.22k
            if expected_cost > max_cost {
364
2.37k
                return err(operand_list, "cost exceeded");
365
854
            }
366
854
            if expected_cost == 0 {
367
248
                return err(operand_list, "cost must be > 0");
368
606
            }
369
370
            // we can't blindly propagate errors here, since we handle errors
371
            // differently depending on whether we allow unknown ops or not
372
606
            let (ext, prg, env) = match self.parse_softfork_arguments(operand_list) {
373
487
                Ok(ret_values) => ret_values,
374
119
                Err(err) => {
375
119
                    if self.dialect.allow_unknown_ops() {
376
                        // In this case, we encountered a softfork invocation
377
                        // that doesn't pass the correct arguments.
378
                        // if we're in consensus mode, we have to accept this as
379
                        // something we don't understand
380
82
                        self.push(self.allocator.nil())?;
381
82
                        return Ok(expected_cost);
382
37
                    }
383
37
                    return Err(err);
384
                }
385
            };
386
387
487
            self.softfork_stack.push(SoftforkGuard {
388
487
                expected_cost: current_cost + expected_cost,
389
487
                allocator_state: self.allocator.checkpoint(),
390
487
                operator_set: ext,
391
487
                #[cfg(test)]
392
487
                start_cost: current_cost,
393
487
            });
394
487
395
487
            // once the softfork guard exits, we need to ensure the cost that was
396
487
            // specified match the true cost. We also free heap allocations
397
487
            self.op_stack.push(Operation::ExitGuard);
398
487
399
487
            self.eval_pair(prg, env).map(|c| c + GUARD_COST)
400
        } else {
401
428k
            let current_extensions = if let Some(sf) = self.softfork_stack.last() {
402
699
                sf.operator_set
403
            } else {
404
427k
                OperatorSet::Default
405
            };
406
407
428k
            let r = self.dialect.op(
408
428k
                self.allocator,
409
428k
                operator,
410
428k
                operand_list,
411
428k
                max_cost,
412
428k
                current_extensions,
413
428k
            )?;
414
385k
            self.push(r.1)?;
415
385k
            Ok(r.0)
416
        }
417
434k
    }
418
419
14
    fn exit_guard(&mut self, current_cost: Cost) -> Result<Cost, EvalErr> {
420
14
        // this is called when we are done executing a softfork program.
421
14
        // This is when we have to validate the cost
422
14
        let guard = self
423
14
            .softfork_stack
424
14
            .pop()
425
14
            .expect("internal error. exiting a softfork that's already been popped");
426
14
427
14
        if current_cost != guard.expected_cost {
428
            #[cfg(test)]
429
            println!(
430
                "actual cost: {} specified cost: {}",
431
                current_cost - guard.start_cost,
432
                guard.expected_cost - guard.start_cost
433
            );
434
14
            return err(self.allocator.nil(), "softfork specified cost mismatch");
435
0
        }
436
0
437
0
        // restore the allocator to the state when we entered the softfork guard
438
0
        // This is an optimization to reclaim all heap space allocated by the
439
0
        // softfork program. Since the softfork always return nil, no value can
440
0
        // escape the softfork program, and it's therefore safe to restore the
441
0
        // heap
442
0
        self.allocator.restore_checkpoint(&guard.allocator_state);
443
0
444
0
        // the softfork always returns nil, pop the value pushed by the
445
0
        // evaluation of the program and push nil instead
446
0
        self.pop()
447
0
            .expect("internal error, softfork program did not push value onto stack");
448
0
449
0
        self.push(self.allocator.nil())?;
450
451
0
        Ok(0)
452
14
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE10exit_guardB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE10exit_guardCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
419
14
    fn exit_guard(&mut self, current_cost: Cost) -> Result<Cost, EvalErr> {
420
14
        // this is called when we are done executing a softfork program.
421
14
        // This is when we have to validate the cost
422
14
        let guard = self
423
14
            .softfork_stack
424
14
            .pop()
425
14
            .expect("internal error. exiting a softfork that's already been popped");
426
14
427
14
        if current_cost != guard.expected_cost {
428
            #[cfg(test)]
429
            println!(
430
                "actual cost: {} specified cost: {}",
431
                current_cost - guard.start_cost,
432
                guard.expected_cost - guard.start_cost
433
            );
434
14
            return err(self.allocator.nil(), "softfork specified cost mismatch");
435
0
        }
436
0
437
0
        // restore the allocator to the state when we entered the softfork guard
438
0
        // This is an optimization to reclaim all heap space allocated by the
439
0
        // softfork program. Since the softfork always return nil, no value can
440
0
        // escape the softfork program, and it's therefore safe to restore the
441
0
        // heap
442
0
        self.allocator.restore_checkpoint(&guard.allocator_state);
443
0
444
0
        // the softfork always returns nil, pop the value pushed by the
445
0
        // evaluation of the program and push nil instead
446
0
        self.pop()
447
0
            .expect("internal error, softfork program did not push value onto stack");
448
0
449
0
        self.push(self.allocator.nil())?;
450
451
0
        Ok(0)
452
14
    }
453
454
109k
    pub fn run_program(&mut self, program: NodePtr, env: NodePtr, max_cost: Cost) -> Response {
455
109k
        self.val_stack = vec![];
456
109k
        self.op_stack = vec![];
457
458
        // max_cost is always in effect, and necessary to prevent wrap-around of
459
        // the cost integer.
460
109k
        let max_cost = if max_cost == 0 { Cost::MAX } else { max_cost };
461
109k
        let max_cost_ptr = self.allocator.new_number(max_cost.into())?;
462
463
109k
        let mut cost: Cost = 0;
464
109k
465
109k
        cost += self.eval_pair(program, env)?;
466
467
        loop {
468
            // if we are in a softfork guard, temporarily use the guard's
469
            // expected cost as the upper limit. This lets us fail early in case
470
            // it's wrong. It's guaranteed to be <= max_cost, because we check
471
            // that when entering the softfork guard
472
2.53M
            let effective_max_cost = if let Some(sf) = self.softfork_stack.last() {
473
4.39k
                sf.expected_cost
474
            } else {
475
2.53M
                max_cost
476
            };
477
478
2.53M
            if cost > effective_max_cost {
479
114
                return err(max_cost_ptr, "cost exceeded");
480
2.53M
            }
481
2.53M
            let top = self.op_stack.pop();
482
2.53M
            let op = match top {
483
2.47M
                Some(f) => f,
484
61.8k
                None => break,
485
            };
486
2.47M
            cost += match op {
487
434k
                Operation::Apply => augment_cost_errors(
488
434k
                    self.apply_op(cost, effective_max_cost - cost),
489
434k
                    max_cost_ptr,
490
434k
                )?,
491
14
                Operation::ExitGuard => self.exit_guard(cost)?,
492
980k
                Operation::Cons => self.cons_op()?,
493
1.06M
                Operation::SwapEval => augment_cost_errors(self.swap_eval_op(), max_cost_ptr)?,
494
                #[cfg(feature = "pre-eval")]
495
                Operation::PostEval => {
496
                    let f = self.posteval_stack.pop().unwrap();
497
                    let peek: Option<NodePtr> = self.val_stack.last().copied();
498
                    f(self.allocator, peek);
499
                    0
500
                }
501
            };
502
        }
503
61.8k
        Ok(Reduction(cost, self.pop()?))
504
109k
    }
Unexecuted instantiation: _RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextpE11run_programB4_
_RNvMNtCs4RkbDk9WRL5_5clvmr11run_programINtB2_17RunProgramContextNtNtB4_12chia_dialect11ChiaDialectE11run_programCs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
454
109k
    pub fn run_program(&mut self, program: NodePtr, env: NodePtr, max_cost: Cost) -> Response {
455
109k
        self.val_stack = vec![];
456
109k
        self.op_stack = vec![];
457
458
        // max_cost is always in effect, and necessary to prevent wrap-around of
459
        // the cost integer.
460
109k
        let max_cost = if max_cost == 0 { Cost::MAX } else { max_cost };
461
109k
        let max_cost_ptr = self.allocator.new_number(max_cost.into())?;
462
463
109k
        let mut cost: Cost = 0;
464
109k
465
109k
        cost += self.eval_pair(program, env)?;
466
467
        loop {
468
            // if we are in a softfork guard, temporarily use the guard's
469
            // expected cost as the upper limit. This lets us fail early in case
470
            // it's wrong. It's guaranteed to be <= max_cost, because we check
471
            // that when entering the softfork guard
472
2.53M
            let effective_max_cost = if let Some(sf) = self.softfork_stack.last() {
473
4.39k
                sf.expected_cost
474
            } else {
475
2.53M
                max_cost
476
            };
477
478
2.53M
            if cost > effective_max_cost {
479
114
                return err(max_cost_ptr, "cost exceeded");
480
2.53M
            }
481
2.53M
            let top = self.op_stack.pop();
482
2.53M
            let op = match top {
483
2.47M
                Some(f) => f,
484
61.8k
                None => break,
485
            };
486
2.47M
            cost += match op {
487
434k
                Operation::Apply => augment_cost_errors(
488
434k
                    self.apply_op(cost, effective_max_cost - cost),
489
434k
                    max_cost_ptr,
490
434k
                )?,
491
14
                Operation::ExitGuard => self.exit_guard(cost)?,
492
980k
                Operation::Cons => self.cons_op()?,
493
1.06M
                Operation::SwapEval => augment_cost_errors(self.swap_eval_op(), max_cost_ptr)?,
494
                #[cfg(feature = "pre-eval")]
495
                Operation::PostEval => {
496
                    let f = self.posteval_stack.pop().unwrap();
497
                    let peek: Option<NodePtr> = self.val_stack.last().copied();
498
                    f(self.allocator, peek);
499
                    0
500
                }
501
            };
502
        }
503
61.8k
        Ok(Reduction(cost, self.pop()?))
504
109k
    }
505
}
506
507
109k
pub fn run_program<'a, D: Dialect>(
508
109k
    allocator: &'a mut Allocator,
509
109k
    dialect: &'a D,
510
109k
    program: NodePtr,
511
109k
    env: NodePtr,
512
109k
    max_cost: Cost,
513
109k
) -> Response {
514
109k
    let mut rpc = RunProgramContext::new(allocator, dialect);
515
109k
    rpc.run_program(program, env, max_cost)
516
109k
}
Unexecuted instantiation: _RINvNtCs4RkbDk9WRL5_5clvmr11run_program11run_programpEB4_
_RINvNtCs4RkbDk9WRL5_5clvmr11run_program11run_programNtNtB4_12chia_dialect11ChiaDialectECs4LiGCEBy0PZ_16fuzz_run_program
Line
Count
Source
507
109k
pub fn run_program<'a, D: Dialect>(
508
109k
    allocator: &'a mut Allocator,
509
109k
    dialect: &'a D,
510
109k
    program: NodePtr,
511
109k
    env: NodePtr,
512
109k
    max_cost: Cost,
513
109k
) -> Response {
514
109k
    let mut rpc = RunProgramContext::new(allocator, dialect);
515
109k
    rpc.run_program(program, env, max_cost)
516
109k
}
517
518
#[cfg(feature = "pre-eval")]
519
pub fn run_program_with_pre_eval<'a, D: Dialect>(
520
    allocator: &'a mut Allocator,
521
    dialect: &'a D,
522
    program: NodePtr,
523
    env: NodePtr,
524
    max_cost: Cost,
525
    pre_eval: Option<PreEval>,
526
) -> Response {
527
    let mut rpc = RunProgramContext::new_with_pre_eval(allocator, dialect, pre_eval);
528
    rpc.run_program(program, env, max_cost)
529
}
530
531
#[cfg(feature = "counters")]
532
pub fn run_program_with_counters<'a, D: Dialect>(
533
    allocator: &'a mut Allocator,
534
    dialect: &'a D,
535
    program: NodePtr,
536
    env: NodePtr,
537
    max_cost: Cost,
538
) -> (Counters, Response) {
539
    let mut rpc = RunProgramContext::new(allocator, dialect);
540
    let ret = rpc.run_program(program, env, max_cost);
541
    rpc.counters.atom_count = rpc.allocator.atom_count() as u32;
542
    rpc.counters.small_atom_count = rpc.allocator.small_atom_count() as u32;
543
    rpc.counters.pair_count = rpc.allocator.pair_count() as u32;
544
    rpc.counters.heap_size = rpc.allocator.heap_size() as u32;
545
    (rpc.counters, ret)
546
}
547
548
#[cfg(test)]
549
struct RunProgramTest<'a> {
550
    prg: &'a str,
551
    args: &'a str,
552
    flags: u32,
553
    result: Option<&'a str>,
554
    cost: Cost,
555
    err: &'a str,
556
}
557
558
#[cfg(test)]
559
use crate::test_ops::parse_exp;
560
561
#[cfg(test)]
562
use crate::chia_dialect::{ENABLE_BLS_OPS_OUTSIDE_GUARD, NO_UNKNOWN_OPS};
563
564
#[cfg(test)]
565
const TEST_CASES: &[RunProgramTest] = &[
566
    RunProgramTest {
567
        prg: "(/ (q . 10) (q . -3))",
568
        args: "()",
569
        flags: 0,
570
        result: Some("-4"),
571
        cost: 1047,
572
        err: "",
573
    },
574
    RunProgramTest {
575
        prg: "(/ (q . -10) (q . 3))",
576
        args: "()",
577
        flags: 0,
578
        result: Some("-4"),
579
        cost: 1047,
580
        err: "",
581
    },
582
    RunProgramTest {
583
        prg: "(/ (q . -1) (q . 2))",
584
        args: "()",
585
        flags: 0,
586
        result: Some("-1"),
587
        cost: 1047,
588
        err: "",
589
    },
590
    // (mod (X N) (defun power (X N) (if (= N 0) 1 (* X (power X (- N 1))))) (power X N))
591
    RunProgramTest {
592
        prg: "(a (q 2 2 (c 2 (c 5 (c 11 ())))) (c (q 2 (i (= 11 ()) (q 1 . 1) (q 18 5 (a 2 (c 2 (c 5 (c (- 11 (q . 1)) ())))))) 1) 1))",
593
        args: "(5033 1000)",
594
        flags: 0,
595
        result: Some("0x024d4f505f1f813ca5e0ae8805bad8707347e65c5f7595da4852be5074288431d1df11a0c326d249f1f52ee051579403d1d0c23a7a1e9af18b7d7dc4c63c73542863c434ae9dfa80141a30cf4acee0d6c896aa2e64ea748404427a3bdaa1b97e4e09b8f5e4f8e9c568a4fc219532dbbad5ec54476d19b7408f8e7e7df16b830c20a1e83d90cc0620b0677b7606307f725539ef223561cdb276baf8e92156ee6492d97159c8f64768349ea7e219fd07fa818a59d81d0563b140396402f0ff758840da19808440e0a57c94c48ef84b4ab7ca8c5f010b69b8f443b12b50bd91bdcf2a96208ddac283fa294d6a99f369d57ab41d03eab5bb4809223c141ad94378516e6766a5054e22e997e260978af68a86893890d612f081b40d54fd1e940af35c0d7900c9a917e2458a61ef8a83f7211f519b2c5f015dfa7c2949ef8bedd02d3bad64ca9b2963dc2bb79f24092331133a7a299872079b9d0422b8fc0eeba4e12c7667ac7282cc6ff98a7c670614c9fce5a061b8d5cd4dd3c6d62d245688b62f9713dc2604bdd5bbc85c070c51f784a9ebac0e0eaa2e29e82d93e570887aa7e1a9d25baf0b2c55a4615f35ec0dbe9baa921569700f95e10cd2d4f6ba152a2ac288c37b60980df33dadfa920fd43dbbf55a0b333b88a3237d954e33d80ed6582019faf51db5f1b52e392559323f8bdd945e7fc6cb8f97f2b8417cfc184d7bfbfa5314d4114f95b725847523f1848d13c28ad96662298ee4e2d87af23e7cb4e58d7a20a5c57ae6833b4a37dcafccca0245a0d6ef28f83200d74db390281e03dd3a8b782970895764c3fcef31c5ed6d0b6e4e796a62ad5654691eea0d9db351cc4fee63248405b24c98bd5e68e4a5e0ab11e90e3c7de270c594d3a35639d931853b7010c8c896f6b28b2af719e53da65da89d44b926b6f06123c9217a43be35d751516bd02c18c4f868a2eae78ae3c6deab1115086c8ce58414db4561865d17ab95c7b3d4e1bfc6d0a4d3fbf5f20a0a7d77a9270e4da354c588da55b0063aec76654019ffb310e1503d99a7bc81ccdf5f8b15c8638156038624cf35988d8420bfdb59184c4b86bf5448df65c44aedc2e98eead7f1ba4be8f402baf12d41076b8f0991cfc778e04ba2c05d1440c70488ffaeefde537064035037f729b683e8ff1b3d0b4aa26a2b30bcaa9379f7fcc7072ff9a2c3e801c5979b0ab3e7acf89373de642d596f26514b9fa213ca217181a8429ad69d14445a822b16818c2509480576dc0ff7bac48c557e6d1883039f4daf873fa4f9a4d849130e2e4336049cfaf9e69a7664f0202b901cf07c7065c4dc93c46f98c5ea5c9c9d911b733093490da3bf1c95f43cd18b7be3798535a55ac6da3442946a268b74bde1349ca9807c41d90c7ec218a17efd2c21d5fcd720501f8a488f1dfba0a423dfdb2a877707b77930e80d734ceabcdb24513fad8f2e2470604d041df083bf184edd0e9720dd2b608b1ee1df951d7ce8ec671317b4f5a3946aa75280658b4ef77b3f504ce73e7ecac84eec3c2b45fb62f6fbd5ab78c744abd3bf5d0ab37d7b19124d2470d53db09ddc1f9dd9654b0e6a3a44c95d0a5a5e061bd24813508d3d1c901544dc3e6b84ca38dd2fde5ea60a57cbc12428848c4e3f6fd4941ebd23d709a717a090dd01830436659f7c20fd2d70c916427e9f3f12ac479128c2783f02a9824aa4e31de133c2704e049a50160f656e28aa0a2615b32bd48bb5d5d13d363a487324c1e9b8703be938bc545654465c9282ad5420978263b3e3ba1bb45e1a382554ac68e5a154b896c9c4c2c3853fbbfc877c4fb7dc164cc420f835c413839481b1d2913a68d206e711fb19b284a7bb2bd2033531647cf135833a0f3026b0c1dc0c184120d30ef4865985fdacdfb848ab963d2ae26a784b7b6a64fdb8feacf94febed72dcd0a41dc12be26ed79af88f1d9cba36ed1f95f2da8e6194800469091d2dfc7b04cfe93ab7a7a888b2695bca45a76a1458d08c3b6176ab89e7edc56c7e01142adfff944641b89cd5703a911145ac4ec42164d90b6fcd78b39602398edcd1f935485894fb8a1f416e031624806f02fbd07f398dbfdd48b86dfacf2045f85ecfe5bb1f01fae758dcdb4ae3b1e2aac6f0878f700d1f430b8ca47c9d8254059bd5c006042c4605f33ca98b41"),
596
        cost: 15073165,
597
        err: "",
598
    },
599
    // '
600
    RunProgramTest {
601
        prg: "(= (point_add (pubkey_for_exp (q . -2)) (pubkey_for_exp (q . 5))) (pubkey_for_exp (q . 3)))",
602
        args: "()",
603
        flags: 0,
604
        result: Some("1"),
605
        cost: 6768556,
606
        err: "",
607
    },
608
    RunProgramTest {
609
        prg: "(= (point_add (pubkey_for_exp (q . 2)) (pubkey_for_exp (q . 3))) (pubkey_for_exp (q . 5)))",
610
        args: "()",
611
        flags: 0,
612
        result: Some("1"),
613
        cost: 6768556,
614
        err: "",
615
    },
616
    RunProgramTest {
617
        prg: "(point_add (pubkey_for_exp (q . 1)) (pubkey_for_exp (q . 2)))",
618
        args: "()",
619
        flags: 0,
620
        result: Some("0x89ece308f9d1f0131765212deca99697b112d61f9be9a5f1f3780a51335b3ff981747a0b2ca2179b96d2c0c9024e5224"),
621
        cost: 5442073,
622
        err: "",
623
    },
624
    RunProgramTest {
625
        prg: "(f (f (q . ((100 200 300) 400 500))))",
626
        args: "()",
627
        flags: 0,
628
        result: Some("0x64"),
629
        cost: 82,
630
        err: "",
631
    },
632
    RunProgramTest {
633
        prg: "(= (f 1) (+ (f (r 1)) (f (r (r 1)))))",
634
        args: "(7 3 3)",
635
        flags: 0,
636
        result: Some("()"),
637
        cost: 1194,
638
        err: "",
639
    },
640
    RunProgramTest {
641
        prg: "(= (f 1) (+ (f (r 1)) (f (r (r 1)))))",
642
        args: "(7 3 4)",
643
        flags: 0,
644
        result: Some("1"),
645
        cost: 1194,
646
        err: "",
647
    },
648
    RunProgramTest {
649
        prg: "(i (f (r (r 1))) (f 1) (f (r 1)))",
650
        args: "(200 300 400)",
651
        flags: 0,
652
        result: Some("0x00c8"),
653
        cost: 352,
654
        err: "",
655
    },
656
    RunProgramTest {
657
        prg: "(i (f (r (r 1))) (f 1) (f (r 1)))",
658
        args: "(200 300 1)",
659
        flags: 0,
660
        result: Some("0x00c8"),
661
        cost: 352,
662
        err: "",
663
    },
664
    RunProgramTest {
665
        prg: "(r (r (q . ((100 200 300) 400 500))))",
666
        args: "()",
667
        flags: 0,
668
        result: Some("(500)"),
669
        cost: 82,
670
        err: "",
671
    },
672
    RunProgramTest {
673
        prg: "(* (q . 10000000000000000000000000000000000) (q . 10000000000000000000000000000000) (q . 100000000000000000000000000000000000000) (q . 1000000000000000000000000000000) (q . 1000000000000000000000000000000) (q . 1000000000000000000000000000000) (q . 1000000000000000000000000000000) (q . 1000000000000000000000000000000) (q . 1000000000000000000000000000000) (q . 1000000000000000000000000000000) (q . 1000000000000000000000000000000) (q . 1000000000000000000000000000000) (q . 1000000000000000000000000000000) (q . 1000000000000000000000000000000) (q . 1000000000000000000000000000000))",
674
        args: "()",
675
        flags: 0,
676
        result: Some("0x04261a5c969abab851babdb4f178e63bf2ed3879fc13a4c75622d73c909440a4763849b52e49cd2522500f555f6a3131775f93ddcf24eda7a1dbdf828a033626da873caaaa880a9121f4c44a157973f60443dc53bc99ac12d5bd5fa20a88320ae2ccb8e1b5e792cbf0d001bb0fbd7765d3936e412e2fc8f1267833237237fcb638dda0a7aa674680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
677
        cost: 24255,
678
        err: "",
679
    },
680
681
    // ## APPLY
682
    RunProgramTest {
683
        prg: "(a (q 0x0fffffffff) (q ()))",
684
        args: "()",
685
        flags: 0,
686
        result: None,
687
        cost: 0,
688
        err: "invalid operator",
689
    },
690
    RunProgramTest {
691
        prg: "(a (q . 0) (q . 1) (q . 2))",
692
        args: "()",
693
        flags: 0,
694
        result: None,
695
        cost: 0,
696
        err: "apply takes exactly 2 arguments",
697
    },
698
    RunProgramTest {
699
        prg: "(a (q 0x00ffffffffffffffffffff00) (q ()))",
700
        args: "()",
701
        flags: 0,
702
        result: None,
703
        cost: 0,
704
        err: "invalid operator",
705
    },
706
    RunProgramTest {
707
        prg: "(a (q . 1))",
708
        args: "()",
709
        flags: 0,
710
        result: None,
711
        cost: 0,
712
        err: "apply takes exactly 2 arguments",
713
    },
714
    RunProgramTest {
715
        prg: "(a (q . 1) (q . (100 200)))",
716
        args: "()",
717
        flags: 0,
718
        result: Some("(100 200)"),
719
        cost: 175,
720
        err: "",
721
    },
722
    RunProgramTest {
723
        prg: "(a (q . (+ 2 5)) (q . (20 30)))",
724
        args: "()",
725
        flags: 0,
726
        result: Some("50"),
727
        cost: 987,
728
        err: "",
729
    },
730
    RunProgramTest {
731
        prg: "((c (q . (+ (q . 50) 1)) (q . 500)))",
732
        args: "()",
733
        flags: 0,
734
        result: None,
735
        cost: 0,
736
        err: "in the ((X)...) syntax, the inner list takes exactly 1 argument",
737
    },
738
    RunProgramTest {
739
        prg: "((#c) (q . 3) (q . 4))",
740
        args: "()",
741
        flags: 0,
742
        result: Some("((1 . 3) 1 . 4)"),
743
        cost: 140,
744
        err: "",
745
    },
746
    RunProgramTest {
747
        prg: "((#+) 1 2 3)",
748
        args: "()",
749
        flags: 0,
750
        result: Some("6"),
751
        cost: 1168,
752
        err: "",
753
    },
754
    RunProgramTest {
755
        prg: "(a (q . 2) (q . (3 4 5)))",
756
        args: "()",
757
        flags: 0,
758
        result: Some("3"),
759
        cost: 179,
760
        err: "",
761
    },
762
763
    // ## PATH LOOKUPS
764
765
    // 0
766
    RunProgramTest {
767
        prg: "0",
768
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
769
        flags: 0,
770
        result: Some("()"),
771
        cost: 44,
772
        err: "",
773
    },
774
    // 1
775
    RunProgramTest {
776
        prg: "1",
777
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
778
        flags: 0,
779
        result: Some("(((8 . 12) 10 . 14) (9 . 13) 11 . 15)"),
780
        cost: 44,
781
        err: "",
782
    },
783
    // 2
784
    RunProgramTest {
785
        prg: "2",
786
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
787
        flags: 0,
788
        result: Some("((8 . 12) 10 . 14)"),
789
        cost: 48,
790
        err: "",
791
    },
792
    // 3
793
    RunProgramTest {
794
        prg: "3",
795
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
796
        flags: 0,
797
        result: Some("((9 . 13) 11 . 15)"),
798
        cost: 48,
799
        err: "",
800
    },
801
    // 4
802
    RunProgramTest {
803
        prg: "4",
804
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
805
        flags: 0,
806
        result: Some("(8 . 12)"),
807
        cost: 52,
808
        err: "",
809
    },
810
    // 5
811
    RunProgramTest {
812
        prg: "5",
813
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
814
        flags: 0,
815
        result: Some("(9 . 13)"),
816
        cost: 52,
817
        err: "",
818
    },
819
    // 6
820
    RunProgramTest {
821
        prg: "6",
822
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
823
        flags: 0,
824
        result: Some("(10 . 14)"),
825
        cost: 52,
826
        err: "",
827
    },
828
    // 7
829
    RunProgramTest {
830
        prg: "7",
831
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
832
        flags: 0,
833
        result: Some("(11 . 15)"),
834
        cost: 52,
835
        err: "",
836
    },
837
    RunProgramTest {
838
        prg: "8",
839
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
840
        flags: 0,
841
        result: Some("8"),
842
        cost: 56,
843
        err: "",
844
    },
845
    RunProgramTest {
846
        prg: "9",
847
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
848
        flags: 0,
849
        result: Some("9"),
850
        cost: 56,
851
        err: "",
852
    },
853
    RunProgramTest {
854
        prg: "10",
855
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
856
        flags: 0,
857
        result: Some("10"),
858
        cost: 56,
859
        err: "",
860
    },
861
    RunProgramTest {
862
        prg: "11",
863
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
864
        flags: 0,
865
        result: Some("11"),
866
        cost: 56,
867
        err: "",
868
    },
869
    RunProgramTest {
870
        prg: "12",
871
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
872
        flags: 0,
873
        result: Some("12"),
874
        cost: 56,
875
        err: "",
876
    },
877
    RunProgramTest {
878
        prg: "13",
879
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
880
        flags: 0,
881
        result: Some("13"),
882
        cost: 56,
883
        err: "",
884
    },
885
    RunProgramTest {
886
        prg: "14",
887
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
888
        flags: 0,
889
        result: Some("14"),
890
        cost: 56,
891
        err: "",
892
    },
893
    RunProgramTest {
894
        prg: "15",
895
        args: "(((8 . 12) . (10 . 14)) . ((9 . 13) . (11 . 15)))",
896
        flags: 0,
897
        result: Some("15"),
898
        cost: 56,
899
        err: "",
900
    },
901
    RunProgramTest {
902
        prg: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
903
        args: "(((0x1337 . (0x1337 . (42 . 0x1337))) . 0x1337) . 0x1337)",
904
        flags: 0,
905
        result: Some("(((0x1337 . (0x1337 . (42 . 0x1337))) . 0x1337) . 0x1337)"),
906
        cost: 536,
907
        err: "",
908
    },
909
    RunProgramTest {
910
        prg: "0x0000C8C141AB3121E776",
911
        args: "((0x1337 . (0x1337 . ((0x1337 . (0x1337 . (0x1337 . ((0x1337 . (0x1337 . (0x1337 . (((0x1337 . (0x1337 . (0x1337 . (0x1337 . (((((0x1337 . (((0x1337 . ((((0x1337 . (0x1337 . (((0x1337 . (0x1337 . ((0x1337 . ((0x1337 . ((0x1337 . (0x1337 . ((((((0x1337 . ((0x1337 . ((((((0x1337 . (0x1337 . ((((0x1337 . (((0x1337 . 42) . 0x1337) . 0x1337)) . 0x1337) . 0x1337) . 0x1337))) . 0x1337) . 0x1337) . 0x1337) . 0x1337) . 0x1337)) . 0x1337)) . 0x1337) . 0x1337) . 0x1337) . 0x1337) . 0x1337))) . 0x1337)) . 0x1337)) . 0x1337))) . 0x1337) . 0x1337))) . 0x1337) . 0x1337) . 0x1337)) . 0x1337) . 0x1337)) . 0x1337) . 0x1337) . 0x1337) . 0x1337))))) . 0x1337) . 0x1337)))) . 0x1337)))) . 0x1337))) . 0x1337)",
912
        flags: 0,
913
        result: Some("42"),
914
        cost: 304,
915
        err: "",
916
    },
917
    RunProgramTest {
918
        prg: "7708975405620101644641102810267383005",
919
        args: "(0x1337 . ((0x1337 . (0x1337 . (0x1337 . ((0x1337 . (0x1337 . (((0x1337 . ((0x1337 . (0x1337 . (0x1337 . (0x1337 . (0x1337 . ((0x1337 . (0x1337 . ((0x1337 . (((0x1337 . (0x1337 . (0x1337 . ((0x1337 . (((0x1337 . (((0x1337 . (0x1337 . (0x1337 . (0x1337 . ((0x1337 . ((0x1337 . (((((0x1337 . ((0x1337 . ((0x1337 . (0x1337 . (0x1337 . (((0x1337 . (0x1337 . ((0x1337 . (0x1337 . ((((0x1337 . (0x1337 . (0x1337 . (0x1337 . (((((0x1337 . (0x1337 . (0x1337 . (0x1337 . (0x1337 . (((((0x1337 . (((((0x1337 . ((0x1337 . (0x1337 . ((((0x1337 . ((((0x1337 . ((0x1337 . ((0x1337 . ((0x1337 . (0x1337 . (0x1337 . ((((0x1337 . (0x1337 . ((0x1337 . (((0x1337 . (0x1337 . (((0x1337 . (0x1337 . (0x1337 . (42 . 0x1337)))) . 0x1337) . 0x1337))) . 0x1337) . 0x1337)) . 0x1337))) . 0x1337) . 0x1337) . 0x1337)))) . 0x1337)) . 0x1337)) . 0x1337)) . 0x1337) . 0x1337) . 0x1337)) . 0x1337) . 0x1337) . 0x1337))) . 0x1337)) . 0x1337) . 0x1337) . 0x1337) . 0x1337)) . 0x1337) . 0x1337) . 0x1337) . 0x1337)))))) . 0x1337) . 0x1337) . 0x1337) . 0x1337))))) . 0x1337) . 0x1337) . 0x1337))) . 0x1337))) . 0x1337) . 0x1337)))) . 0x1337)) . 0x1337)) . 0x1337) . 0x1337) . 0x1337) . 0x1337)) . 0x1337)) . 0x1337))))) . 0x1337) . 0x1337)) . 0x1337) . 0x1337)) . 0x1337)))) . 0x1337) . 0x1337)) . 0x1337))) . 0x1337)))))) . 0x1337)) . 0x1337) . 0x1337))) . 0x1337)))) . 0x1337))",
920
        flags: 0,
921
        result: Some("42"),
922
        cost: 532,
923
        err: "",
924
    },
925
    RunProgramTest {
926
        prg: "1",
927
        args: "1",
928
        flags: 0,
929
        result: Some("1"),
930
        cost: 44,
931
        err: "",
932
    },
933
    RunProgramTest {
934
        prg: "(> 3 3)",
935
        args: "()",
936
        flags: 0,
937
        result: None,
938
        cost: 0,
939
        err: "path into atom",
940
    },
941
942
    // ## SOFTFORK
943
944
    // the arguments to softfork are checked in mempool mode, but in consensus
945
    // mode, only the cost argument is
946
    RunProgramTest {
947
        prg: "(softfork (q . 979))",
948
        args: "()",
949
        flags: 0,
950
        result: Some("()"),
951
        cost: 1000,
952
        err: "",
953
    },
954
    RunProgramTest {
955
        prg: "(softfork (q . 979))",
956
        args: "()",
957
        flags: NO_UNKNOWN_OPS,
958
        result: None,
959
        cost: 1000,
960
        err: "softfork takes exactly 4 arguments",
961
    },
962
    RunProgramTest {
963
        prg: "(softfork (q . 959) (q . 9))",
964
        args: "()",
965
        flags: 0,
966
        result: Some("()"),
967
        cost: 1000,
968
        err: "",
969
    },
970
    RunProgramTest {
971
        prg: "(softfork (q . 959) (q . 9))",
972
        args: "()",
973
        flags: NO_UNKNOWN_OPS,
974
        result: None,
975
        cost: 1000,
976
        err: "softfork takes exactly 4 arguments",
977
    },
978
    RunProgramTest {
979
        prg: "(softfork (q . 939) (q . 9) (q x))",
980
        args: "()",
981
        flags: 0,
982
        result: Some("()"),
983
        cost: 1000,
984
        err: "",
985
    },
986
    RunProgramTest {
987
        prg: "(softfork (q . 939) (q . 9) (q x))",
988
        args: "()",
989
        flags: NO_UNKNOWN_OPS,
990
        result: None,
991
        cost: 1000,
992
        err: "softfork takes exactly 4 arguments",
993
    },
994
    // this is a valid invocation, but we don't implement any extensions (yet)
995
    // so the extension specifier 0 is still unknown
996
    RunProgramTest {
997
        prg: "(softfork (q . 919) (q . 9) (q x) (q . ()))",
998
        args: "()",
999
        flags: 0,
1000
        result: Some("()"),
1001
        cost: 1000,
1002
        err: "",
1003
    },
1004
    // when parsing the cost argument, we ignore redundant leading zeroes
1005
    RunProgramTest {
1006
        prg: "(softfork (q . 0x00000397) (q . 9) (q x) (q . ()))",
1007
        args: "()",
1008
        flags: 0,
1009
        result: Some("()"),
1010
        cost: 1000,
1011
        err: "",
1012
    },
1013
    RunProgramTest {
1014
        prg: "(softfork (q . 919) (q . 9) (q x) (q . ()))",
1015
        args: "()",
1016
        flags: NO_UNKNOWN_OPS,
1017
        result: None,
1018
        cost: 1000,
1019
        err: "unknown softfork extension",
1020
    },
1021
1022
    // this is a valid invocation, but we don't implement any extensions (yet)
1023
    RunProgramTest {
1024
        prg: "(softfork (q . 919) (q . 0x00ffffffff) (q x) (q . ()))",
1025
        args: "()",
1026
        flags: 0,
1027
        result: Some("()"),
1028
        cost: 1000,
1029
        err: "",
1030
    },
1031
    RunProgramTest {
1032
        prg: "(softfork (q . 919) (q . 0x00ffffffff) (q x) (q . ()))",
1033
        args: "()",
1034
        flags: NO_UNKNOWN_OPS,
1035
        result: None,
1036
        cost: 1000,
1037
        err: "unknown softfork extension",
1038
    },
1039
1040
    // we don't allow negative "extension" parameters
1041
    RunProgramTest {
1042
        prg: "(softfork (q . 919) (q . -1) (q x) (q . ()))",
1043
        args: "()",
1044
        flags: 0,
1045
        result: Some("()"),
1046
        cost: 1000,
1047
        err: "",
1048
    },
1049
    RunProgramTest {
1050
        prg: "(softfork (q . 919) (q . -1) (q x) (q . ()))",
1051
        args: "()",
1052
        flags: NO_UNKNOWN_OPS,
1053
        result: None,
1054
        cost: 1000,
1055
        err: "softfork requires positive int arg",
1056
    },
1057
1058
    // we don't allow "extension" parameters > u32::MAX
1059
    RunProgramTest {
1060
        prg: "(softfork (q . 919) (q . 0x0100000000) (q x) (q . ()))",
1061
        args: "()",
1062
        flags: 0,
1063
        result: Some("()"),
1064
        cost: 1000,
1065
        err: "",
1066
    },
1067
    RunProgramTest {
1068
        prg: "(softfork (q . 919) (q . 0x0100000000) (q x) (q . ()))",
1069
        args: "()",
1070
        flags: NO_UNKNOWN_OPS,
1071
        result: None,
1072
        cost: 1000,
1073
        err: "softfork requires u32 arg",
1074
    },
1075
1076
    // we don't allow pairs as extension specifier
1077
    RunProgramTest {
1078
        prg: "(softfork (q . 919) (q 1 2 3) (q x) (q . ()))",
1079
        args: "()",
1080
        flags: 0,
1081
        result: Some("()"),
1082
        cost: 1000,
1083
        err: "",
1084
    },
1085
    RunProgramTest {
1086
        prg: "(softfork (q . 919) (q 1 2 3) (q x) (q . ()))",
1087
        args: "()",
1088
        flags: NO_UNKNOWN_OPS,
1089
        result: None,
1090
        cost: 1000,
1091
        err: "softfork requires int arg",
1092
    },
1093
1094
    // the cost value is checked in consensus mode as well
1095
    RunProgramTest {
1096
        prg: "(softfork (q . 1000))",
1097
        args: "()",
1098
        flags: 0,
1099
        result: None,
1100
        cost: 1000,
1101
        err: "cost exceeded",
1102
    },
1103
    // the cost parameter is mandatory
1104
    RunProgramTest {
1105
        prg: "(softfork)",
1106
        args: "()",
1107
        flags: 0,
1108
        result: None,
1109
        cost: 0,
1110
        err: "first of non-cons",
1111
    },
1112
    RunProgramTest {
1113
        prg: "(softfork (q . 0))",
1114
        args: "()",
1115
        flags: 0,
1116
        result: None,
1117
        cost: 1000,
1118
        err: "cost must be > 0",
1119
    },
1120
    // negative costs are not allowed
1121
    RunProgramTest {
1122
        prg: "(softfork (q . -1))",
1123
        args: "()",
1124
        flags: 0,
1125
        result: None,
1126
        cost: 1000,
1127
        err: "softfork requires positive int arg",
1128
    },
1129
    RunProgramTest {
1130
        prg: "(softfork (q 1 2 3))",
1131
        args: "()",
1132
        flags: 0,
1133
        result: None,
1134
        cost: 1000,
1135
        err: "softfork requires int arg",
1136
    },
1137
1138
    // test mismatching cost
1139
    RunProgramTest {
1140
        prg: "(softfork (q . 160) (q . 0) (q . (q . 42)) (q . ()))",
1141
        args: "()",
1142
        flags: 0,
1143
        result: Some("()"),
1144
        cost: 241,
1145
        err: "",
1146
    },
1147
    // the program under the softfork is restricted by the specified cost
1148
    RunProgramTest {
1149
        prg: "(softfork (q . 159) (q . 0) (q . (q . 42)) (q . ()))",
1150
        args: "()",
1151
        flags: 0,
1152
        result: None,
1153
        cost: 241,
1154
        err: "cost exceeded",
1155
    },
1156
    // the cost specified on the softfork must match exactly the cost of
1157
    // executing the program
1158
    RunProgramTest {
1159
        prg: "(softfork (q . 161) (q . 0) (q . (q . 42)) (q . ()))",
1160
        args: "()",
1161
        flags: 0,
1162
        result: None,
1163
        cost: 10000,
1164
        err: "softfork specified cost mismatch",
1165
    },
1166
1167
    // without the flag to enable the BLS extensions, it's an unknown extension
1168
    RunProgramTest {
1169
        prg: "(softfork (q . 161) (q . 1) (q . (q . 42)) (q . ()))",
1170
        args: "()",
1171
        flags: NO_UNKNOWN_OPS,
1172
        result: None,
1173
        cost: 10000,
1174
        err: "unknown softfork extension",
1175
    },
1176
1177
    // coinid extension
1178
    // make sure we can execute the coinid operator under softfork 0
1179
    // this program raises an exception if the computed coin ID matches the
1180
    // expected
1181
    RunProgramTest {
1182
        prg: "(softfork (q . 1432) (q . 0) (q a (i (= (coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789)) (q . 0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bc)) (q x) (q . 0)) (q . ())) (q . ()))",
1183
        args: "()",
1184
        flags: 0,
1185
        result: None,
1186
        cost: 1513,
1187
        err: "clvm raise",
1188
    },
1189
    // also test the opposite. This program is the same as above but it raises
1190
    // if the coin ID is a mismatch
1191
    RunProgramTest {
1192
        prg: "(softfork (q . 1432) (q . 0) (q a (i (= (coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789)) (q . 0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bc)) (q . 0) (q x)) (q . ())) (q . ()))",
1193
        args: "()",
1194
        flags: 0,
1195
        result: Some("()"),
1196
        cost: 1513,
1197
        err: "",
1198
    },
1199
1200
    // coinid operator after hardfork, where coinid is available outside the
1201
    // softfork guard.
1202
    RunProgramTest {
1203
        prg: "(coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789))",
1204
        args: "()",
1205
        flags: ENABLE_BLS_OPS_OUTSIDE_GUARD,
1206
        result: Some("0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bc"),
1207
        cost: 861,
1208
        err: "",
1209
    },
1210
    RunProgramTest {
1211
        prg: "(coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 0x000123456789))",
1212
        args: "()",
1213
        flags: ENABLE_BLS_OPS_OUTSIDE_GUARD,
1214
        result: None,
1215
        cost: 861,
1216
        err: "coinid: invalid amount (may not have redundant leading zero)",
1217
    },
1218
    // make sure the coinid operator is not available unless the flag is
1219
    // specified
1220
    RunProgramTest {
1221
        prg: "(coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 0x000123456789))",
1222
        args: "()",
1223
        flags: NO_UNKNOWN_OPS,
1224
        result: None,
1225
        cost: 861,
1226
        err: "unimplemented operator",
1227
    },
1228
1229
    // secp261k1
1230
1231
    RunProgramTest {
1232
        prg: "(secp256k1_verify (q . 0x02888b0c110ef0b4962e3fc6929cbba7a8bb25b4b2c885f55c76365018c909b439) (q . 0x74c2941eb2ebe5aa4f2287a4c5e506a6290c045004058de97a7edf0122548668) (q . 0x1acb7a6e062e78ccd4237b12c22f02b5a8d9b33cb3ba13c35e88e036baa1cbca75253bb9a96ffc48b43196c69c2972d8f965b1baa4e52348d8081cde65e6c018))",
1233
        args: "()",
1234
        flags: 0,
1235
        result: Some("0"),
1236
        cost: 1300061,
1237
        err: "",
1238
    },
1239
    // invalid signature
1240
    RunProgramTest {
1241
        prg: "(secp256k1_verify (q . 0x02888b0c110ef0b4962e3fc6929cbba7a8bb25b4b2c885f55c76365018c909b439) (q . 0x74c2941eb2ebe5aa4f2287a4c5e506a6290c045004058de97a7edf0122548668) (q . 0x1acb7a6e062e78ccd4237b12c22f02b5a8d9b33cb3ba13c35e88e036baa1cbca75253bb9a96ffc48b43196c69c2972d8f965b1baa4e52348d8081cde65e6c019))",
1242
        args: "()",
1243
        flags: 0,
1244
        result: None,
1245
        cost: 0,
1246
        err: "secp256k1_verify failed",
1247
    },
1248
1249
    // secp261r1
1250
1251
    RunProgramTest {
1252
        prg: "(secp256r1_verify (q . 0x0437a1674f3883b7171a11a20140eee014947b433723cf9f181a18fee4fcf96056103b3ff2318f00cca605e6f361d18ff0d2d6b817b1fa587e414f8bb1ab60d2b9) (q . 0x9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08) (q . 0xe8de121f4cceca12d97527cc957cca64a4bcfc685cffdee051b38ee81cb22d7e2c187fec82c731018ed2d56f08a4a5cbc40c5bfe9ae18c02295bb65e7f605ffc))",
1253
        args: "()",
1254
        flags: 0,
1255
        result: Some("0"),
1256
        cost: 1850061,
1257
        err: "",
1258
    },
1259
    // invalid signature
1260
    RunProgramTest {
1261
        prg: "(secp256r1_verify (q . 0x0437a1674f3883b7171a11a20140eee014947b433723cf9f181a18fee4fcf96056103b3ff2318f00cca605e6f361d18ff0d2d6b817b1fa587e414f8bb1ab60d2b9) (q . 0x9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08) (q . 0xe8de121f4cceca12d97527cc957cca64a4bcfc685cffdee051b38ee81cb22d7e2c187fec82c731018ed2d56f08a4a5cbc40c5bfe9ae18c02295bb65e7f605ffd))",
1262
        args: "()",
1263
        flags: 0,
1264
        result: None,
1265
        cost: 0,
1266
        err: "secp256r1_verify failed",
1267
    },
1268
];
1269
1270
#[cfg(test)]
1271
fn check(res: (NodePtr, &str)) -> NodePtr {
1272
    assert_eq!(res.1, "");
1273
    res.0
1274
}
1275
1276
#[cfg(test)]
1277
fn run_test_case(t: &RunProgramTest) {
1278
    use crate::chia_dialect::ChiaDialect;
1279
    use crate::test_ops::node_eq;
1280
    let mut allocator = Allocator::new();
1281
1282
    let program = check(parse_exp(&mut allocator, t.prg));
1283
    let args = check(parse_exp(&mut allocator, t.args));
1284
    let expected_result = &t.result.map(|v| check(parse_exp(&mut allocator, v)));
1285
1286
    let dialect = ChiaDialect::new(t.flags);
1287
    println!("prg: {}", t.prg);
1288
    match run_program(&mut allocator, &dialect, program, args, t.cost) {
1289
        Ok(Reduction(cost, prg_result)) => {
1290
            assert!(node_eq(&allocator, prg_result, expected_result.unwrap()));
1291
            assert_eq!(cost, t.cost);
1292
1293
            // now, run the same program again but with the cost limit 1 too low, to
1294
            // ensure it fails with the correct error
1295
            let expected_cost_exceeded =
1296
                run_program(&mut allocator, &dialect, program, args, t.cost - 1).unwrap_err();
1297
            assert_eq!(expected_cost_exceeded.1, "cost exceeded");
1298
        }
1299
        Err(err) => {
1300
            println!("FAILED: {}", err.1);
1301
            assert_eq!(err.1, t.err);
1302
            assert!(expected_result.is_none());
1303
        }
1304
    }
1305
}
1306
1307
#[test]
1308
fn test_run_program() {
1309
    for t in TEST_CASES {
1310
        run_test_case(t);
1311
    }
1312
}
1313
1314
#[cfg(test)]
1315
use rstest::rstest;
1316
1317
// the test cases for this test consists of:
1318
// prg: the program to run inside the softfork guard
1319
// cost: the expected cost of the program (the test adds the apply-operator)
1320
// enabled: the softfork extension number that enables operator in prg
1321
// hard_fork_flag: the flag that enables the program to be run outside the guard
1322
// err: the expected error message, empty string means OK
1323
// The test programs are carefully crafted such that they fail with "clvm raise"
1324
// when run in consensus mode and the operators are unknown. e.g. (coinid ...)
1325
// returns NIL in that case, which compares not equal to the coin ID, which
1326
// raises the exception.
1327
// This property is relied on for the non-mempool and fork-not-activated cases.
1328
#[cfg(test)]
1329
#[rstest]
1330
// make sure we can execute the coinid operator under softfork 0
1331
// this program raises an exception if the computed coin ID matches the
1332
// expected
1333
#[case::coinid("(i (= (coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789)) (q . 0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bd)) (q . 0) (q x))",
1334
    (1432, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD),
1335
    "clvm raise")]
1336
// also test the opposite. This program is the same as above but it raises
1337
// if the coin ID is a mismatch
1338
#[case::coinid("(i (= (coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789)) (q . 0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bc)) (q . 0) (q x))",
1339
    (1432, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD),
1340
    "")]
1341
// modpow
1342
#[case::modpow(
1343
    "(i (= (modpow (q . 12345) (q . 6789) (q . 44444444444)) (q . 13456191581)) (q . 0) (q x))",
1344
    (18241, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD),
1345
    ""
1346
)]
1347
#[case::modpow(
1348
    "(i (= (modpow (q . 12345) (q . 6789) (q . 44444444444)) (q . 13456191582)) (q . 0) (q x))",
1349
    (18241, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD),
1350
    "clvm raise"
1351
)]
1352
// mod
1353
#[case::modulus(
1354
    "(i (= (% (q . 80001) (q . 73)) (q . 66)) (q . 0) (q x))",
1355
    (1564, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD),
1356
    ""
1357
)]
1358
#[case::modulus(
1359
    "(i (= (% (q . 80001) (q . 73)) (q . 67)) (q . 0) (q x))",
1360
    (1564, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD),
1361
    "clvm raise"
1362
)]
1363
// g1_multiply
1364
#[case::g1_mul("(i (= (g1_multiply  (q . 0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb) (q . 2)) (q . 0xa572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e)) (q . 0) (q x))",
1365
    (706634, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD),
1366
    "")]
1367
#[case::g1_mul(
1368
    "(i (= (g1_multiply  (q . 0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb) (q . 2)) (q . 0xa572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4f)) (q . 0) (q x))",
1369
    (706634, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD),
1370
    "clvm raise")]
1371
#[case::g1_neg("(i (= (g1_negate (q . 0xb7f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0xb7f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0) (q x))", (706634, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD), "clvm raise")]
1372
#[case::g1_neg("(i (= (g1_negate (q . 0xb2f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0xb7f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0) (q x))",
1373
    (706634, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD),
1374
    "atom is not a valid G1 point")]
1375
#[case::g2_add("(i (= (g2_add (q . 0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8) (q . 0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8)) (q . 0xaa4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c335771638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053)) (q . 0) (q x))",
1376
    (3981700, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD),
1377
    "")]
1378
#[case::g2_add("(i (= (g2_add (q . 0x93e12b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8) (q . 0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8)) (q . 0xaa4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c335771638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053)) (q . 0) (q x))",
1379
    (3981700, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD),
1380
    "atom is not a G2 point")]
1381
fn test_softfork(
1382
    #[case] prg: &'static str,
1383
    #[case] fields: (u64, u8, u32), // cost, enabled, hard_fork_flag
1384
    #[case] err: &'static str,
1385
    #[values(0)] flags: u32,
1386
    #[values(false, true)] mempool: bool,
1387
    #[values(0, 1, 2)] test_ext: u8,
1388
) {
1389
    let (cost, enabled, hard_fork_flag) = fields;
1390
    let softfork_prg =
1391
        format!("(softfork (q . {cost}) (q . {test_ext}) (q . (a {prg} (q . 0))) (q . 0))");
1392
1393
    let flags = flags | if mempool { NO_UNKNOWN_OPS } else { 0 };
1394
1395
    // softfork extensions that are enabled
1396
    #[allow(clippy::match_like_matches_macro)]
1397
    let ext_enabled = match test_ext {
1398
        0 => true,
1399
        _ => false,
1400
    };
1401
1402
    println!("mempool: {mempool} ext: {test_ext} flags: {flags}");
1403
    let expect_err = match (ext_enabled as u8, (test_ext >= enabled) as u8) {
1404
        // the extension we're running has not been activated, and we're not
1405
        // running an extension that supports the operator
1406
        (0, 0) => {
1407
            if mempool {
1408
                "unimplemented operator"
1409
            } else {
1410
                ""
1411
            }
1412
        }
1413
        // the softfork extension hasn't been activated yet. It's a failure in
1414
        // mempool mode but ignored in consensus mode
1415
        (0, 1) => {
1416
            if mempool {
1417
                "unknown softfork extension"
1418
            } else {
1419
                ""
1420
            }
1421
        }
1422
        // the extension we're invoking has been enabled, but the operator is
1423
        // not part of this extension. In mempool mode it's an error, in
1424
        // consensus mode the operator is considered unknown, returning
1425
        // NIL/false. This in turn will make the return value test fail, and
1426
        // raise an exception.
1427
        (1, 0) => {
1428
            if mempool {
1429
                "unimplemented operator"
1430
            } else {
1431
                "clvm raise"
1432
            }
1433
        }
1434
        // the extension we're running has been activated, and we're running an
1435
        // extension the operator is available in. The program is executed and
1436
        // we get the expected result.
1437
        (1, 1) => err,
1438
        _ => unreachable!(),
1439
    };
1440
1441
    println!("expect: {expect_err} cost: {cost}");
1442
    let t = RunProgramTest {
1443
        prg: softfork_prg.as_str(),
1444
        args: "()",
1445
        flags,
1446
        result: if expect_err.is_empty() {
1447
            Some("()")
1448
        } else {
1449
            None
1450
        },
1451
        cost: cost + 81,
1452
        err: expect_err,
1453
    };
1454
1455
    run_test_case(&t);
1456
1457
    // now test outside the guard (should fail unless hard_fork_flag is set).
1458
1459
    let outside_guard_prg = format!("(a {prg} (q . 0))");
1460
1461
    // without the hard fork flag
1462
    println!("outside guard, no hard fork");
1463
    let t = RunProgramTest {
1464
        prg: outside_guard_prg.as_str(),
1465
        args: "()",
1466
        flags,
1467
        result: None,
1468
        cost: cost - 140,
1469
        err: if mempool {
1470
            "unimplemented operator"
1471
        } else {
1472
            "clvm raise"
1473
        },
1474
    };
1475
    run_test_case(&t);
1476
1477
    // with the hard fork flag
1478
    println!("outside guard, hard fork activated");
1479
    let t = RunProgramTest {
1480
        prg: outside_guard_prg.as_str(),
1481
        args: "()",
1482
        flags: flags | hard_fork_flag,
1483
        result: if err.is_empty() { Some("()") } else { None },
1484
        cost: cost - 140,
1485
        err,
1486
    };
1487
    run_test_case(&t);
1488
}
1489
1490
#[cfg(feature = "counters")]
1491
#[test]
1492
fn test_counters() {
1493
    use crate::chia_dialect::ChiaDialect;
1494
1495
    let mut a = Allocator::new();
1496
1497
    let program = check(parse_exp(&mut a, "(a (q 2 2 (c 2 (c 5 (c 11 ())))) (c (q 2 (i (= 11 ()) (q 1 . 1) (q 18 5 (a 2 (c 2 (c 5 (c (- 11 (q . 1)) ())))))) 1) 1))"));
1498
    let args = check(parse_exp(&mut a, "(5033 1000)"));
1499
    let cost = 15073165;
1500
1501
    let (counters, result) =
1502
        run_program_with_counters(&mut a, &ChiaDialect::new(0), program, args, cost);
1503
1504
    assert_eq!(counters.val_stack_usage, 3015);
1505
    assert_eq!(counters.env_stack_usage, 1005);
1506
    assert_eq!(counters.op_stack_usage, 3014);
1507
    assert_eq!(counters.atom_count, 998);
1508
    assert_eq!(counters.small_atom_count, 1042);
1509
    assert_eq!(counters.pair_count, 22077);
1510
    assert_eq!(counters.heap_size, 769963);
1511
1512
    assert_eq!(result.unwrap().0, cost);
1513
}
/home/oof/clvm_rs/src/runtime_dialect.rs
Line
Count
Source
1
use crate::allocator::{Allocator, NodePtr};
2
use crate::chia_dialect::NO_UNKNOWN_OPS;
3
use crate::cost::Cost;
4
use crate::dialect::{Dialect, OperatorSet};
5
use crate::err_utils::err;
6
use crate::f_table::{f_lookup_for_hashmap, FLookup};
7
use crate::more_ops::op_unknown;
8
use crate::reduction::Response;
9
use std::collections::HashMap;
10
11
pub struct RuntimeDialect {
12
    f_lookup: FLookup,
13
    quote_kw: Vec<u8>,
14
    apply_kw: Vec<u8>,
15
    softfork_kw: Vec<u8>,
16
    flags: u32,
17
}
18
19
impl RuntimeDialect {
20
0
    pub fn new(
21
0
        op_map: HashMap<String, Vec<u8>>,
22
0
        quote_kw: Vec<u8>,
23
0
        apply_kw: Vec<u8>,
24
0
        flags: u32,
25
0
    ) -> RuntimeDialect {
26
0
        RuntimeDialect {
27
0
            f_lookup: f_lookup_for_hashmap(op_map),
28
0
            quote_kw,
29
0
            apply_kw,
30
0
            softfork_kw: vec![36], // softfork opcode
31
0
            flags,
32
0
        }
33
0
    }
34
}
35
36
impl Dialect for RuntimeDialect {
37
0
    fn op(
38
0
        &self,
39
0
        allocator: &mut Allocator,
40
0
        o: NodePtr,
41
0
        argument_list: NodePtr,
42
0
        max_cost: Cost,
43
0
        _extensions: OperatorSet,
44
0
    ) -> Response {
45
0
        let atom = allocator.atom(o);
46
0
        let b = atom.as_ref();
47
0
48
0
        if b.len() == 1 {
49
0
            if let Some(f) = self.f_lookup[b[0] as usize] {
50
0
                return f(allocator, argument_list, max_cost);
51
0
            }
52
0
        }
53
0
        if (self.flags & NO_UNKNOWN_OPS) != 0 {
54
0
            err(o, "unimplemented operator")
55
        } else {
56
0
            op_unknown(allocator, o, argument_list, max_cost)
57
        }
58
0
    }
59
60
0
    fn quote_kw(&self) -> u32 {
61
0
        self.quote_kw[0] as u32
62
0
    }
63
0
    fn apply_kw(&self) -> u32 {
64
0
        self.apply_kw[0] as u32
65
0
    }
66
0
    fn softfork_kw(&self) -> u32 {
67
0
        self.softfork_kw[0] as u32
68
0
    }
69
70
0
    fn softfork_extension(&self, _ext: u32) -> OperatorSet {
71
0
        OperatorSet::Default
72
0
    }
73
74
0
    fn allow_unknown_ops(&self) -> bool {
75
0
        (self.flags & NO_UNKNOWN_OPS) == 0
76
0
    }
77
}
/home/oof/clvm_rs/src/secp_ops.rs
Line
Count
Source
1
use crate::allocator::{Allocator, NodePtr};
2
use crate::cost::{check_cost, Cost};
3
use crate::err_utils::err;
4
use crate::op_utils::{atom, get_args};
5
use crate::reduction::{Reduction, Response};
6
use k256::ecdsa::{Signature as K1Signature, VerifyingKey as K1VerifyingKey};
7
use p256::ecdsa::signature::hazmat::PrehashVerifier;
8
use p256::ecdsa::{Signature as P1Signature, VerifyingKey as P1VerifyingKey};
9
10
const SECP256R1_VERIFY_COST: Cost = 1850000;
11
const SECP256K1_VERIFY_COST: Cost = 1300000;
12
13
// expects: pubkey msg sig
14
1.27k
pub fn op_secp256r1_verify(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
15
1.27k
    let cost = SECP256R1_VERIFY_COST;
16
1.27k
    check_cost(a, cost, max_cost)?;
17
18
1.27k
    let [pubkey, msg, sig] = get_args::<3>(a, input, "secp256r1_verify")?;
19
20
    // first argument is sec1 encoded pubkey
21
1.22k
    let pubkey = atom(a, pubkey, "secp256r1_verify pubkey")?;
22
1.21k
    let verifier = P1VerifyingKey::from_sec1_bytes(pubkey.as_ref())
23
1.21k
        .or_else(|_| err(input, "secp256r1_verify pubkey is not valid"))?;
24
25
    // second arg is sha256 hash of message
26
1.14k
    let msg = atom(a, msg, "secp256r1_verify msg")?;
27
1.13k
    if msg.as_ref().len() != 32 {
28
240
        return err(input, "secp256r1_verify message digest is not 32 bytes");
29
895
    }
30
31
    // third arg is a fixed-size signature
32
895
    let sig = atom(a, sig, "secp256r1_verify sig")?;
33
885
    let sig = P1Signature::from_slice(sig.as_ref())
34
885
        .or_else(|_| err(input, "secp256r1_verify sig is not valid"))?;
35
36
    // verify signature
37
838
    let result = verifier.verify_prehash(msg.as_ref(), &sig);
38
838
39
838
    if result.is_err() {
40
788
        err(input, "secp256r1_verify failed")
41
    } else {
42
50
        Ok(Reduction(cost, a.nil()))
43
    }
44
1.27k
}
45
46
// expects: pubkey msg sig
47
1.34k
pub fn op_secp256k1_verify(a: &mut Allocator, input: NodePtr, max_cost: Cost) -> Response {
48
1.34k
    let cost = SECP256K1_VERIFY_COST;
49
1.34k
    check_cost(a, cost, max_cost)?;
50
51
1.33k
    let [pubkey, msg, sig] = get_args::<3>(a, input, "secp256k1_verify")?;
52
53
    // first argument is sec1 encoded pubkey
54
1.31k
    let pubkey = atom(a, pubkey, "secp256k1_verify pubkey")?;
55
1.30k
    let verifier = K1VerifyingKey::from_sec1_bytes(pubkey.as_ref())
56
1.30k
        .or_else(|_| err(input, "secp256k1_verify pubkey is not valid"))?;
57
58
    // second arg is message
59
712
    let msg = atom(a, msg, "secp256k1_verify msg")?;
60
702
    if msg.as_ref().len() != 32 {
61
124
        return err(input, "secp256k1_verify message digest is not 32 bytes");
62
578
    }
63
64
    // third arg is a fixed-size signature
65
578
    let sig = atom(a, sig, "secp256k1_verify sig")?;
66
568
    let sig = K1Signature::from_slice(sig.as_ref())
67
568
        .or_else(|_| err(input, "secp256k1_verify sig is not valid"))?;
68
69
    // verify signature
70
534
    let result = verifier.verify_prehash(msg.as_ref(), &sig);
71
534
72
534
    if result.is_err() {
73
425
        err(input, "secp256k1_verify failed")
74
    } else {
75
109
        Ok(Reduction(cost, a.nil()))
76
    }
77
1.34k
}
/home/oof/clvm_rs/src/serde/bytes32.rs
Line
Count
Source
1
use crate::sha2::Sha256;
2
3
pub type Bytes32 = [u8; 32];
4
5
0
pub fn hash_blob(blob: &[u8]) -> Bytes32 {
6
0
    let mut sha256 = Sha256::new();
7
0
    sha256.update(blob);
8
0
    sha256.finalize()
9
0
}
10
11
0
pub fn hash_blobs(blobs: &[&[u8]]) -> Bytes32 {
12
0
    let mut sha256 = Sha256::new();
13
0
    for blob in blobs.iter() {
14
0
        sha256.update(blob);
15
0
    }
16
0
    sha256.finalize()
17
0
}
/home/oof/clvm_rs/src/serde/de.rs
Line
Count
Source
1
use std::io;
2
use std::io::{Cursor, Read};
3
4
use crate::allocator::{Allocator, NodePtr};
5
6
use super::parse_atom::parse_atom;
7
8
const CONS_BOX_MARKER: u8 = 0xff;
9
10
#[repr(u8)]
11
enum ParseOp {
12
    SExp,
13
    Cons,
14
}
15
16
/// deserialize a clvm node from a `std::io::Cursor`
17
27.3k
pub fn node_from_stream(allocator: &mut Allocator, f: &mut Cursor<&[u8]>) -> io::Result<NodePtr> {
18
27.3k
    let mut values: Vec<NodePtr> = Vec::new();
19
27.3k
    let mut ops = vec![ParseOp::SExp];
20
27.3k
21
27.3k
    let mut b = [0; 1];
22
2.84M
    while let Some(op) = ops.pop() {
23
2.81M
        match op {
24
            ParseOp::SExp => {
25
1.89M
                f.read_exact(&mut b)?;
26
1.89M
                if b[0] == CONS_BOX_MARKER {
27
938k
                    ops.push(ParseOp::Cons);
28
938k
                    ops.push(ParseOp::SExp);
29
938k
                    ops.push(ParseOp::SExp);
30
938k
                } else {
31
953k
                    values.push(parse_atom(allocator, b[0], f)?);
32
                }
33
            }
34
            ParseOp::Cons => {
35
                // cons
36
922k
                let v2 = values.pop();
37
922k
                let v1 = values.pop();
38
922k
                values.push(allocator.new_pair(v1.unwrap(), v2.unwrap())?);
39
            }
40
        }
41
    }
42
27.3k
    Ok(values.pop().unwrap())
43
27.3k
}
44
45
27.3k
pub fn node_from_bytes(allocator: &mut Allocator, b: &[u8]) -> io::Result<NodePtr> {
46
27.3k
    let mut buffer = Cursor::new(b);
47
27.3k
    node_from_stream(allocator, &mut buffer)
48
27.3k
}
/home/oof/clvm_rs/src/serde/de_br.rs
Line
Count
Source
1
use std::collections::HashSet;
2
use std::io;
3
use std::io::{Cursor, Read};
4
5
use crate::allocator::{Allocator, NodePtr, SExp};
6
use crate::traverse_path::traverse_path;
7
8
use super::parse_atom::{parse_atom, parse_path};
9
10
const BACK_REFERENCE: u8 = 0xfe;
11
const CONS_BOX_MARKER: u8 = 0xff;
12
13
#[repr(u8)]
14
enum ParseOp {
15
    SExp,
16
    Cons,
17
}
18
19
/// deserialize a clvm node from a `std::io::Cursor`
20
0
pub fn node_from_stream_backrefs(
21
0
    allocator: &mut Allocator,
22
0
    f: &mut Cursor<&[u8]>,
23
0
    mut backref_callback: impl FnMut(NodePtr),
24
0
) -> io::Result<NodePtr> {
25
0
    let mut values = allocator.nil();
26
0
    let mut ops = vec![ParseOp::SExp];
27
0
28
0
    let mut b = [0; 1];
29
0
    while let Some(op) = ops.pop() {
30
0
        match op {
31
            ParseOp::SExp => {
32
0
                f.read_exact(&mut b)?;
33
0
                if b[0] == CONS_BOX_MARKER {
34
0
                    ops.push(ParseOp::Cons);
35
0
                    ops.push(ParseOp::SExp);
36
0
                    ops.push(ParseOp::SExp);
37
0
                } else if b[0] == BACK_REFERENCE {
38
0
                    let path = parse_path(f)?;
39
0
                    let reduction = traverse_path(allocator, path, values)?;
40
0
                    let back_reference = reduction.1;
41
0
                    backref_callback(back_reference);
42
0
                    values = allocator.new_pair(back_reference, values)?;
43
                } else {
44
0
                    let new_atom = parse_atom(allocator, b[0], f)?;
45
0
                    values = allocator.new_pair(new_atom, values)?;
46
                }
47
            }
48
            ParseOp::Cons => {
49
                // cons
50
0
                if let SExp::Pair(v1, v2) = allocator.sexp(values) {
51
0
                    if let SExp::Pair(v3, v4) = allocator.sexp(v2) {
52
0
                        let new_root = allocator.new_pair(v3, v1)?;
53
0
                        values = allocator.new_pair(new_root, v4)?;
54
0
                    }
55
0
                }
56
            }
57
        }
58
    }
59
0
    match allocator.sexp(values) {
60
0
        SExp::Pair(v1, _v2) => Ok(v1),
61
0
        _ => panic!("unexpected atom"),
62
    }
63
0
}
Unexecuted instantiation: _RINvNtNtCs4RkbDk9WRL5_5clvmr5serde5de_br25node_from_stream_backrefsNCNvB2_24node_from_bytes_backrefs0EB6_
Unexecuted instantiation: _RINvNtNtCs4RkbDk9WRL5_5clvmr5serde5de_br25node_from_stream_backrefsNCNvB2_31node_from_bytes_backrefs_record0EB6_
64
65
0
pub fn node_from_bytes_backrefs(allocator: &mut Allocator, b: &[u8]) -> io::Result<NodePtr> {
66
0
    let mut buffer = Cursor::new(b);
67
0
    node_from_stream_backrefs(allocator, &mut buffer, |_node| {})
68
0
}
69
70
0
pub fn node_from_bytes_backrefs_record(
71
0
    allocator: &mut Allocator,
72
0
    b: &[u8],
73
0
) -> io::Result<(NodePtr, HashSet<NodePtr>)> {
74
0
    let mut buffer = Cursor::new(b);
75
0
    let mut backrefs = HashSet::<NodePtr>::new();
76
0
    let ret = node_from_stream_backrefs(allocator, &mut buffer, |node| {
77
0
        backrefs.insert(node);
78
0
    })?;
79
0
    Ok((ret, backrefs))
80
0
}
81
82
#[cfg(test)]
83
use hex::FromHex;
84
85
#[test]
86
fn test_deserialize_with_backrefs() {
87
    fn deserialize_check(serialization_as_hex: &str, expected_hash_as_hex: &str) {
88
        use crate::serde::object_cache::{treehash, ObjectCache};
89
        let buf = Vec::from_hex(serialization_as_hex).unwrap();
90
        let mut allocator = Allocator::new();
91
        let node = node_from_bytes_backrefs(&mut allocator, &buf).unwrap();
92
93
        let mut oc = ObjectCache::new(&allocator, treehash);
94
        let calculated_hash = oc.get_or_calculate(&node).unwrap();
95
        let ch: &[u8] = calculated_hash;
96
        let expected_hash: Vec<u8> = Vec::from_hex(expected_hash_as_hex).unwrap();
97
        assert_eq!(expected_hash, ch);
98
    }
99
100
    // ("foobar" "foobar")
101
    deserialize_check(
102
        "ff86666f6f626172ff86666f6f62617280",
103
        "9148834131750904c023598bed28db269bdb29012514579e723d63e27829bcba",
104
    );
105
    deserialize_check(
106
        "ff86666f6f626172fe01", // ("foobar" "foobar")
107
        "9148834131750904c023598bed28db269bdb29012514579e723d63e27829bcba",
108
    );
109
110
    // ((1 2 3 4) 1 2 3 4)
111
    deserialize_check(
112
        "ffff01ff02ff03ff0480ff01ff02ff03ff0480",
113
        "028c16eb4fec600e6153d8dde60eb3916d13d0dc446b5cd7936a1248f8963bf8",
114
    );
115
    deserialize_check(
116
        "ffff01ff02ff03ff0480fe02", // ((1 2 3 4) 1 2 3 4)
117
        "028c16eb4fec600e6153d8dde60eb3916d13d0dc446b5cd7936a1248f8963bf8",
118
    );
119
120
    // `(((((a_very_long_repeated_string . 1) .  (2 . 3)) . ((4 . 5) .  (6 . 7))) . (8 . 9)) 10 a_very_long_repeated_string)`
121
    deserialize_check(
122
        "ffffffffff9b615f766572795f6c6f6e675f72657065617465645f737472696e6701ff0203ffff04\
123
         05ff0607ff0809ff0aff9b615f766572795f6c6f6e675f72657065617465645f737472696e6780",
124
        "e23c73777f814e8a4e2785487b272b8b22ddaded1f7cfb808b43f1148602882f",
125
    );
126
    deserialize_check(
127
        "ffffffffff9b615f766572795f6c6f6e675f72657065617465645f737472696e6701ff0203ffff0405ff0607ff0809ff0afffe4180",
128
        "e23c73777f814e8a4e2785487b272b8b22ddaded1f7cfb808b43f1148602882f",
129
    );
130
}
131
132
#[test]
133
fn test_deserialize_with_backrefs_record() {
134
    fn deserialize_check(serialization_as_hex: &str, expected_backrefs: &[&'static str]) {
135
        use crate::serde::node_to_bytes;
136
        let buf = Vec::from_hex(serialization_as_hex).unwrap();
137
        let mut allocator = Allocator::new();
138
        let (_node, backrefs) = node_from_bytes_backrefs_record(&mut allocator, &buf)
139
            .expect("node_from_bytes_backrefs_records");
140
        println!("backrefs: {:?}", backrefs);
141
        assert_eq!(backrefs.len(), expected_backrefs.len());
142
143
        let expected_backrefs =
144
            HashSet::<String>::from_iter(expected_backrefs.iter().map(|s| s.to_string()));
145
        let backrefs = HashSet::from_iter(
146
            backrefs
147
                .iter()
148
                .map(|br| hex::encode(node_to_bytes(&allocator, *br).expect("node_to_bytes"))),
149
        );
150
151
        assert_eq!(backrefs, expected_backrefs);
152
    }
153
154
    // ("foobar" "foobar")
155
    // no-backrefs
156
    deserialize_check("ff86666f6f626172ff86666f6f62617280", &[]);
157
    // with back-refs
158
    deserialize_check(
159
        "ff86666f6f626172fe01", // ("foobar" "foobar")
160
        &["ff86666f6f62617280"],
161
    );
162
163
    // ((1 2 3 4) 1 2 3 4)
164
    // no-backrefs
165
    deserialize_check("ffff01ff02ff03ff0480ff01ff02ff03ff0480", &[]);
166
    // with back-refs
167
    deserialize_check(
168
        "ffff01ff02ff03ff0480fe02", // ((1 2 3 4) 1 2 3 4)
169
        &["ff01ff02ff03ff0480"],
170
    );
171
172
    // `(((((a_very_long_repeated_string . 1) .  (2 . 3)) . ((4 . 5) .  (6 . 7))) . (8 . 9)) 10 a_very_long_repeated_string)`
173
    // no-backrefs
174
    deserialize_check(
175
        "ffffffffff9b615f766572795f6c6f6e675f72657065617465645f737472696e6701ff0203ffff04\
176
         05ff0607ff0809ff0aff9b615f766572795f6c6f6e675f72657065617465645f737472696e6780",
177
        &[],
178
    );
179
    // with back-refs
180
    deserialize_check(
181
        "ffffffffff9b615f766572795f6c6f6e675f72657065617465645f737472696e6701ff0203ffff0405ff0607ff0809ff0afffe4180",
182
        &["9b615f766572795f6c6f6e675f72657065617465645f737472696e67"],
183
    );
184
}
/home/oof/clvm_rs/src/serde/de_tree.rs
Line
Count
Source
1
use std::io::{Error, Read, Result, Write};
2
3
use crate::sha2::Sha256;
4
5
use super::parse_atom::decode_size_with_offset;
6
use super::utils::{copy_exactly, skip_bytes};
7
8
const MAX_SINGLE_BYTE: u8 = 0x7f;
9
const CONS_BOX_MARKER: u8 = 0xff;
10
11
struct ShaWrapper(Sha256);
12
13
impl Write for ShaWrapper {
14
0
    fn write(&mut self, blob: &[u8]) -> std::result::Result<usize, Error> {
15
0
        self.0.update(blob);
16
0
        Ok(blob.len())
17
0
    }
18
0
    fn flush(&mut self) -> std::result::Result<(), Error> {
19
0
        Ok(())
20
0
    }
21
}
22
23
/// This data structure is used with `parse_triples`, which returns a triple of
24
/// integer values for each clvm object in a tree. It's a port of python code.
25
///
26
/// The deserializer iterates through the blob and caches a triple of
27
/// integers for each subtree: the first two integers represent the
28
/// `(start_offset, end_offset)` within the blob that corresponds to the
29
/// serialization of that object. You can check the contents of
30
/// `blob[start_offset]` to determine if the object is a pair (in which case
31
/// that byte is 0xff) or an atom (anything else). For a pair, the third
32
/// number corresponds to the index of the array that is the "rest" of the
33
/// pair (the "first" is always this object's index plus one, so we don't
34
/// need to save that); for an atom, the third number corresponds to an
35
/// offset of where the atom's binary data is relative to
36
/// `blob[start_offset]` (so the atom data is at `blob[triple[0] +
37
/// triple[2]:triple[1]]`)
38
39
#[derive(Debug, PartialEq, Eq)]
40
pub enum ParsedTriple {
41
    // if `buffer[start] != 0xff`, this is an atom
42
    Atom {
43
        start: u64,
44
        end: u64,
45
        atom_offset: u32,
46
    },
47
    // otherwise, it's an pair
48
    Pair {
49
        start: u64,
50
        end: u64,
51
        right_index: u32,
52
    },
53
}
54
55
enum ParseOpRef {
56
    ParseObj,
57
    SaveEnd(usize),
58
    SaveRightIndex(usize),
59
}
60
61
0
fn sha_blobs(blobs: &[&[u8]]) -> [u8; 32] {
62
0
    let mut h = Sha256::new();
63
0
    for blob in blobs {
64
0
        h.update(blob);
65
0
    }
66
0
    h.finalize()
67
0
        .as_slice()
68
0
        .try_into()
69
0
        .expect("wrong slice length")
70
0
}
71
72
0
fn tree_hash_for_byte(b: u8, calculate_tree_hashes: bool) -> Option<[u8; 32]> {
73
0
    if calculate_tree_hashes {
74
0
        Some(sha_blobs(&[&[1, b]]))
75
    } else {
76
0
        None
77
    }
78
0
}
79
80
0
fn skip_or_sha_bytes<R: Read>(
81
0
    f: &mut R,
82
0
    size: u64,
83
0
    calculate_tree_hashes: bool,
84
0
) -> Result<Option<[u8; 32]>> {
85
0
    if calculate_tree_hashes {
86
0
        let mut h = Sha256::new();
87
0
        h.update([1]);
88
0
        let mut w = ShaWrapper(h);
89
0
        copy_exactly(f, &mut w, size)?;
90
0
        let r: [u8; 32] =
91
0
            w.0.finalize()
92
0
                .as_slice()
93
0
                .try_into()
94
0
                .expect("wrong slice length");
95
0
        Ok(Some(r))
96
    } else {
97
0
        skip_bytes(f, size)?;
98
0
        Ok(None)
99
    }
100
0
}
101
102
/// parse a serialized clvm object tree to an array of `ParsedTriple` objects
103
104
/// This alternative mechanism of deserialization generates an array of
105
/// references to each clvm object. A reference contains three values:
106
/// a start offset within the blob, an end offset, and a third value that
107
/// is either: an atom offset (relative to the start offset) where the atom
108
/// data starts (and continues to the end offset); or an index in the array
109
/// corresponding to the "right" element of the pair (in which case, the
110
/// "left" element corresponds to the current index + 1).
111
///
112
/// Since these values are offsets into the original buffer, that buffer needs
113
/// to be kept around to get the original atoms.
114
115
type ParsedTriplesOutput = (Vec<ParsedTriple>, Option<Vec<[u8; 32]>>);
116
117
0
pub fn parse_triples<R: Read>(
118
0
    f: &mut R,
119
0
    calculate_tree_hashes: bool,
120
0
) -> Result<ParsedTriplesOutput> {
121
0
    let mut r = Vec::new();
122
0
    let mut tree_hashes = Vec::new();
123
0
    let mut op_stack = vec![ParseOpRef::ParseObj];
124
0
    let mut cursor: u64 = 0;
125
0
    while let Some(op) = op_stack.pop() {
126
0
        match op {
127
            ParseOpRef::ParseObj => {
128
0
                let mut b: [u8; 1] = [0];
129
0
                f.read_exact(&mut b)?;
130
0
                let start = cursor;
131
0
                cursor += 1;
132
0
                let b = b[0];
133
0
                if b == CONS_BOX_MARKER {
134
0
                    let index = r.len();
135
0
                    let new_obj = ParsedTriple::Pair {
136
0
                        start,
137
0
                        end: 0,
138
0
                        right_index: 0,
139
0
                    };
140
0
                    r.push(new_obj);
141
0
                    if calculate_tree_hashes {
142
0
                        tree_hashes.push([0; 32])
143
0
                    }
144
0
                    op_stack.push(ParseOpRef::SaveEnd(index));
145
0
                    op_stack.push(ParseOpRef::ParseObj);
146
0
                    op_stack.push(ParseOpRef::SaveRightIndex(index));
147
0
                    op_stack.push(ParseOpRef::ParseObj);
148
                } else {
149
0
                    let (start, end, atom_offset, tree_hash) = {
150
0
                        if b <= MAX_SINGLE_BYTE {
151
0
                            (
152
0
                                start,
153
0
                                start + 1,
154
0
                                0,
155
0
                                tree_hash_for_byte(b, calculate_tree_hashes),
156
0
                            )
157
                        } else {
158
0
                            let (atom_offset, atom_size) = decode_size_with_offset(f, b)?;
159
0
                            let end = start + (atom_offset as u64) + atom_size;
160
0
                            let h = skip_or_sha_bytes(f, atom_size, calculate_tree_hashes)?;
161
0
                            (start, end, atom_offset as u32, h)
162
                        }
163
                    };
164
0
                    if calculate_tree_hashes {
165
0
                        tree_hashes.push(tree_hash.expect("failed unwrap"))
166
0
                    }
167
0
                    let new_obj = ParsedTriple::Atom {
168
0
                        start,
169
0
                        end,
170
0
                        atom_offset,
171
0
                    };
172
0
                    cursor = end;
173
0
                    r.push(new_obj);
174
                }
175
            }
176
0
            ParseOpRef::SaveEnd(index) => match &mut r[index] {
177
                ParsedTriple::Pair {
178
                    start: _,
179
0
                    end,
180
0
                    right_index,
181
0
                } => {
182
0
                    if calculate_tree_hashes {
183
0
                        let h = sha_blobs(&[
184
0
                            &[2],
185
0
                            &tree_hashes[index + 1],
186
0
                            &tree_hashes[*right_index as usize],
187
0
                        ]);
188
0
                        tree_hashes[index] = h;
189
0
                    }
190
0
                    *end = cursor;
191
                }
192
                _ => {
193
0
                    panic!("internal error: SaveEnd")
194
                }
195
            },
196
0
            ParseOpRef::SaveRightIndex(index) => {
197
0
                let new_index = r.len() as u32;
198
0
                match &mut r[index] {
199
                    ParsedTriple::Pair {
200
                        start: _,
201
                        end: _,
202
0
                        right_index,
203
0
                    } => {
204
0
                        *right_index = new_index;
205
0
                    }
206
                    _ => {
207
0
                        panic!("internal error: SaveRightIndex")
208
                    }
209
                }
210
            }
211
        }
212
    }
213
    Ok((
214
0
        r,
215
0
        if calculate_tree_hashes {
216
0
            Some(tree_hashes)
217
        } else {
218
0
            None
219
        },
220
    ))
221
0
}
222
223
#[cfg(test)]
224
use std::io::Cursor;
225
226
#[cfg(test)]
227
use hex::FromHex;
228
229
#[cfg(test)]
230
fn check_parse_tree(h: &str, expected: Vec<ParsedTriple>, expected_sha_tree_hex: &str) {
231
    let b = Vec::from_hex(h).unwrap();
232
    println!("{:?}", b);
233
    let mut f = Cursor::new(b);
234
    let (p, tree_hash) = parse_triples(&mut f, false).unwrap();
235
    assert_eq!(p, expected);
236
    assert_eq!(tree_hash, None);
237
238
    let b = Vec::from_hex(h).unwrap();
239
    let mut f = Cursor::new(b);
240
    let (p, tree_hash) = parse_triples(&mut f, true).unwrap();
241
    assert_eq!(p, expected);
242
243
    let est = Vec::from_hex(expected_sha_tree_hex).unwrap();
244
    assert_eq!(tree_hash.unwrap()[0].to_vec(), est);
245
}
246
247
#[cfg(test)]
248
fn check_sha_blobs(h: &str, blobs: &[&[u8]]) {
249
    let exp_sha = Vec::from_hex(h).unwrap();
250
    let actual_sha = sha_blobs(blobs);
251
    assert_eq!(exp_sha, actual_sha);
252
}
253
254
#[test]
255
fn test_sha_blobs() {
256
    check_sha_blobs(
257
        "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a",
258
        &[&[1_u8]],
259
    );
260
    check_sha_blobs(
261
        "9dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2",
262
        &[&[1], &[1]],
263
    );
264
    check_sha_blobs(
265
        "812195e02ed84360ceafab26f9fa6072f8aa76ba34a735894c3f3c2e4fe6911d",
266
        &[&[1, 250, 17], &[28]],
267
    );
268
}
269
270
#[test]
271
fn test_parse_tree() {
272
    check_parse_tree(
273
        "80",
274
        vec![ParsedTriple::Atom {
275
            start: 0,
276
            end: 1,
277
            atom_offset: 1,
278
        }],
279
        "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a",
280
    );
281
282
    check_parse_tree(
283
        "ff648200c8",
284
        vec![
285
            ParsedTriple::Pair {
286
                start: 0,
287
                end: 5,
288
                right_index: 2,
289
            },
290
            ParsedTriple::Atom {
291
                start: 1,
292
                end: 2,
293
                atom_offset: 0,
294
            },
295
            ParsedTriple::Atom {
296
                start: 2,
297
                end: 5,
298
                atom_offset: 1,
299
            },
300
        ],
301
        "247f7d3f63b346ea93ca47f571cd0f4455392348b888a4286072bef0ac6069b5",
302
    );
303
304
    check_parse_tree(
305
        "ff83666f6fff83626172ff8362617a80", // `(foo bar baz)`
306
        vec![
307
            ParsedTriple::Pair {
308
                start: 0,
309
                end: 16,
310
                right_index: 2,
311
            },
312
            ParsedTriple::Atom {
313
                start: 1,
314
                end: 5,
315
                atom_offset: 1,
316
            },
317
            ParsedTriple::Pair {
318
                start: 5,
319
                end: 16,
320
                right_index: 4,
321
            },
322
            ParsedTriple::Atom {
323
                start: 6,
324
                end: 10,
325
                atom_offset: 1,
326
            },
327
            ParsedTriple::Pair {
328
                start: 10,
329
                end: 16,
330
                right_index: 6,
331
            },
332
            ParsedTriple::Atom {
333
                start: 11,
334
                end: 15,
335
                atom_offset: 1,
336
            },
337
            ParsedTriple::Atom {
338
                start: 15,
339
                end: 16,
340
                atom_offset: 1,
341
            },
342
        ],
343
        "47f30bf9935e25e4262023124fb5e986d755b9ed65a28ac78925c933bfd57dbd",
344
    );
345
346
    let s = "c0a0".to_owned() + &hex::encode([0x31u8; 160]);
347
    check_parse_tree(
348
        &s,
349
        vec![ParsedTriple::Atom {
350
            start: 0,
351
            end: 162,
352
            atom_offset: 2,
353
        }],
354
        "d1c109981a9c5a3bbe2d98795a186a0f057dc9a3a7f5e1eb4dfb63a1636efa2d",
355
    );
356
}
/home/oof/clvm_rs/src/serde/errors.rs
Line
Count
Source
1
use std::io::{Error, ErrorKind};
2
3
34
pub fn bad_encoding() -> Error {
4
34
    Error::new(ErrorKind::InvalidInput, "bad encoding")
5
34
}
6
7
0
pub fn internal_error() -> Error {
8
0
    Error::new(ErrorKind::InvalidInput, "internal error")
9
0
}
/home/oof/clvm_rs/src/serde/object_cache.rs
Line
Count
Source
1
/// `ObjectCache` provides a way to calculate and cache values for each node
2
/// in a clvm object tree. It can be used to calculate the sha256 tree hash
3
/// for an object and save the hash for all the child objects for building
4
/// usage tables, for example.
5
///
6
/// It also allows a function that's defined recursively on a clvm tree to
7
/// have a non-recursive implementation (as it keeps a stack of uncached
8
/// objects locally).
9
use crate::allocator::{Allocator, NodePtr, SExp};
10
use std::collections::HashMap;
11
type CachedFunction<T> = fn(&mut ObjectCache<T>, &Allocator, NodePtr) -> Option<T>;
12
use super::bytes32::{hash_blobs, Bytes32};
13
14
pub struct ObjectCache<'a, T> {
15
    cache: HashMap<NodePtr, T>,
16
    allocator: &'a Allocator,
17
18
    /// The function `f` is expected to calculate its T value recursively based
19
    /// on the T values for the left and right child for a pair. For an atom, the
20
    /// function f must calculate the T value directly.
21
    ///
22
    /// If a pair is passed and one of the children does not have its T value cached
23
    /// in `ObjectCache` yet, return `None` and f will be called with each child in turn.
24
    /// Don't recurse in f; that's the point of this structure.
25
    f: CachedFunction<T>,
26
}
27
28
impl<'a, T: Clone> ObjectCache<'a, T> {
29
0
    pub fn new(allocator: &'a Allocator, f: CachedFunction<T>) -> Self {
30
0
        Self {
31
0
            cache: HashMap::new(),
32
0
            allocator,
33
0
            f,
34
0
        }
35
0
    }
Unexecuted instantiation: _RNvMNtNtCs4RkbDk9WRL5_5clvmr5serde12object_cacheINtB2_11ObjectCacheAhj20_E3newB6_
Unexecuted instantiation: _RNvMNtNtCs4RkbDk9WRL5_5clvmr5serde12object_cacheINtB2_11ObjectCacheyE3newB6_
36
37
    /// return the function value for this node, either from cache
38
    /// or by calculating it
39
0
    pub fn get_or_calculate(&mut self, node: &NodePtr) -> Option<&T> {
40
0
        self.calculate(node);
41
0
        self.get_from_cache(node)
42
0
    }
Unexecuted instantiation: _RNvMNtNtCs4RkbDk9WRL5_5clvmr5serde12object_cacheINtB2_11ObjectCacheAhj20_E16get_or_calculateB6_
Unexecuted instantiation: _RNvMNtNtCs4RkbDk9WRL5_5clvmr5serde12object_cacheINtB2_11ObjectCacheyE16get_or_calculateB6_
43
44
    /// return the cached value for this node, or `None`
45
0
    fn get_from_cache(&self, node: &NodePtr) -> Option<&T> {
46
0
        self.cache.get(node)
47
0
    }
Unexecuted instantiation: _RNvMNtNtCs4RkbDk9WRL5_5clvmr5serde12object_cacheINtB2_11ObjectCacheAhj20_E14get_from_cacheB6_
Unexecuted instantiation: _RNvMNtNtCs4RkbDk9WRL5_5clvmr5serde12object_cacheINtB2_11ObjectCacheyE14get_from_cacheB6_
48
49
    /// set the cached value for a node
50
0
    fn set(&mut self, node: &NodePtr, v: T) {
51
0
        self.cache.insert(*node, v);
52
0
    }
Unexecuted instantiation: _RNvMNtNtCs4RkbDk9WRL5_5clvmr5serde12object_cacheINtB2_11ObjectCacheAhj20_E3setB6_
Unexecuted instantiation: _RNvMNtNtCs4RkbDk9WRL5_5clvmr5serde12object_cacheINtB2_11ObjectCacheyE3setB6_
53
54
    /// calculate the function's value for the given node, traversing uncached children
55
    /// as necessary
56
0
    fn calculate(&mut self, root_node: &NodePtr) {
57
0
        let mut obj_list = vec![*root_node];
58
0
        while let Some(node) = obj_list.pop() {
59
0
            let v = self.get_from_cache(&node);
60
0
            match v {
61
0
                Some(_) => {}
62
0
                None => match (self.f)(self, self.allocator, node) {
63
0
                    None => match self.allocator.sexp(node) {
64
0
                        SExp::Pair(left, right) => {
65
0
                            obj_list.push(node);
66
0
                            obj_list.push(left);
67
0
                            obj_list.push(right);
68
0
                        }
69
0
                        _ => panic!("f returned `None` for atom"),
70
                    },
71
0
                    Some(v) => {
72
0
                        self.set(&node, v);
73
0
                    }
74
                },
75
            }
76
        }
77
0
    }
Unexecuted instantiation: _RNvMNtNtCs4RkbDk9WRL5_5clvmr5serde12object_cacheINtB2_11ObjectCacheAhj20_E9calculateB6_
Unexecuted instantiation: _RNvMNtNtCs4RkbDk9WRL5_5clvmr5serde12object_cacheINtB2_11ObjectCacheyE9calculateB6_
78
}
79
80
/// calculate the standard `sha256tree` has for a node
81
82
0
pub fn treehash(
83
0
    cache: &mut ObjectCache<Bytes32>,
84
0
    allocator: &Allocator,
85
0
    node: NodePtr,
86
0
) -> Option<Bytes32> {
87
0
    match allocator.sexp(node) {
88
0
        SExp::Pair(left, right) => match cache.get_from_cache(&left) {
89
0
            None => None,
90
0
            Some(left_value) => cache
91
0
                .get_from_cache(&right)
92
0
                .map(|right_value| hash_blobs(&[&[2], left_value, right_value])),
93
        },
94
0
        SExp::Atom => Some(hash_blobs(&[&[1], allocator.atom(node).as_ref()])),
95
    }
96
0
}
97
98
/// calculate the serialized length (without backrefs) of a node. This is used
99
/// to check if using backrefs is actually smaller.
100
101
0
pub fn serialized_length(
102
0
    cache: &mut ObjectCache<u64>,
103
0
    allocator: &Allocator,
104
0
    node: NodePtr,
105
0
) -> Option<u64> {
106
0
    match allocator.sexp(node) {
107
0
        SExp::Pair(left, right) => match cache.get_from_cache(&left) {
108
0
            None => None,
109
0
            Some(left_value) => cache.get_from_cache(&right).map(|right_value| {
110
0
                1_u64
111
0
                    .saturating_add(*left_value)
112
0
                    .saturating_add(*right_value)
113
0
            }),
114
        },
115
        SExp::Atom => {
116
0
            let buf = allocator.atom(node);
117
0
            let lb: u64 = buf.as_ref().len().try_into().unwrap_or(u64::MAX);
118
0
            Some(if lb == 0 || (lb == 1 && buf.as_ref()[0] < 128) {
119
0
                1
120
0
            } else if lb < 0x40 {
121
0
                1 + lb
122
0
            } else if lb < 0x2000 {
123
0
                2 + lb
124
0
            } else if lb < 0x100000 {
125
0
                3 + lb
126
0
            } else if lb < 0x8000000 {
127
0
                4 + lb
128
            } else {
129
0
                5 + lb
130
            })
131
        }
132
    }
133
0
}
134
135
#[cfg(test)]
136
use std::cmp::max;
137
138
#[cfg(test)]
139
use std::fmt::Debug;
140
141
#[cfg(test)]
142
use std::io::Cursor;
143
144
#[cfg(test)]
145
use hex::FromHex;
146
147
#[cfg(test)]
148
use crate::serde::de::node_from_stream;
149
150
/// calculate the depth of a node. Used for tests
151
152
#[cfg(test)]
153
fn calculate_depth_simple(
154
    cache: &mut ObjectCache<usize>,
155
    allocator: &Allocator,
156
    node: NodePtr,
157
) -> Option<usize> {
158
    match allocator.sexp(node) {
159
        SExp::Pair(left, right) => match cache.get_from_cache(&left) {
160
            None => None,
161
            Some(left_value) => cache
162
                .get_from_cache(&right)
163
                .map(|right_value| 1 + max(*left_value, *right_value)),
164
        },
165
        SExp::Atom => Some(0),
166
    }
167
}
168
169
#[cfg(test)]
170
fn check_cached_function<T>(obj_as_hex: &str, expected_value: T, f: CachedFunction<T>)
171
where
172
    T: Clone + Eq + Debug,
173
{
174
    let mut allocator = Allocator::new();
175
    let blob: Vec<u8> = Vec::from_hex(obj_as_hex).unwrap();
176
    let mut cursor: Cursor<&[u8]> = Cursor::new(&blob);
177
    let obj = node_from_stream(&mut allocator, &mut cursor).unwrap();
178
    let mut oc = ObjectCache::new(&allocator, f);
179
180
    assert_eq!(oc.get_from_cache(&obj), None);
181
182
    oc.calculate(&obj);
183
184
    assert_eq!(oc.get_from_cache(&obj), Some(&expected_value));
185
186
    assert_eq!(oc.get_or_calculate(&obj).unwrap().clone(), expected_value);
187
188
    assert_eq!(oc.get_from_cache(&obj), Some(&expected_value));
189
190
    // do it again, but the simple way
191
    let mut oc = ObjectCache::new(&allocator, f);
192
    assert_eq!(oc.get_or_calculate(&obj).unwrap().clone(), expected_value);
193
}
194
195
#[test]
196
fn test_depths_cache() {
197
    let check = |a, b| check_cached_function(a, b, calculate_depth_simple);
198
    check("01", 0); // 1
199
    check("ff83666f6f83626172", 1); // (foo . bar)
200
    check("ff83666f6fff8362617280", 2); // (foo bar)
201
    check("ffff0102ff0304", 2); // ((1 . 2) . (3 . 4))
202
    check("ff01ff02ff03ff04ff05ff0680", 6); // (1 2 3 4 5 6)
203
}
204
205
#[test]
206
fn test_treehash() {
207
    let check = |a, b| check_cached_function(a, Bytes32::from_hex(b).unwrap(), treehash);
208
    check(
209
        "ff83666f6f83626172",
210
        "c518e45ae6a7b4146017b7a1d81639051b132f1f5572ce3088a3898a9ed1280b",
211
    ); // (foo . bar)
212
    check(
213
        "ff83666f6fff8362617280",
214
        "c97d97cc81100a4980080ba81ff1ba3985f7cff1db9d41d904b9d512bb875144",
215
    ); // (foo bar)
216
    check(
217
        "ffff0102ff0304",
218
        "2824018d148bc6aed0847e2c86aaa8a5407b916169f15b12cea31fa932fc4c8d",
219
    ); // ((1 . 2) . (3 . 4))
220
    check(
221
        "ff01ff02ff03ff04ff05ff0680",
222
        "65de5098d18bebd62aee37de32f0b62d1803d9c7c48f10dca25501243d7a0392",
223
    ); // (1 2 3 4 5 6)
224
}
225
226
#[test]
227
fn test_serialized_length() {
228
    let check = |a, b| check_cached_function(a, b, serialized_length);
229
    check("ff83666f6f83626172", 9); // (foo . bar)
230
    check("ff83666f6fff8362617280", 11); // (foo bar)
231
    check("ffff0102ff0304", 7); // ((1 . 2) . (3 . 4))
232
    check("ff01ff02ff03ff04ff05ff0680", 13); // (1 2 3 4 5 6)
233
}
234
235
// this test takes a very long time (>60s) in debug mode, so it only runs in release mode
236
237
#[cfg(not(debug_assertions))]
238
#[test]
239
fn test_very_long_list() {
240
    // in this test, we check that `treehash` and `serialized_length` can handle very deep trees that
241
    // would normally blow out the stack. It's expensive to create such a long list, so we do both
242
    // tests here so we only have to to create the list once
243
244
    const LIST_SIZE: u64 = 20_000_000;
245
    let mut allocator = Allocator::new();
246
    let mut top = allocator.nil();
247
    for _ in 0..LIST_SIZE {
248
        let atom = allocator.one();
249
        top = allocator.new_pair(atom, top).unwrap();
250
    }
251
252
    let expected_value = LIST_SIZE * 2 + 1;
253
    let mut oc = ObjectCache::new(&allocator, serialized_length);
254
    assert_eq!(oc.get_or_calculate(&top).unwrap().clone(), expected_value);
255
256
    let expected_value =
257
        <[u8; 32]>::from_hex("a168fce695099a30c0745075e6db3722ed7f059e0d7cc4d7e7504e215db5017b")
258
            .unwrap();
259
    let mut oc = ObjectCache::new(&allocator, treehash);
260
    assert_eq!(oc.get_or_calculate(&top).unwrap().clone(), expected_value);
261
}
/home/oof/clvm_rs/src/serde/parse_atom.rs
Line
Count
Source
1
use std::io::{Cursor, Read, Result, Seek, SeekFrom};
2
3
use crate::allocator::{Allocator, NodePtr};
4
5
use super::errors::{bad_encoding, internal_error};
6
7
const MAX_SINGLE_BYTE: u8 = 0x7f;
8
9
/// decode the length prefix for an atom, returning both the offset to the start
10
/// of the atom and the full length of the atom.
11
/// Atoms whose value fit in 7 bits don't have a length prefix, so those should
12
/// be handled specially and never passed to this function.
13
196k
pub fn decode_size_with_offset<R: Read>(f: &mut R, initial_b: u8) -> Result<(u8, u64)> {
14
196k
    debug_assert!((initial_b & 0x80) != 0);
15
196k
    if (initial_b & 0x80) == 0 {
16
0
        return Err(internal_error());
17
196k
    }
18
196k
19
196k
    let mut atom_start_offset = 0;
20
196k
    let mut bit_mask: u8 = 0x80;
21
196k
    let mut b = initial_b;
22
426k
    while b & bit_mask != 0 {
23
229k
        atom_start_offset += 1;
24
229k
        b &= 0xff ^ bit_mask;
25
229k
        bit_mask >>= 1;
26
229k
    }
27
196k
    let mut stack_allocation = [0_u8; 8];
28
196k
    let size_blob = &mut stack_allocation[..atom_start_offset];
29
196k
    size_blob[0] = b;
30
196k
    if atom_start_offset > 1 {
31
31.7k
        let remaining_buffer = &mut size_blob[1..];
32
31.7k
        f.read_exact(remaining_buffer)?;
33
165k
    }
34
    // need to convert size_blob to an int
35
196k
    let mut atom_size: u64 = 0;
36
196k
    if size_blob.len() > 6 {
37
3
        return Err(bad_encoding());
38
196k
    }
39
426k
    for b in size_blob {
40
229k
        atom_size <<= 8;
41
229k
        atom_size += *b as u64;
42
229k
    }
43
196k
    if atom_size >= 0x400000000 {
44
3
        return Err(bad_encoding());
45
196k
    }
46
196k
    Ok((atom_start_offset as u8, atom_size))
47
196k
}
48
49
196k
pub fn decode_size<R: Read>(f: &mut R, initial_b: u8) -> Result<u64> {
50
196k
    decode_size_with_offset(f, initial_b).map(|v| v.1)
51
196k
}
52
53
/// parse an atom from the stream and return a pointer to it
54
/// the first byte has already been read
55
56
441k
fn parse_atom_ptr<'a>(f: &'a mut Cursor<&[u8]>, first_byte: u8) -> Result<&'a [u8]> {
57
441k
    let blob = if first_byte <= MAX_SINGLE_BYTE {
58
244k
        let pos = f.position() as usize;
59
244k
        &f.get_ref()[pos - 1..pos]
60
    } else {
61
196k
        let blob_size = decode_size(f, first_byte)?;
62
196k
        let pos = f.position() as usize;
63
196k
        if f.get_ref().len() < pos + blob_size as usize {
64
28
            return Err(bad_encoding());
65
196k
        }
66
196k
        f.seek(SeekFrom::Current(blob_size as i64))?;
67
196k
        &f.get_ref()[pos..(pos + blob_size as usize)]
68
    };
69
441k
    Ok(blob)
70
441k
}
71
72
/// parse an atom from the stream into the allocator
73
/// At this point, the first byte has already been read to ensure it's
74
/// not a special code like `CONS_BOX_MARKER` = 0xff, so it must be
75
/// passed in too
76
77
953k
pub fn parse_atom(
78
953k
    allocator: &mut Allocator,
79
953k
    first_byte: u8,
80
953k
    f: &mut Cursor<&[u8]>,
81
953k
) -> Result<NodePtr> {
82
953k
    if first_byte == 0x01 {
83
284k
        Ok(allocator.one())
84
668k
    } else if first_byte == 0x80 {
85
227k
        Ok(allocator.nil())
86
    } else {
87
441k
        let blob = parse_atom_ptr(f, first_byte)?;
88
441k
        Ok(allocator.new_atom(blob)?)
89
    }
90
953k
}
91
92
/// parse an atom from the stream and return a pointer to it
93
94
0
pub fn parse_path<'a>(f: &'a mut Cursor<&[u8]>) -> Result<&'a [u8]> {
95
0
    let mut buf1: [u8; 1] = [0];
96
0
    f.read_exact(&mut buf1)?;
97
0
    parse_atom_ptr(f, buf1[0])
98
0
}
99
100
#[cfg(test)]
101
use std::io::ErrorKind;
102
103
#[cfg(test)]
104
use super::write_atom::write_atom;
105
106
#[test]
107
fn test_decode_size() {
108
    // single-byte length prefix
109
    let mut buffer = Cursor::new(&[]);
110
    assert_eq!(
111
        decode_size_with_offset(&mut buffer, 0x80 | 0x20).unwrap(),
112
        (1, 0x20)
113
    );
114
115
    // two-byte length prefix
116
    let first = 0b11001111;
117
    let mut buffer = Cursor::new(&[0xaa]);
118
    assert_eq!(
119
        decode_size_with_offset(&mut buffer, first).unwrap(),
120
        (2, 0xfaa)
121
    );
122
}
123
124
#[test]
125
fn test_large_decode_size() {
126
    // this is an atom length-prefix 0xffffffffffff, or (2^48 - 1).
127
    // We don't support atoms this large and we should fail before attempting to
128
    // allocate this much memory
129
    let first = 0b11111110;
130
    let mut buffer = Cursor::new(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
131
    let ret = decode_size_with_offset(&mut buffer, first);
132
    let e = ret.unwrap_err();
133
    assert_eq!(e.kind(), bad_encoding().kind());
134
    assert_eq!(e.to_string(), "bad encoding");
135
136
    // this is still too large
137
    let first = 0b11111100;
138
    let mut buffer = Cursor::new(&[0x4, 0, 0, 0, 0]);
139
    let ret = decode_size_with_offset(&mut buffer, first);
140
    let e = ret.unwrap_err();
141
    assert_eq!(e.kind(), bad_encoding().kind());
142
    assert_eq!(e.to_string(), "bad encoding");
143
144
    // But this is *just* within what we support
145
    // Still a very large blob, probably enough for a DoS attack
146
    let first = 0b11111100;
147
    let mut buffer = Cursor::new(&[0x3, 0xff, 0xff, 0xff, 0xff]);
148
    assert_eq!(
149
        decode_size_with_offset(&mut buffer, first).unwrap(),
150
        (6, 0x3ffffffff)
151
    );
152
153
    // this ensures a fuzzer-found bug doesn't reoccur
154
    let mut buffer = Cursor::new(&[0xff, 0xfe]);
155
    let ret = decode_size_with_offset(&mut buffer, first);
156
    let e = ret.unwrap_err();
157
    assert_eq!(e.kind(), ErrorKind::UnexpectedEof);
158
    assert_eq!(e.to_string(), "failed to fill whole buffer");
159
}
160
161
#[test]
162
fn test_truncated_decode_size() {
163
    // the stream is truncated
164
    let first = 0b11111100;
165
    let mut cursor = Cursor::new(&[0x4, 0, 0, 0]);
166
    let ret = decode_size_with_offset(&mut cursor, first);
167
    let e = ret.unwrap_err();
168
    assert_eq!(e.kind(), ErrorKind::UnexpectedEof);
169
}
170
171
#[cfg(test)]
172
fn check_parse_atom(blob: &[u8], expected_atom: &[u8]) {
173
    let mut cursor = Cursor::<&[u8]>::new(blob);
174
    let mut first: [u8; 1] = [0];
175
    cursor.read_exact(&mut first).unwrap();
176
    let first = first[0];
177
178
    let mut allocator = Allocator::new();
179
    let atom_node = parse_atom(&mut allocator, first, &mut cursor).unwrap();
180
181
    let atom = allocator.atom(atom_node);
182
183
    assert_eq!(expected_atom, atom.as_ref());
184
}
185
186
#[cfg(test)]
187
fn check_parse_atom_str(blob_hex: &str, expected_atom_hex: &str) {
188
    let blob = hex::decode(blob_hex).unwrap();
189
    let expected_atom: &[u8] = &hex::decode(expected_atom_hex).unwrap();
190
    check_parse_atom(&blob, expected_atom);
191
}
192
193
#[test]
194
fn test_parse_atom() {
195
    check_parse_atom_str("80", "");
196
    // try "00", "01", "02", ..., "7f"
197
    for idx in 0..128 {
198
        check_parse_atom(&[idx], &[idx]);
199
    }
200
201
    // check a short atom
202
    check_parse_atom_str("83666f6f", "666f6f");
203
204
    // check long atoms near boundary conditions
205
    let n = 3;
206
    let base_lengths = [0, 0x40 - n, 0x2000 - n, 0x100000 - n, 0x08000000 - n];
207
    let mut atom_vec = vec![];
208
    for base_length in base_lengths.iter() {
209
        for size_offset in 0..6 {
210
            let size = base_length + size_offset;
211
            atom_vec.resize(size, 0x66);
212
            let mut buffer: Vec<u8> = vec![];
213
            let mut cursor = Cursor::new(&mut buffer);
214
            write_atom(&mut cursor, &atom_vec).unwrap();
215
        }
216
    }
217
}
218
219
#[test]
220
fn test_truncated_parse_atom() {
221
    // the stream is truncated
222
    let first = 0b11111100;
223
    let mut cursor = Cursor::<&[u8]>::new(&[0x4, 0, 0, 0]);
224
    let mut allocator = Allocator::new();
225
    let ret = parse_atom(&mut allocator, first, &mut cursor);
226
    let err = ret.unwrap_err();
227
    assert_eq!(err.kind(), ErrorKind::UnexpectedEof);
228
}
/home/oof/clvm_rs/src/serde/read_cache_lookup.rs
Line
Count
Source
1
/// When deserializing a clvm object, a stack of deserialized child objects
2
/// is created, which can be used with back-references. A `ReadCacheLookup` keeps
3
/// track of the state of this stack and all child objects under each root
4
/// node in the stack so that we can quickly determine if a relevant
5
/// back-reference is available.
6
///
7
/// In other words, if we've already serialized an object with tree hash T,
8
/// and we encounter another object with that tree hash, we don't re-serialize
9
/// it, but rather include a back-reference to it. This data structure lets
10
/// us quickly determine which back-reference has the shortest path.
11
///
12
/// Note that there is a counter. This is because the stack contains some
13
/// child objects that are transient, and no longer appear in the stack
14
/// at later times in the parsing. We don't want to waste time looking for
15
/// these objects that no longer exist, so we reference-count them.
16
///
17
/// All hashes correspond to sha256 tree hashes.
18
use std::collections::{HashMap, HashSet};
19
20
use super::bytes32::{hash_blob, hash_blobs, Bytes32};
21
22
#[derive(Debug)]
23
pub struct ReadCacheLookup {
24
    root_hash: Bytes32,
25
26
    /// the stack is a cons-based list of objects. The
27
    /// `read_stack` corresponds to cons cells and contains
28
    /// the tree hashes of the contents on the left and right
29
    read_stack: Vec<(Bytes32, Bytes32)>,
30
31
    count: HashMap<Bytes32, u32>,
32
33
    /// a mapping of tree hashes to `(parent, is_right)` tuples
34
    parent_lookup: HashMap<Bytes32, Vec<(Bytes32, u8)>>,
35
}
36
37
impl Default for ReadCacheLookup {
38
0
    fn default() -> Self {
39
0
        Self::new()
40
0
    }
41
}
42
43
impl ReadCacheLookup {
44
0
    pub fn new() -> Self {
45
0
        let root_hash = hash_blob(&[1]);
46
0
        let read_stack = vec![];
47
0
        let mut count = HashMap::default();
48
0
        count.insert(root_hash, 1);
49
0
        let parent_lookup = HashMap::default();
50
0
        Self {
51
0
            root_hash,
52
0
            read_stack,
53
0
            count,
54
0
            parent_lookup,
55
0
        }
56
0
    }
57
58
    /// update the cache based on pushing an object with the given tree hash
59
0
    pub fn push(&mut self, id: Bytes32) {
60
0
        // we add two new entries: the new root of the tree, and this object (by id)
61
0
        // new_root: (id, old_root)
62
0
63
0
        let new_root_hash = hash_blobs(&[&[2], &id, &self.root_hash]);
64
0
65
0
        self.read_stack.push((id, self.root_hash));
66
0
67
0
        *self.count.entry(id).or_insert(0) += 1;
68
0
        *self.count.entry(new_root_hash).or_insert(0) += 1;
69
0
70
0
        let new_parent_to_old_root = (new_root_hash, 0);
71
0
        self.parent_lookup
72
0
            .entry(id)
73
0
            .or_default()
74
0
            .push(new_parent_to_old_root);
75
0
76
0
        let new_parent_to_id = (new_root_hash, 1);
77
0
        self.parent_lookup
78
0
            .entry(self.root_hash)
79
0
            .or_default()
80
0
            .push(new_parent_to_id);
81
0
82
0
        self.root_hash = new_root_hash;
83
0
    }
84
85
    /// update the cache based on popping the top-most object
86
    /// returns the hash of the object in this position and
87
    /// the new root hash
88
0
    fn pop(&mut self) -> (Bytes32, Bytes32) {
89
0
        let item = self.read_stack.pop().expect("stack empty");
90
0
        *self.count.entry(item.0).or_insert(0) -= 1;
91
0
        *self.count.entry(self.root_hash).or_insert(0) -= 1;
92
0
        self.root_hash = item.1;
93
0
        item
94
0
    }
95
96
    /// update the cache based on the "pop/pop/cons" operation used
97
    /// during deserialization
98
0
    pub fn pop2_and_cons(&mut self) {
99
0
        // we remove two items: each side of each left/right pair
100
0
        let right = self.pop();
101
0
        let left = self.pop();
102
0
103
0
        *self.count.entry(left.0).or_insert(0) += 1;
104
0
        *self.count.entry(right.0).or_insert(0) += 1;
105
0
106
0
        let new_root_hash = hash_blobs(&[&[2], &left.0, &right.0]);
107
0
108
0
        self.parent_lookup
109
0
            .entry(left.0)
110
0
            .or_default()
111
0
            .push((new_root_hash, 0));
112
0
113
0
        self.parent_lookup
114
0
            .entry(right.0)
115
0
            .or_default()
116
0
            .push((new_root_hash, 1));
117
0
118
0
        self.push(new_root_hash);
119
0
    }
120
121
    /// return the list of minimal-length paths to the given hash which will serialize to no larger
122
    /// than the given size (or an empty list if no such path exists)
123
0
    pub fn find_paths(&self, id: &Bytes32, serialized_length: u64) -> Vec<Vec<u8>> {
124
0
        let mut seen_ids = HashSet::<&Bytes32>::default();
125
0
        let mut possible_responses = vec![];
126
0
        if serialized_length < 3 {
127
0
            return possible_responses;
128
0
        }
129
0
        assert!(serialized_length > 2);
130
0
        let max_bytes_for_path_encoding = serialized_length - 2; // 1 byte for 0xfe, 1 min byte for savings
131
0
        let max_path_length: usize = (max_bytes_for_path_encoding.saturating_mul(8) - 1)
132
0
            .try_into()
133
0
            .unwrap_or(usize::MAX);
134
0
        seen_ids.insert(id);
135
0
        let mut partial_paths = vec![(*id, vec![])];
136
137
0
        while !partial_paths.is_empty() {
138
0
            let mut new_partial_paths = vec![];
139
0
            for (node, path) in partial_paths.iter_mut() {
140
0
                if *node == self.root_hash {
141
0
                    possible_responses.push(reversed_path_to_vec_u8(path));
142
0
                    continue;
143
0
                }
144
0
145
0
                let parents = self.parent_lookup.get(node);
146
0
                if let Some(items) = parents {
147
0
                    for (parent, direction) in items.iter() {
148
0
                        if *(self.count.get(parent).unwrap_or(&0)) > 0 && !seen_ids.contains(parent)
149
                        {
150
0
                            let mut new_path = path.clone();
151
0
                            new_path.push(*direction);
152
0
                            if new_path.len() > max_path_length {
153
0
                                return possible_responses;
154
0
                            }
155
0
                            new_partial_paths.push((*parent, new_path));
156
0
                        }
157
0
                        seen_ids.insert(parent);
158
                    }
159
0
                }
160
            }
161
0
            if !possible_responses.is_empty() {
162
0
                break;
163
0
            }
164
0
            partial_paths = new_partial_paths;
165
        }
166
0
        possible_responses
167
0
    }
168
169
    /// If multiple paths exist, the lexicographically smallest one will be returned.
170
0
    pub fn find_path(&self, id: &Bytes32, serialized_length: u64) -> Option<Vec<u8>> {
171
0
        let mut paths = self.find_paths(id, serialized_length);
172
0
        if !paths.is_empty() {
173
0
            paths.sort();
174
0
            paths.truncate(1);
175
0
            paths.pop()
176
        } else {
177
0
            None
178
        }
179
0
    }
180
}
181
182
/// Turn a list of 0/1 values (for "left/right") into `Vec<u8>` representing
183
/// the corresponding clvm path in the standard way.
184
/// `[]` => `1`
185
/// If `A` => `v` then `[A] + [0]` => `v * 2` and `[A] + [1]` => `v * 2 + 1`
186
/// Then the integer is turned into the minimal-length array of `u8` representing
187
/// that value as an unsigned integer.
188
189
0
fn reversed_path_to_vec_u8(path: &[u8]) -> Vec<u8> {
190
0
    let byte_count = (path.len() + 1 + 7) >> 3;
191
0
    let mut v = vec![0; byte_count];
192
0
    let mut index = byte_count - 1;
193
0
    let mut mask: u8 = 1;
194
0
    for p in path.iter().rev() {
195
0
        if *p != 0 {
196
0
            v[index] |= mask;
197
0
        }
198
        mask = {
199
0
            if mask == 0x80 {
200
0
                index -= 1;
201
0
                1
202
            } else {
203
0
                mask + mask
204
            }
205
        };
206
    }
207
0
    v[index] |= mask;
208
0
    v
209
0
}
210
211
#[test]
212
fn test_path_to_vec_u8() {
213
    assert_eq!(reversed_path_to_vec_u8(&[]), vec!(0b1));
214
    assert_eq!(reversed_path_to_vec_u8(&[0]), vec!(0b10));
215
    assert_eq!(reversed_path_to_vec_u8(&[1]), vec!(0b11));
216
    assert_eq!(reversed_path_to_vec_u8(&[0, 0]), vec!(0b100));
217
    assert_eq!(reversed_path_to_vec_u8(&[0, 1]), vec!(0b101));
218
    assert_eq!(reversed_path_to_vec_u8(&[1, 0]), vec!(0b110));
219
    assert_eq!(reversed_path_to_vec_u8(&[1, 1]), vec!(0b111));
220
    assert_eq!(reversed_path_to_vec_u8(&[1, 1, 1]), vec!(0b1111));
221
    assert_eq!(reversed_path_to_vec_u8(&[0, 1, 1, 1]), vec!(0b10111));
222
    assert_eq!(reversed_path_to_vec_u8(&[1, 0, 1, 1, 1]), vec!(0b110111));
223
    assert_eq!(
224
        reversed_path_to_vec_u8(&[1, 1, 0, 1, 1, 1]),
225
        vec!(0b1110111)
226
    );
227
    assert_eq!(
228
        reversed_path_to_vec_u8(&[0, 1, 1, 0, 1, 1, 1]),
229
        vec!(0b10110111)
230
    );
231
    assert_eq!(
232
        reversed_path_to_vec_u8(&[0, 0, 1, 1, 0, 1, 1, 1]),
233
        vec!(0b1, 0b00110111)
234
    );
235
    assert_eq!(
236
        reversed_path_to_vec_u8(&[1, 0, 0, 1, 1, 0, 1, 1, 1]),
237
        vec!(0b11, 0b00110111)
238
    );
239
}
240
241
#[test]
242
fn test_read_cache_lookup() {
243
    let large_max = 30;
244
    let mut rcl = ReadCacheLookup::new();
245
246
    // the only thing cached right now is a nil, right at the top of the tree (ie. `1`)
247
    let hash_of_nil = hash_blob(&[1]);
248
    assert_eq!(rcl.find_paths(&hash_of_nil, large_max), [[1]]);
249
250
    assert_eq!(rcl.count.get(&hash_of_nil).unwrap(), &1);
251
252
    // the atom `1` is not in the tree anywhere
253
    let hash_of_1_atom = hash_blobs(&[&[1], &[1]]);
254
    assert!(rcl.find_paths(&hash_of_1_atom, large_max).is_empty());
255
256
    // now let's push a `5` atom to the top
257
    // tree: `(5 . 0)`
258
    let hash_of_5_atom = hash_blobs(&[&[1], &[5]]);
259
    rcl.push(hash_of_5_atom);
260
    let hash_of_cons_5_nil = hash_blobs(&[&[2], &hash_of_5_atom, &hash_of_nil]);
261
    assert_eq!(rcl.find_paths(&hash_of_cons_5_nil, large_max), [[1]]);
262
    assert_eq!(rcl.find_paths(&hash_of_5_atom, large_max), [[2]]);
263
    assert_eq!(rcl.find_paths(&hash_of_nil, large_max), [[3]]);
264
265
    assert_eq!(rcl.count.get(&hash_of_cons_5_nil).unwrap(), &1);
266
    assert_eq!(rcl.count.get(&hash_of_5_atom).unwrap(), &1);
267
    assert_eq!(rcl.count.get(&hash_of_nil).unwrap(), &1);
268
269
    // the atom `1` is still not in the tree anywhere
270
    assert!(rcl.find_paths(&hash_of_1_atom, large_max).is_empty());
271
272
    // now let's push a `9` atom to the top
273
    // tree: `(9 . (5 . 0))`
274
    let hash_of_9_atom = hash_blobs(&[&[1], &[9]]);
275
    rcl.push(hash_of_9_atom);
276
    let hash_of_cons_9_cons_5_nil = hash_blobs(&[&[2], &hash_of_9_atom, &hash_of_cons_5_nil]);
277
278
    assert_eq!(rcl.find_paths(&hash_of_cons_9_cons_5_nil, large_max), [[1]]);
279
    assert_eq!(rcl.find_paths(&hash_of_9_atom, large_max), [[2]]);
280
    assert_eq!(rcl.find_paths(&hash_of_cons_5_nil, large_max), [[3]]);
281
    assert_eq!(rcl.find_paths(&hash_of_5_atom, large_max), [[5]]);
282
    assert_eq!(rcl.find_paths(&hash_of_nil, large_max), [[7]]);
283
284
    assert_eq!(rcl.count.get(&hash_of_cons_9_cons_5_nil).unwrap(), &1);
285
    assert_eq!(rcl.count.get(&hash_of_9_atom).unwrap(), &1);
286
    assert_eq!(rcl.count.get(&hash_of_cons_5_nil).unwrap(), &1);
287
    assert_eq!(rcl.count.get(&hash_of_5_atom).unwrap(), &1);
288
    assert_eq!(rcl.count.get(&hash_of_nil).unwrap(), &1);
289
290
    // the atom `1` is still not in the tree anywhere
291
    assert!(rcl.find_paths(&hash_of_1_atom, large_max).is_empty());
292
293
    // now let's push a `10` atom to the top
294
    // tree: `(10 . (9 . (5 . 0)))`
295
296
    let hash_of_10_atom = hash_blobs(&[&[1], &[10]]);
297
    rcl.push(hash_of_10_atom);
298
    let hash_of_cons_10_cons_9_cons_5_nil =
299
        hash_blobs(&[&[2], &hash_of_10_atom, &hash_of_cons_9_cons_5_nil]);
300
    assert_eq!(
301
        rcl.find_paths(&hash_of_cons_10_cons_9_cons_5_nil, large_max),
302
        [[1]]
303
    );
304
    assert_eq!(rcl.find_paths(&hash_of_10_atom, large_max), [[2]]);
305
    assert_eq!(rcl.find_paths(&hash_of_cons_9_cons_5_nil, large_max), [[3]]);
306
    assert_eq!(rcl.find_paths(&hash_of_9_atom, large_max), [[5]]);
307
    assert_eq!(rcl.find_paths(&hash_of_cons_5_nil, large_max), [[7]]);
308
    assert_eq!(rcl.find_paths(&hash_of_5_atom, large_max), [[11]]);
309
    assert_eq!(rcl.find_paths(&hash_of_nil, large_max), [[15]]);
310
311
    assert_eq!(
312
        rcl.count.get(&hash_of_cons_10_cons_9_cons_5_nil).unwrap(),
313
        &1
314
    );
315
    assert_eq!(rcl.count.get(&hash_of_10_atom).unwrap(), &1);
316
    assert_eq!(rcl.count.get(&hash_of_cons_9_cons_5_nil).unwrap(), &1);
317
    assert_eq!(rcl.count.get(&hash_of_9_atom).unwrap(), &1);
318
    assert_eq!(rcl.count.get(&hash_of_cons_5_nil).unwrap(), &1);
319
    assert_eq!(rcl.count.get(&hash_of_5_atom).unwrap(), &1);
320
    assert_eq!(rcl.count.get(&hash_of_nil).unwrap(), &1);
321
322
    // the atom `1` is still not in the tree anywhere
323
    assert!(rcl.find_paths(&hash_of_1_atom, large_max).is_empty());
324
325
    // now let's do a `pop2_and_cons`
326
    // tree: `((9 . 10) . (5 . 0))`
327
    // 2 => (9 . 10)
328
    // 3 => (5 . 0)
329
    // 4 => 9
330
    // 5 => 5
331
    // 6 => 10
332
    // 7 => 0
333
    rcl.pop2_and_cons();
334
    let hash_of_cons_9_10 = hash_blobs(&[&[2], &hash_of_9_atom, &hash_of_10_atom]);
335
    let hash_of_cons_cons_9_10_cons_5_nil =
336
        hash_blobs(&[&[2], &hash_of_cons_9_10, &hash_of_cons_5_nil]);
337
    assert_eq!(
338
        rcl.find_paths(&hash_of_cons_cons_9_10_cons_5_nil, large_max),
339
        [[1]]
340
    );
341
    assert_eq!(rcl.find_paths(&hash_of_cons_9_10, large_max), [[2]]);
342
    assert_eq!(rcl.find_paths(&hash_of_cons_5_nil, large_max), [[3]]);
343
    assert_eq!(rcl.find_paths(&hash_of_9_atom, large_max), [[4]]);
344
    assert_eq!(rcl.find_paths(&hash_of_10_atom, large_max), [[6]]);
345
    assert_eq!(rcl.find_paths(&hash_of_5_atom, large_max), [[5]]);
346
    assert_eq!(rcl.find_paths(&hash_of_nil, large_max), [[7]]);
347
348
    // `(9 . (5 . 0))` is no longer in the tree
349
    assert!(rcl
350
        .find_paths(&hash_of_cons_9_cons_5_nil, large_max)
351
        .is_empty());
352
353
    assert_eq!(
354
        rcl.count.get(&hash_of_cons_cons_9_10_cons_5_nil).unwrap(),
355
        &1
356
    );
357
    assert_eq!(rcl.count.get(&hash_of_cons_9_10).unwrap(), &1);
358
    assert_eq!(rcl.count.get(&hash_of_cons_5_nil).unwrap(), &1);
359
    assert_eq!(rcl.count.get(&hash_of_9_atom).unwrap(), &1);
360
    assert_eq!(rcl.count.get(&hash_of_10_atom).unwrap(), &1);
361
    assert_eq!(rcl.count.get(&hash_of_5_atom).unwrap(), &1);
362
    assert_eq!(rcl.count.get(&hash_of_nil).unwrap(), &1);
363
364
    // `(9 . (5 . 0))` is no longer in the tree
365
    assert_eq!(rcl.count.get(&hash_of_cons_9_cons_5_nil).unwrap(), &0);
366
367
    // the atom `1` is still not in the tree anywhere
368
    assert!(rcl.find_paths(&hash_of_1_atom, large_max).is_empty());
369
370
    assert!(!rcl.count.contains_key(&hash_of_1_atom));
371
}
/home/oof/clvm_rs/src/serde/ser.rs
Line
Count
Source
1
use std::io;
2
use std::io::Cursor;
3
use std::io::ErrorKind;
4
use std::io::Write;
5
6
use super::write_atom::write_atom;
7
use crate::allocator::{len_for_value, Allocator, NodePtr, NodeVisitor};
8
9
const CONS_BOX_MARKER: u8 = 0xff;
10
11
pub struct LimitedWriter<W: io::Write> {
12
    inner: W,
13
    limit: usize,
14
}
15
16
impl<W: io::Write> LimitedWriter<W> {
17
0
    pub fn new(w: W, limit: usize) -> LimitedWriter<W> {
18
0
        LimitedWriter { inner: w, limit }
19
0
    }
20
21
0
    pub fn into_inner(self) -> W {
22
0
        self.inner
23
0
    }
24
}
25
26
impl<W: io::Write> Write for LimitedWriter<W> {
27
0
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
28
0
        if self.limit < buf.len() {
29
0
            return Err(ErrorKind::OutOfMemory.into());
30
0
        }
31
0
        let written = self.inner.write(buf)?;
32
0
        self.limit -= written;
33
0
        Ok(written)
34
0
    }
35
0
    fn flush(&mut self) -> io::Result<()> {
36
0
        self.inner.flush()
37
0
    }
38
}
39
40
/// serialize a node
41
0
pub fn node_to_stream<W: io::Write>(a: &Allocator, node: NodePtr, f: &mut W) -> io::Result<()> {
42
0
    let mut values: Vec<NodePtr> = vec![node];
43
0
    while let Some(v) = values.pop() {
44
0
        match a.node(v) {
45
0
            NodeVisitor::Buffer(buf) => write_atom(f, buf)?,
46
0
            NodeVisitor::U32(val) => {
47
0
                let buf = val.to_be_bytes();
48
0
                let len = len_for_value(val);
49
0
                write_atom(f, &buf[4 - len..])?
50
            }
51
0
            NodeVisitor::Pair(left, right) => {
52
0
                f.write_all(&[CONS_BOX_MARKER])?;
53
0
                values.push(right);
54
0
                values.push(left);
55
            }
56
        }
57
    }
58
0
    Ok(())
59
0
}
60
61
0
pub fn node_to_bytes_limit(a: &Allocator, node: NodePtr, limit: usize) -> io::Result<Vec<u8>> {
62
0
    let buffer = Cursor::new(Vec::new());
63
0
    let mut writer = LimitedWriter::new(buffer, limit);
64
0
    node_to_stream(a, node, &mut writer)?;
65
0
    let vec = writer.into_inner().into_inner();
66
0
    Ok(vec)
67
0
}
68
69
0
pub fn node_to_bytes(a: &Allocator, node: NodePtr) -> io::Result<Vec<u8>> {
70
0
    node_to_bytes_limit(a, node, 2000000)
71
0
}
72
73
#[test]
74
fn test_serialize_limit() {
75
    let mut a = Allocator::new();
76
77
    let leaf = a.new_atom(&[1, 2, 3, 4, 5]).unwrap();
78
    let l1 = a.new_pair(leaf, leaf).unwrap();
79
    let l2 = a.new_pair(l1, l1).unwrap();
80
    let l3 = a.new_pair(l2, l2).unwrap();
81
82
    {
83
        let buffer = Cursor::new(Vec::new());
84
        let mut writer = LimitedWriter::new(buffer, 55);
85
        node_to_stream(&a, l3, &mut writer).unwrap();
86
        let vec = writer.into_inner().into_inner();
87
        assert_eq!(
88
            vec,
89
            &[
90
                0xff, 0xff, 0xff, 133, 1, 2, 3, 4, 5, 133, 1, 2, 3, 4, 5, 0xff, 133, 1, 2, 3, 4, 5,
91
                133, 1, 2, 3, 4, 5, 0xff, 0xff, 133, 1, 2, 3, 4, 5, 133, 1, 2, 3, 4, 5, 0xff, 133,
92
                1, 2, 3, 4, 5, 133, 1, 2, 3, 4, 5
93
            ]
94
        );
95
    }
96
97
    {
98
        let buffer = Cursor::new(Vec::new());
99
        let mut writer = LimitedWriter::new(buffer, 54);
100
        assert_eq!(
101
            node_to_stream(&a, l3, &mut writer).unwrap_err().kind(),
102
            io::ErrorKind::OutOfMemory
103
        );
104
    }
105
}
/home/oof/clvm_rs/src/serde/ser_br.rs
Line
Count
Source
1
// Serialization with "back-references"
2
3
use std::io;
4
use std::io::Cursor;
5
6
use super::object_cache::{serialized_length, treehash, ObjectCache};
7
use super::read_cache_lookup::ReadCacheLookup;
8
use super::write_atom::write_atom;
9
use crate::allocator::{Allocator, NodePtr, SExp};
10
use crate::serde::ser::LimitedWriter;
11
12
const BACK_REFERENCE: u8 = 0xfe;
13
const CONS_BOX_MARKER: u8 = 0xff;
14
15
#[derive(PartialEq, Eq)]
16
enum ReadOp {
17
    Parse,
18
    Cons,
19
}
20
21
// these test cases were produced by:
22
23
// from chia.types.blockchain_format.program import Program
24
// a = Program.to(...)
25
// print(bytes(a).hex())
26
// print(a.get_tree_hash().hex())
27
28
0
pub fn node_to_stream_backrefs<W: io::Write>(
29
0
    allocator: &Allocator,
30
0
    node: NodePtr,
31
0
    f: &mut W,
32
0
) -> io::Result<()> {
33
0
    let mut read_op_stack: Vec<ReadOp> = vec![ReadOp::Parse];
34
0
    let mut write_stack: Vec<NodePtr> = vec![node];
35
0
36
0
    let mut read_cache_lookup = ReadCacheLookup::new();
37
0
38
0
    let mut thc = ObjectCache::new(allocator, treehash);
39
0
    let mut slc = ObjectCache::new(allocator, serialized_length);
40
41
0
    while let Some(node_to_write) = write_stack.pop() {
42
0
        let op = read_op_stack.pop();
43
0
        assert!(op == Some(ReadOp::Parse));
44
45
0
        let node_serialized_length = *slc
46
0
            .get_or_calculate(&node_to_write)
47
0
            .expect("couldn't calculate serialized length");
48
0
        let node_tree_hash = thc
49
0
            .get_or_calculate(&node_to_write)
50
0
            .expect("can't get treehash");
51
0
        match read_cache_lookup.find_path(node_tree_hash, node_serialized_length) {
52
0
            Some(path) => {
53
0
                f.write_all(&[BACK_REFERENCE])?;
54
0
                write_atom(f, &path)?;
55
0
                read_cache_lookup.push(*node_tree_hash);
56
            }
57
0
            None => match allocator.sexp(node_to_write) {
58
0
                SExp::Pair(left, right) => {
59
0
                    f.write_all(&[CONS_BOX_MARKER])?;
60
0
                    write_stack.push(right);
61
0
                    write_stack.push(left);
62
0
                    read_op_stack.push(ReadOp::Cons);
63
0
                    read_op_stack.push(ReadOp::Parse);
64
0
                    read_op_stack.push(ReadOp::Parse);
65
                }
66
                SExp::Atom => {
67
0
                    let atom = allocator.atom(node_to_write);
68
0
                    write_atom(f, atom.as_ref())?;
69
0
                    read_cache_lookup.push(*node_tree_hash);
70
                }
71
            },
72
        }
73
0
        while !read_op_stack.is_empty() && read_op_stack[read_op_stack.len() - 1] == ReadOp::Cons {
74
0
            read_op_stack.pop();
75
0
            read_cache_lookup.pop2_and_cons();
76
0
        }
77
    }
78
0
    Ok(())
79
0
}
Unexecuted instantiation: _RINvNtNtCs4RkbDk9WRL5_5clvmr5serde6ser_br23node_to_stream_backrefsINtNtB4_3ser13LimitedWriterINtNtNtCsVNp5ty2IzJ_3std2io6cursor6CursorINtNtCsiBl6Lc3cFal_5alloc3vec3VechEEEEB6_
Unexecuted instantiation: _RINvNtNtCs4RkbDk9WRL5_5clvmr5serde6ser_br23node_to_stream_backrefsINtNtNtCsVNp5ty2IzJ_3std2io6cursor6CursorINtNtCsiBl6Lc3cFal_5alloc3vec3VechEEEB6_
80
81
0
pub fn node_to_bytes_backrefs_limit(
82
0
    a: &Allocator,
83
0
    node: NodePtr,
84
0
    limit: usize,
85
0
) -> io::Result<Vec<u8>> {
86
0
    let buffer = Cursor::new(Vec::new());
87
0
    let mut writer = LimitedWriter::new(buffer, limit);
88
0
    node_to_stream_backrefs(a, node, &mut writer)?;
89
0
    let vec = writer.into_inner().into_inner();
90
0
    Ok(vec)
91
0
}
92
93
0
pub fn node_to_bytes_backrefs(a: &Allocator, node: NodePtr) -> io::Result<Vec<u8>> {
94
0
    let mut buffer = Cursor::new(Vec::new());
95
0
    node_to_stream_backrefs(a, node, &mut buffer)?;
96
0
    let vec = buffer.into_inner();
97
0
    Ok(vec)
98
0
}
99
100
#[test]
101
fn test_serialize_limit() {
102
    let mut a = Allocator::new();
103
104
    let leaf = a.new_atom(&[1, 2, 3, 4, 5]).unwrap();
105
    let l1 = a.new_pair(leaf, leaf).unwrap();
106
    let l2 = a.new_pair(l1, l1).unwrap();
107
    let l3 = a.new_pair(l2, l2).unwrap();
108
109
    let expected = &[255, 255, 255, 133, 1, 2, 3, 4, 5, 254, 2, 254, 2, 254, 2];
110
111
    {
112
        assert_eq!(node_to_bytes_backrefs(&a, l3).unwrap(), expected);
113
    }
114
115
    {
116
        assert_eq!(node_to_bytes_backrefs_limit(&a, l3, 15).unwrap(), expected);
117
    }
118
119
    {
120
        assert_eq!(
121
            node_to_bytes_backrefs_limit(&a, l3, 14).unwrap_err().kind(),
122
            io::ErrorKind::OutOfMemory
123
        );
124
    }
125
}
/home/oof/clvm_rs/src/serde/tools.rs
Line
Count
Source
1
use std::io;
2
use std::io::{Cursor, Read, Seek, SeekFrom};
3
4
use super::errors::bad_encoding;
5
use super::parse_atom::decode_size;
6
7
const MAX_SINGLE_BYTE: u8 = 0x7f;
8
const BACK_REFERENCE: u8 = 0xfe;
9
const CONS_BOX_MARKER: u8 = 0xff;
10
11
0
pub fn serialized_length_from_bytes_trusted(b: &[u8]) -> io::Result<u64> {
12
0
    let mut f = Cursor::new(b);
13
0
    let mut ops_counter = 1;
14
0
    let mut b = [0; 1];
15
0
    while ops_counter > 0 {
16
0
        ops_counter -= 1;
17
0
        f.read_exact(&mut b)?;
18
0
        if b[0] == CONS_BOX_MARKER {
19
0
            // we expect to parse two more items from the stream
20
0
            // the left and right sub tree
21
0
            ops_counter += 2;
22
0
        } else if b[0] == BACK_REFERENCE {
23
            // This is a back-ref. We don't actually need to resolve it, just
24
            // parse the path and move on
25
0
            let mut first_byte = [0; 1];
26
0
            f.read_exact(&mut first_byte)?;
27
0
            if first_byte[0] > MAX_SINGLE_BYTE {
28
0
                let path_size = decode_size(&mut f, first_byte[0])?;
29
0
                f.seek(SeekFrom::Current(path_size as i64))?;
30
0
                if (f.get_ref().len() as u64) < f.position() {
31
0
                    return Err(bad_encoding());
32
0
                }
33
0
            }
34
0
        } else if b[0] == 0x80 || b[0] <= MAX_SINGLE_BYTE {
35
0
            // This one byte we just read was the whole atom.
36
0
            // or the special case of NIL
37
0
        } else {
38
0
            let blob_size = decode_size(&mut f, b[0])?;
39
0
            f.seek(SeekFrom::Current(blob_size as i64))?;
40
0
            if (f.get_ref().len() as u64) < f.position() {
41
0
                return Err(bad_encoding());
42
0
            }
43
        }
44
    }
45
0
    Ok(f.position())
46
0
}
47
48
use crate::sha2::Sha256;
49
50
0
fn hash_atom(buf: &[u8]) -> [u8; 32] {
51
0
    let mut ctx = Sha256::new();
52
0
    ctx.update([1_u8]);
53
0
    ctx.update(buf);
54
0
    ctx.finalize()
55
0
}
56
57
0
fn hash_pair(left: &[u8; 32], right: &[u8; 32]) -> [u8; 32] {
58
0
    let mut ctx = Sha256::new();
59
0
    ctx.update([2_u8]);
60
0
    ctx.update(left);
61
0
    ctx.update(right);
62
0
    ctx.finalize()
63
0
}
64
65
#[repr(u8)]
66
enum ParseOp {
67
    SExp,
68
    Cons,
69
}
70
71
// computes the tree-hash of a CLVM structure in serialized form
72
0
pub fn tree_hash_from_stream(f: &mut Cursor<&[u8]>) -> io::Result<[u8; 32]> {
73
0
    let mut values: Vec<[u8; 32]> = Vec::new();
74
0
    let mut ops = vec![ParseOp::SExp];
75
0
76
0
    let mut b = [0; 1];
77
0
    while let Some(op) = ops.pop() {
78
0
        match op {
79
            ParseOp::SExp => {
80
0
                f.read_exact(&mut b)?;
81
0
                if b[0] == CONS_BOX_MARKER {
82
0
                    ops.push(ParseOp::Cons);
83
0
                    ops.push(ParseOp::SExp);
84
0
                    ops.push(ParseOp::SExp);
85
0
                } else if b[0] == 0x80 {
86
0
                    values.push(hash_atom(&[]));
87
0
                } else if b[0] <= MAX_SINGLE_BYTE {
88
0
                    values.push(hash_atom(&b));
89
0
                } else {
90
0
                    let blob_size = decode_size(f, b[0])?;
91
0
                    let blob = &f.get_ref()[f.position() as usize..];
92
0
                    if (blob.len() as u64) < blob_size {
93
0
                        return Err(bad_encoding());
94
0
                    }
95
0
                    f.set_position(f.position() + blob_size);
96
0
                    values.push(hash_atom(&blob[..blob_size as usize]));
97
                }
98
            }
99
0
            ParseOp::Cons => {
100
0
                // cons
101
0
                let v2 = values.pop();
102
0
                let v1 = values.pop();
103
0
                values.push(hash_pair(&v1.unwrap(), &v2.unwrap()));
104
0
            }
105
        }
106
    }
107
0
    Ok(values.pop().unwrap())
108
0
}
109
110
/// validate that a buffer is a valid CLVM serialization, and return the length
111
/// of the CLVM object. This may fail if the serialization contains an invalid
112
/// back-reference or if the buffer is truncated.
113
0
pub fn serialized_length_from_bytes(b: &[u8]) -> io::Result<u64> {
114
    use crate::serde::parse_atom::parse_path;
115
    use crate::traverse_path::traverse_path;
116
    use crate::{allocator::SExp, Allocator};
117
118
0
    let mut f = Cursor::new(b);
119
0
    let mut b = [0; 1];
120
0
121
0
    // the allocator is just used to track the tree structure, in order to
122
0
    // validate back-references
123
0
    let mut allocator = Allocator::new();
124
0
    let nil = allocator.nil();
125
0
    let mut values = nil;
126
0
    let mut ops = vec![ParseOp::SExp];
127
128
0
    while let Some(op) = ops.pop() {
129
0
        match op {
130
            ParseOp::SExp => {
131
0
                f.read_exact(&mut b)?;
132
0
                if b[0] == CONS_BOX_MARKER {
133
0
                    ops.push(ParseOp::Cons);
134
0
                    ops.push(ParseOp::SExp);
135
0
                    ops.push(ParseOp::SExp);
136
0
                } else if b[0] == BACK_REFERENCE {
137
0
                    let path = parse_path(&mut f)?;
138
0
                    let back_reference = traverse_path(&allocator, path, values)?.1;
139
0
                    values = allocator.new_pair(back_reference, values)?;
140
0
                } else if b[0] == 0x80 || b[0] <= MAX_SINGLE_BYTE {
141
                    // This one byte we just read was the whole atom.
142
                    // or the special case of NIL
143
0
                    values = allocator.new_pair(nil, values)?;
144
                } else {
145
0
                    let blob_size = decode_size(&mut f, b[0])?;
146
0
                    f.seek(SeekFrom::Current(blob_size as i64))?;
147
0
                    if (f.get_ref().len() as u64) < f.position() {
148
0
                        return Err(bad_encoding());
149
0
                    }
150
0
                    values = allocator.new_pair(nil, values)?;
151
                }
152
            }
153
            ParseOp::Cons => {
154
                // cons
155
0
                let SExp::Pair(v1, v2) = allocator.sexp(values) else {
156
0
                    return Err(bad_encoding());
157
                };
158
159
0
                let SExp::Pair(v3, v4) = allocator.sexp(v2) else {
160
0
                    return Err(bad_encoding());
161
                };
162
163
0
                let new_root = allocator.new_pair(v3, v1)?;
164
0
                values = allocator.new_pair(new_root, v4)?;
165
            }
166
        }
167
    }
168
0
    match allocator.sexp(values) {
169
0
        SExp::Pair(_, _) => Ok(f.position()),
170
0
        _ => Err(bad_encoding()),
171
    }
172
0
}
173
174
#[test]
175
fn test_tree_hash_max_single_byte() {
176
    let mut ctx = Sha256::new();
177
    ctx.update([1_u8]);
178
    ctx.update([0x7f_u8]);
179
    let mut cursor = Cursor::<&[u8]>::new(&[0x7f_u8]);
180
    assert_eq!(
181
        tree_hash_from_stream(&mut cursor).unwrap(),
182
        ctx.finalize().as_slice()
183
    );
184
}
185
186
#[test]
187
fn test_tree_hash_one() {
188
    let mut ctx = Sha256::new();
189
    ctx.update([1_u8]);
190
    ctx.update([1_u8]);
191
    let mut cursor = Cursor::<&[u8]>::new(&[1_u8]);
192
    assert_eq!(
193
        tree_hash_from_stream(&mut cursor).unwrap(),
194
        ctx.finalize().as_slice()
195
    );
196
}
197
198
#[test]
199
fn test_tree_hash_zero() {
200
    let mut ctx = Sha256::new();
201
    ctx.update([1_u8]);
202
    ctx.update([0_u8]);
203
    let mut cursor = Cursor::<&[u8]>::new(&[0_u8]);
204
    assert_eq!(
205
        tree_hash_from_stream(&mut cursor).unwrap(),
206
        ctx.finalize().as_slice()
207
    );
208
}
209
210
#[test]
211
fn test_tree_hash_nil() {
212
    let mut ctx = Sha256::new();
213
    ctx.update([1_u8]);
214
    let mut cursor = Cursor::<&[u8]>::new(&[0x80_u8]);
215
    assert_eq!(
216
        tree_hash_from_stream(&mut cursor).unwrap(),
217
        ctx.finalize().as_slice()
218
    );
219
}
220
221
#[test]
222
fn test_tree_hash_overlong() {
223
    let mut cursor = Cursor::<&[u8]>::new(&[0x8f, 0xff]);
224
    let e = tree_hash_from_stream(&mut cursor).unwrap_err();
225
    assert_eq!(e.kind(), bad_encoding().kind());
226
227
    let mut cursor = Cursor::<&[u8]>::new(&[0b11001111, 0xff]);
228
    let e = tree_hash_from_stream(&mut cursor).unwrap_err();
229
    assert_eq!(e.kind(), bad_encoding().kind());
230
231
    let mut cursor = Cursor::<&[u8]>::new(&[0b11001111, 0xff, 0, 0]);
232
    let e = tree_hash_from_stream(&mut cursor).unwrap_err();
233
    assert_eq!(e.kind(), bad_encoding().kind());
234
}
235
236
#[cfg(test)]
237
use hex::FromHex;
238
239
// these test cases were produced by:
240
241
// from chia.types.blockchain_format.program import Program
242
// a = Program.to(...)
243
// print(bytes(a).hex())
244
// print(a.get_tree_hash().hex())
245
246
#[test]
247
fn test_tree_hash_list() {
248
    // this is the list (1 (2 (3 (4 (5 ())))))
249
    let buf = Vec::from_hex("ff01ff02ff03ff04ff0580").unwrap();
250
    let mut cursor = Cursor::<&[u8]>::new(&buf);
251
    assert_eq!(
252
        tree_hash_from_stream(&mut cursor).unwrap().to_vec(),
253
        Vec::from_hex("123190dddde51acfc61f48429a879a7b905d1726a52991f7d63349863d06b1b6").unwrap()
254
    );
255
}
256
257
#[test]
258
fn test_tree_hash_tree() {
259
    // this is the tree ((1, 2), (3, 4))
260
    let buf = Vec::from_hex("ffff0102ff0304").unwrap();
261
    let mut cursor = Cursor::<&[u8]>::new(&buf);
262
    assert_eq!(
263
        tree_hash_from_stream(&mut cursor).unwrap().to_vec(),
264
        Vec::from_hex("2824018d148bc6aed0847e2c86aaa8a5407b916169f15b12cea31fa932fc4c8d").unwrap()
265
    );
266
}
267
268
#[test]
269
fn test_tree_hash_tree_large_atom() {
270
    // this is the tree ((1, 2), (3, b"foobar"))
271
    let buf = Vec::from_hex("ffff0102ff0386666f6f626172").unwrap();
272
    let mut cursor = Cursor::<&[u8]>::new(&buf);
273
    assert_eq!(
274
        tree_hash_from_stream(&mut cursor).unwrap().to_vec(),
275
        Vec::from_hex("b28d5b401bd02b65b7ed93de8e916cfc488738323e568bcca7e032c3a97a12e4").unwrap()
276
    );
277
}
278
279
#[cfg(test)]
280
mod test {
281
    use super::*;
282
    use crate::serde::node_from_bytes_backrefs;
283
    use crate::Allocator;
284
    use rstest::rstest;
285
286
    #[test]
287
    fn test_serialized_length_from_bytes_trusted() {
288
        assert_eq!(
289
            serialized_length_from_bytes_trusted(&[0x7f, 0x00, 0x00, 0x00]).unwrap(),
290
            1
291
        );
292
        assert_eq!(
293
            serialized_length_from_bytes_trusted(&[0x80, 0x00, 0x00, 0x00]).unwrap(),
294
            1
295
        );
296
        assert_eq!(
297
            serialized_length_from_bytes_trusted(&[0xff, 0x00, 0x00, 0x00]).unwrap(),
298
            3
299
        );
300
        assert_eq!(
301
            serialized_length_from_bytes_trusted(&[0xff, 0x01, 0xff, 0x80, 0x80, 0x00]).unwrap(),
302
            5
303
        );
304
305
        // this is an invalid back-ref
306
        // but it's not validated
307
        assert_eq!(
308
            serialized_length_from_bytes_trusted(&[0xff, 0x01, 0xff, 0xfe, 0x10, 0x80, 0x00])
309
                .unwrap(),
310
            6
311
        );
312
313
        let e = serialized_length_from_bytes_trusted(&[0x8f, 0xff]).unwrap_err();
314
        assert_eq!(e.kind(), bad_encoding().kind());
315
        assert_eq!(e.to_string(), "bad encoding");
316
317
        let e = serialized_length_from_bytes_trusted(&[0b11001111, 0xff]).unwrap_err();
318
        assert_eq!(e.kind(), bad_encoding().kind());
319
        assert_eq!(e.to_string(), "bad encoding");
320
321
        let e = serialized_length_from_bytes_trusted(&[0b11001111, 0xff, 0, 0]).unwrap_err();
322
        assert_eq!(e.kind(), bad_encoding().kind());
323
        assert_eq!(e.to_string(), "bad encoding");
324
325
        assert_eq!(
326
            serialized_length_from_bytes_trusted(&[
327
                0x8f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
328
            ])
329
            .unwrap(),
330
            16
331
        );
332
    }
333
334
    #[test]
335
    fn test_serialized_length_from_bytes() {
336
        use std::io::ErrorKind;
337
        assert_eq!(
338
            serialized_length_from_bytes(&[0x7f, 0x00, 0x00, 0x00]).unwrap(),
339
            1
340
        );
341
        assert_eq!(
342
            serialized_length_from_bytes(&[0x80, 0x00, 0x00, 0x00]).unwrap(),
343
            1
344
        );
345
        assert_eq!(
346
            serialized_length_from_bytes(&[0xff, 0x00, 0x00, 0x00]).unwrap(),
347
            3
348
        );
349
        assert_eq!(
350
            serialized_length_from_bytes(&[0xff, 0x01, 0xff, 0x80, 0x80, 0x00]).unwrap(),
351
            5
352
        );
353
354
        // this is an invalid back-ref
355
        let e =
356
            serialized_length_from_bytes(&[0xff, 0x01, 0xff, 0xfe, 0x10, 0x80, 0x00]).unwrap_err();
357
        assert_eq!(e.kind(), ErrorKind::Other);
358
        assert_eq!(e.to_string(), "path into atom");
359
360
        let e = serialized_length_from_bytes(&[0x8f, 0xff]).unwrap_err();
361
        assert_eq!(e.kind(), bad_encoding().kind());
362
        assert_eq!(e.to_string(), "bad encoding");
363
364
        let e = serialized_length_from_bytes(&[0b11001111, 0xff]).unwrap_err();
365
        assert_eq!(e.kind(), bad_encoding().kind());
366
        assert_eq!(e.to_string(), "bad encoding");
367
368
        let e = serialized_length_from_bytes(&[0b11001111, 0xff, 0, 0]).unwrap_err();
369
        assert_eq!(e.kind(), bad_encoding().kind());
370
        assert_eq!(e.to_string(), "bad encoding");
371
372
        assert_eq!(
373
            serialized_length_from_bytes(&[0x8f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
374
                .unwrap(),
375
            16
376
        );
377
    }
378
379
    #[rstest]
380
    // ("foobar" "foobar")
381
    #[case("ff86666f6f626172ff86666f6f62617280")]
382
    // ("foobar" "foobar")
383
    #[case("ff86666f6f626172fe01")]
384
    // ((1 2 3 4) 1 2 3 4)
385
    #[case("ffff01ff02ff03ff0480ff01ff02ff03ff0480")]
386
    // ((1 2 3 4) 1 2 3 4)
387
    #[case("ffff01ff02ff03ff0480fe02")]
388
    // `(((((a_very_long_repeated_string . 1) .  (2 . 3)) . ((4 . 5) .  (6 . 7))) . (8 . 9)) 10 a_very_long_repeated_string)`
389
    #[case(
390
        "ffffffffff9b615f766572795f6c6f6e675f72657065617465645f737472696e6701ff0203ffff04\
391
05ff0607ff0809ff0aff9b615f766572795f6c6f6e675f72657065617465645f737472696e6780"
392
    )]
393
    #[case("ffffffffff9b615f766572795f6c6f6e675f72657065617465645f737472696e6701ff0203ffff0405ff0607ff0809ff0afffe4180")]
394
    #[case(
395
        "ff01ffffffa022cf3c17be4e0e0e0b2e2a3f6dd1ee955528f737f0cb724247bc2e4a776cb989ff\
396
ff02ffff01ff02ffff01ff02ffff03ffff18ff2fffff010180ffff01ff02ff36ffff04ff02ffff\
397
04ff05ffff04ff17ffff04ffff02ff26ffff04ff02ffff04ff0bff80808080ffff04ff2fffff04\
398
ff0bffff04ff5fff808080808080808080ffff01ff088080fe81ffffff04ffff01ffffffff4602\
399
ff3304ffff0101ff02ffff02ffff03ff05ffff01ff02ff5cffff04ff02ffff04ff0dffff04ffff\
400
0bff2cffff0bff24ff3880ffff0bff2cffff0bff2cffff0bff24ff3480ff0980ffff0bff2cff0b\
401
ffff0bff24ff8080808080ff8080808080ffff010b80ff0180ff02ffff03ff0bffff01ff02ff32\
402
ffff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04ffff02ff2affff04ff02ffff04ffff02\
403
ffff03ffff09ff23ff2880ffff0181b3ff8080ff0180fe7a8080ff80808080808080ffff01ff02\
404
ffff03ff17ff80fe837b7fffff018080fe3bffffffff0bffff0bff17ffff02ff3affff04ff02ff\
405
ff04ff09ffff04ff2fffff04ffff02ff26ffff04ff02ffff04ff05ff80808080ff808080808080\
406
ff5f80ff0bff81bf80ff02ffff03ffff20ffff22ff4fff178080ffff01ff02ff7effff04ff02ff\
407
ff04ff6fffff04ffff04ffff02ffff03ff4fffff01ff04ff23ffff04ffff02ff3affff04ff02ff\
408
ff04ff09ffff04ff53fe861db6d7ffffff808080ffff04ff81b3ff80808080ffff011380ff0180\
409
ffff02ff7cffff04ff02ffff04ff05ffff04ff1bffff04ffff21ff4fff1780ff80808080808080\
410
ff8080808080fe82f6ffff0180ffff04ffff09ffff18ff05fe8301d6fffe0effff09ff05ffff01\
411
818f8080ff0bff2cffff0bff24ff3080ffff0bff2cffff0bff2cffff0bff24ff3480ff0580ffff\
412
0bff2cffff02ff5cffff04ff02ffff04ff07ffff04ffff0bff24ff2480ff8080808080fe861eee\
413
b6ed77ff8080ffffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff26ffff04ff02ff\
414
ff04ff09ff80808080ffff02ff26ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101\
415
fe6f80ff0180ff02ff5effff04ff02ffff04ff05ffff04ff0bffff04ffff02ff3affff04ff02ff\
416
ff04ff09ffff04ff17fe853b6da3ffff808080ffff04ff17ffff04ff2fffff04ff5fffff04ff81\
417
bfff80808080808080808080ffff04ffff04ff20ffff04ff17ff808080ffff02ff7cffff04ff02\
418
ffff04ff05ffff04ffff02ff82017fffff04ffff04ffff04ff17ff2f80ffff04ffff04ff5fff81\
419
bf80ffff04ff0bff05808080ff8202ff8080ffff01ff80808080808080ffff02ff2effff04ff02\
420
ffff04ff05ffff04ff0bffff04ffff02ffff03ff3bffff01ff02ff22ffff04ff02ffff04ff05ff\
421
ff04ff17ffff04ff13ffff04ff2bffff04ff5bffff04ff5fff808080808080808080ffff01ff02\
422
ffff03ffff09ff15ffff0bff13ff1dff2b8080ffff01ff0bff15ff17ff5f80fe841ecfffffff01\
423
8080ff0180ffff04ff17ffff04ff2fffff04ff5fffff04ff81bfffff04ff82017fff8080808080\
424
808080808080ff02ffff03ff05ffff011bfe8307aeffff0180fe7b80ffff04ffff01ffa024e044\
425
101e57b3d8c908b8a38ad57848afd29d3eecc439dba45f4412df4954fdffa0f08eda9271f9dd1c\
426
00d9789ba0f3e4f547d66c8ad6f75edbb587b8c68d8ef5f1a0eff07522495060c066f66f32acc2\
427
a77e3a3e737aca8baea4d1a64ea4cdc13da9ffff04ffff01ff02ffff01ff02ffff01ff02ffff03\
428
ff8202ffffff01ff02ff16ffff04ff02ffff04ff05ffff04ff8204bfffff04ff8206bfffff04ff\
429
82017fffff04ffff0bffff19ff2fffff18ffff019100ffffffffffffffffffffffffffffffffff\
430
8202ff8080ff0bfffe2f80ff8080808080808080ffff01ff04ffff04ff08ffff04ff17ffff04ff\
431
ff02ff1effff04ff02fe8876db6db7d77fffff80ff80808080ffff04ffff04ff1cffff04ff5fff\
432
ff04ff8206bfff80808080ff80808080ff0180ffff04ffff01ffff32ff3d33ff3effff04ffff04\
433
ff1cffff04ff0bfe8503af5dffff80ffff04ffff04ff1cffff04ff05ffff04ff2fff80808080ff\
434
ff04ffff04ff0afe87076db6edb7ffffffff04ffff04ff14ffff04ffff0bff5fffff012480ff80\
435
8080fe76808080ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff1efe861dda75dfff\
436
ffffff02ff1efe8677b4ebbfffff80fe8507a75dffffff0180fe7b80ffff04ffff01a02f2c9ba1\
437
b2315d413a92b5f034fa03282ccba1767fd9ae7b14d942b969ed5d57ffff04ffff01a0c4a8fb8a\
438
651c5e8636c6dd67ed8c8f7a70f516f41ab73abd14dd79c7582f079affff04ffff01b08116639d\
439
853ecd6109277a9d83d3acc7e53a18d3524262ec9b99df923d22a390cbf0f632bced556dd9886b\
440
bf53f444b6ffff04ffff01a0ccd5bb71183532bff220ba46c268991a0000000000000000000000\
441
0000000000ffff04ffff01a022c0df3c66541eb57c226e12742a9f7182ceb0318cdaf5a84facb6\
442
c80bfaac1aff01808080808080fe81ff8080ff01ffffffa01daef44c653c413eba01d89790edfb\
443
613cb020ed0979d8447d6ed398327d0958ffa0976299e4fbb74e8732ae1ea7092ab617af435218\
444
f20912f99689d8fc69d12318fe3fff01ffffffff70c07101022f2c9ba1b2315d413a92b5f034fa\
445
03282ccba1767fd9ae7b14d942b969ed5d578116639d853ecd6109277a9d83d3acc7e53a18d352\
446
4262ec9b99df923d22a390cbf0f632bced556dd9886bbf53f444b6010000001668747470733a2f\
447
2f6575312e706f6f6c2e73706163650000004080ff80808080ffffa0e8058c610f8f50e5e603ad\
448
136f58ff3b1f0120a76bb4985553db8bda88738ca9ffff02fffe81abffff04ffff01fffe82ab5f\
449
ffa0df84418c7ba1b1a847fa23bd1101fcee22b2bd81c69d10e6d4b280f09eba2c70fe8307ad7f\
450
ffff04ffff01ff02fffe835adaffffff04fffe840aeb6bffffff04ffff01a09c117e3fba164415\
451
fb868361a5c6d9c8a4551c71e5a359807cb27810b80f23bdffff04ffff01b08a505367d099210c\
452
24f1be8945a83de7db6d9396a9742c8f609aebf7ba56bbaacb038819b122741211bbc9227c9035\
453
73ffff04fffe86056dbadaffffffff04ffff01a0a78f9cbed5f7e1b529aa32088dcc3c53ac1df5\
454
7bd0c8f4773f4c0ddae048a8edff01808080808080ff01808080ff01ffffffa0245c7e4ad426a2\
455
a6b6eb5622286d2fd8178fca04cdb9a23aeb8da08ae6d6e6c0ffa0c79f2213f98b1ac6bfa141b6\
456
724138223236e89ae456e6c6727f8709e4b28ed6fe7fff01ffffffff70c07101022f2c9ba1b231\
457
5d413a92b5f034fa03282ccba1767fd9ae7b14d942b969ed5d578a505367d099210c24f1be8945\
458
a83de7db6d9396a9742c8f609aebf7ba56bbaacb038819b122741211bbc9227c90357301000000\
459
1668747470733a2f2f6e61312e706f6f6c2e73706163650000004080ff80808080ffffa0bc334d\
460
2f6b030790debd7e4a998a38d0628b2b853fa7895db16ce14da37c441dffff02fffe81abffff04\
461
ffff01fffe82ab5fffa01a3272c823c1175f83016303bfd33823687df39736e2b7eaf9057f0067\
462
1d9f97fe8307ad7fffff04ffff01ff02fffe835adaffffff04ffff01a09d9c5296f00b89c2271a\
463
b4a00f249ab3a0106d8d73dd02242f3ea6357b4cde04ffff04ffff01a0e691c76d0108a7a7a445\
464
91b3784ecf4099bf5fb057173a0bb2f79fdfa2ed9fceffff04ffff01b0ab6824901d856c5a8c16\
465
64c990d1ef94a19ed7b4ab28a6b8e064f1a11e07f5e75bdb6ff8242f517534df36ae03c81da0ff\
466
ff04fffe86056dbadaffffffff04ffff01a0ab43e98b62a2dc33caf0b16fb5a3c037e3303fc8e1\
467
77ddf437eef233c87d32f2ff01808080808080ff01808080ff01ffffffa00afb9bf9c6a13d380c\
468
9645ae07e466bf71a171ae6fe35bc3a7ac5fb5df53a937ffa0cec914e2de9e524237e7a76f3d48\
469
3a9cf1674be213d4c5bf51fe28b6dab92898ff0180ff01ffffffff70c07001029d9c5296f00b89\
470
c2271ab4a00f249ab3a0106d8d73dd02242f3ea6357b4cde04ab6824901d856c5a8c1664c990d1\
471
ef94a19ed7b4ab28a6b8e064f1a11e07f5e75bdb6ff8242f517534df36ae03c81da00100000015\
472
68747470733a2f2f636869612e64706f6f6c2e63630000002080ff80808080ffffa07016fd25c1\
473
4831bfe48a08cd3cd9eeb6d416436087252e1061e62cdc95cc892affff02fffe81abffff04ffff\
474
01fffe82ab5fffa0cb75e5c90f2ab4bdf1db8a420e56e9edb261b919b73a6f8756453c07d73d43\
475
0ffe8307ad7fffff04ffff01ff02ffff01ff02ffff01ff02ffff03ff82017fffff01ff04ffff04\
476
ff1cfe8676db6edb7fffffff04ffff04ff12ffff04ff8205fffe8803b5ddb6b6bfffff80ffff04\
477
ffff04ff08ffff04ff17ffff04ffff02ff1effff04ff02ffff04ffff04ff8205ffffff04ff8202\
478
ffff808080fe768080ff80808080ff80808080ffff01ff02ff16ffff04ff02ffff04ff05ffff04\
479
ff8204bfffff04ff8206bfffff04ff8202ffffff04ffff0bffff19ff2fffff18fffe8b15ab6db7\
480
6db5b5ffffffffff8205ff8080ff0bfffe2f80ff808080808080808080ff0180ffff04ffff01ff\
481
ff32ff3d52ffff333effff04ffff04ff12fe8675d76b6bffffffff04ffff04ff12fe870eb75dad\
482
afffffffff04ffff04ff1afe83edb7fffe873b6ebb5b5fffff8080fe8601f5dadafffffe7b80ff\
483
ff04fffe840aeb6bffffff04ffff01a0a219765e3616e24fb86a7ddace966d0aacfcdb8d8b6823\
484
e9760e6b4a0469e07affff04ffff01b0afdbc8d2811665196a20931b06ffe981a2ec64aebd2d91\
485
7478bf8441d77cb2b62f96194277d91983c5ca9edf0a17fdccffff04fffe86056dbadaffffffff\
486
04ffff0120ff01808080808080ff01808080ff01ffffffa0b3957791c7e84aa27e759b217ef972\
487
85c3c260b0410f230679a00a346ee695b4ffa03732f9605848b5ee1fe700dd36aab3aa23110d35\
488
c0e5917676d042883330c39aff0180ff01ffff01ffffff70c0570101016127e457a90eb1229665\
489
8006a7928d5acffbe3c707b705177efe504d1beae0afdbc8d2811665196a20931b06ffe981a2ec\
490
64aebd2d917478bf8441d77cb2b62f96194277d91983c5ca9edf0a17fdcc000000000080ffa062\
491
e47157eea5430b839a8fcd8390ce3c162b61acd19f94eeb97db81d7622a52e808080ffffa0b63a\
492
7ce25b1050bfd97a9e4e67fcf42ca6545eaf392a13c67307ee3614e59bc2ffff02fffe81abffff\
493
04ffff01fffe82ab5fffa05a7cdf809298a6c314bfd6ec63c6761b396fca802c0067d87de23644\
494
d17a8bb5fe8307ad7fffff04ffff01ff02fffe835adaffffff04fffe840aeb6bffffff04ffff01\
495
a06dd75452b3a13128591f83a68263fb0dc9bedfb519af3af01933782ae65dca1bffff04ffff01\
496
b08e2ab4bd0f4b65f0e6e1cc1f54fd3a953a36afc98ec25a741958bf1f19d0a416f2b39b89d4bd\
497
9870f11d6bf09030780efe8576dd6d7fff808080ff01808080ff01ffffffa0f447a4cda2bd4e2c\
498
14398f96d1402e8ed0c35302b0c57f8219861d9433ba150cffa0eb4e5fc93add634ac692d2c28b\
499
0eed8dcdca399639cd7986dc6879c7a872e5f4ff0180ff01ffff01ffffff70c07701030213db9c\
500
b540a52c39071ef70acdf81796303189061b5aa0ee8098a05d5ceff58e2ab4bd0f4b65f0e6e1cc\
501
1f54fd3a953a36afc98ec25a741958bf1f19d0a416f2b39b89d4bd9870f11d6bf09030780e0100\
502
00001c68747470733a2f2f7669702e746565706f6f6c2e636f6d3a393434330000002080ffa0a6\
503
322ec0a3d445a051349cf8289660b2d9686608484ecb42c135fd5bd4ea4b11808080ffffa077c5\
504
2e138369b3a545a59f3daf2904197f350010676506eead7f5875f511f063ffff02fffe81abffff\
505
04ffff01fffe82ab5fffa00485de73367a4b49eb34c7f80df3c9b70c739411d40632428e42495d\
506
a7c0ba91fe8307ad7fffff04ffff01ff02fffe835adaffffff04fffe840aeb6bffffff04ffff01\
507
a0671ce6fd24697788441f93773e5905c1f1153ba7f5d3fbb6a4e2855a05b42731ffff04ffff01\
508
b0a5383a3b9a6c1a94a85e4f982e1fa3af2c99087e5f6df8b887d30c109f71043671683a1ae985\
509
d7d874fbe07dfa6d88b7fe8576dd6d7fff808080ff01808080ff01ffffffa01dc8c9c3356a6eef\
510
ee37744901b3f730c710052bd38deac264ecea45460faffeffa031460205316513dc6b11d09934\
511
62776f0994223cac2f215bf8afbeae5a0cce3fff0180ff01ffff01ffffff70c0730103e3b9adc4\
512
eb09d18d83bd56482aee566820f5afdce595b3ed095eb36c5cef9301a5383a3b9a6c1a94a85e4f\
513
982e1fa3af2c99087e5f6df8b887d30c109f71043671683a1ae985d7d874fbe07dfa6d88b70100\
514
00001868747470733a2f2f6368696170702e68706f6f6c2e636f6d0000004080ffa0fc0b1e9409\
515
ae5c3c40c50832a7aecc0b3ba4646568a00c01289c45e1f03b2b488080808080"
516
    )]
517
    fn serialized_length_with_backrefs(#[case] serialization_as_hex: &str) {
518
        let buf = Vec::from_hex(serialization_as_hex).unwrap();
519
        let len = serialized_length_from_bytes(&buf).expect("serialized_length_from_bytes");
520
521
        // make sure the serialization is valid
522
        let mut allocator = Allocator::new();
523
        assert!(node_from_bytes_backrefs(&mut allocator, &buf).is_ok());
524
525
        assert_eq!(len, buf.len() as u64);
526
    }
527
}
/home/oof/clvm_rs/src/serde/utils.rs
Line
Count
Source
1
use std::io;
2
use std::io::{copy, sink, Error, Read, Write};
3
4
0
pub fn copy_exactly<R: Read, W: ?Sized + Write>(
5
0
    reader: &mut R,
6
0
    writer: &mut W,
7
0
    expected_size: u64,
8
0
) -> io::Result<()> {
9
0
    let mut reader = reader.by_ref().take(expected_size);
10
11
0
    let count = copy(&mut reader, writer)?;
12
0
    if count < expected_size {
13
0
        Err(Error::new(
14
0
            std::io::ErrorKind::UnexpectedEof,
15
0
            "copy terminated early",
16
0
        ))
17
    } else {
18
0
        Ok(())
19
    }
20
0
}
21
22
0
pub fn skip_bytes<R: Read>(f: &mut R, size: u64) -> io::Result<()> {
23
0
    copy_exactly(f, &mut sink(), size)
24
0
}
/home/oof/clvm_rs/src/serde/write_atom.rs
Line
Count
Source
1
use std::io;
2
use std::io::ErrorKind;
3
4
/// all atoms serialize their contents verbatim. All expect those one-byte atoms
5
/// from 0x00-0x7f also have a prefix encoding their length. This function
6
/// writes the correct prefix for an atom of size `size` whose first byte is `atom_0`.
7
/// If the atom is of size 0, use any placeholder first byte, as it's ignored anyway.
8
9
0
fn write_atom_encoding_prefix_with_size<W: io::Write>(
10
0
    f: &mut W,
11
0
    atom_0: u8,
12
0
    size: u64,
13
0
) -> io::Result<()> {
14
0
    if size == 0 {
15
0
        f.write_all(&[0x80])
16
0
    } else if size == 1 && atom_0 < 0x80 {
17
0
        Ok(())
18
0
    } else if size < 0x40 {
19
0
        f.write_all(&[0x80 | (size as u8)])
20
0
    } else if size < 0x2000 {
21
0
        f.write_all(&[0xc0 | (size >> 8) as u8, size as u8])
22
0
    } else if size < 0x10_0000 {
23
0
        f.write_all(&[
24
0
            (0xe0 | (size >> 16)) as u8,
25
0
            ((size >> 8) & 0xff) as u8,
26
0
            ((size) & 0xff) as u8,
27
0
        ])
28
0
    } else if size < 0x800_0000 {
29
0
        f.write_all(&[
30
0
            (0xf0 | (size >> 24)) as u8,
31
0
            ((size >> 16) & 0xff) as u8,
32
0
            ((size >> 8) & 0xff) as u8,
33
0
            ((size) & 0xff) as u8,
34
0
        ])
35
0
    } else if size < 0x4_0000_0000 {
36
0
        f.write_all(&[
37
0
            (0xf8 | (size >> 32)) as u8,
38
0
            ((size >> 24) & 0xff) as u8,
39
0
            ((size >> 16) & 0xff) as u8,
40
0
            ((size >> 8) & 0xff) as u8,
41
0
            ((size) & 0xff) as u8,
42
0
        ])
43
    } else {
44
0
        Err(io::Error::new(ErrorKind::InvalidData, "atom too big"))
45
    }
46
0
}
Unexecuted instantiation: _RINvNtNtCs4RkbDk9WRL5_5clvmr5serde10write_atom36write_atom_encoding_prefix_with_sizeINtNtB4_3ser13LimitedWriterINtNtNtCsVNp5ty2IzJ_3std2io6cursor6CursorINtNtCsiBl6Lc3cFal_5alloc3vec3VechEEEEB6_
Unexecuted instantiation: _RINvNtNtCs4RkbDk9WRL5_5clvmr5serde10write_atom36write_atom_encoding_prefix_with_sizeINtNtNtCsVNp5ty2IzJ_3std2io6cursor6CursorINtNtCsiBl6Lc3cFal_5alloc3vec3VechEEEB6_
47
48
/// serialize an atom
49
0
pub fn write_atom<W: io::Write>(f: &mut W, atom: &[u8]) -> io::Result<()> {
50
0
    let u8_0 = if !atom.is_empty() { atom[0] } else { 0 };
51
0
    write_atom_encoding_prefix_with_size(f, u8_0, atom.len() as u64)?;
52
0
    f.write_all(atom)
53
0
}
Unexecuted instantiation: _RINvNtNtCs4RkbDk9WRL5_5clvmr5serde10write_atom10write_atomINtNtB4_3ser13LimitedWriterINtNtNtCsVNp5ty2IzJ_3std2io6cursor6CursorINtNtCsiBl6Lc3cFal_5alloc3vec3VechEEEEB6_
Unexecuted instantiation: _RINvNtNtCs4RkbDk9WRL5_5clvmr5serde10write_atom10write_atomINtNtNtCsVNp5ty2IzJ_3std2io6cursor6CursorINtNtCsiBl6Lc3cFal_5alloc3vec3VechEEEB6_
54
55
#[test]
56
fn test_write_atom_encoding_prefix_with_size() {
57
    let mut buf = Vec::<u8>::new();
58
    assert!(write_atom_encoding_prefix_with_size(&mut buf, 0, 0).is_ok());
59
    assert_eq!(buf, vec![0x80]);
60
61
    for v in 0..0x7f {
62
        let mut buf = Vec::<u8>::new();
63
        assert!(write_atom_encoding_prefix_with_size(&mut buf, v, 1).is_ok());
64
        assert_eq!(buf, vec![]);
65
    }
66
67
    for v in 0x80..0xff {
68
        let mut buf = Vec::<u8>::new();
69
        assert!(write_atom_encoding_prefix_with_size(&mut buf, v, 1).is_ok());
70
        assert_eq!(buf, vec![0x81]);
71
    }
72
73
    for size in 0x1_u8..0x3f_u8 {
74
        let mut buf = Vec::<u8>::new();
75
        assert!(write_atom_encoding_prefix_with_size(&mut buf, 0xaa, size as u64).is_ok());
76
        assert_eq!(buf, vec![0x80 + size]);
77
    }
78
79
    let mut buf = Vec::<u8>::new();
80
    assert!(write_atom_encoding_prefix_with_size(&mut buf, 0xaa, 0b111111).is_ok());
81
    assert_eq!(buf, vec![0b10111111]);
82
83
    let mut buf = Vec::<u8>::new();
84
    assert!(write_atom_encoding_prefix_with_size(&mut buf, 0xaa, 0b1000000).is_ok());
85
    assert_eq!(buf, vec![0b11000000, 0b1000000]);
86
87
    let mut buf = Vec::<u8>::new();
88
    assert!(write_atom_encoding_prefix_with_size(&mut buf, 0xaa, 0xfffff).is_ok());
89
    assert_eq!(buf, vec![0b11101111, 0xff, 0xff]);
90
91
    let mut buf = Vec::<u8>::new();
92
    assert!(write_atom_encoding_prefix_with_size(&mut buf, 0xaa, 0xffffff).is_ok());
93
    assert_eq!(buf, vec![0b11110000, 0xff, 0xff, 0xff]);
94
95
    let mut buf = Vec::<u8>::new();
96
    assert!(write_atom_encoding_prefix_with_size(&mut buf, 0xaa, 0xffffffff).is_ok());
97
    assert_eq!(buf, vec![0b11111000, 0xff, 0xff, 0xff, 0xff]);
98
99
    // this is the largest possible atom size
100
    let mut buf = Vec::<u8>::new();
101
    assert!(write_atom_encoding_prefix_with_size(&mut buf, 0xaa, 0x3ffffffff).is_ok());
102
    assert_eq!(buf, vec![0b11111011, 0xff, 0xff, 0xff, 0xff]);
103
104
    // this is too large
105
    let mut buf = Vec::<u8>::new();
106
    assert!(write_atom_encoding_prefix_with_size(&mut buf, 0xaa, 0x400000000).is_err());
107
108
    for (size, expected_prefix) in [
109
        (0x1, vec![0x81]),
110
        (0x2, vec![0x82]),
111
        (0x3f, vec![0xbf]),
112
        (0x40, vec![0xc0, 0x40]),
113
        (0x1fff, vec![0xdf, 0xff]),
114
        (0x2000, vec![0xe0, 0x20, 0x00]),
115
        (0xf_ffff, vec![0xef, 0xff, 0xff]),
116
        (0x10_0000, vec![0xf0, 0x10, 0x00, 0x00]),
117
        (0x7ff_ffff, vec![0xf7, 0xff, 0xff, 0xff]),
118
        (0x800_0000, vec![0xf8, 0x08, 0x00, 0x00, 0x00]),
119
        (0x3_ffff_ffff, vec![0xfb, 0xff, 0xff, 0xff, 0xff]),
120
    ] {
121
        let mut buf = Vec::<u8>::new();
122
        assert!(write_atom_encoding_prefix_with_size(&mut buf, 0xaa, size).is_ok());
123
        assert_eq!(buf, expected_prefix);
124
    }
125
}
126
127
#[test]
128
fn test_write_atom() {
129
    let mut buf = Vec::<u8>::new();
130
    assert!(write_atom(&mut buf, &[]).is_ok());
131
    assert_eq!(buf, vec![0b10000000]);
132
133
    let mut buf = Vec::<u8>::new();
134
    assert!(write_atom(&mut buf, &[0x00]).is_ok());
135
    assert_eq!(buf, vec![0b00000000]);
136
137
    let mut buf = Vec::<u8>::new();
138
    assert!(write_atom(&mut buf, &[0x7f]).is_ok());
139
    assert_eq!(buf, vec![0x7f]);
140
141
    let mut buf = Vec::<u8>::new();
142
    assert!(write_atom(&mut buf, &[0x80]).is_ok());
143
    assert_eq!(buf, vec![0x81, 0x80]);
144
145
    let mut buf = Vec::<u8>::new();
146
    assert!(write_atom(&mut buf, &[0xff]).is_ok());
147
    assert_eq!(buf, vec![0x81, 0xff]);
148
149
    let mut buf = Vec::<u8>::new();
150
    assert!(write_atom(&mut buf, &[0xaa, 0xbb]).is_ok());
151
    assert_eq!(buf, vec![0x82, 0xaa, 0xbb]);
152
153
    for (size, mut expected_prefix) in [
154
        (0x1, vec![0x81]),
155
        (0x2, vec![0x82]),
156
        (0x3f, vec![0xbf]),
157
        (0x40, vec![0xc0, 0x40]),
158
        (0x1fff, vec![0xdf, 0xff]),
159
        (0x2000, vec![0xe0, 0x20, 0x00]),
160
        (0xf_ffff, vec![0xef, 0xff, 0xff]),
161
        (0x10_0000, vec![0xf0, 0x10, 0x00, 0x00]),
162
        (0x7ff_ffff, vec![0xf7, 0xff, 0xff, 0xff]),
163
        (0x800_0000, vec![0xf8, 0x08, 0x00, 0x00, 0x00]),
164
        // the next one represents 17 GB of memory, which it then has to serialize
165
        // so let's not do it until some time in the future when all machines have
166
        // 64 GB of memory
167
        // (0x3_ffff_ffff, vec![0xfb, 0xff, 0xff, 0xff, 0xff]),
168
    ] {
169
        let mut buf = Vec::<u8>::new();
170
        let atom = vec![0xaa; size];
171
        assert!(write_atom(&mut buf, &atom).is_ok());
172
        expected_prefix.extend(atom);
173
        assert_eq!(buf, expected_prefix);
174
    }
175
}
/home/oof/clvm_rs/src/sha2.rs
Line
Count
Source
1
#[cfg(feature = "openssl")]
2
use openssl;
3
4
#[cfg(not(feature = "openssl"))]
5
use sha2::Digest;
6
7
#[derive(Default, Clone)]
8
pub struct Sha256 {
9
    #[cfg(feature = "openssl")]
10
    ctx: openssl::sha::Sha256,
11
12
    #[cfg(not(feature = "openssl"))]
13
    ctx: sha2::Sha256,
14
}
15
16
impl Sha256 {
17
9.63k
    pub fn new() -> Self {
18
9.63k
        Self::default()
19
9.63k
    }
20
29.0k
    pub fn update(&mut self, buf: impl AsRef<[u8]>) {
21
29.0k
        self.ctx.update(buf.as_ref());
22
29.0k
    }
Unexecuted instantiation: _RINvMNtCs4RkbDk9WRL5_5clvmr4sha2NtB3_6Sha2566updateAhj1_EB5_
_RINvMNtCs4RkbDk9WRL5_5clvmr4sha2NtB3_6Sha2566updateNtNtB5_9allocator4AtomEB5_
Line
Count
Source
20
26.9k
    pub fn update(&mut self, buf: impl AsRef<[u8]>) {
21
26.9k
        self.ctx.update(buf.as_ref());
22
26.9k
    }
Unexecuted instantiation: _RINvMNtCs4RkbDk9WRL5_5clvmr4sha2NtB3_6Sha2566updateRAhj20_EB5_
Unexecuted instantiation: _RINvMNtCs4RkbDk9WRL5_5clvmr4sha2NtB3_6Sha2566updateRRShEB5_
_RINvMNtCs4RkbDk9WRL5_5clvmr4sha2NtB3_6Sha2566updateRShEB5_
Line
Count
Source
20
2.05k
    pub fn update(&mut self, buf: impl AsRef<[u8]>) {
21
2.05k
        self.ctx.update(buf.as_ref());
22
2.05k
    }
23
9.60k
    pub fn finalize(self) -> [u8; 32] {
24
9.60k
        #[cfg(feature = "openssl")]
25
9.60k
        {
26
9.60k
            self.ctx.finish()
27
9.60k
        }
28
9.60k
        #[cfg(not(feature = "openssl"))]
29
9.60k
        {
30
9.60k
            self.ctx.finalize().into()
31
9.60k
        }
32
9.60k
    }
33
}
34
35
#[test]
36
fn test_sha256() {
37
    // https://www.di-mgt.com.au/sha_testvectors.html
38
39
    let output = &[
40
        0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22,
41
        0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00,
42
        0x15, 0xad,
43
    ];
44
45
    let mut ctx = Sha256::new();
46
    ctx.update([0x61, 0x62, 0x63]);
47
    assert_eq!(&ctx.finalize().as_slice(), output);
48
49
    let mut ctx = Sha256::new();
50
    ctx.update([0x61]);
51
    ctx.update([0x62]);
52
    ctx.update([0x63]);
53
    assert_eq!(&ctx.finalize().as_slice(), output);
54
55
    let mut ctx = Sha256::new();
56
    ctx.update([0x61, 0x62]);
57
    ctx.update([0x63]);
58
    assert_eq!(&ctx.finalize().as_slice(), output);
59
60
    let mut ctx = Sha256::new();
61
    ctx.update([0x61]);
62
    ctx.update([0x62, 0x63]);
63
    assert_eq!(&ctx.finalize().as_slice(), output);
64
}
/home/oof/clvm_rs/src/traverse_path.rs
Line
Count
Source
1
use crate::allocator::{Allocator, NodePtr, SExp};
2
use crate::cost::Cost;
3
use crate::reduction::{EvalErr, Reduction, Response};
4
5
// lowered from measured 147 per bit. It doesn't seem to take this long in
6
// practice
7
const TRAVERSE_BASE_COST: Cost = 40;
8
const TRAVERSE_COST_PER_ZERO_BYTE: Cost = 4;
9
const TRAVERSE_COST_PER_BIT: Cost = 4;
10
11
// `run_program` has two stacks: the operand stack (of `Node` objects) and the
12
// operator stack (of Operation)
13
14
// return a bitmask with a single bit set, for the most significant set bit in
15
// the input byte
16
138
fn msb_mask(byte: u8) -> u8 {
17
138
    let mut byte = (byte | (byte >> 1)) as u32;
18
138
    byte |= byte >> 2;
19
138
    byte |= byte >> 4;
20
138
    debug_assert!((byte + 1) >> 1 <= 0x80);
21
138
    ((byte + 1) >> 1) as u8
22
138
}
23
24
// return the index of the first non-zero byte in buf. If all bytes are 0, the
25
// length (one past end) will be returned.
26
1.18k
const fn first_non_zero(buf: &[u8]) -> usize {
27
1.18k
    let mut c: usize = 0;
28
6.41k
    while c < buf.len() && buf[c] == 0 {
29
5.22k
        c += 1;
30
5.22k
    }
31
1.18k
    c
32
1.18k
}
33
34
1.18k
pub fn traverse_path(allocator: &Allocator, node_index: &[u8], args: NodePtr) -> Response {
35
1.18k
    let mut arg_list: NodePtr = args;
36
1.18k
37
1.18k
    // find first non-zero byte
38
1.18k
    let first_bit_byte_index = first_non_zero(node_index);
39
1.18k
40
1.18k
    let mut cost: Cost = TRAVERSE_BASE_COST
41
1.18k
        + (first_bit_byte_index as Cost) * TRAVERSE_COST_PER_ZERO_BYTE
42
1.18k
        + TRAVERSE_COST_PER_BIT;
43
1.18k
44
1.18k
    if first_bit_byte_index >= node_index.len() {
45
1.04k
        return Ok(Reduction(cost, allocator.nil()));
46
138
    }
47
138
48
138
    // find first non-zero bit (the most significant bit is a sentinel)
49
138
    let last_bitmask = msb_mask(node_index[first_bit_byte_index]);
50
138
51
138
    // follow through the bits, moving left and right
52
138
    let mut byte_idx = node_index.len() - 1;
53
138
    let mut bitmask = 0x01;
54
321
    while byte_idx > first_bit_byte_index || bitmask < last_bitmask {
55
289
        let is_bit_set: bool = (node_index[byte_idx] & bitmask) != 0;
56
289
        match allocator.sexp(arg_list) {
57
            SExp::Atom => {
58
106
                return Err(EvalErr(arg_list, "path into atom".into()));
59
            }
60
183
            SExp::Pair(left, right) => {
61
183
                arg_list = if is_bit_set { right } else { left };
62
            }
63
        }
64
183
        if bitmask == 0x80 {
65
14
            bitmask = 0x01;
66
14
            byte_idx -= 1;
67
169
        } else {
68
169
            bitmask <<= 1;
69
169
        }
70
183
        cost += TRAVERSE_COST_PER_BIT;
71
    }
72
32
    Ok(Reduction(cost, arg_list))
73
1.18k
}
74
75
// The cost calculation for this version of traverse_path assumes the node_index has the canonical
76
// integer representation (which is true for SmallAtom in the allocator). If there are any
77
// redundant leading zeros, the slow path must be used
78
18.3k
pub fn traverse_path_fast(allocator: &Allocator, mut node_index: u32, args: NodePtr) -> Response {
79
18.3k
    if node_index == 0 {
80
10.9k
        return Ok(Reduction(
81
10.9k
            TRAVERSE_BASE_COST + TRAVERSE_COST_PER_BIT,
82
10.9k
            allocator.nil(),
83
10.9k
        ));
84
7.49k
    }
85
7.49k
86
7.49k
    let mut arg_list: NodePtr = args;
87
7.49k
88
7.49k
    let mut cost: Cost = TRAVERSE_BASE_COST + TRAVERSE_COST_PER_BIT;
89
7.49k
    let mut num_bits = 0;
90
7.62k
    while node_index != 1 {
91
515
        let SExp::Pair(left, right) = allocator.sexp(arg_list) else {
92
384
            return Err(EvalErr(arg_list, "path into atom".into()));
93
        };
94
95
131
        let is_bit_set: bool = (node_index & 0x01) != 0;
96
131
        arg_list = if is_bit_set { right } else { left };
97
131
        node_index >>= 1;
98
131
        num_bits += 1
99
    }
100
101
7.11k
    cost += num_bits * TRAVERSE_COST_PER_BIT;
102
7.11k
    // since positive numbers sometimes need a leading zero, e.g. 0x80, 0x8000 etc. We also
103
7.11k
    // need to add the cost of that leading zero byte
104
7.11k
    if num_bits == 7 || num_bits == 15 || num_bits == 23 || num_bits == 31 {
105
6
        cost += TRAVERSE_COST_PER_ZERO_BYTE;
106
7.10k
    }
107
108
7.11k
    Ok(Reduction(cost, arg_list))
109
18.3k
}
110
111
#[test]
112
fn test_msb_mask() {
113
    assert_eq!(msb_mask(0x0), 0x0);
114
    assert_eq!(msb_mask(0x01), 0x01);
115
    assert_eq!(msb_mask(0x02), 0x02);
116
    assert_eq!(msb_mask(0x04), 0x04);
117
    assert_eq!(msb_mask(0x08), 0x08);
118
    assert_eq!(msb_mask(0x10), 0x10);
119
    assert_eq!(msb_mask(0x20), 0x20);
120
    assert_eq!(msb_mask(0x40), 0x40);
121
    assert_eq!(msb_mask(0x80), 0x80);
122
123
    assert_eq!(msb_mask(0x44), 0x40);
124
    assert_eq!(msb_mask(0x2a), 0x20);
125
    assert_eq!(msb_mask(0xff), 0x80);
126
    assert_eq!(msb_mask(0x0f), 0x08);
127
}
128
129
#[test]
130
fn test_first_non_zero() {
131
    assert_eq!(first_non_zero(&[]), 0);
132
    assert_eq!(first_non_zero(&[1]), 0);
133
    assert_eq!(first_non_zero(&[0]), 1);
134
    assert_eq!(first_non_zero(&[0, 0, 0, 1, 1, 1]), 3);
135
    assert_eq!(first_non_zero(&[0, 0, 0, 0, 0, 0]), 6);
136
    assert_eq!(first_non_zero(&[1, 0, 0, 0, 0, 0]), 0);
137
}
138
139
#[test]
140
fn test_traverse_path() {
141
    use crate::allocator::Allocator;
142
143
    let mut a = Allocator::new();
144
    let nul = a.nil();
145
    let n1 = a.new_atom(&[0, 1, 2]).unwrap();
146
    let n2 = a.new_atom(&[4, 5, 6]).unwrap();
147
148
    assert_eq!(traverse_path(&a, &[], n1).unwrap(), Reduction(44, nul));
149
    assert_eq!(traverse_path(&a, &[0b1], n1).unwrap(), Reduction(44, n1));
150
    assert_eq!(traverse_path(&a, &[0b1], n2).unwrap(), Reduction(44, n2));
151
152
    // cost for leading zeros
153
    assert_eq!(traverse_path(&a, &[0], n1).unwrap(), Reduction(48, nul));
154
    assert_eq!(traverse_path(&a, &[0, 0], n1).unwrap(), Reduction(52, nul));
155
    assert_eq!(
156
        traverse_path(&a, &[0, 0, 0], n1).unwrap(),
157
        Reduction(56, nul)
158
    );
159
    assert_eq!(
160
        traverse_path(&a, &[0, 0, 0, 0], n1).unwrap(),
161
        Reduction(60, nul)
162
    );
163
164
    let n3 = a.new_pair(n1, n2).unwrap();
165
    assert_eq!(traverse_path(&a, &[0b1], n3).unwrap(), Reduction(44, n3));
166
    assert_eq!(traverse_path(&a, &[0b10], n3).unwrap(), Reduction(48, n1));
167
    assert_eq!(traverse_path(&a, &[0b11], n3).unwrap(), Reduction(48, n2));
168
    assert_eq!(traverse_path(&a, &[0b11], n3).unwrap(), Reduction(48, n2));
169
170
    let list = a.new_pair(n1, nul).unwrap();
171
    let list = a.new_pair(n2, list).unwrap();
172
173
    assert_eq!(traverse_path(&a, &[0b10], list).unwrap(), Reduction(48, n2));
174
    assert_eq!(
175
        traverse_path(&a, &[0b101], list).unwrap(),
176
        Reduction(52, n1)
177
    );
178
    assert_eq!(
179
        traverse_path(&a, &[0b111], list).unwrap(),
180
        Reduction(52, nul)
181
    );
182
183
    // errors
184
    assert_eq!(
185
        traverse_path(&a, &[0b1011], list).unwrap_err(),
186
        EvalErr(nul, "path into atom".to_string())
187
    );
188
    assert_eq!(
189
        traverse_path(&a, &[0b1101], list).unwrap_err(),
190
        EvalErr(n1, "path into atom".to_string())
191
    );
192
    assert_eq!(
193
        traverse_path(&a, &[0b1001], list).unwrap_err(),
194
        EvalErr(n1, "path into atom".to_string())
195
    );
196
    assert_eq!(
197
        traverse_path(&a, &[0b1010], list).unwrap_err(),
198
        EvalErr(n2, "path into atom".to_string())
199
    );
200
    assert_eq!(
201
        traverse_path(&a, &[0b1110], list).unwrap_err(),
202
        EvalErr(n2, "path into atom".to_string())
203
    );
204
}
205
206
#[test]
207
fn test_traverse_path_fast_fast() {
208
    use crate::allocator::Allocator;
209
210
    let mut a = Allocator::new();
211
    let nul = a.nil();
212
    let n1 = a.new_atom(&[0, 1, 2]).unwrap();
213
    let n2 = a.new_atom(&[4, 5, 6]).unwrap();
214
215
    assert_eq!(traverse_path_fast(&a, 0, n1).unwrap(), Reduction(44, nul));
216
    assert_eq!(traverse_path_fast(&a, 0b1, n1).unwrap(), Reduction(44, n1));
217
    assert_eq!(traverse_path_fast(&a, 0b1, n2).unwrap(), Reduction(44, n2));
218
219
    let n3 = a.new_pair(n1, n2).unwrap();
220
    assert_eq!(traverse_path_fast(&a, 0b1, n3).unwrap(), Reduction(44, n3));
221
    assert_eq!(traverse_path_fast(&a, 0b10, n3).unwrap(), Reduction(48, n1));
222
    assert_eq!(traverse_path_fast(&a, 0b11, n3).unwrap(), Reduction(48, n2));
223
    assert_eq!(traverse_path_fast(&a, 0b11, n3).unwrap(), Reduction(48, n2));
224
225
    let list = a.new_pair(n1, nul).unwrap();
226
    let list = a.new_pair(n2, list).unwrap();
227
228
    assert_eq!(
229
        traverse_path_fast(&a, 0b10, list).unwrap(),
230
        Reduction(48, n2)
231
    );
232
    assert_eq!(
233
        traverse_path_fast(&a, 0b101, list).unwrap(),
234
        Reduction(52, n1)
235
    );
236
    assert_eq!(
237
        traverse_path_fast(&a, 0b111, list).unwrap(),
238
        Reduction(52, nul)
239
    );
240
241
    // errors
242
    assert_eq!(
243
        traverse_path_fast(&a, 0b1011, list).unwrap_err(),
244
        EvalErr(nul, "path into atom".to_string())
245
    );
246
    assert_eq!(
247
        traverse_path_fast(&a, 0b1101, list).unwrap_err(),
248
        EvalErr(n1, "path into atom".to_string())
249
    );
250
    assert_eq!(
251
        traverse_path_fast(&a, 0b1001, list).unwrap_err(),
252
        EvalErr(n1, "path into atom".to_string())
253
    );
254
    assert_eq!(
255
        traverse_path_fast(&a, 0b1010, list).unwrap_err(),
256
        EvalErr(n2, "path into atom".to_string())
257
    );
258
    assert_eq!(
259
        traverse_path_fast(&a, 0b1110, list).unwrap_err(),
260
        EvalErr(n2, "path into atom".to_string())
261
    );
262
}
/home/oof/libfuzzer/src/lib.rs
Line
Count
Source
1
//! Bindings to [libFuzzer](http://llvm.org/docs/LibFuzzer.html): a runtime for
2
//! coverage-guided fuzzing.
3
//!
4
//! See [the `cargo-fuzz`
5
//! guide](https://rust-fuzz.github.io/book/cargo-fuzz.html) for a usage
6
//! tutorial.
7
//!
8
//! The main export of this crate is [the `fuzz_target!`
9
//! macro](./macro.fuzz_target.html), which allows you to define targets for
10
//! libFuzzer to exercise.
11
12
#![deny(missing_docs, missing_debug_implementations)]
13
14
pub use arbitrary;
15
use std::sync::OnceLock;
16
17
/// Indicates whether the input should be kept in the corpus or rejected. This
18
/// should be returned by your fuzz target. If your fuzz target does not return
19
/// a value (i.e., returns `()`), then the input will be kept in the corpus.
20
#[derive(Debug)]
21
pub enum Corpus {
22
    /// Keep the input in the corpus.
23
    Keep,
24
25
    /// Reject the input and do not keep it in the corpus.
26
    Reject,
27
}
28
29
impl From<()> for Corpus {
30
0
    fn from(_: ()) -> Self {
31
0
        Self::Keep
32
0
    }
33
}
34
35
impl Corpus {
36
    #[doc(hidden)]
37
    /// Convert this Corpus result into the [integer codes used by
38
    /// `libFuzzer`](https://llvm.org/docs/LibFuzzer.html#rejecting-unwanted-inputs).
39
    /// This is -1 for reject, 0 for keep.
40
0
    pub fn to_libfuzzer_code(self) -> i32 {
41
0
        match self {
42
0
            Corpus::Keep => 0,
43
0
            Corpus::Reject => -1,
44
        }
45
0
    }
46
}
47
48
extern "C" {
49
    // We do not actually cross the FFI bound here.
50
    #[allow(improper_ctypes)]
51
    fn rust_fuzzer_test_input(input: &[u8]) -> i32;
52
53
    fn LLVMFuzzerMutate(data: *mut u8, size: usize, max_size: usize) -> usize;
54
}
55
56
/// Do not use; only for LibFuzzer's consumption.
57
#[doc(hidden)]
58
#[export_name = "LLVMFuzzerTestOneInput"]
59
27.3k
pub unsafe fn test_input_wrap(data: *const u8, size: usize) -> i32 {
60
27.3k
    let test_input = ::std::panic::catch_unwind(|| {
61
27.3k
        let data_slice = ::std::slice::from_raw_parts(data, size);
62
27.3k
        rust_fuzzer_test_input(data_slice)
63
27.3k
    });
64
27.3k
65
27.3k
    match test_input {
66
27.3k
        Ok(i) => i,
67
        Err(_) => {
68
            // hopefully the custom panic hook will be called before and abort the
69
            // process before the stack frames are unwinded.
70
0
            ::std::process::abort();
71
        }
72
    }
73
27.3k
}
74
75
#[doc(hidden)]
76
27.3k
pub fn rust_libfuzzer_debug_path() -> &'static Option<String> {
77
    static RUST_LIBFUZZER_DEBUG_PATH: OnceLock<Option<String>> = OnceLock::new();
78
27.3k
    RUST_LIBFUZZER_DEBUG_PATH.get_or_init(|| std::env::var("RUST_LIBFUZZER_DEBUG_PATH").ok())
79
27.3k
}
80
81
#[doc(hidden)]
82
#[export_name = "LLVMFuzzerInitialize"]
83
2
pub fn initialize(_argc: *const isize, _argv: *const *const *const u8) -> isize {
84
2
    // Registers a panic hook that aborts the process before unwinding.
85
2
    // It is useful to abort before unwinding so that the fuzzer will then be
86
2
    // able to analyse the process stack frames to tell different bugs appart.
87
2
    //
88
2
    // HACK / FIXME: it would be better to use `-C panic=abort` but it's currently
89
2
    // impossible to build code using compiler plugins with this flag.
90
2
    // We will be able to remove this code when
91
2
    // https://github.com/rust-lang/cargo/issues/5423 is fixed.
92
2
    let default_hook = ::std::panic::take_hook();
93
2
    ::std::panic::set_hook(Box::new(move |panic_info| {
94
0
        default_hook(panic_info);
95
0
        ::std::process::abort();
96
2
    }));
97
2
    0
98
2
}
99
100
/// Define a fuzz target.
101
///
102
/// ## Example
103
///
104
/// This example takes a `&[u8]` slice and attempts to parse it. The parsing
105
/// might fail and return an `Err`, but it shouldn't ever panic or segfault.
106
///
107
/// ```no_run
108
/// #![no_main]
109
///
110
/// use libfuzzer_sys::fuzz_target;
111
///
112
/// // Note: `|input|` is short for `|input: &[u8]|`.
113
/// fuzz_target!(|input| {
114
///     let _result: Result<_, _> = my_crate::parse(input);
115
/// });
116
/// # mod my_crate { pub fn parse(_: &[u8]) -> Result<(), ()> { unimplemented!() } }
117
/// ```
118
///
119
/// ## Rejecting Inputs
120
///
121
/// It may be desirable to reject some inputs, i.e. to not add them to the
122
/// corpus.
123
///
124
/// For example, when fuzzing an API consisting of parsing and other logic,
125
/// one may want to allow only those inputs into the corpus that parse
126
/// successfully. To indicate whether an input should be kept in or rejected
127
/// from the corpus, return either [Corpus::Keep] or [Corpus::Reject] from your
128
/// fuzz target. The default behavior (e.g. if `()` is returned) is to keep the
129
/// input in the corpus.
130
///
131
/// For example:
132
///
133
/// ```no_run
134
/// #![no_main]
135
///
136
/// use libfuzzer_sys::{Corpus, fuzz_target};
137
///
138
/// fuzz_target!(|input: String| -> Corpus {
139
///     let parts: Vec<&str> = input.splitn(2, '=').collect();
140
///     if parts.len() != 2 {
141
///         return Corpus::Reject;
142
///     }
143
///
144
///     let key = parts[0];
145
///     let value = parts[1];
146
///     let _result: Result<_, _> = my_crate::parse(key, value);
147
///     Corpus::Keep
148
/// });
149
/// # mod my_crate { pub fn parse(_key: &str, _value: &str) -> Result<(), ()> { unimplemented!() } }
150
/// ```
151
///
152
/// ## Arbitrary Input Types
153
///
154
/// The input is a `&[u8]` slice by default, but you can take arbitrary input
155
/// types, as long as the type implements [the `arbitrary` crate's `Arbitrary`
156
/// trait](https://docs.rs/arbitrary/*/arbitrary/trait.Arbitrary.html) (which is
157
/// also re-exported as `libfuzzer_sys::arbitrary::Arbitrary` for convenience).
158
///
159
/// For example, if you wanted to take an arbitrary RGB color, you could do the
160
/// following:
161
///
162
/// ```no_run
163
/// #![no_main]
164
/// # mod foo {
165
///
166
/// use libfuzzer_sys::{arbitrary::{Arbitrary, Error, Unstructured}, fuzz_target};
167
///
168
/// #[derive(Debug)]
169
/// pub struct Rgb {
170
///     r: u8,
171
///     g: u8,
172
///     b: u8,
173
/// }
174
///
175
/// impl<'a> Arbitrary<'a> for Rgb {
176
///     fn arbitrary(raw: &mut Unstructured<'a>) -> Result<Self, Error> {
177
///         let mut buf = [0; 3];
178
///         raw.fill_buffer(&mut buf)?;
179
///         let r = buf[0];
180
///         let g = buf[1];
181
///         let b = buf[2];
182
///         Ok(Rgb { r, g, b })
183
///     }
184
/// }
185
///
186
/// // Write a fuzz target that works with RGB colors instead of raw bytes.
187
/// fuzz_target!(|color: Rgb| {
188
///     my_crate::convert_color(color);
189
/// });
190
/// # mod my_crate {
191
/// #     use super::Rgb;
192
/// #     pub fn convert_color(_: Rgb) {}
193
/// # }
194
/// # }
195
/// ```
196
///
197
/// You can also enable the `arbitrary` crate's custom derive via this crate's
198
/// `"arbitrary-derive"` cargo feature.
199
#[macro_export]
200
macro_rules! fuzz_target {
201
    (|$bytes:ident| $body:expr) => {
202
        const _: () = {
203
            /// Auto-generated function
204
            #[no_mangle]
205
27.3k
            pub extern "C" fn rust_fuzzer_test_input(bytes: &[u8]) -> i32 {
206
                // When `RUST_LIBFUZZER_DEBUG_PATH` is set, write the debug
207
                // formatting of the input to that file. This is only intended for
208
                // `cargo fuzz`'s use!
209
210
                // `RUST_LIBFUZZER_DEBUG_PATH` is set in initialization.
211
27.3k
                if let Some(path) = $crate::rust_libfuzzer_debug_path() {
212
                    use std::io::Write;
213
0
                    let mut file = std::fs::File::create(path)
214
0
                        .expect("failed to create `RUST_LIBFUZZER_DEBUG_PATH` file");
215
0
                    writeln!(&mut file, "{:?}", bytes)
216
0
                        .expect("failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file");
217
0
                    return 0;
218
27.3k
                }
219
27.3k
220
27.3k
                __libfuzzer_sys_run(bytes);
221
27.3k
                0
222
27.3k
            }
223
27.3k
224
27.3k
            // Split out the actual fuzzer into a separate function which is
225
27.3k
            // tagged as never being inlined. This ensures that if the fuzzer
226
27.3k
            // panics there's at least one stack frame which is named uniquely
227
27.3k
            // according to this specific fuzzer that this is embedded within.
228
27.3k
            //
229
27.3k
            // Systems like oss-fuzz try to deduplicate crashes and without this
230
27.3k
            // panics in separate fuzzers can accidentally appear the same
231
27.3k
            // because each fuzzer will have a function called
232
27.3k
            // `rust_fuzzer_test_input`. By using a normal Rust function here
233
27.3k
            // it's named something like `the_fuzzer_name::_::__libfuzzer_sys_run` which should
234
27.3k
            // ideally help prevent oss-fuzz from deduplicate fuzz bugs across
235
27.3k
            // distinct targets accidentally.
236
27.3k
            #[inline(never)]
237
27.3k
            fn __libfuzzer_sys_run($bytes: &[u8]) {
238
                $body
239
27.3k
            }
240
27.3k
        };
241
27.3k
    };
242
27.3k
243
27.3k
    (|$data:ident: &[u8]| $body:expr) => {
244
27.3k
        $crate::fuzz_target!(|$data| $body);
245
27.3k
    };
246
27.3k
247
27.3k
    (|$data:ident: $dty:ty| $body:expr) => {
248
27.3k
        $crate::fuzz_target!(|$data: $dty| -> () { $body });
249
27.3k
    };
250
27.3k
251
27.3k
    (|$data:ident: $dty:ty| -> $rty:ty $body:block) => {
252
27.3k
        const _: () = {
253
27.3k
            /// Auto-generated function
254
27.3k
            #[no_mangle]
255
27.3k
            pub extern "C" fn rust_fuzzer_test_input(bytes: &[u8]) -> i32 {
256
27.3k
                use $crate::arbitrary::{Arbitrary, Unstructured};
257
27.3k
258
27.3k
                // Early exit if we don't have enough bytes for the `Arbitrary`
259
27.3k
                // implementation. This helps the fuzzer avoid exploring all the
260
27.3k
                // different not-enough-input-bytes paths inside the `Arbitrary`
261
27.3k
                // implementation. Additionally, it exits faster, letting the fuzzer
262
27.3k
                // get to longer inputs that actually lead to interesting executions
263
27.3k
                // quicker.
264
27.3k
                if bytes.len() < <$dty as Arbitrary>::size_hint(0).0 {
265
27.3k
                    return -1;
266
27.3k
                }
267
27.3k
268
27.3k
                let mut u = Unstructured::new(bytes);
269
27.3k
                let data = <$dty as Arbitrary>::arbitrary_take_rest(u);
270
27.3k
271
27.3k
                // When `RUST_LIBFUZZER_DEBUG_PATH` is set, write the debug
272
27.3k
                // formatting of the input to that file. This is only intended for
273
27.3k
                // `cargo fuzz`'s use!
274
27.3k
275
27.3k
                // `RUST_LIBFUZZER_DEBUG_PATH` is set in initialization.
276
27.3k
                if let Some(path) = $crate::rust_libfuzzer_debug_path() {
277
27.3k
                    use std::io::Write;
278
27.3k
                    let mut file = std::fs::File::create(path)
279
27.3k
                        .expect("failed to create `RUST_LIBFUZZER_DEBUG_PATH` file");
280
27.3k
                    (match data {
281
27.3k
                        Ok(data) => writeln!(&mut file, "{:#?}", data),
282
27.3k
                        Err(err) => writeln!(&mut file, "Arbitrary Error: {}", err),
283
27.3k
                    })
284
27.3k
                    .expect("failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file");
285
27.3k
                    return -1;
286
27.3k
                }
287
27.3k
288
27.3k
                let data = match data {
289
27.3k
                    Ok(d) => d,
290
27.3k
                    Err(_) => return -1,
291
27.3k
                };
292
27.3k
293
27.3k
                let result = ::libfuzzer_sys::Corpus::from(__libfuzzer_sys_run(data));
294
27.3k
                result.to_libfuzzer_code()
295
27.3k
            }
296
27.3k
297
27.3k
            // See above for why this is split to a separate function.
298
27.3k
            #[inline(never)]
299
27.3k
            fn __libfuzzer_sys_run($data: $dty) -> $rty {
300
27.3k
                $body
301
27.3k
            }
302
27.3k
        };
303
27.3k
    };
304
27.3k
}
305
27.3k
306
27.3k
/// Define a custom mutator.
307
27.3k
///
308
27.3k
/// This is optional, and libFuzzer will use its own, default mutation strategy
309
27.3k
/// if this is not provided.
310
27.3k
///
311
27.3k
/// You might consider using a custom mutator when your fuzz target is very
312
27.3k
/// particular about the shape of its input:
313
27.3k
///
314
27.3k
/// * You want to fuzz "deeper" than just the parser.
315
27.3k
/// * The input contains checksums that have to match the hash of some subset of
316
27.3k
///   the data or else the whole thing is invalid, and therefore mutating any of
317
27.3k
///   that subset means you need to recompute the checksums.
318
27.3k
/// * Small random changes to the input buffer make it invalid.
319
27.3k
///
320
27.3k
/// That is, a custom mutator is useful in similar situations where [a `T:
321
27.3k
/// Arbitrary` input type](macro.fuzz_target.html#arbitrary-input-types) is
322
27.3k
/// useful. Note that the two approaches are not mutually exclusive; you can use
323
27.3k
/// whichever is easier for your problem domain or both!
324
27.3k
///
325
27.3k
/// ## Implementation Contract
326
27.3k
///
327
27.3k
/// The original, unmodified input is given in `data[..size]`.
328
27.3k
///
329
27.3k
/// You must modify the data in place and return the new size.
330
27.3k
///
331
27.3k
/// The new size should not be greater than `max_size`. If this is not the case,
332
27.3k
/// then the `data` will be truncated to fit within `max_size`. Note that
333
27.3k
/// `max_size < size` is possible when shrinking test cases.
334
27.3k
///
335
27.3k
/// You must produce the same mutation given the same `seed`. Generally, when
336
27.3k
/// choosing what kind of mutation to make or where to mutate, you should start
337
27.3k
/// by creating a random number generator (RNG) that is seeded with the given
338
27.3k
/// `seed` and then consult the RNG whenever making a decision:
339
27.3k
///
340
27.3k
/// ```no_run
341
27.3k
/// #![no_main]
342
27.3k
///
343
27.3k
/// use rand::{rngs::StdRng, Rng, SeedableRng};
344
27.3k
///
345
27.3k
/// libfuzzer_sys::fuzz_mutator!(|data: &mut [u8], size: usize, max_size: usize, seed: u32| {
346
27.3k
///     let mut rng = StdRng::seed_from_u64(seed as u64);
347
27.3k
///
348
27.3k
/// #   let first_mutation = |_, _, _, _| todo!();
349
27.3k
/// #   let second_mutation = |_, _, _, _| todo!();
350
27.3k
/// #   let third_mutation = |_, _, _, _| todo!();
351
27.3k
/// #   let fourth_mutation = |_, _, _, _| todo!();
352
27.3k
///     // Choose which of our four supported kinds of mutations we want to make.
353
27.3k
///     match rng.gen_range(0..4) {
354
27.3k
///         0 => first_mutation(rng, data, size, max_size),
355
27.3k
///         1 => second_mutation(rng, data, size, max_size),
356
27.3k
///         2 => third_mutation(rng, data, size, max_size),
357
27.3k
///         3 => fourth_mutation(rng, data, size, max_size),
358
27.3k
///         _ => unreachable!()
359
27.3k
///     }
360
27.3k
/// });
361
27.3k
/// ```
362
27.3k
///
363
27.3k
/// ## Example: Compression
364
27.3k
///
365
27.3k
/// Consider a simple fuzz target that takes compressed data as input,
366
27.3k
/// decompresses it, and then asserts that the decompressed data doesn't begin
367
27.3k
/// with "boom". It is difficult for `libFuzzer` (or any other fuzzer) to crash
368
27.3k
/// this fuzz target because nearly all mutations it makes will invalidate the
369
27.3k
/// compression format. Therefore, we use a custom mutator that decompresses the
370
27.3k
/// raw input, mutates the decompressed data, and then recompresses it. This
371
27.3k
/// allows `libFuzzer` to quickly discover crashing inputs.
372
27.3k
///
373
27.3k
/// ```no_run
374
27.3k
/// #![no_main]
375
27.3k
///
376
27.3k
/// use flate2::{read::GzDecoder, write::GzEncoder, Compression};
377
27.3k
/// use libfuzzer_sys::{fuzz_mutator, fuzz_target};
378
27.3k
/// use std::io::{Read, Write};
379
27.3k
///
380
27.3k
/// fuzz_target!(|data: &[u8]| {
381
27.3k
///     // Decompress the input data and crash if it starts with "boom".
382
27.3k
///     if let Some(data) = decompress(data) {
383
27.3k
///         if data.starts_with(b"boom") {
384
27.3k
///             panic!();
385
27.3k
///         }
386
27.3k
///     }
387
27.3k
/// });
388
27.3k
///
389
27.3k
/// fuzz_mutator!(
390
27.3k
///     |data: &mut [u8], size: usize, max_size: usize, _seed: u32| {
391
27.3k
///         // Decompress the input data. If that fails, use a dummy value.
392
27.3k
///         let mut decompressed = decompress(&data[..size]).unwrap_or_else(|| b"hi".to_vec());
393
27.3k
///
394
27.3k
///         // Mutate the decompressed data with `libFuzzer`'s default mutator. Make
395
27.3k
///         // the `decompressed` vec's extra capacity available for insertion
396
27.3k
///         // mutations via `resize`.
397
27.3k
///         let len = decompressed.len();
398
27.3k
///         let cap = decompressed.capacity();
399
27.3k
///         decompressed.resize(cap, 0);
400
27.3k
///         let new_decompressed_size = libfuzzer_sys::fuzzer_mutate(&mut decompressed, len, cap);
401
27.3k
///
402
27.3k
///         // Recompress the mutated data.
403
27.3k
///         let compressed = compress(&decompressed[..new_decompressed_size]);
404
27.3k
///
405
27.3k
///         // Copy the recompressed mutated data into `data` and return the new size.
406
27.3k
///         let new_size = std::cmp::min(max_size, compressed.len());
407
27.3k
///         data[..new_size].copy_from_slice(&compressed[..new_size]);
408
27.3k
///         new_size
409
27.3k
///     }
410
27.3k
/// );
411
27.3k
///
412
27.3k
/// fn decompress(compressed_data: &[u8]) -> Option<Vec<u8>> {
413
27.3k
///     let mut decoder = GzDecoder::new(compressed_data);
414
27.3k
///     let mut decompressed = Vec::new();
415
27.3k
///     if decoder.read_to_end(&mut decompressed).is_ok() {
416
27.3k
///         Some(decompressed)
417
27.3k
///     } else {
418
27.3k
///         None
419
27.3k
///     }
420
27.3k
/// }
421
27.3k
///
422
27.3k
/// fn compress(data: &[u8]) -> Vec<u8> {
423
27.3k
///     let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
424
27.3k
///     encoder
425
27.3k
///         .write_all(data)
426
27.3k
///         .expect("writing into a vec is infallible");
427
27.3k
///     encoder.finish().expect("writing into a vec is infallible")
428
27.3k
/// }
429
27.3k
/// ```
430
27.3k
///
431
27.3k
/// This example is inspired by [a similar example from the official `libFuzzer`
432
27.3k
/// docs](https://github.com/google/fuzzing/blob/master/docs/structure-aware-fuzzing.md#example-compression).
433
27.3k
///
434
27.3k
/// ## More Example Ideas
435
27.3k
///
436
27.3k
/// * A PNG custom mutator that decodes a PNG, mutates the image, and then
437
27.3k
/// re-encodes the mutated image as a new PNG.
438
27.3k
///
439
27.3k
/// * A [`serde`](https://serde.rs/) custom mutator that deserializes your
440
27.3k
///   structure, mutates it, and then reserializes it.
441
27.3k
///
442
27.3k
/// * A Wasm binary custom mutator that inserts, replaces, and removes a
443
27.3k
///   bytecode instruction in a function's body.
444
27.3k
///
445
27.3k
/// * An HTTP request custom mutator that inserts, replaces, and removes a
446
27.3k
///   header from an HTTP request.
447
27.3k
#[macro_export]
448
27.3k
macro_rules! fuzz_mutator {
449
27.3k
    (
450
27.3k
        |
451
27.3k
        $data:ident : &mut [u8] ,
452
27.3k
        $size:ident : usize ,
453
27.3k
        $max_size:ident : usize ,
454
27.3k
        $seed:ident : u32 $(,)*
455
27.3k
        |
456
27.3k
        $body:block
457
27.3k
    ) => {
458
27.3k
        /// Auto-generated function. Do not use; only for LibFuzzer's
459
27.3k
        /// consumption.
460
27.3k
        #[export_name = "LLVMFuzzerCustomMutator"]
461
27.3k
        #[doc(hidden)]
462
27.3k
        pub unsafe fn rust_fuzzer_custom_mutator(
463
27.3k
            $data: *mut u8,
464
27.3k
            $size: usize,
465
27.3k
            $max_size: usize,
466
27.3k
            $seed: std::os::raw::c_uint,
467
27.3k
        ) -> usize {
468
27.3k
            // Depending on if we are growing or shrinking the test case, `size`
469
27.3k
            // might be larger or smaller than `max_size`. The `data`'s capacity
470
27.3k
            // is the maximum of the two.
471
27.3k
            let len = std::cmp::max($max_size, $size);
472
27.3k
            let $data: &mut [u8] = std::slice::from_raw_parts_mut($data, len);
473
27.3k
474
27.3k
            // `unsigned int` is generally a `u32`, but not on all targets. Do
475
27.3k
            // an infallible (and potentially lossy, but that's okay because it
476
27.3k
            // preserves determinism) conversion.
477
27.3k
            let $seed = $seed as u32;
478
27.3k
479
27.3k
            // Define and invoke a new, safe function so that the body doesn't
480
27.3k
            // inherit `unsafe`.
481
27.3k
            fn custom_mutator(
482
27.3k
                $data: &mut [u8],
483
27.3k
                $size: usize,
484
27.3k
                $max_size: usize,
485
27.3k
                $seed: u32,
486
27.3k
            ) -> usize {
487
27.3k
                $body
488
27.3k
            }
489
27.3k
            let new_size = custom_mutator($data, $size, $max_size, $seed);
490
27.3k
491
27.3k
            // Truncate the new size if it is larger than the max.
492
27.3k
            std::cmp::min(new_size, $max_size)
493
27.3k
        }
494
27.3k
    };
495
27.3k
}
496
27.3k
497
27.3k
/// The default `libFuzzer` mutator.
498
27.3k
///
499
27.3k
/// You generally don't have to use this at all unless you're defining a
500
27.3k
/// custom mutator with [the `fuzz_mutator!` macro][crate::fuzz_mutator].
501
27.3k
///
502
27.3k
/// Mutates `data[..size]` in place such that the mutated data is no larger than
503
27.3k
/// `max_size` and returns the new size of the mutated data.
504
27.3k
///
505
27.3k
/// To only allow shrinking mutations, make `max_size < size`.
506
27.3k
///
507
27.3k
/// To additionally allow mutations that grow the size of the data, make
508
27.3k
/// `max_size > size`.
509
27.3k
///
510
27.3k
/// Both `size` and `max_size` must be less than or equal to `data.len()`.
511
27.3k
///
512
27.3k
/// # Example
513
27.3k
///
514
27.3k
/// ```no_run
515
27.3k
/// // Create some data in a buffer.
516
27.3k
/// let mut data = vec![0; 128];
517
27.3k
/// data[..b"hello".len()].copy_from_slice(b"hello");
518
27.3k
///
519
27.3k
/// // Ask `libFuzzer` to mutate the data. By setting `max_size` to our buffer's
520
27.3k
/// // full length, we are allowing `libFuzzer` to perform mutations that grow
521
27.3k
/// // the size of the data, such as insertions.
522
27.3k
/// let size = b"hello".len();
523
27.3k
/// let max_size = data.len();
524
27.3k
/// let new_size = libfuzzer_sys::fuzzer_mutate(&mut data, size, max_size);
525
27.3k
///
526
27.3k
/// // Get the mutated data out of the buffer.
527
27.3k
/// let mutated_data = &data[..new_size];
528
27.3k
/// ```
529
27.3k
pub fn fuzzer_mutate(data: &mut [u8], size: usize, max_size: usize) -> usize {
530
0
    assert!(size <= data.len());
531
0
    assert!(max_size <= data.len());
532
0
    let new_size = unsafe { LLVMFuzzerMutate(data.as_mut_ptr(), size, max_size) };
533
0
    assert!(new_size <= data.len());
534
0
    new_size
535
0
}
536
537
/// Define a custom cross-over function to combine test cases.
538
///
539
/// This is optional, and libFuzzer will use its own, default cross-over strategy
540
/// if this is not provided. (As of the time of writing, this default strategy
541
/// takes alternating byte sequences from the two test cases, to construct the
542
/// new one) (see `FuzzerCrossOver.cpp`)
543
///
544
/// This could potentially be useful if your input is, for instance, a
545
/// sequence of fixed sized, multi-byte values and the crossover could then
546
/// merge discrete values rather than joining parts of a value.
547
///
548
/// ## Implementation Contract
549
///
550
/// The original, read-only inputs are given in the full slices of `data1`, and
551
/// `data2` (as opposed to the, potentially, partial slice of `data` in
552
/// [the `fuzz_mutator!` macro][crate::fuzz_mutator]).
553
///
554
/// You must place the new input merged from the two existing inputs' data
555
/// into `out` and return the size of the relevant data written to that slice.
556
///
557
/// The deterministic requirements from [the `fuzz_mutator!` macro][crate::fuzz_mutator]
558
/// apply as well to the `seed` parameter
559
///
560
/// ## Example: Floating-Point Sum NaN
561
///
562
/// ```no_run
563
/// #![no_main]
564
///
565
/// use libfuzzer_sys::{fuzz_crossover, fuzz_mutator, fuzz_target, fuzzer_mutate};
566
/// use rand::{rngs::StdRng, Rng, SeedableRng};
567
/// use std::mem::size_of;
568
///
569
/// fuzz_target!(|data: &[u8]| {
570
///     let (_, floats, _) = unsafe { data.align_to::<f64>() };
571
///
572
///     let res = floats
573
///         .iter()
574
///         .fold(0.0, |a, b| if b.is_nan() { a } else { a + b });
575
///
576
///     assert!(
577
///         !res.is_nan(),
578
///         "The sum of the following floats resulted in a NaN: {floats:?}"
579
///     );
580
/// });
581
///
582
/// // Inject some ...potentially problematic values to make the example close
583
/// // more quickly.
584
/// fuzz_mutator!(|data: &mut [u8], size: usize, max_size: usize, seed: u32| {
585
///     let mut gen = StdRng::seed_from_u64(seed.into());
586
///
587
///     let (_, floats, _) = unsafe { data[..size].align_to_mut::<f64>() };
588
///
589
///     let x = gen.gen_range(0..=1000);
590
///     if x == 0 && !floats.is_empty() {
591
///         floats[0] = f64::INFINITY;
592
///     } else if x == 1000 && floats.len() > 1 {
593
///         floats[1] = f64::NEG_INFINITY;
594
///     } else {
595
///         return fuzzer_mutate(data, size, max_size);
596
///     }
597
///
598
///     size
599
/// });
600
///
601
/// fuzz_crossover!(|data1: &[u8], data2: &[u8], out: &mut [u8], _seed: u32| {
602
///     // Decode each source to see how many floats we can pull with proper
603
///     // alignment, and destination as to how many will fit with proper alignment
604
///     //
605
///     // Keep track of the unaligned prefix to `out`, as we will need to remember
606
///     // that those bytes will remain prepended to the actual floats that we
607
///     // write into the out buffer.
608
///     let (out_pref, out_floats, _) = unsafe { out.align_to_mut::<f64>() };
609
///     let (_, d1_floats, _) = unsafe { data1.align_to::<f64>() };
610
///     let (_, d2_floats, _) = unsafe { data2.align_to::<f64>() };
611
///
612
///     // Put into the destination, floats first from data1 then from data2, ...if
613
///     // possible given the size of `out`
614
///     let mut i: usize = 0;
615
///     for float in d1_floats.iter().chain(d2_floats).take(out_floats.len()) {
616
///         out_floats[i] = *float;
617
///         i += 1;
618
///     }
619
///
620
///     // Now that we have written the true floats, report back to the fuzzing
621
///     // engine that we left the unaligned `out` prefix bytes at the beginning of
622
///     // `out` and also then the floats that we wrote into the aligned float
623
///     // section.
624
///     out_pref.len() * size_of::<u8>() + i * size_of::<f64>()
625
/// });
626
/// ```
627
///
628
/// This example is a minimized version of [Erik Rigtorp's floating point summation fuzzing example][1].
629
/// A more detailed version of this experiment can be found in the
630
/// `example_crossover` directory.
631
///
632
/// [1]: https://rigtorp.se/fuzzing-floating-point-code/
633
#[macro_export]
634
macro_rules! fuzz_crossover {
635
    (
636
        |
637
        $data1:ident : &[u8] ,
638
        $data2:ident : &[u8] ,
639
        $out:ident : &mut [u8] ,
640
        $seed:ident : u32 $(,)*
641
        |
642
        $body:block
643
    ) => {
644
        /// Auto-generated function. Do not use; only for LibFuzzer's
645
        /// consumption.
646
        #[export_name = "LLVMFuzzerCustomCrossOver"]
647
        #[doc(hidden)]
648
        pub unsafe fn rust_fuzzer_custom_crossover(
649
            $data1: *const u8,
650
            size1: usize,
651
            $data2: *const u8,
652
            size2: usize,
653
            $out: *mut u8,
654
            max_out_size: usize,
655
            $seed: std::os::raw::c_uint,
656
        ) -> usize {
657
            let $data1: &[u8] = std::slice::from_raw_parts($data1, size1);
658
            let $data2: &[u8] = std::slice::from_raw_parts($data2, size2);
659
            let $out: &mut [u8] = std::slice::from_raw_parts_mut($out, max_out_size);
660
661
            // `unsigned int` is generally a `u32`, but not on all targets. Do
662
            // an infallible (and potentially lossy, but that's okay because it
663
            // preserves determinism) conversion.
664
            let $seed = $seed as u32;
665
666
            // Define and invoke a new, safe function so that the body doesn't
667
            // inherit `unsafe`.
668
            fn custom_crossover(
669
                $data1: &[u8],
670
                $data2: &[u8],
671
                $out: &mut [u8],
672
                $seed: u32,
673
            ) -> usize {
674
                $body
675
            }
676
677
            custom_crossover($data1, $data2, $out, $seed)
678
        }
679
    };
680
}